diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 750d6f2af71..44d54b2bea7 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -913,12 +913,21 @@ if (empty($reshook))
$object->fk_facture_source = $sourceinvoice > 0 ? $sourceinvoice : '';
$object->type = Facture::TYPE_CREDIT_NOTE;
+ $facture_source = new Facture($db); // fetch origin object
+ if ($facture_source->fetch($object->fk_facture_source)>0)
+ {
+ if ($facture_source->type == Facture::TYPE_SITUATION)
+ {
+ $object->situation_counter = $facture_source->situation_counter;
+ $object->situation_cycle_ref = $facture_source->situation_cycle_ref;
+ $facture_source->fetchPreviousNextSituationInvoice();
+ }
+ }
$id = $object->create($user);
- $facture_source = new Facture($db); // fetch origin object
if (GETPOST('invoiceAvoirWithLines', 'int')==1 && $id>0)
{
- if ($facture_source->fetch($object->fk_facture_source)>0)
+ if (!empty($facture_source->lines))
{
$fk_parent_line = 0;
@@ -934,6 +943,61 @@ if (empty($reshook))
if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
$fk_parent_line = 0;
}
+
+
+
+
+ if($facture_source->type == Facture::TYPE_SITUATION)
+ {
+
+ if(!empty($facture_source->tab_previous_situation_invoice))
+ {
+ // search the last invoice in cycle
+ $lineIndex = count($facture_source->tab_previous_situation_invoice) - 1;
+ $searchPreviousInvoice = true;
+ while( $searchPreviousInvoice )
+ {
+ if($facture_source->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_SITUATION || $lineIndex < 1)
+ {
+ $searchPreviousInvoice=false; // find, exit;
+ break;
+ }
+ else
+ {
+ $lineIndex--; // go to previous invoice in cycle
+ }
+ }
+
+
+ $maxPrevSituationPercent = 0;
+ foreach($facture_source->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine)
+ {
+ if($prevLine->id == $line->fk_prev_id)
+ {
+ $maxPrevSituationPercent = max($maxPrevSituationPercent,$prevLine->situation_percent);
+
+ //$line->subprice = $line->subprice - $prevLine->subprice;
+ $line->total_ht = $line->total_ht - $prevLine->total_ht;
+ $line->total_tva = $line->total_tva - $prevLine->total_tva;
+ $line->total_ttc = $line->total_ttc - $prevLine->total_ttc;
+ $line->total_localtax1 = $line->total_localtax1 - $prevLine->total_localtax1;
+ $line->total_localtax2 = $line->total_localtax2 - $prevLine->total_localtax2;
+
+ $line->multicurrency_subprice = $line->multicurrency_subprice - $prevLine->multicurrency_subprice;
+ $line->multicurrency_total_ht = $line->multicurrency_total_ht - $prevLine->multicurrency_total_ht;
+ $line->multicurrency_total_tva = $line->multicurrency_total_tva - $prevLine->multicurrency_total_tva;
+ $line->multicurrency_total_ttc = $line->multicurrency_total_ttc - $prevLine->multicurrency_total_ttc;
+
+
+ }
+ }
+
+ // prorata
+ $line->situation_percent = $maxPrevSituationPercent - $line->situation_percent;
+
+
+ }
+ }
$line->fk_facture = $object->id;
$line->fk_parent_line = $fk_parent_line;
@@ -1959,7 +2023,25 @@ if (empty($reshook))
$line->fetch(GETPOST('lineid'));
$percent = $line->get_prev_progress($object->id);
- if (GETPOST('progress') < $percent)
+ if($object->type == Facture::TYPE_CREDIT_NOTE && $object->situation_cycle_ref>0)
+ {
+ // in case of situation credit note
+ if(GETPOST('progress') >= 0 )
+ {
+ $mesg = $langs->trans("CantBeNullOrPositive");
+ setEventMessages($mesg, null, 'warnings');
+ $error++;
+ $result = -1;
+ }
+ elseif (GETPOST('progress') < $line->situation_percent) // TODO : use a modified $line->get_prev_progress($object->id) result
+ {
+ $mesg = $langs->trans("CantBeLessThanMinPercent");
+ setEventMessages($mesg, null, 'warnings');
+ $error++;
+ $result = -1;
+ }
+ }
+ elseif (GETPOST('progress') < $percent)
{
$mesg = '
' . $langs->trans("CantBeLessThanMinPercent") . '
';
setEventMessages($mesg, null, 'warnings');
@@ -2104,6 +2186,126 @@ if (empty($reshook))
header('Location: ' . $_SERVER["PHP_SELF"] . '?facid=' . $id); // Pour reaffichage de la fiche en cours d'edition
exit();
}
+
+ // Outing situation invoice from cycle
+ elseif ($action == 'confirm_situationout' && $confirm == 'yes' && $user->rights->facture->creer)
+ {
+ $object->fetch($id,'', '','', true);
+
+ if ($object->statut == Facture::STATUS_VALIDATED
+ && $object->type == Facture::TYPE_SITUATION
+ && $user->rights->facture->creer
+ && !$objectidnext
+ && $object->is_last_in_cycle()
+ && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer))
+ || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->unvalidate)))
+ )
+ {
+ $outingError = 0;
+ $newCycle = $object->newCycle(); // we need to keep the "situation behavior" so we place it on a new situation cycle
+ if($newCycle > 1)
+ {
+ // Search credit notes
+ $lastCycle = $object->situation_cycle_ref;
+ $lastSituationCounter = $object->situation_counter;
+ $linkedCreditNotesList = array();
+
+ if (count($object->tab_next_situation_invoice) > 0) {
+ foreach ($object->tab_next_situation_invoice as $next_invoice) {
+ if($next_invoice->type == Facture::TYPE_CREDIT_NOTE
+ && $next_invoice->situation_counter == $object->situation_counter
+ && $next_invoice->fk_facture_source == $object->id
+ )
+ {
+ $linkedCreditNotesList[] = $next_invoice->id ;
+ }
+ }
+ }
+
+ $object->situation_cycle_ref = $newCycle;
+ $object->situation_counter = 1;
+ $object->situation_final = 0;
+ if($object->update($user) > 0)
+ {
+ $errors = 0;
+ if(count($linkedCreditNotesList) > 0)
+ {
+ // now, credit note must follow
+ $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture ';
+ $sql.= ' SET situation_cycle_ref='.$newCycle;
+ $sql.= ' , situation_final=0';
+ $sql.= ' , situation_counter='.$object->situation_counter;
+ $sql.= ' WHERE rowid IN ('.implode(',',$linkedCreditNotesList).')';
+
+ $resql=$db->query($sql);
+ if (!$resql) $errors++;
+
+ // Change each progression persent on each lines
+ foreach($object->lines as $line)
+ {
+
+ // no traitement for special product
+ if ($line->product_type == 9 ) continue;
+
+
+ if(!empty($object->tab_previous_situation_invoice))
+ {
+ // search the last invoice in cycle
+ $lineIndex = count($object->tab_previous_situation_invoice) - 1;
+ $searchPreviousInvoice = true;
+ while( $searchPreviousInvoice )
+ {
+ if($object->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_SITUATION || $lineIndex < 1)
+ {
+ $searchPreviousInvoice=false; // find, exit;
+ break;
+ }
+ else
+ {
+ $lineIndex--; // go to previous invoice in cycle
+ }
+ }
+
+
+ $maxPrevSituationPercent = 0;
+ foreach($object->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine)
+ {
+ if($prevLine->id == $line->fk_prev_id)
+ {
+ $maxPrevSituationPercent = max($maxPrevSituationPercent,$prevLine->situation_percent);
+ }
+ }
+
+
+ $line->situation_percent = $line->situation_percent - $maxPrevSituationPercent;
+
+ if($line->update()<0) $errors++;
+
+ }
+ }
+ }
+
+ if (!$errors)
+ {
+ setEventMessages($langs->trans('Updated'));
+ header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
+ }
+ else
+ {
+ setEventMessages($langs->trans('ErrorOutingSituationInvoiceCreditNote'), array(), 'errors');
+ }
+ }
+ else
+ {
+ setEventMessages($langs->trans('ErrorOutingSituationInvoiceOnUpdate'), array(), 'errors');
+ }
+ }
+ else
+ {
+ setEventMessages($langs->trans('ErrorFindNextSituationInvoice'), array(), 'errors');
+ }
+ }
+ }
// add lines from objectlinked
elseif($action == 'import_lines_from_object'
@@ -2114,7 +2316,7 @@ if (empty($reshook))
$fromElement = GETPOST('fromelement');
$fromElementid = GETPOST('fromelementid');
$importLines = GETPOST('line_checkbox');
-
+
if(!empty($importLines) && is_array($importLines) && !empty($fromElement) && ctype_alpha($fromElement) && !empty($fromElementid))
{
if($fromElement == 'commande')
@@ -2166,7 +2368,7 @@ if (empty($reshook))
$fk_prev_id = '';
$fk_unit = $originLine->fk_unit;
$pu_ht_devise = $originLine->multicurrency_subprice;
-
+
$res = $object->addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $date_start, $date_end, $ventil, $info_bits, $fk_remise_except, $price_base_type, $pu_ttc, $type, $rang, $special_code, $origin, $origin_id, $fk_parent_line, $fk_fournprice, $pa_ht, $label, $array_options, $situation_percent, $fk_prev_id, $fk_unit,$pu_ht_devise);
if($res > 0){
@@ -2175,18 +2377,18 @@ if (empty($reshook))
$error++;
}
}
- else{
- $error++;
+ else{
+ $error++;
}
}
-
+
if($error)
{
setEventMessage($langs->trans('ErrorsOnXLines',$error), 'errors');
}
}
}
-
+
// Actions when printing a doc from card
include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
@@ -3140,6 +3342,24 @@ else if ($id > 0 || ! empty($ref))
$formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $langs->trans('DeleteBill'), $text, 'confirm_delete', '', 'no', 1);
}
}
+
+ // Confirmation to remove invoice from cycle
+ if ($action == 'situationout') {
+ $text = $langs->trans('ConfirmRemoveSituationFromCycle', $object->ref);
+ $label = $langs->trans("ConfirmOuting");
+ $formquestion = array();
+ // remove situation from cycle
+ if ($object->statut == Facture::STATUS_VALIDATED
+ && $user->rights->facture->creer
+ && !$objectidnext
+ && $object->is_last_in_cycle()
+ && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer))
+ || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->unvalidate)))
+ )
+ {
+ $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?facid=' . $object->id, $label, $text, 'confirm_situationout', $formquestion, "yes", 1);
+ }
+ }
// Confirmation of validation
if ($action == 'valid')
@@ -3622,54 +3842,10 @@ else if ($id > 0 || ! empty($ref))
print "";
print '';
- // Situations
- if (! empty($conf->global->INVOICE_USE_SITUATION))
- {
- if ($object->type == 5 && ($object->situation_counter > 1))
- {
- $prevsits = $object->get_prev_sits();
- print '| ';
- print $langs->trans('SituationAmount');
- print ' ';
+
- print $prevsits[0]->situation_counter;
- $cprevsits = count($prevsits);
-
- for ($i = 1; $i < $cprevsits; $i++) {
- print ' + ';
- print $prevsits[$i]->situation_counter;
- }
- print ' + ';
- print $object->situation_counter;
-
- print ' | ';
- print '';
-
- $prevsits_total_amount = 0;
- foreach ($prevsits as $situation) {
- $prevsits_total_amount += $situation->total_ht;
- }
- $prevsits_total_amount += $object->total_ht;
-
- print price($prevsits_total_amount, 0, $langs, 1, -1, -1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency) );
-
- print ' |
';
-
- // Previous situation(s) deduction(s)
- for ($i = 0; $i < $cprevsits; $i++) {
- print '| ';
- print '';
- print $langs->trans('SituationDeduction');
- print ' ';
- print $prevsits[$i]->situation_counter;
- print ' | ';
-
- print '';
- print '- ' . price($prevsits[$i]->total_ht, 0, $langs, 1, -1, -1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency) );
- print ' |
';
- }
- }
- }
+
+
// Incoterms
if (!empty($conf->incoterm->enabled))
@@ -3828,88 +4004,129 @@ else if ($id > 0 || ! empty($ref))
if (! empty($conf->incoterm->enabled))
$nbrows += 1;
- if ($object->type == Facture::TYPE_SITUATION && ! empty($conf->global->INVOICE_USE_SITUATION))
+ // List of previous situation invoices
+ if (($object->situation_cycle_ref > 0) && ! empty($conf->global->INVOICE_USE_SITUATION))
{
- if (count($object->tab_previous_situation_invoice) > 0 || count($object->tab_next_situation_invoice) > 0)
- print '';
-
- if (count($object->tab_previous_situation_invoice) > 0) {
- // List of previous invoices
- print '';
- print '| ' . $langs->trans('ListOfPreviousSituationInvoices') . ' | ';
- print ' | ';
- if (! empty($conf->banque->enabled)) print ' | ';
- print '' . $langs->trans('AmountHT') . ' | ';
- print '' . $langs->trans('AmountTTC') . ' | ';
- print ' | ';
- print '
';
-
- $total_prev_ht = $total_prev_ttc = 0;
- foreach ($object->tab_previous_situation_invoice as $prev_invoice) {
- $totalpaye = $prev_invoice->getSommePaiement();
- $total_prev_ht += $prev_invoice->total_ht;
- $total_prev_ttc += $prev_invoice->total_ttc;
- print '';
- print '| ' . $prev_invoice->getNomUrl(1) . ' | ';
- print ' | ';
- if (! empty($conf->banque->enabled)) print ' | ';
- print '' . price($prev_invoice->total_ht) . ' | ';
- print '' . price($prev_invoice->total_ttc) . ' | ';
- print '' . $prev_invoice->getLibStatut(3, $totalpaye) . ' | ';
- print '
';
-
- }
-
- print '';
- print ' | ';
- print ' | ';
- if (! empty($conf->banque->enabled)) print ' | ';
- print '' . price($total_prev_ht) . ' | ';
- print '' . price($total_prev_ttc) . ' | ';
- print ' | ';
- print '
';
- }
-
- if (count($object->tab_next_situation_invoice) > 0) {
- // List of next invoices
- print '';
- print '| ' . $langs->trans('ListOfNextSituationInvoices') . ' | ';
- print ' | ';
- if (! empty($conf->banque->enabled)) print ' | ';
- print '' . $langs->trans('AmountHT') . ' | ';
- print '' . $langs->trans('AmountTTC') . ' | ';
- print ' | ';
- print '
';
-
- $total_next_ht = $total_next_ttc = 0;
-
- foreach ($object->tab_next_situation_invoice as $next_invoice) {
- $totalpaye = $next_invoice->getSommePaiement();
- $total_next_ht += $next_invoice->total_ht;
- $total_next_ttc += $next_invoice->total_ttc;
- print '';
- print '| ' . $next_invoice->getNomUrl(1) . ' | ';
- print ' | ';
- if (! empty($conf->banque->enabled)) print ' | ';
- print '' . price($next_invoice->total_ht) . ' | ';
- print '' . price($next_invoice->total_ttc) . ' | ';
- print '' . $next_invoice->getLibStatut(3, $totalpaye) . ' | ';
- print '
';
-
- }
-
- print '';
- print ' | ';
- if (! empty($conf->banque->enabled)) print ' | ';
-
- print '' . price($total_next_ht) . ' | ';
- print '' . price($total_next_ttc) . ' | ';
- print ' | ';
- print '
';
- }
-
- if (count($object->tab_previous_situation_invoice) > 0 || count($object->tab_next_situation_invoice) > 0)
- print '
';
+
+ print '';
+
+
+ print '';
+ print '| ' . $langs->trans('ListOfSituationInvoices') . ' | ';
+ print ' | ';
+ print '' . $langs->trans('Situation') . ' | ';
+ if (! empty($conf->banque->enabled)) print ' | ';
+ print '' . $langs->trans('AmountHT') . ' | ';
+ print '' . $langs->trans('AmountTTC') . ' | ';
+ print ' | ';
+ print '
';
+
+
+ $total_prev_ht = $total_prev_ttc = 0;
+ $total_global_ht = $total_global_ttc = 0;
+
+ if (count($object->tab_previous_situation_invoice) > 0) {
+ // List of previous invoices
+
+ $current_situation_counter = array();
+ foreach ($object->tab_previous_situation_invoice as $prev_invoice) {
+ $totalpaye = $prev_invoice->getSommePaiement();
+ $total_prev_ht += $prev_invoice->total_ht;
+ $total_prev_ttc += $prev_invoice->total_ttc;
+ $current_situation_counter[] = (($prev_invoice->type == Facture::TYPE_CREDIT_NOTE)?-1:1) * $prev_invoice->situation_counter;
+ print '';
+ print '| ' . $prev_invoice->getNomUrl(1) . ' | ';
+ print ' | ';
+ print ''.(($prev_invoice->type == Facture::TYPE_CREDIT_NOTE)?$langs->trans('situationInvoiceShortcode_AS'):$langs->trans('situationInvoiceShortcode_S')) . $prev_invoice->situation_counter.' | ';
+ if (! empty($conf->banque->enabled)) print ' | ';
+ print '' . price($prev_invoice->total_ht) . ' | ';
+ print '' . price($prev_invoice->total_ttc) . ' | ';
+ print '' . $prev_invoice->getLibStatut(3, $totalpaye) . ' | ';
+ print '
';
+ }
+ }
+
+
+ $total_global_ht += $total_prev_ht ;
+ $total_global_ttc += $total_prev_ttc ;
+ $total_global_ht += $object->total_ht;
+ $total_global_ttc += $object->total_ttc;
+ $current_situation_counter[] = (($object->type == Facture::TYPE_CREDIT_NOTE)?-1:1) * $object->situation_counter;
+ print '';
+ print '| ' . $object->getNomUrl(1) . ' | ';
+ print ' | ';
+ print ''.(($object->type == Facture::TYPE_CREDIT_NOTE)?$langs->trans('situationInvoiceShortcode_AS'):$langs->trans('situationInvoiceShortcode_S')) . $object->situation_counter.' | ';
+ if (! empty($conf->banque->enabled)) print ' | ';
+ print '' . price($object->total_ht) . ' | ';
+ print '' . price($object->total_ttc) . ' | ';
+ print '' . $object->getLibStatut(3, $object->getSommePaiement()) . ' | ';
+ print '
';
+
+
+ print '';
+ print '| ' . $langs->trans('CurrentSituationTotal') . ' | ';
+ print '';
+ $i =0;
+ foreach ($current_situation_counter as $sit)
+ {
+ $curSign = $sit>0?'+':'-';
+ $curType = $sit>0?$langs->trans('situationInvoiceShortcode_S'):$langs->trans('situationInvoiceShortcode_AS');
+ if($i>0) print ' '.$curSign.' ';
+ print $curType . abs($sit);
+ $i++;
+ }
+ print ' | ';
+ if (! empty($conf->banque->enabled)) print ' | ';
+ print '' . price($total_global_ht) . ' | ';
+ print '' . price($total_global_ttc) . ' | ';
+ print ' | ';
+ print '
';
+
+
+ if (count($object->tab_next_situation_invoice) > 0) {
+ // List of next invoices
+ /*print '';
+ print '| ' . $langs->trans('ListOfNextSituationInvoices') . ' | ';
+ print ' | ';
+ print ' | ';
+ if (! empty($conf->banque->enabled)) print ' | ';
+ print '' . $langs->trans('AmountHT') . ' | ';
+ print '' . $langs->trans('AmountTTC') . ' | ';
+ print ' | ';
+ print '
';*/
+
+ $total_next_ht = $total_next_ttc = 0;
+
+ foreach ($object->tab_next_situation_invoice as $next_invoice) {
+ $totalpaye = $next_invoice->getSommePaiement();
+ $total_next_ht += $next_invoice->total_ht;
+ $total_next_ttc += $next_invoice->total_ttc;
+
+ print '';
+ print '| ' . $next_invoice->getNomUrl(1) . ' | ';
+ print ' | ';
+ print ''.(($next_invoice->type == Facture::TYPE_CREDIT_NOTE)?$langs->trans('situationInvoiceShortcode_AS'):$langs->trans('situationInvoiceShortcode_S')) . $next_invoice->situation_counter.' | ';
+ if (! empty($conf->banque->enabled)) print ' | ';
+ print '' . price($next_invoice->total_ht) . ' | ';
+ print '' . price($next_invoice->total_ttc) . ' | ';
+ print '' . $next_invoice->getLibStatut(3, $totalpaye) . ' | ';
+ print '
';
+
+ }
+
+ $total_global_ht += $total_next_ht;
+ $total_global_ttc += $total_next_ttc;
+
+ print '';
+ print ' | ';
+ if (! empty($conf->banque->enabled)) print ' | ';
+ print '' . price($total_global_ht) . ' | ';
+ print '' . price($total_global_ttc) . ' | ';
+ print ' | ';
+ print '
';
+ }
+
+ print '
';
}
@@ -4465,6 +4682,45 @@ else if ($id > 0 || ! empty($ref))
}
}
+ // For situation invoice with excess received
+ if ($object->statut == Facture::STATUS_VALIDATED
+ && ($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits) > 0
+ && $user->rights->facture->creer
+ && !$objectidnext
+ && $object->is_last_in_cycle()
+ && $conf->global->INVOICE_USE_SITUATION_CREDIT_NOTE
+ )
+ {
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer))
+ || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->unvalidate)))
+ {
+ print '';
+ } else {
+ print '' . $langs->trans("CreateCreditNote") . '
';
+ }
+ }
+
+ // remove situation from cycle
+ if ($object->statut == Facture::STATUS_VALIDATED
+ && $object->type == Facture::TYPE_SITUATION
+ && $user->rights->facture->creer
+ && !$objectidnext
+ && $object->situation_counter > 1
+ && $object->is_last_in_cycle()
+ && ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->creer))
+ || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->facture->invoice_advance->unvalidate)))
+ )
+ {
+ if(($object->total_ttc - $totalcreditnotes ) == 0 )
+ {
+ print '';
+ }
+ else
+ {
+ print '';
+ }
+ }
+
// Create next situation invoice
if ($user->rights->facture->creer && ($object->type == 5) && ($object->statut == 1 || $object->statut == 2)) {
if ($object->is_last_in_cycle() && $object->situation_final != 1) {
@@ -4533,16 +4789,16 @@ else if ($id > 0 || ! empty($ref))
// Show links to link elements
$linktoelem = $form->showLinkToObjectBlock($object, null, array('invoice'));
-
+
$compatibleImportElementsList = false;
- if($user->rights->facture->creer
- && $object->statut == Facture::STATUS_DRAFT
+ if($user->rights->facture->creer
+ && $object->statut == Facture::STATUS_DRAFT
&& ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) )
{
$compatibleImportElementsList = array('commande','propal'); // import from linked elements
}
$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem,$compatibleImportElementsList);
-
+
// Show online payment link
$useonlinepayment = (! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled));
diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
index 84461ab0493..67b24b4d7b2 100644
--- a/htdocs/compta/facture/class/facture.class.php
+++ b/htdocs/compta/facture/class/facture.class.php
@@ -1348,8 +1348,8 @@ class Facture extends CommonInvoice
$this->multicurrency_total_ht = $obj->multicurrency_total_ht;
$this->multicurrency_total_tva = $obj->multicurrency_total_tva;
$this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
-
- if ($this->type == self::TYPE_SITUATION && $fetch_situation)
+
+ if (($this->type == self::TYPE_SITUATION || ($this->type == self::TYPE_CREDIT_NOTE && $this->situation_cycle_ref > 0)) && $fetch_situation)
{
$this->fetchPreviousNextSituationInvoice();
}
@@ -1521,8 +1521,16 @@ class Facture extends CommonInvoice
$invoice = new Facture($this->db);
if ($invoice->fetch($objp->rowid) > 0)
{
- if ($objp->situation_counter < $this->situation_counter) $this->tab_previous_situation_invoice[] = $invoice;
- else $this->tab_next_situation_invoice[] = $invoice;
+ if ($objp->situation_counter < $this->situation_counter
+ || ($objp->situation_counter == $this->situation_counter && $objp->rowid < $this->id) // This case appear when there are credit notes
+ )
+ {
+ $this->tab_previous_situation_invoice[] = $invoice;
+ }
+ else
+ {
+ $this->tab_next_situation_invoice[] = $invoice;
+ }
}
}
}
@@ -3493,6 +3501,7 @@ class Facture extends CommonInvoice
$return = array();
+
$sql = "SELECT f.rowid as rowid, f.facnumber, f.fk_statut, f.type, f.paye, pf.fk_paiement";
$sql.= " FROM ".MAIN_DB_PREFIX."facture as f";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture";
@@ -3504,6 +3513,23 @@ class Facture extends CommonInvoice
// $sql.= " OR f.close_code IS NOT NULL)"; // Classee payee partiellement
$sql.= " AND ff.type IS NULL"; // Renvoi vrai si pas facture de remplacement
$sql.= " AND f.type != ".self::TYPE_CREDIT_NOTE; // Type non 2 si facture non avoir
+
+ if($conf->global->INVOICE_USE_SITUATION_CREDIT_NOTE){
+ // Select the last situation invoice
+ $sqlSit = 'SELECT MAX(fs.rowid)';
+ $sqlSit.= " FROM ".MAIN_DB_PREFIX."facture as fs";
+ $sqlSit.= " WHERE fs.entity = ".$conf->entity;
+ $sqlSit.= " AND fs.type = ".self::TYPE_SITUATION;
+ $sqlSit.= " AND fs.fk_statut in (".self::STATUS_VALIDATED.",".self::STATUS_CLOSED.")";
+ $sqlSit.= " GROUP BY fs.situation_cycle_ref";
+ $sqlSit.= " ORDER BY fs.situation_counter";
+ $sql.= " AND ( f.type != ".self::TYPE_SITUATION . " OR f.rowid IN (".$sqlSit.") )"; // Type non 5 si facture non avoir
+ }
+ else
+ {
+ $sql.= " AND f.type != ".self::TYPE_SITUATION ; // Type non 5 si facture non avoir
+ }
+
if ($socid > 0) $sql.=" AND f.fk_soc = ".$socid;
$sql.= " ORDER BY f.facnumber";
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index 4c236324373..c6442c730f0 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -2660,7 +2660,7 @@ abstract class CommonObject
$this->multicurrency_total_ttc += isset($this->revenuestamp)?($this->revenuestamp * $multicurrency_tx):0;
// Situations totals
- if ($this->situation_cycle_ref && $this->situation_counter > 1 && method_exists($this, 'get_prev_sits'))
+ if ($this->situation_cycle_ref && $this->situation_counter > 1 && method_exists($this, 'get_prev_sits') && $this->type != $this::TYPE_CREDIT_NOTE )
{
$prev_sits = $this->get_prev_sits();
@@ -2704,7 +2704,7 @@ abstract class CommonObject
$sql .= ", multicurrency_total_ttc='".price2num($this->multicurrency_total_ttc, 'MT', 1)."'";
$sql .= ' WHERE rowid = '.$this->id;
- //print "xx".$sql;
+
dol_syslog(get_class($this)."::update_price", LOG_DEBUG);
$resql=$this->db->query($sql);
if (! $resql)
diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang
index b4891579763..e158f7a691d 100644
--- a/htdocs/langs/en_US/bills.lang
+++ b/htdocs/langs/en_US/bills.lang
@@ -339,6 +339,12 @@ PaymentOnDifferentThirdBills=Allow payments on different thirdparties bills but
PaymentNote=Payment note
ListOfPreviousSituationInvoices=List of previous situation invoices
ListOfNextSituationInvoices=List of next situation invoices
+ListOfSituationInvoices=List of situation invoices
+CurrentSituationTotal=Total current situation
+DisabledBecauseNotEnouthCreditNote=To remove a situation invoice from cycle, this invoice's credit note total must cover this invoice total
+RemoveSituationFromCycle=Remove this invoice from cycle
+ConfirmRemoveSituationFromCycle=Remove this invoice %s from cycle ?
+ConfirmOuting=Confirm outing
FrequencyPer_d=Every %s days
FrequencyPer_m=Every %s months
FrequencyPer_y=Every %s years
@@ -505,9 +511,14 @@ SituationAmount=Situation invoice amount(net)
SituationDeduction=Situation subtraction
ModifyAllLines=Modify all lines
CreateNextSituationInvoice=Create next situation
+ErrorFindNextSituationInvoice=Error unable to find next situation cycle ref
+ErrorOutingSituationInvoiceOnUpdate=Unable to outing this situation invoice.
+ErrorOutingSituationInvoiceCreditNote=Unable to outing linked credit note.
NotLastInCycle=This invoice is not the latest in cycle and must not be modified.
DisabledBecauseNotLastInCycle=The next situation already exists.
DisabledBecauseFinal=This situation is final.
+situationInvoiceShortcode_AS=AS
+situationInvoiceShortcode_S=S
CantBeLessThanMinPercent=The progress can't be smaller than its value in the previous situation.
NoSituations=No open situations
InvoiceSituationLast=Final and general invoice