diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 0bb22c4c794..41e2fcd38b8 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1092,6 +1092,11 @@ if (empty($reshook)) } $id = $object->create($user); + // NOTE: Pb with situation invoice + // NOTE: fields total on situation invoice are stored as cumulative values on total of lines (bad) but delta on invoice total + // NOTE: fields total on credit note are stored as delta both on total of lines and on invoice total (good) + // NOTE: fields situation_percent on situation invoice are stored as cumulative values on lines (bad) + // NOTE: fields situation_percent on credit note are stored as delta on lines (good) if (GETPOST('invoiceAvoirWithLines', 'int') == 1 && $id > 0) { if (!empty($facture_source->lines)) @@ -1112,17 +1117,17 @@ if (empty($reshook)) } - - if ($facture_source->type == Facture::TYPE_SITUATION) { $source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id - $line->fk_prev_id = $line->id; // Credit note line need to be linked to the situation invoice it is create from + $line->fk_prev_id = $line->id; // The new line of the new credit note we are creating must be linked to the situation invoice line it is created from if (!empty($facture_source->tab_previous_situation_invoice)) { - // search the last invoice in cycle - $lineIndex = count($facture_source->tab_previous_situation_invoice) - 1; + // search the last standard invoice in cycle and the possible credit note between this last and facture_source + // TODO Move this out of loop of $facture_source->lines + $tab_jumped_credit_notes = array(); + $lineIndex = count($facture_source->tab_previous_situation_invoice) - 1; $searchPreviousInvoice = true; while ($searchPreviousInvoice) { @@ -1133,11 +1138,13 @@ if (empty($reshook)) } else { + if ($facture_source->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_CREDIT_NOTE) { + $tab_jumped_credit_notes[$lineIndex] = $facture_source->tab_previous_situation_invoice[$lineIndex]->id; + } $lineIndex--; // go to previous invoice in cycle } } - $maxPrevSituationPercent = 0; foreach ($facture_source->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine) { @@ -1161,6 +1168,36 @@ if (empty($reshook)) // prorata $line->situation_percent = $maxPrevSituationPercent - $line->situation_percent; + + //print 'New line based on invoice id '.$facture_source->tab_previous_situation_invoice[$lineIndex]->id.' fk_prev_id='.$source_fk_prev_id.' will be fk_prev_id='.$line->fk_prev_id.' '.$line->total_ht.' '.$line->situation_percent.'
'; + + // If there is some credit note between last situation invoice and invoice used for credit note generation (note: credit notes are stored as delta) + $maxPrevSituationPercent = 0; + foreach ($tab_jumped_credit_notes as $index => $creditnoteid) { + foreach ($facture_source->tab_previous_situation_invoice[$index]->lines as $prevLine) + { + if ($prevLine->fk_prev_id == $source_fk_prev_id) + { + $maxPrevSituationPercent = $prevLine->situation_percent; + + $line->total_ht -= $prevLine->total_ht; + $line->total_tva -= $prevLine->total_tva; + $line->total_ttc -= $prevLine->total_ttc; + $line->total_localtax1 -= $prevLine->total_localtax1; + $line->total_localtax2 -= $prevLine->total_localtax2; + + $line->multicurrency_subprice -= $prevLine->multicurrency_subprice; + $line->multicurrency_total_ht -= $prevLine->multicurrency_total_ht; + $line->multicurrency_total_tva -= $prevLine->multicurrency_total_tva; + $line->multicurrency_total_ttc -= $prevLine->multicurrency_total_ttc; + } + } + } + + // prorata + $line->situation_percent += $maxPrevSituationPercent; + + //print 'New line based on invoice id '.$facture_source->tab_previous_situation_invoice[$lineIndex]->id.' fk_prev_id='.$source_fk_prev_id.' will be fk_prev_id='.$line->fk_prev_id.' '.$line->total_ht.' '.$line->situation_percent.'
'; } } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 80a0e4273aa..d3c9ae19721 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1740,7 +1740,8 @@ class Facture extends CommonInvoice } /** - * Fetch previous and next situations invoices + * Fetch previous and next situations invoices. + * Return all previous and next invoices (both standard and credit notes). * * @return void */ @@ -1751,7 +1752,7 @@ class Facture extends CommonInvoice $this->tab_previous_situation_invoice = array(); $this->tab_next_situation_invoice = array(); - $sql = 'SELECT rowid, situation_counter FROM '.MAIN_DB_PREFIX.'facture'; + $sql = 'SELECT rowid, type, situation_cycle_ref, situation_counter FROM '.MAIN_DB_PREFIX.'facture'; $sql .= ' WHERE rowid <> '.$this->id; $sql .= ' AND entity = '.$this->entity; $sql .= ' AND situation_cycle_ref = '.(int) $this->situation_cycle_ref; diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index 28fe1697449..aa5ab65d3ff 100644 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -495,7 +495,7 @@ UPDATE llx_accounting_bookkeeping set date_creation = tms where date_creation IS UPDATE llx_facturedet SET situation_percent = 100 WHERE situation_percent IS NULL AND fk_prev_id IS NULL; -- Test inconsistency of data into situation invoices: If it differs, it may be the total_ht that is wrong and situation_percent that is good. --- select f.rowid, f.type, qty, subprice, situation_percent, total_ht, total_ttc, total_tva, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc, (situation_percent / 100 * subprice * qty * (1 - (fd.remise_percent / 100))) +-- select f.rowid, f.type, fd.qty, fd.subprice, fd.situation_percent, fd.total_ht, fd.total_ttc, fd.total_tva, fd.multicurrency_total_ht, fd.multicurrency_total_tva, fd.multicurrency_total_ttc, (situation_percent / 100 * subprice * qty * (1 - (fd.remise_percent / 100))) -- from llx_facturedet as fd, llx_facture as f where fd.fk_facture = f.rowid AND (total_ht - situation_percent / 100 * subprice * qty * (1 - (fd.remise_percent / 100))) > 0.01 and f.type = 5;