From b50cb2a65d3cdd1de8e4d6da362b3c06ac10f9ad Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 1 Jan 2020 19:04:14 +0100 Subject: [PATCH] Fix solution to solve a blocking situation (credit note both refunded and consumed) --- htdocs/compta/facture/card.php | 21 ++++++++++++++- htdocs/fourn/facture/card.php | 49 ++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 2cacb885fa9..4f9229bf839 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -780,6 +780,23 @@ if (empty($reshook)) } } + // If some payments were already done, we change the amount to pay using same prorate + if (! empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED)) { + $alreadypaid = $object->getSommePaiement(); // This can be not 0 if we allow to create credit to reuse from credit notes partially refunded. + if ($alreadypaid && abs($alreadypaid) < abs($object->total_ttc)) { + $ratio = abs(($object->total_ttc - $alreadypaid) / $object->total_ttc); + foreach($amount_ht as $vatrate => $val) { + $amount_ht[$vatrate] = price2num($amount_ht[$vatrate] * $ratio, 'MU'); + $amount_tva[$vatrate] = price2num($amount_tva[$vatrate] * $ratio, 'MU'); + $amount_ttc[$vatrate] = price2num($amount_ttc[$vatrate] * $ratio, 'MU'); + $multicurrency_amount_ht[$line->tva_tx] = price2num($multicurrency_amount_ht[$vatrate] * $ratio, 'MU'); + $multicurrency_amount_tva[$line->tva_tx] = price2num($multicurrency_amount_tva[$vatrate] * $ratio, 'MU'); + $multicurrency_amount_ttc[$line->tva_tx] = price2num($multicurrency_amount_ttc[$vatrate] * $ratio, 'MU'); + } + } + } + //var_dump($amount_ht);var_dump($amount_tva);var_dump($amount_ttc);exit; + // Insert one discount by VAT rate category $discount = new DiscountAbsolute($db); if ($object->type == Facture::TYPE_CREDIT_NOTE) @@ -5014,7 +5031,9 @@ elseif ($id > 0 || !empty($ref)) print ''.$langs->trans('ConvertExcessReceivedToReduc').''; } // For credit note - if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate && $object->getSommePaiement() == 0) { + if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate + && (! empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0) + ) { print ''.$langs->trans('ConvertToReduc').''; } // For deposit invoice diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index fab706b7221..1e0ea5ba92a 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -99,6 +99,8 @@ if (!empty($user->socid)) $socid = $user->socid; $isdraft = (($object->statut == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); $result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture', 'fk_soc', 'rowid', $isdraft); +$usercancreate = $user->rights->fournisseur->facture->creer; + $permissionnote = $user->rights->fournisseur->facture->creer; // Used by the include of actions_setnotes.inc.php $permissiondellink = $user->rights->fournisseur->facture->creer; // Used by the include of actions_dellink.inc.php $permissiontoedit = $user->rights->fournisseur->facture->creer; // Used by the include of actions_lineupdown.inc.php @@ -403,7 +405,7 @@ if (empty($reshook)) $result = $object->update($user); if ($result < 0) dol_print_error($db, $object->error); } - elseif ($action == "setabsolutediscount" && $user->rights->fournisseur->facture->creer) + elseif ($action == "setabsolutediscount" && $usercancreate) { // POST[remise_id] or POST[remise_id_for_payment] @@ -461,7 +463,7 @@ if (empty($reshook)) } } // Convertir en reduc - elseif ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $user->rights->fournisseur->facture->creer) + elseif ($action == 'confirm_converttoreduc' && $confirm == 'yes' && $usercancreate) { $object->fetch($id); $object->fetch_thirdparty(); @@ -473,13 +475,14 @@ if (empty($reshook)) $canconvert = 0; if ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert = 1; // we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc) - if (($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) + if (($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not refunded completely and not already converted and amount of payment is 0 (see also the real condition used as the condition to show button converttoreduc) if ($canconvert) { $db->begin(); $amount_ht = $amount_tva = $amount_ttc = array(); - + $multicurrency_amount_ht = $multicurrency_amount_tva = $multicurrency_amount_ttc = array(); + // Loop on each vat rate $i = 0; foreach ($object->lines as $line) @@ -493,6 +496,20 @@ if (empty($reshook)) } } + // If some payments were already done, we change the amount to pay using same prorate + if (! empty($conf->global->SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED)) { + $alreadypaid = $object->getSommePaiement(); // This can be not 0 if we allow to create credit to reuse from credit notes partially refunded. + if ($alreadypaid && abs($alreadypaid) < abs($object->total_ttc)) { + $ratio = abs(($object->total_ttc - $alreadypaid) / $object->total_ttc); + foreach($amount_ht as $vatrate => $val) { + $amount_ht[$vatrate] = price2num($amount_ht[$vatrate] * $ratio, 'MU'); + $amount_tva[$vatrate] = price2num($amount_tva[$vatrate] * $ratio, 'MU'); + $amount_ttc[$vatrate] = price2num($amount_ttc[$vatrate] * $ratio, 'MU'); + } + } + } + //var_dump($amount_ht);var_dump($amount_tva);var_dump($amount_ttc);exit; + // Insert one discount by VAT rate category $discount = new DiscountAbsolute($db); if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) @@ -514,6 +531,7 @@ if (empty($reshook)) { // If we're on a standard invoice, we have to get excess paid to create a discount in TTC without VAT + // Total payments $sql = 'SELECT SUM(pf.amount) as total_paiements'; $sql .= ' FROM '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf, '.MAIN_DB_PREFIX.'paiementfourn as p'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id AND c.entity IN ('.getEntity('c_paiement').')'; @@ -527,7 +545,20 @@ if (empty($reshook)) $res = $db->fetch_object($resql); $total_paiements = $res->total_paiements; - $discount->amount_ht = $discount->amount_ttc = $total_paiements - $object->total_ttc; + // Total credit note and deposit + $total_creditnote_and_deposit = 0; + $sql = "SELECT re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc,"; + $sql .= " re.description, re.fk_invoice_supplier_source"; + $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re"; + $sql .= " WHERE fk_invoice_supplier = ".$object->id; + $resql = $db->query($sql); + if (!empty($resql)) { + while ($obj = $db->fetch_object($resql)) { + $total_creditnote_and_deposit += $obj->amount_ttc; + } + } else dol_print_error($db); + + $discount->amount_ht = $discount->amount_ttc = $total_paiements + $total_creditnote_and_deposit - $object->total_ttc; $discount->amount_tva = 0; $discount->tva_tx = 0; @@ -601,7 +632,7 @@ if (empty($reshook)) } // Create - elseif ($action == 'add' && $user->rights->fournisseur->facture->creer) + elseif ($action == 'add' && $usercancreate) { if ($socid > 0) $object->socid = GETPOST('socid', 'int'); @@ -633,7 +664,7 @@ if (empty($reshook)) if (!$error) { // This is a replacement invoice - $result = $object->fetch(GETPOST('fac_replacement'), 'int'); + $result = $object->fetch(GETPOST('fac_replacement', 'int')); $object->fetch_thirdparty(); $object->ref = GETPOST('ref', 'nohtml'); @@ -3144,7 +3175,9 @@ else print '
'.$langs->trans('ConvertExcessPaidToReduc').'
'; } // For credit note - if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->fournisseur->facture->creer && $object->getSommePaiement() == 0) { + if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $user->rights->fournisseur->facture->creer + && (! empty($conf->global->SUPPLIER_INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0) + ) { print '
'.$langs->trans('ConvertToReduc').'
'; } // For deposit invoice