diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php
index 7dc88a6939a..a88524ec5d4 100644
--- a/htdocs/accountancy/customer/index.php
+++ b/htdocs/accountancy/customer/index.php
@@ -520,16 +520,23 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange
print '
'.$langs->trans('MonthShort'.str_pad($j, 2, '0', STR_PAD_LEFT)).' | ';
}
print ''.$langs->trans("Total").' | ';
-
$sql = "SELECT '".$db->escape($langs->trans("Vide"))."' AS marge,";
for ($i = 1; $i <= 12; $i++) {
$j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1;
if ($j > 12) {
$j -= 12;
}
- $sql .= " SUM(".$db->ifsql('MONTH(f.datef)='.$j, '(fd.total_ht-(fd.qty * fd.buy_price_ht))', '0').") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).",";
+ $sql .= '
+ SUM('.$db->ifsql('MONTH(f.datef)='.$j,
+ ' ('.
+ $db->ifsql('fd.total_ht < 0',
+ ' (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100))))',
+ ' (fd.total_ht - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100)))'
+ ).')',
+ 0).') AS month'.str_pad($j, 2, '0', STR_PAD_LEFT).',';
}
$sql .= " SUM((fd.total_ht-(fd.qty * fd.buy_price_ht))) as total";
+
$sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = fd.fk_facture";
$sql .= " WHERE f.datef >= '".$db->idate($search_date_start)."'";
@@ -546,7 +553,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange
} else {
$sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_DEPOSIT.", ".Facture::TYPE_SITUATION.")";
}
-
dol_syslog('htdocs/accountancy/customer/index.php');
$resql = $db->query($sql);
if ($resql) {
diff --git a/htdocs/compta/bank/info.php b/htdocs/compta/bank/info.php
index c61f6e50bff..8be615c4827 100644
--- a/htdocs/compta/bank/info.php
+++ b/htdocs/compta/bank/info.php
@@ -34,10 +34,12 @@ $ref = GETPOST('ref', 'alpha');
// Security check
$fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref : ''));
+
$fieldtype = (!empty($ref) ? 'ref' : 'rowid');
if ($user->socid) {
$socid = $user->socid;
}
+
$result = restrictedArea($user, 'banque', $fieldvalue, 'bank_account', '', '', $fieldtype);
if (!$user->rights->banque->lire && !$user->rights->banque->consolidate) {
accessforbidden();
diff --git a/htdocs/compta/bank/line.php b/htdocs/compta/bank/line.php
index 05aed6a215e..f75a8240e00 100644
--- a/htdocs/compta/bank/line.php
+++ b/htdocs/compta/bank/line.php
@@ -51,7 +51,7 @@ if (!empty($conf->salaries->enabled)) {
}
-$id = (GETPOST('id', 'int') ? GETPOST('id', 'int') : GETPOST('account', 'int'));
+$id = (GETPOST('rowid', 'int') ? GETPOST('rowid', 'int') : GETPOST('account', 'int'));
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
@@ -66,6 +66,7 @@ $fieldtype = (!empty($ref) ? 'ref' : 'rowid');
if ($user->socid) {
$socid = $user->socid;
}
+
$result = restrictedArea($user, 'banque', $fieldvalue, 'bank_account', '', '', $fieldtype);
if (!$user->rights->banque->lire && !$user->rights->banque->consolidate) {
accessforbidden();
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index da77b75d9a6..1ca81169cfb 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -970,10 +970,13 @@ if (empty($reshook)) {
$object->fetch($id);
if ($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0) {
$paiement = new Paiement($db);
- $result = $paiement->fetch(GETPOST('paiement_id'));
+ $result = $paiement->fetch(GETPOST('paiement_id', 'int'));
if ($result > 0) {
$result = $paiement->delete(); // If fetch ok and found
- header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
+ if ($result >= 0) {
+ header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
+ exit;
+ }
}
if ($result < 0) {
setEventMessages($paiement->error, $paiement->errors, 'errors');
@@ -3857,7 +3860,6 @@ if ($action == 'create') {
// For example print 239.2 - 229.3 - 9.9; does not return 0.
// $resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT);
// $resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
-
$resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT');
// Multicurrency
@@ -3866,7 +3868,10 @@ if ($action == 'create') {
$multicurrency_totalcreditnotes = $object->getSumCreditNotesUsed(1);
$multicurrency_totaldeposits = $object->getSumDepositsUsed(1);
$multicurrency_resteapayer = price2num($object->multicurrency_total_ttc - $multicurrency_totalpaye - $multicurrency_totalcreditnotes - $multicurrency_totaldeposits, 'MT');
- $resteapayer = price2num($multicurrency_resteapayer / $object->multicurrency_tx, 'MT');
+ // Code to fix case of corrupted data
+ if ($resteapayer == 0 && $multicurrency_resteapayer != 0) {
+ $resteapayer = price2num($multicurrency_resteapayer / $object->multicurrency_tx, 'MT');
+ }
}
if ($object->paye) {
@@ -5297,7 +5302,7 @@ if ($action == 'create') {
$discount = new DiscountAbsolute($db);
$result = $discount->fetch(0, $object->id);
- // Reopen a standard paid invoice
+ // Reopen an invoice
if ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT)
|| ($object->type == Facture::TYPE_CREDIT_NOTE && empty($discount->id))
|| ($object->type == Facture::TYPE_DEPOSIT && empty($discount->id))
@@ -5362,14 +5367,18 @@ if ($action == 'create') {
if ($objectidnext) {
print ''.$langs->trans('DoPayment').'';
} else {
- //if ($resteapayer == 0) { // Sometimes we can receive more, so we accept to enter more and will offer a button to convert into discount (but it is not a credit note, just a prepayment done)
- // print '' . $langs->trans('DoPayment') . '
';
- //} else {
+ if ($object->type == Facture::TYPE_DEPOSIT && $resteapayer == 0) {
+ // For down payment, we refuse to receive more than amount to pay.
+ print ''.$langs->trans('DoPayment').'';
+ } else {
+ // Sometimes we can receive more, so we accept to enter more and will offer a button to convert into discount (but it is not a credit note, just a prepayment done)
print ''.$langs->trans('DoPayment').'';
- //}
+ }
}
}
+ $sumofpayment = $object->getSommePaiement();
+
// Reverse back money or convert to reduction
if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) {
// For credit note only
@@ -5387,21 +5396,31 @@ if ($action == 'create') {
}
// For credit note
if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercancreate
- && (!empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0)
+ && (!empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $sumofpayment == 0)
) {
print 'id.'&action=converttoreduc" title="'.dol_escape_htmltag($langs->trans("ConfirmConvertToReduc2")).'">'.$langs->trans('ConvertToReduc').'';
}
// For deposit invoice
if ($object->type == Facture::TYPE_DEPOSIT && $usercancreate && $object->statut > 0 && empty($discount->id)) {
- print 'id.'&action=converttoreduc">'.$langs->trans('ConvertToReduc').'';
+ if (price2num($object->total_ttc, 'MT') == price2num($sumofpayment, 'MT')) {
+ // We can close a down payment only if paid amount is same than amount of down payment (by definition)
+ print 'id.'&action=converttoreduc">'.$langs->trans('ConvertToReduc').'';
+ } else {
+ print ''.$langs->trans('ConvertToReduc').'';
+ }
}
}
// Classify paid
- if (($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercanissuepayment && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0)))
- || ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 0 && $object->total_ttc > 0 && $resteapayer == 0 && $usercanissuepayment && empty($discount->id))
+ if (($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercanissuepayment
+ && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0) || ($object->type == Facture::TYPE_DEPOSIT && $object->total_ttc > 0)))
) {
- print ''.$langs->trans('ClassifyPaid').'';
+ if ($object->type == Facture::TYPE_DEPOSIT && price2num($object->total_ttc, 'MT') != price2num($sumofpayment, 'MT')) {
+ // We can close a down payment only if paid amount is same than amount of down payment (by definition)
+ print ''.$langs->trans('ClassifyPaid').'';
+ } else {
+ print ''.$langs->trans('ClassifyPaid').'';
+ }
}
// Classify 'closed not completely paid' (possible if validated and not yet filed paid)
diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
index 971400afa5e..6b5ab4ef333 100644
--- a/htdocs/compta/paiement/class/paiement.class.php
+++ b/htdocs/compta/paiement/class/paiement.class.php
@@ -483,7 +483,7 @@ class Paiement extends CommonObject
// Verifier si paiement porte pas sur une facture classee
// Si c'est le cas, on refuse la suppression
- $billsarray = $this->getBillsArray('fk_statut > 1');
+ $billsarray = $this->getBillsArray('f.fk_statut > 1');
if (is_array($billsarray)) {
if (count($billsarray)) {
$this->error = "ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible";
diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php
index 605ffec63bd..f6edbd3f8d4 100644
--- a/htdocs/core/class/commoninvoice.class.php
+++ b/htdocs/core/class/commoninvoice.class.php
@@ -168,6 +168,7 @@ abstract class CommonInvoice extends CommonObject
$discountstatic = new DiscountAbsolute($this->db);
$result = $discountstatic->getSumDepositsUsed($this, $multicurrency);
+
if ($result >= 0) {
return $result;
} else {
diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php
index 475649701ae..57ed0791300 100644
--- a/htdocs/core/lib/security.lib.php
+++ b/htdocs/core/lib/security.lib.php
@@ -227,6 +227,10 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f
if ($features == 'product') {
$features = 'produit';
}
+ if ($features == 'banque') {
+ $parentfortableentity = 'fk_account@bank_account';
+ }
+
// Get more permissions checks from hooks
$parameters = array('features'=>$features, 'originalfeatures'=>$originalfeatures, 'objectid'=>$objectid, 'dbt_select'=>$dbt_select, 'idtype'=>$dbt_select, 'isdraft'=>$isdraft);
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index 79a93cf3b0c..9efb21c4594 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -2412,7 +2412,10 @@ if ($action == 'create') {
$multicurrency_totalcreditnotes = $object->getSumCreditNotesUsed(1);
$multicurrency_totaldeposits = $object->getSumDepositsUsed(1);
$multicurrency_resteapayer = price2num($object->multicurrency_total_ttc - $multicurrency_totalpaye - $multicurrency_totalcreditnotes - $multicurrency_totaldeposits, 'MT');
- $resteapayer = price2num($multicurrency_resteapayer / $object->multicurrency_tx, 'MT');
+ // Code to fix case of corrupted data
+ if ($resteapayer == 0 && $multicurrency_resteapayer != 0) {
+ $resteapayer = price2num($multicurrency_resteapayer / $object->multicurrency_tx, 'MT');
+ }
}
if ($object->paye) {
diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql
index 5208a733769..4935577cbf8 100644
--- a/htdocs/install/mysql/migration/repair.sql
+++ b/htdocs/install/mysql/migration/repair.sql
@@ -534,6 +534,9 @@ UPDATE llx_facturedet SET situation_percent = 100 WHERE situation_percent IS NUL
--update llx_facture set paye = 1, fk_statut = 2 where rowid in (select rowid from tmp_invoice_deposit_mark_as_available);
+-- TODO We should fix multicurrency_amount that are empty into llx_societe_remise_except, but we can't because we don't know what is the rate
+-- We may retreive info fro minvoice line by using fk_facture_line or fk_facture_supplier_line
+-- select * from llx_societe_remise_except where multicurrency_amount_ht = 0 and amount_ht <> 0;
-- Note to migrate from old counter aquarium to new one