diff --git a/ChangeLog b/ChangeLog index ff5b8cd9805..793d96519c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,26 @@ Following changes may create regressions for some external modules, but were nec +***** ChangeLog for 9.0.1 compared to 9.0.0 ***** +FIX: #10381 +FIX: #10460 compatibility with MariaDB 10.4 +FIX: #10485 +FIX: add fk_unit on addline action +FIX: better test on fetch +FIX: Default language of company is not set +FIX: error report not returned +FIX: expedition: reset status on rollback + replace hardcoded status with const +FIX: line edit template: keep fk_parent_line +FIX: Missing province in export of invoice +FIX: must fetch member in current entity +FIX: Price in combo list of service does not use the correct price level +FIX: supplier invoice payment total doesnt care about deposit or credit +FIX: supplier invoice product stats total ht is line total not invoice total +FIX: Translation not loaded by scheduled jobs +FIX: wrong merged conflict +FIX: wrong tests on fetch +NEW: Add protection to avoid packaging if files non indexed exists into + ***** ChangeLog for 9.0.0 compared to 8.0.0 ***** For Users: NEW: Stable module: DAV (WebDAV only for the moment) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index bbdfa564183..16b4f64a0d2 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -387,6 +387,15 @@ if ($nboftargetok) { #----------------------- if ($CHOOSEDTARGET{'-CHKSUM'}) { + $ret=`git ls-files . --exclude-standard --others`; + if ($ret) + { + print "Some files exists in source directory and are not indexed neither excluded in .gitignore.\n"; + print $ret; + print "Canceled.\n"; + exit; + } + print 'Create xml check file with md5 checksum with command php '.$SOURCE.'/build/generate_filelist_xml.php release='.$MAJOR.'.'.$MINOR.'.'.$BUILD."\n"; $ret=`php $SOURCE/build/generate_filelist_xml.php release=$MAJOR.$MINOR.$BUILD`; print $ret."\n"; diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 1d6789d4e38..42d138402e9 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -367,6 +367,8 @@ abstract class CommonDocGenerator global $conf; $sumpayed=$sumdeposit=$sumcreditnote=''; + $already_payed_all=0; + $remain_to_pay=0; if ($object->element == 'facture') { $invoice_source=new Facture($this->db); @@ -377,6 +379,8 @@ abstract class CommonDocGenerator $sumpayed = $object->getSommePaiement(); $sumdeposit = $object->getSumDepositsUsed(); $sumcreditnote = $object->getSumCreditNotesUsed(); + $already_payed_all=$sumpayed + $sumdeposit + $sumcreditnote; + $remain_to_pay=$sumpayed - $sumdeposit - $sumcreditnote; } $date = ($object->element == 'contrat' ? $object->date_contrat : $object->date); @@ -438,12 +442,12 @@ abstract class CommonDocGenerator $array_key.'_already_creditnote_locale'=>price($sumcreditnote, 0, $outputlangs), $array_key.'_already_creditnote'=>price2num($sumcreditnote), - $array_key.'_already_payed_all_locale'=>price(price2num($sumpayed + $sumdeposit + $sumcreditnote, 'MT'), 0, $outputlangs), - $array_key.'_already_payed_all'=> price2num(($sumpayed + $sumdeposit + $sumcreditnote), 'MT'), + $array_key.'_already_payed_all_locale'=>price(price2num($already_payed_all, 'MT'), 0, $outputlangs), + $array_key.'_already_payed_all'=> price2num($already_payed_all, 'MT'), // Remain to pay with all know infrmation (except open direct debit requests) - $array_key.'_remain_to_pay_locale'=>price(price2num($object->total_ttc - $sumpayed - $sumdeposit - $sumcreditnote, 'MT'), 0, $outputlangs), - $array_key.'_remain_to_pay'=>price2num($object->total_ttc - $sumpayed - $sumdeposit - $sumcreditnote, 'MT') + $array_key.'_remain_to_pay_locale'=>price(price2num($object->total_ttc - $remain_to_pay, 'MT'), 0, $outputlangs), + $array_key.'_remain_to_pay'=>price2num($object->total_ttc - $remain_to_pay, 'MT') ); if (method_exists($object, 'getTotalDiscount')) { diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index 729470711e2..1145be1849b 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -152,6 +152,8 @@ class DoliDBPgsql extends DoliDB */ static function convertSQLFromMysql($line, $type = 'auto', $unescapeslashquot = false) { + global $conf; + // Removed empty line if this is a comment line for SVN tagging if (preg_match('/^--\s\$Id/i', $line)) { return ''; @@ -311,7 +313,14 @@ class DoliDBPgsql extends DoliDB } // To have postgresql case sensitive - $line=str_replace(' LIKE \'', ' ILIKE \'', $line); + $count_like=0; + $line=str_replace(' LIKE \'', ' ILIKE \'', $line, $count_like); + if (!empty($conf->global->PSQL_USE_UNACCENT) && $count_like > 0) + { + // @see https://docs.postgresql.fr/11/unaccent.html : 'unaccent()' function must be installed before + $line=preg_replace('/\s+(\(+\s*)([a-zA-Z0-9\-\_\.]+) ILIKE /', ' \1unaccent(\2) ILIKE ', $line); + } + $line=str_replace(' LIKE BINARY \'', ' LIKE \'', $line); // Replace INSERT IGNORE into INSERT diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8918b361bde..67217f9837f 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5890,10 +5890,10 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__REF__'] = $object->ref; $substitutionarray['__REF_CLIENT__'] = (isset($object->ref_client) ? $object->ref_client : (isset($object->ref_customer) ? $object->ref_customer : null)); $substitutionarray['__REF_SUPPLIER__'] = (isset($object->ref_supplier) ? $object->ref_supplier : null); + $substitutionarray['__SUPPLIER_ORDER_DATE_DELIVERY__'] = (isset($object->date_livraison) ? dol_print_date($object->date_livraison, 'day', 0, $outputlangs): ''); // For backward compatibility $substitutionarray['__REFCLIENT__'] = (isset($object->ref_client) ? $object->ref_client : (isset($object->ref_customer) ? $object->ref_customer : null)); $substitutionarray['__REFSUPPLIER__'] = (isset($object->ref_supplier) ? $object->ref_supplier : null); - $substitutionarray['__SUPPLIER_ORDER_DATE_DELIVERY__'] = (isset($object->date_livraison) ? dol_print_date($object->date_livraison, 'day', 0, $outputlangs): ''); // TODO Remove this $msgishtml = 0; diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 6d30a300726..5d9c156acc5 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -739,7 +739,7 @@ class pdf_crabe extends ModelePDFFactures // Affiche zone versements if (($deja_regle || $amount_credit_notes_included || $amount_deposits_included) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS)) { - $posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs); + $posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs, $heightforfooter); } // Pied de page @@ -785,9 +785,10 @@ class pdf_crabe extends ModelePDFFactures * @param Object $object Object invoice * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output + * @param int $heightforfooter height for footer * @return int <0 if KO, >0 if OK */ - function _tableau_versements(&$pdf, $object, $posy, $outputlangs) + function _tableau_versements(&$pdf, $object, $posy, $outputlangs, $heightforfooter = 0) { // phpcs:enable global $conf; @@ -795,6 +796,7 @@ class pdf_crabe extends ModelePDFFactures $sign=1; if ($object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1; + $current_page = $pdf->getPage(); $tab3_posx = 120; $tab3_top = $posy + 8; $tab3_width = 80; @@ -806,26 +808,7 @@ class pdf_crabe extends ModelePDFFactures $default_font_size = pdf_getPDFFontSize($outputlangs); - $title=$outputlangs->transnoentities("PaymentsAlreadyDone"); - if ($object->type == 2) $title=$outputlangs->transnoentities("PaymentsBackAlreadyDone"); - - $pdf->SetFont('', '', $default_font_size - 3); - $pdf->SetXY($tab3_posx, $tab3_top - 4); - $pdf->MultiCell(60, 3, $title, 0, 'L', 0); - - $pdf->line($tab3_posx, $tab3_top, $tab3_posx+$tab3_width, $tab3_top); - - $pdf->SetFont('', '', $default_font_size - 4); - $pdf->SetXY($tab3_posx, $tab3_top); - $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Payment"), 0, 'L', 0); - $pdf->SetXY($tab3_posx+21, $tab3_top); - $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Amount"), 0, 'L', 0); - $pdf->SetXY($tab3_posx+40, $tab3_top); - $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Type"), 0, 'L', 0); - $pdf->SetXY($tab3_posx+58, $tab3_top); - $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Num"), 0, 'L', 0); - - $pdf->line($tab3_posx, $tab3_top-1+$tab3_height, $tab3_posx+$tab3_width, $tab3_top-1+$tab3_height); + $this->_tableau_versements_header($pdf, $object, $outputlangs, $default_font_size, $tab3_posx, $tab3_top, $tab3_width, $tab3_height); $y=0; @@ -847,6 +830,17 @@ class pdf_crabe extends ModelePDFFactures while ($i < $num) { $y+=3; + if ($tab3_top+$y >= ($this->page_hauteur - $heightforfooter)) + { + $y=0; + $current_page++; + $pdf->AddPage('','',true); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($current_page); + $this->_tableau_versements_header($pdf, $object, $outputlangs, $default_font_size, $tab3_posx, $tab3_top+$y-3, $tab3_width, $tab3_height); + } + $obj = $this->db->fetch_object($resql); if ($obj->type == 2) $text=$outputlangs->transnoentities("CreditNote"); @@ -893,6 +887,17 @@ class pdf_crabe extends ModelePDFFactures $i=0; while ($i < $num) { $y+=3; + if ($tab3_top+$y >= ($this->page_hauteur - $heightforfooter)) + { + $y=0; + $current_page++; + $pdf->AddPage('','',true); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $pdf->setPage($current_page); + $this->_tableau_versements_header($pdf, $object, $outputlangs, $default_font_size, $tab3_posx, $tab3_top+$y-3, $tab3_width, $tab3_height); + } + $row = $this->db->fetch_object($resql); $pdf->SetXY($tab3_posx, $tab3_top+$y); @@ -918,6 +923,41 @@ class pdf_crabe extends ModelePDFFactures } } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps + /** + * @param PDF $pdf Object PDF + * @param Facture $object Object invoice + * @param Translate $outputlangs Object langs for output + * @param int $default_font_size Font size + * @param int $tab3_posx pos x + * @param int $tab3_top pos y + * @param int $tab3_width width + * @param int $tab3_height height + */ + function _tableau_versements_header($pdf, $object, $outputlangs, $default_font_size, $tab3_posx, $tab3_top, $tab3_width, $tab3_height) + { + // phpcs:enable + $title=$outputlangs->transnoentities("PaymentsAlreadyDone"); + if ($object->type == 2) $title=$outputlangs->transnoentities("PaymentsBackAlreadyDone"); + + $pdf->SetFont('', '', $default_font_size - 3); + $pdf->SetXY($tab3_posx, $tab3_top - 4); + $pdf->MultiCell(60, 3, $title, 0, 'L', 0); + + $pdf->line($tab3_posx, $tab3_top, $tab3_posx+$tab3_width, $tab3_top); + + $pdf->SetFont('','', $default_font_size - 4); + $pdf->SetXY($tab3_posx, $tab3_top); + $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Payment"), 0, 'L', 0); + $pdf->SetXY($tab3_posx+21, $tab3_top); + $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Amount"), 0, 'L', 0); + $pdf->SetXY($tab3_posx+40, $tab3_top); + $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Type"), 0, 'L', 0); + $pdf->SetXY($tab3_posx+58, $tab3_top); + $pdf->MultiCell(20, 3, $outputlangs->transnoentities("Num"), 0, 'L', 0); + + $pdf->line($tab3_posx, $tab3_top-1+$tab3_height, $tab3_posx+$tab3_width, $tab3_top-1+$tab3_height); + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps /** diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 26560a89d05..1797cc2fe7e 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -73,9 +73,13 @@ $coldisplay=-1; // We remove first td + fk_product > 0) { ?> + fk_parent_line > 0) echo img_picto('', 'rightarrow'); + ?> product_type==1) echo img_object($langs->trans('ShowService'), 'service'); diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 8c4f7aa7835..9c908d32a95 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -601,7 +601,7 @@ class Expedition extends CommonObject $this->db->free($result); - if ($this->statut == 0) $this->brouillon = 1; + if ($this->statut == self::STATUS_DRAFT) $this->brouillon = 1; // Tracking url $this->getUrlTrackingStatus($obj->tracking_number); @@ -841,7 +841,7 @@ class Expedition extends CommonObject if (! $error) { $this->ref = $numref; - $this->statut = 1; + $this->statut = self::STATUS_VALIDATED; } if (! $error) @@ -876,7 +876,7 @@ class Expedition extends CommonObject if ($conf->livraison_bon->enabled) { - if ($this->statut == 1 || $this->statut == 2) + if ($this->statut == self::STATUS_VALIDATED || $this->statut == self::STATUS_CLOSED) { // Expedition validee include_once DOL_DOCUMENT_ROOT.'/livraison/class/livraison.class.php'; @@ -1184,7 +1184,7 @@ class Expedition extends CommonObject } // Stock control - if (! $error && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > 0) + if (! $error && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > self::STATUS_DRAFT) { require_once DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php"; @@ -1734,7 +1734,7 @@ class Expedition extends CommonObject $this->id=0; $this->ref = 'SPECIMEN'; $this->specimen=1; - $this->statut = 1; + $this->statut = self::STATUS_VALIDATED; $this->livraison_id = 0; $this->date = $now; $this->date_creation = $now; @@ -2117,6 +2117,7 @@ class Expedition extends CommonObject } else { + $this->statut = self::STATUS_VALIDATED; $this->db->rollback(); return -1; } @@ -2142,7 +2143,7 @@ class Expedition extends CommonObject $resql=$this->db->query($sql); if ($resql) { - $this->statut=2; + $this->statut=self::STATUS_CLOSED; $this->billed=1; // Call trigger @@ -2161,6 +2162,8 @@ class Expedition extends CommonObject } else { + $this->statut=self::STATUS_VALIDATED; + $this->billed=0; $this->db->rollback(); return -1; } @@ -2185,13 +2188,15 @@ class Expedition extends CommonObject $this->db->begin(); + $oldbilled=$this->billed; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'expedition SET fk_statut=1'; $sql .= ' WHERE rowid = '.$this->id.' AND fk_statut > 0'; $resql=$this->db->query($sql); if ($resql) { - $this->statut=1; + $this->statut=self::STATUS_VALIDATED; $this->billed=0; // If stock increment is done on closing @@ -2288,6 +2293,8 @@ class Expedition extends CommonObject } else { + $this->statut=self::STATUS_CLOSED; + $this->billed=$oldbilled; $this->db->rollback(); return -1; } diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index d8b644f1e50..d5de0ebccb3 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -622,7 +622,10 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie print ''.price($objp->total_ttc).''; - print ''.price($objp->am).''; + print ''.price($objp->am); + if ($creditnotes) print '+'.price($creditnotes); + if ($deposits) print '+'.price($deposits); + print ''; print ''.price($remaintopay).''; @@ -677,6 +680,8 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie $total+=$objp->total_ht; $total_ttc+=$objp->total_ttc; $totalrecu+=$objp->am; + $totalrecucreditnote+=$creditnotes; + $totalrecudeposits+=$deposits; $i++; } if ($i > 1) @@ -689,8 +694,11 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie if (!empty($conf->multicurrency->enabled)) print ' '; if (!empty($conf->multicurrency->enabled)) print ' '; print ''.price($total_ttc).''; - print ''.price($totalrecu).''; - print ''.price($total_ttc - $totalrecu).''; + print ''.price($totalrecu); + if ($totalrecucreditnote) print '+'.price($totalrecucreditnote); + if ($totalrecudeposits) print '+'.price($totalrecudeposits); + print ''; + print ''.price(price2num($total_ttc - $totalrecu - $totalrecucreditnote - $totalrecudeposits,'MT')).''; print ''; // Autofilled if (!empty($conf->multicurrency->enabled)) print ''; print "\n"; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 17e9c40f224..7964c378003 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -1328,8 +1328,8 @@ if ($step == 5 && $datatoimport) } print '   '.$langs->trans("Modify").''; } else { - if ($objimport->array_import_updatekeys[0] && count($objimport->array_import_updatekeys[0])) - {//TODO dropdown UL is created inside nested SPANS + if (is_array($objimport->array_import_updatekeys[0]) && count($objimport->array_import_updatekeys[0])) + { //TODO dropdown UL is created inside nested SPANS print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%'); print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt")); } diff --git a/htdocs/product/stats/facture_fournisseur.php b/htdocs/product/stats/facture_fournisseur.php index febda891f08..f64228140cd 100644 --- a/htdocs/product/stats/facture_fournisseur.php +++ b/htdocs/product/stats/facture_fournisseur.php @@ -126,7 +126,7 @@ if ($id > 0 || ! empty($ref)) if ($user->rights->fournisseur->facture->lire) { - $sql = "SELECT DISTINCT s.nom as name, s.rowid as socid, s.code_client, d.rowid, d.total_ht as total_ht,"; + $sql = "SELECT DISTINCT s.nom as name, s.rowid as socid, s.code_client, d.rowid, d.total_ht as line_total_ht,"; $sql .= " f.rowid as facid, f.ref, f.ref_supplier, f.datef, f.libelle, f.total_ht, f.total_ttc, f.total_tva, f.paye, f.fk_statut as statut, d.qty"; if (! $user->rights->societe->client->voir && ! $socid) $sql .= ", sc.fk_soc, sc.fk_user "; @@ -205,7 +205,7 @@ if ($id > 0 || ! empty($ref)) print_liste_field_titre("SupplierCode", $_SERVER["PHP_SELF"], "s.code_client", "", $option, '', $sortfield, $sortorder); print_liste_field_titre("DateInvoice", $_SERVER["PHP_SELF"], "f.datef", "", $option, 'align="center"', $sortfield, $sortorder); print_liste_field_titre("Qty", $_SERVER["PHP_SELF"], "d.qty", "", $option, 'align="center"', $sortfield, $sortorder); - print_liste_field_titre("AmountHT", $_SERVER["PHP_SELF"], "f.total_ht", "", $option, 'align="right"', $sortfield, $sortorder); + print_liste_field_titre("AmountHT", $_SERVER["PHP_SELF"], "d.total_ht", "", $option, 'align="right"', $sortfield, $sortorder); print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "f.paye,f.fk_statut", "", $option, 'align="right"', $sortfield, $sortorder); print "\n"; @@ -215,7 +215,7 @@ if ($id > 0 || ! empty($ref)) { $objp = $db->fetch_object($result); - $total_ht+=$objp->total_ht; + $total_ht+=$objp->line_total_ht; $total_qty+=$objp->qty; $supplierinvoicestatic->id = $objp->facid; @@ -237,7 +237,7 @@ if ($id > 0 || ! empty($ref)) print ''; print dol_print_date($db->jdate($objp->datef), 'dayhour') . ""; print '' . $objp->qty . "\n"; - print '' . price($objp->total_ht) . "\n"; + print '' . price($objp->line_total_ht) . "\n"; print '' . $supplierinvoicestatic->LibStatut($objp->paye, $objp->statut, 5) . ''; print "\n"; $i++; diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 9c9822677a1..f16849c2cfe 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -639,8 +639,11 @@ if (empty($reshook)) $ref_supplier = $productsupplier->ref_supplier; + $fk_unit = $productsupplier->fk_unit; + $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha')); $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, GETPOST('idprodfournprice', 'alpha')); + if (empty($tva_tx)) $tva_npr=0; $localtax1_tx= get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr); $localtax2_tx= get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);