diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 31e318f0c39..0521d203331 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1851,7 +1851,7 @@ if ($action == 'create') { // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva $objectsrc->remise_absolue = $remise_absolue; // deprecated $objectsrc->remise_percent = $remise_percent; - $objectsrc->update_price(1, - 1, 1); + $objectsrc->update_price(1, 'auto', 1); } print "\n"; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 61b0c4b6302..0c53be74ef7 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3785,7 +3785,7 @@ if ($action == 'create') { // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva $objectsrc->remise_absolue = $remise_absolue; $objectsrc->remise_percent = $remise_percent; - $objectsrc->update_price(1, - 1, 1); + $objectsrc->update_price(1, 'auto', 1); } print "\n\n"; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index aead087a9bc..a18341cc179 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3512,7 +3512,7 @@ abstract class CommonObject * * @param int $exclspec >0 = Exclude special product (product_type=9) * @param string $roundingadjust 'none'=Do nothing, 'auto'=Use default method (MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND if defined, or '0'), '0'=Force mode Total of rounding, '1'=Force mode Rounding of total - * @param int $nodatabaseupdate 1=Do not update database. Update only properties of object. + * @param int $nodatabaseupdate 1=Do not update database total fields of the main object. Update only properties in memory. Can be used to save SQL when this method is called several times, so we can do it only once at end. * @param Societe $seller If roundingadjust is '0' or '1' or maybe 'auto', it means we recalculate total for lines before calculating total for object and for this, we need seller object (used to analyze lines to check corrupted data). * @return int <0 if KO, >0 if OK */ @@ -3558,10 +3558,6 @@ abstract class CommonObject include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; - if ($roundingadjust == '-1') { - $roundingadjust = 'auto'; // For backward compatibility - } - $forcedroundingmode = $roundingadjust; if ($forcedroundingmode == 'auto' && isset($conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND)) { $forcedroundingmode = $conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND; @@ -3573,7 +3569,7 @@ abstract class CommonObject $multicurrency_tx = !empty($this->multicurrency_tx) ? $this->multicurrency_tx : 1; - // Define constants to find lines to sum + // Define constants to find lines to sum (field name int the table_element_line not into table_element) $fieldtva = 'total_tva'; $fieldlocaltax1 = 'total_localtax1'; $fieldlocaltax2 = 'total_localtax2'; @@ -3609,6 +3605,7 @@ abstract class CommonObject $sql .= ' ORDER by rowid'; // We want to be sure to always use same order of line to not change lines differently when option MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND is used dol_syslog(get_class($this)."::update_price", LOG_DEBUG); + $resql = $this->db->query($sql); if ($resql) { $this->total_ht = 0; @@ -3637,14 +3634,26 @@ abstract class CommonObject $localtax_array = array($obj->localtax1_type, $obj->localtax1_tx, $obj->localtax2_type, $obj->localtax2_tx); $tmpcal = calcul_price_total($obj->qty, $obj->up, $obj->remise_percent, $obj->vatrate, $obj->localtax1_tx, $obj->localtax2_tx, 0, 'HT', $obj->info_bits, $obj->product_type, $seller, $localtax_array, (isset($obj->situation_percent) ? $obj->situation_percent : 100), $multicurrency_tx); - $diff_when_using_price_ht = price2num($tmpcal[1] - $obj->total_tva, 'MT', 1); // If price was set with tax price adn unit price HT has a low number of digits, then we may have a diff on recalculation from unit price HT. + $diff_when_using_price_ht = price2num($tmpcal[1] - $obj->total_tva, 'MT', 1); // If price was set with tax price and unit price HT has a low number of digits, then we may have a diff on recalculation from unit price HT. $diff_on_current_total = price2num($obj->total_ttc - $obj->total_ht - $obj->total_tva - $obj->total_localtax1 - $obj->total_localtax2, 'MT', 1); - //var_dump($obj->total_ht.' '.$obj->total_tva.' '.$obj->total_localtax1.' '.$obj->total_localtax2.' =? '.$obj->total_ttc); + //var_dump($obj->total_ht.' '.$obj->total_tva.' '.$obj->total_localtax1.' '.$obj->total_localtax2.' => '.$obj->total_ttc); //var_dump($diff_when_using_price_ht.' '.$diff_on_current_total); - if ($diff_when_using_price_ht && $diff_on_current_total) { + if ($diff_on_current_total) { + // This should not happen, we should always have in table: total_ttc = total_ht + total_vat + total_localtax1 + total_localtax2 $sqlfix = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldtva." = ".price2num((float) $tmpcal[1]).", total_ttc = ".price2num((float) $tmpcal[2])." WHERE rowid = ".((int) $obj->rowid); - dol_syslog('We found unconsistent data into detailed line (diff_when_using_price_ht = '.$diff_when_using_price_ht.' and diff_on_current_total = '.$diff_on_current_total.') for line rowid = '.$obj->rowid." (total vat of line calculated=".$tmpcal[1].", database=".$obj->total_tva."). We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix, LOG_WARNING); + dol_syslog('We found unconsistent data into detailed line (diff_on_current_total = '.$diff_on_current_total.') for line rowid = '.$obj->rowid." (ht=".$obj->total_ht." vat=".$obj->total_tva." tax1=".$obj->total_localtax1." tax2=".$obj->total_localtax2." ttc=".$obj->total_ttc."). We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix, LOG_WARNING); + $resqlfix = $this->db->query($sqlfix); + if (!$resqlfix) { + dol_print_error($this->db, 'Failed to update line'); + } + $obj->total_tva = $tmpcal[1]; + $obj->total_ttc = $tmpcal[2]; + } elseif ($diff_when_using_price_ht && $roundingadjust == '0') { + // After calculation from HT, total is consistent but we have found a difference between VAT part in calculation and into database and + // we ask to force the use of rounding on line (like done on calculation) so we force update of line + $sqlfix = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldtva." = ".price2num((float) $tmpcal[1]).", total_ttc = ".price2num((float) $tmpcal[2])." WHERE rowid = ".((int) $obj->rowid); + dol_syslog('We found a line with different rounding data into detailed line (diff_when_using_price_ht = '.$diff_when_using_price_ht.' and diff_on_current_total = '.$diff_on_current_total.') for line rowid = '.$obj->rowid." (total vat of line calculated=".$tmpcal[1].", database=".$obj->total_tva."). We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix); $resqlfix = $this->db->query($sqlfix); if (!$resqlfix) { dol_print_error($this->db, 'Failed to update line'); @@ -3725,7 +3734,7 @@ abstract class CommonObject $this->db->free($resql); - // Now update global field total_ht, total_ttc, total_tva, total_localtax1, total_localtax2, multicurrency_total_* + // Now update global fields total_ht, total_ttc, total_tva, total_localtax1, total_localtax2, multicurrency_total_* of main object $fieldht = 'total_ht'; $fieldtva = 'tva'; $fieldlocaltax1 = 'localtax1'; diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 6253d9b86b2..3ef3e2bd737 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1358,7 +1358,7 @@ if ($action == 'create') { // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva $objectsrc->remise_absolue = $remise_absolue; $objectsrc->remise_percent = $remise_percent; - $objectsrc->update_price(1, - 1, 1); + $objectsrc->update_price(1, 'auto', 1); } print "\n";