From 46b235c139709fd1e2410da5f60b8f5c4a4892e4 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 20 Feb 2018 15:08:57 +0100 Subject: [PATCH 001/433] add auto select model when select type on create invoice --- htdocs/admin/facture.php | 70 ++++++++++++++++++- htdocs/compta/facture/card.php | 63 +++++++++++++---- htdocs/compta/facture/class/facture.class.php | 17 +++-- htdocs/langs/en_US/admin.lang | 1 + 4 files changed, 131 insertions(+), 20 deletions(-) diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index 1f574175898..ae3b0a66ed5 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -240,6 +240,32 @@ if ($action == 'setforcedate') } } +if ($action == 'setDefaultPDFModulesByType') +{ + $invoicetypemodels = GETPOST('invoicetypemodels'); + + if(!empty($invoicetypemodels) && is_array($invoicetypemodels)) + { + $error = 0; + + foreach ($invoicetypemodels as $type => $value) + { + $res = dolibarr_set_const($db, 'FACTURE_ADDON_PDF_'.intval($type) ,$value,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + } + + if (! $error) + { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } + else + { + setEventMessages($langs->trans("Error"), null, 'errors'); + } + } + + +} /* @@ -469,7 +495,7 @@ print ''.$langs->trans("Preview").''; print "\n"; clearstatcache(); - +$activatedModels = array(); $var=true; foreach ($dirmodels as $reldir) { @@ -588,6 +614,48 @@ foreach ($dirmodels as $reldir) print ''; + + +/* + * Document templates generators + */ +print '
'; +print load_fiche_titre($langs->trans("BillsPDFModulesAccordindToInvoiceType"),'',''); +print '
'; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "\n"; + +$listtype=array( + Facture::TYPE_STANDARD=>$langs->trans("InvoiceStandard"), + Facture::TYPE_REPLACEMENT=>$langs->trans("InvoiceReplacement"), + Facture::TYPE_CREDIT_NOTE=>$langs->trans("InvoiceAvoir"), + Facture::TYPE_DEPOSIT=>$langs->trans("InvoiceDeposit"), +); +if (! empty($conf->global->INVOICE_USE_SITUATION)) +{ + $listtype[Facture::TYPE_SITUATION] = $langs->trans("InvoiceSituation"); +} + +foreach ($listtype as $type => $trans) +{ + $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type; + $curent = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF; + print ''; + print ''; + print ''; + print "\n"; +} + +print '
'.$langs->trans("Type").''.$langs->trans("Name").'
'.$trans.''.$form->selectarray('invoicetypemodels['.$type.']', ModelePDFFactures::liste_modeles($db) , $curent ,0,0, 0).'
'; +print "
"; + + /* * Modes de reglement */ diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 19612349214..277a3bc9697 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2505,7 +2505,8 @@ if ($action == 'create') // Standard invoice print '
'; $tmp=' '; - $desc = $form->textwithpicto($tmp.$langs->trans("InvoiceStandardAsk"), $langs->transnoentities("InvoiceStandardDesc"), 1, 'help', '', 0, 3); + $tmp = $tmp.''; + $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceStandardDesc"), 1, 'help', '', 0, 3); print $desc; print '
'; @@ -2524,7 +2525,8 @@ if ($action == 'create') }); '; - $desc = $form->textwithpicto($tmp.$langs->trans("InvoiceDeposit"), $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3); + $tmp = $tmp.''; + $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceDepositDesc"), 1, 'help', '', 0, 3); print ''; @@ -2548,8 +2550,9 @@ if ($action == 'create') { // First situation invoice print '
'; - $tmp=' '; - $desc = $form->textwithpicto($tmp.$langs->trans("InvoiceFirstSituationAsk"), $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3); + $tmp=' '; + $tmp = $tmp.''; + $desc = $form->textwithpicto($tmp, $langs->transnoentities("InvoiceFirstSituationDesc"), 1, 'help', '', 0, 3); print $desc; print '
'; @@ -2559,7 +2562,7 @@ if ($action == 'create') $tmp='' . $langs->trans('NoSituations') . '') || (GETPOST('origin') && GETPOST('origin') != 'facture' && GETPOST('origin') != 'commande')) $tmp.=' disabled'; $tmp.= '> '; - $text = $tmp.$langs->trans("InvoiceSituationAsk") . ' '; + $text = ' '; $text .= ''; @@ -2583,7 +2586,7 @@ if ($action == 'create') }); }); '; - $text = $tmp.$langs->trans("InvoiceReplacementAsk") . ' '; + $text = ''; $text .= ' '; - $text = $tmp.$langs->trans("InvoiceReplacement") . ' '; + $text = ' '; $text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') '; $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceReplacementDesc"), 1, 'help', '', 0, 3); print $desc; print ''; } - + + if (empty($origin)) { if ($socid > 0) @@ -2637,7 +2641,7 @@ if ($action == 'create') }); }); '; - $text = $tmp.$langs->transnoentities("InvoiceAvoirAsk") . ' '; + $text = ' '; // $text.=''; $text .= ' '; else $tmp=' '; - $text = $tmp.$langs->trans("InvoiceAvoir") . ' '; + $text = ' '; $text.= '('.$langs->trans("YouMustCreateInvoiceFromThird").') '; $desc = $form->textwithpicto($text, $langs->transnoentities("InvoiceAvoirDesc"), 1, 'help', '', 0, 3); print $desc; @@ -2677,7 +2681,7 @@ if ($action == 'create') // Template invoice print '
'; $tmp=' '; - $text = $tmp.$langs->trans("RepeatableInvoice") . ' '; + $text = ' '; //$text.= '('.$langs->trans("YouMustCreateStandardInvoiceFirst").') '; $desc = $form->textwithpicto($text, $langs->transnoentities("YouMustCreateStandardInvoiceFirstDesc"), 1, 'help', '', 0, 3); print $desc; @@ -2685,6 +2689,40 @@ if ($action == 'create') print '
'; + + + // Add auto select default document model + $listtType=array(Facture::TYPE_STANDARD,Facture::TYPE_REPLACEMENT,Facture::TYPE_CREDIT_NOTE,Facture::TYPE_DEPOSIT,Facture::TYPE_SITUATION); + $jsListType=''; + foreach ($listtType as $type) + { + $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type; + $curent = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF; + $jsListType.=(!empty($jsListType)?',':'').'"'.$type.'":"'.$curent.'"'; + } + + print ''; + + + + print '
'; if ($socid > 0) @@ -2782,7 +2820,8 @@ if ($action == 'create') print '"; // Multicurrency diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 7edc3b65b41..91e05827032 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4023,13 +4023,16 @@ class Facture extends CommonInvoice if (! dol_strlen($modele)) { - $modele = 'crabe'; - - if ($this->modelpdf) { - $modele = $this->modelpdf; - } elseif (! empty($conf->global->FACTURE_ADDON_PDF)) { - $modele = $conf->global->FACTURE_ADDON_PDF; - } + $modele = 'crabe'; + $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type; + + if ($this->modelpdf) { + $modele = $this->modelpdf; + }elseif (! empty($conf->global->{'FACTURE_ADDON_PDF_'.$this->type})){ + $modele = $conf->global->{'FACTURE_ADDON_PDF_'.$this->type} ; + }elseif (! empty($conf->global->FACTURE_ADDON_PDF)) { + $modele = $conf->global->FACTURE_ADDON_PDF; + } } $modelpath = "core/modules/facture/doc/"; diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 91a503ba6a6..005b77bd5c2 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1204,6 +1204,7 @@ WebCalUrlForVCalExport=An export link to %s format is available at follow BillsSetup=Invoices module setup BillsNumberingModule=Invoices and credit notes numbering model BillsPDFModules=Invoice documents models +BillsPDFModulesAccordindToInvoiceType=Invoice documents models according to invoice type PaymentsPDFModules=Payment documents models CreditNote=Credit note CreditNotes=Credit notes From d0ef8fe75a0b783b4c93c9b15a21fe81776ae94c Mon Sep 17 00:00:00 2001 From: John Date: Thu, 22 Feb 2018 09:54:36 +0100 Subject: [PATCH 002/433] fix travis errors --- htdocs/admin/facture.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index ae3b0a66ed5..0db1ffc72db 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -250,7 +250,7 @@ if ($action == 'setDefaultPDFModulesByType') foreach ($invoicetypemodels as $type => $value) { - $res = dolibarr_set_const($db, 'FACTURE_ADDON_PDF_'.intval($type) ,$value,'chaine',0,'',$conf->entity); + $res = dolibarr_set_const($db, 'FACTURE_ADDON_PDF_'.intval($type),$value,'chaine',0,'',$conf->entity); if (! $res > 0) $error++; } @@ -645,10 +645,10 @@ if (! empty($conf->global->INVOICE_USE_SITUATION)) foreach ($listtype as $type => $trans) { $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type; - $curent = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF; + $current = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF; print ''; print ''; - print ''; + print ''; print "\n"; } From 227e4ef9a662ed739779a3635792a545dc277d9b Mon Sep 17 00:00:00 2001 From: John Date: Tue, 3 Apr 2018 10:50:15 +0200 Subject: [PATCH 003/433] fix php compatibility --- htdocs/compta/facture/card.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 04217fee7cd..9d2205fc98e 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2820,7 +2820,8 @@ if ($action == 'create') print '"; From 5ac0f77d0e0acae668eade5d9efe03be1d73c0b3 Mon Sep 17 00:00:00 2001 From: BENKE Charlene Date: Wed, 2 May 2018 17:29:31 +0200 Subject: [PATCH 004/433] Add trigger for virtual stock Allow to add/sustract some qty for GPAO OF running --- htdocs/product/class/product.class.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 2f36fd59035..2fa802a532c 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3925,7 +3925,7 @@ class Product extends CommonObject */ function load_virtual_stock() { - global $conf; + global $conf, $user, $langs; $stock_commande_client=0; $stock_commande_fournisseur=0; @@ -3975,6 +3975,16 @@ class Product extends CommonObject if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)) { $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur; } + + // Call triggers + include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + $interface=new Interfaces($this->db); + $result=$interface->run_triggers('LOAD_VIRTUAL_STOCK', $this, $user, $langs, $conf); + if ($result < 0) { + $this->errors=$interface->errors; + return -1; + } + } From 70c9ed960d67f1ff14023d32dcec069dec1fd6bb Mon Sep 17 00:00:00 2001 From: BENKE Charlene Date: Sun, 6 May 2018 22:11:24 +0200 Subject: [PATCH 005/433] let's play with hook --- htdocs/product/class/product.class.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 2fa802a532c..9bdb286db25 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3976,14 +3976,15 @@ class Product extends CommonObject $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur; } - // Call triggers - include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; - $interface=new Interfaces($this->db); - $result=$interface->run_triggers('LOAD_VIRTUAL_STOCK', $this, $user, $langs, $conf); - if ($result < 0) { - $this->errors=$interface->errors; - return -1; + if (! is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); } + $hookmanager->initHooks(array('productdao')); + $parameters=array('id'=>$this->id); + // Note that $action and $object may have been modified by some hooks + $reshook=$hookmanager->executeHooks('loadvirtualstock', $parameters, $this, $action); + if ($reshook > 0) $this->stock_theorique+= $hookmanager->resPrint; } From 8ed3b3e49c9e230592c43283b74cbf03e20e3a7b Mon Sep 17 00:00:00 2001 From: BENKE Charlene Date: Sun, 6 May 2018 22:12:43 +0200 Subject: [PATCH 006/433] Update product.class.php --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 9bdb286db25..06ff0bd3ee6 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -3925,7 +3925,7 @@ class Product extends CommonObject */ function load_virtual_stock() { - global $conf, $user, $langs; + global $conf, $action; $stock_commande_client=0; $stock_commande_fournisseur=0; From 008163628ab1ed78afd5dab12d4f5da593e5eef5 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 26 Jun 2018 08:03:25 +0200 Subject: [PATCH 007/433] New pdf documents using new column system --- .../core/class/commondocgenerator.class.php | 225 ++ .../commande/doc/pdf_eratosthene.modules.php | 1675 ++++++++++++++ .../facture/doc/pdf_sponge.modules.php | 2030 +++++++++++++++++ .../modules/propale/doc/pdf_cyan.modules.php | 1891 +++++++++++++++ htdocs/langs/en_US/bills.lang | 3 +- htdocs/langs/en_US/orders.lang | 3 +- htdocs/langs/en_US/propal.lang | 3 +- 7 files changed, 5827 insertions(+), 3 deletions(-) create mode 100644 htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php create mode 100644 htdocs/core/modules/facture/doc/pdf_sponge.modules.php create mode 100644 htdocs/core/modules/propale/doc/pdf_cyan.modules.php diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index d3d77640540..ef0283a85d5 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -749,5 +749,230 @@ abstract class CommonDocGenerator if (empty($hidebottom)) $pdf->line($x+$l, $y+$h, $x, $y+$h); $pdf->line($x, $y+$h, $x, $y); } + + + /** + * uasort callback function to Sort colums fields + * + * @param array $a PDF lines array fields configs + * @param array $b PDF lines array fields configs + * @return int Return compare result + */ + function columnSort($a, $b) { + + if(empty($a['rank'])){ $a['rank'] = 0; } + if(empty($b['rank'])){ $b['rank'] = 0; } + if ($a['rank'] == $b['rank']) { + return 0; + } + return ($a['rank'] > $b['rank']) ? -1 : 1; + + } + + /** + * Prepare Array Column Field + * + * @param object $object common object + * @param outputlangs $outputlangs langs + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return null + */ + function prepareArrayColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){ + + global $conf; + + $this->defineColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref); + + + // Sorting + uasort ( $this->cols, array( $this, 'columnSort' ) ); + + // Positionning + $curX = $this->page_largeur-$this->marge_droite; // start from right + + // Array witdh + $arrayWidth = $this->page_largeur-$this->marge_droite-$this->marge_gauche; + + // Count flexible column + $totalDefinedColWidth = 0; + $countFlexCol = 0; + foreach ($this->cols as $colKey =>& $colDef) + { + if(!$this->getColumnStatus($colKey)) continue; // continue if desable + + if(!empty($colDef['scale'])){ + // In case of column widht is defined by percentage + $colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100 ); + } + + if(empty($colDef['width'])){ + $countFlexCol++; + } + else{ + $totalDefinedColWidth += $colDef['width']; + } + } + + foreach ($this->cols as $colKey =>& $colDef) + { + // setting empty conf with default + if(!empty($colDef['title'])){ + $colDef['title'] = array_replace($this->defaultTitlesFieldsStyle, $colDef['title']); + } + else{ + $colDef['title'] = $this->defaultTitlesFieldsStyle; + } + + // setting empty conf with default + if(!empty($colDef['content'])){ + $colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']); + } + else{ + $colDef['content'] = $this->defaultContentsFieldsStyle; + } + + if($this->getColumnStatus($colKey)) + { + // In case of flexible column + if(empty($colDef['width'])){ + $colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol; + } + + // Set positions + $lastX = $curX; + $curX = $lastX - $colDef['width']; + $colDef['xStartPos'] = $curX; + $colDef['xEndPos'] = $lastX; + } + } + } + + /** + * get column content width from column key + * + * @param string $colKey the column key + * @return float width in mm + */ + function getColumnContentWidth($colKey) + { + $colDef = $this->cols[$colKey]; + return $colDef['width'] - $colDef['content']['padding'][3] - $colDef['content']['padding'][1]; + } + + + /** + * get column content X (abscissa) left position from column key + * + * @param string $colKey the column key + * @return float X position in mm + */ + function getColumnContentXStart($colKey) + { + $colDef = $this->cols[$colKey]; + return $colDef['xStartPos'] + $colDef['content']['padding'][3]; + } + + /** + * get column position rank from column key + * + * @param string $colKey the column key + * @return int rank on success and -1 on error + */ + function getColumnRank($colKey) + { + if(!isset($this->cols[$colKey]['rank'])) return -1; + return $this->cols[$colKey]['rank']; + } + + /** + * get column position rank from column key + * + * @param string $newColKey the new column key + * @param array $defArray a single column definition array + * @param string $targetCol target column used to place the new column beside + * @param bool $insertAfterTarget insert before or after target column ? + * @return int new rank on success and -1 on error + */ + function insertNewColumnDef($newColKey, $defArray, $targetCol = false, $insertAfterTarget = false) + { + // prepare wanted rank + $rank = -1; + + // try to get rank from target column + if(!empty($targetCol)){ + $rank = $this->getColumnRank($targetCol); + if($rank>=0 && $insertAfterTarget){ $rank++; } + } + + // get rank from new column definition + if($rank<0 && !empty($defArray['rank'])){ + $rank = $defArray['rank']; + } + + // error: no rank + if($rank<0){ return -1; } + + foreach ($this->cols as $colKey =>& $colDef) + { + if( $rank <= $colDef['rank']) + { + $colDef['rank'] = $colDef['rank'] + 1; + } + } + + $defArray['rank'] = $rank; + $this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys + + return $rank; + } + + + /** + * print standard column content + * + * @param PDF $pdf pdf object + * @param float $curY curent Y position + * @param string $colKey the column key + * @param string $columnText column text + * @return int new rank on success and -1 on error + */ + function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '') + { + global $hookmanager; + + $parameters=array( + 'object' => $object, + 'curY' =>& $curY, + 'columnText' => $columnText, + 'colKey' => $colKey + ); + $reshook=$hookmanager->executeHooks('printStdColumnContent',$parameters,$this); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error,$hookmanager->errors,'errors'); + if (!$reshook) + { + if(empty($columnText)) return; + $pdf->SetXY($this->getColumnContentXStart($colKey),$curY); // Set curent position + $colDef = $this->cols[$colKey]; + $pdf->MultiCell( $this->getColumnContentWidth($colKey),2, $columnText,'',$colDef['content']['align']); + } + + } + + + /** + * get column status from column key + * + * @param string $colKey the column key + * @return float width in mm + */ + function getColumnStatus($colKey) + { + if( !empty($this->cols[$colKey]['status'])){ + return true; + } + else return false; + } } diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php new file mode 100644 index 00000000000..58129bea6e2 --- /dev/null +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -0,0 +1,1675 @@ + + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2013 Juanjo Menent + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2015 Marcos García + * Copyright (C) 2017 Ferran Marcet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php + * \ingroup commande + * \brief Fichier de la classe permettant de generer les commandes au modele Eratosthène + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; + + +/** + * Classe to generate PDF orders with template Eratosthene + */ +class pdf_eratosthene extends ModelePDFCommandes +{ + /** + * @var DoliDb Database handler + */ + public $db; + + /** + * @var string model name + */ + public $name; + + /** + * @var string model description (short text) + */ + public $description; + + /** + * @var int Save the name of generated file as the main doc when generating a doc with this template + */ + public $update_main_doc_field; + + /** + * @var string document type + */ + public $type; + + /** + * @var array() Minimum version of PHP required by module. + * e.g.: PHP ≥ 5.3 = array(5, 3) + */ + public $phpmin = array(5, 2); + + /** + * Dolibarr version of the loaded document + * @public string + */ + public $version = 'dolibarr'; + + public $page_largeur; + public $page_hauteur; + public $format; + public $marge_gauche; + public $marge_droite; + public $marge_haute; + public $marge_basse; + + public $emetteur; // Objet societe qui emet + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf,$langs,$mysoc; + + // Translations + $langs->loadLangs(array("main", "bills", "products")); + + $this->db = $db; + $this->name = "eratosthene"; + $this->description = $langs->trans('PDFEratostheneDescription'); + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + + // Dimension page + $this->type = 'pdf'; + $formatarray=pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10; + $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10; + $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10; + $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION + $this->option_modereg = 1; // Affiche mode reglement + $this->option_condreg = 1; // Affiche conditions reglement + $this->option_codeproduitservice = 1; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 1; // Support add of a watermark on drafts + + $this->franchise=!$mysoc->tva_assuj; + + // Get source company + $this->emetteur=$mysoc; + if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined + + // Define position of columns + $this->posxdesc=$this->marge_gauche+1; + + + $this->tva=array(); + $this->localtax1=array(); + $this->localtax2=array(); + $this->atleastoneratenotnull=0; + $this->atleastonediscount=0; + } + + /** + * Function to build pdf onto disk + * + * @param Object $object Object to generate + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1=OK, 0=KO + */ + function write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0) + { + global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblignes; + + if (! is_object($outputlangs)) $outputlangs=$langs; + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1'; + + // Translations + $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "orders", "deliveries")); + + $nblignes = count($object->lines); + + if ($conf->commande->dir_output) + { + $object->fetch_thirdparty(); + + $deja_regle = 0; + + // Definition of $dir and $file + if ($object->specimen) + { + $dir = $conf->commande->dir_output; + $file = $dir . "/SPECIMEN.pdf"; + } + else + { + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->commande->dir_output . "/" . $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + } + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + + if (file_exists($dir)) + { + // Add pdfgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + + // Create pdf instance + $pdf=pdf_getInstance($this->format); + $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance + $pdf->SetAutoPageBreak(1,0); + + $heightforinfotot = 40; // Height reserved to output the info and total part + $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5); // Height reserved to output the free text on last page + $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22); // Height reserved to output the footer (value include bottom margin) + + if (class_exists('TCPDF')) + { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + // Set path to the background PDF File + if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { + $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + $pdf->Open(); + $pagenb=0; + $pdf->SetDrawColor(128,128,128); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("PdfOrderTitle")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfOrderTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + + /// Does we have at least one line with discount $this->atleastonediscount + foreach ($object->lines as $line) { + if ($line->remise_percent){ + $this->atleastonediscount = true; + break; + } + } + + if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS)) + { + $this->posxpicture+=($this->postotalht - $this->posxdiscount); + $this->posxtva+=($this->postotalht - $this->posxdiscount); + $this->posxup+=($this->postotalht - $this->posxdiscount); + $this->posxqty+=($this->postotalht - $this->posxdiscount); + $this->posxdiscount+=($this->postotalht - $this->posxdiscount); + //$this->postotalht; + } + + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + + $tab_top = 90+$top_shift; + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10); + + // Incoterm + if ($conf->incoterm->enabled) + { + $desc_incoterms = $object->getIncotermsForPDF(); + if ($desc_incoterms) + { + $tab_top -= 2; + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1); + $nexY = $pdf->GetY(); + $height_incoterms=$nexY-$tab_top; + + // Rect prend une longueur en 3eme param + $pdf->SetDrawColor(192,192,192); + $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1); + + $tab_top = $nexY+6; + } + } + + // Affiche notes + $notetoshow=empty($object->note_public)?'':$object->note_public; + if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) + { + // Get first sale rep + if (is_object($object->thirdparty)) + { + $salereparray=$object->thirdparty->getSalesRepresentatives($user); + $salerepobj=new User($this->db); + $salerepobj->fetch($salereparray[0]['id']); + if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature); + } + } + + $pagenb = $pdf->getPage(); + if ($notetoshow) + { + $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite; + $pageposbeforenote = $pagenb; + + $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs); + + $tab_top -= 2; + + $pdf->startTransaction(); + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + // Description + $pageposafternote=$pdf->getPage(); + $posyafter = $pdf->GetY(); + + if($pageposafternote>$pageposbeforenote ) + { + $pdf->rollbackTransaction(true); + + // prepar pages to receive notes + while ($pagenb < $pageposafternote) { + $pdf->AddPage(); + $pagenb++; + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + // $this->_pagefoot($pdf,$object,$outputlangs,1); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + } + + // back to start + $pdf->setPage($pageposbeforenote); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + $pageposafternote=$pdf->getPage(); + + $posyafter = $pdf->GetY(); + + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20))) // There is no space left for total+free text + { + $pdf->AddPage('','',true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + //$posyafter = $tab_top_newpage; + } + + + // apply note frame to previus pages + $i = $pageposbeforenote; + while ($i < $pageposafternote) { + $pdf->setPage($i); + + + $pdf->SetDrawColor(128,128,128); + // Draw note frame + if($i>$pageposbeforenote){ + $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1); + } + else{ + $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1); + } + + // Add footer + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $this->_pagefoot($pdf,$object,$outputlangs,1); + + $i++; + } + + // apply note frame to last page + $pdf->setPage($pageposafternote); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $height_note=$posyafter-$tab_top_newpage; + $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1); + + } + else // No pagebreak + { + $pdf->commitTransaction(); + $posyafter = $pdf->GetY(); + $height_note=$posyafter-$tab_top; + $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1); + + + if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) ) + { + // not enough space, need to add page + $pdf->AddPage('','',true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + + $posyafter = $tab_top_newpage; + } + + } + + $tab_height = $tab_height - $height_note; + $tab_top = $posyafter +6; + } + else + { + $height_note=0; + } + + $iniY = $tab_top + 7; + $curY = $tab_top + 7; + $nexY = $tab_top + 7; + + // Use new auto collum system + $this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref); + + // Loop on each lines + $pageposbeforeprintlines=$pdf->getPage(); + $pagenb = $pageposbeforeprintlines; + for ($i = 0 ; $i < $nblignes ; $i++) + { + $curY = $nexY; + $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0,0,0); + + $pdf->setTopMargin($tab_top_newpage); + $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pageposbefore=$pdf->getPage(); + + // Description of product line + $curX = $this->posxdesc-1; + + $showpricebeforepagebreak=1; + + if($this->getColumnStatus('desc')) + { + $pdf->startTransaction(); + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc); + $pageposafter=$pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak + { + $pdf->rollbackTransaction(true); + $pageposafter=$pageposbefore; + //print $pageposafter.'-'.$pageposbefore;exit; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc); + $pageposafter=$pdf->getPage(); + $posyafter=$pdf->GetY(); + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new 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($pageposafter+1); + } + } + else + { + // We found a page break + $showpricebeforepagebreak=0; + } + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + $posYAfterDescription=$pdf->GetY(); + } + + $nexY = $pdf->GetY(); + $pageposafter=$pdf->getPage(); + + $pdf->setPage($pageposbefore); + $pdf->setTopMargin($this->marge_haute); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // We suppose that a too long description is moved completely on next page + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut + + // VAT Rate + if ($this->getColumnStatus('vat')) + { + $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); + $nexY = max($pdf->GetY(),$nexY); + } + + // Unit price before discount + if ($this->getColumnStatus('subprice')) + { + $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax); + $nexY = max($pdf->GetY(),$nexY); + } + + // Quantity + // Enough for 6 chars + if ($this->getColumnStatus('qty')) + { + $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'qty', $qty); + $nexY = max($pdf->GetY(),$nexY); + } + + + // Unit + if ($this->getColumnStatus('unit')) + { + $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); + $this->printStdColumnContent($pdf, $curY, 'unit', $unit); + $nexY = max($pdf->GetY(),$nexY); + } + + // Discount on line + if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) + { + $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); + $nexY = max($pdf->GetY(),$nexY); + } + + // Total HT line + if ($this->getColumnStatus('totalexcltax')) + { + $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax); + $nexY = max($pdf->GetY(),$nexY); + } + + + $parameters=array( + 'object' => $object, + 'i' => $i, + 'pdf' =>& $pdf, + 'curY' =>& $curY, + 'nexY' =>& $nexY, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails + ); + $reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this); // Note that $object may have been modified by hook + + + // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva; + else $tvaligne=$object->lines[$i]->total_tva; + + $localtax1ligne=$object->lines[$i]->total_localtax1; + $localtax2ligne=$object->lines[$i]->total_localtax2; + $localtax1_rate=$object->lines[$i]->localtax1_tx; + $localtax2_rate=$object->lines[$i]->localtax2_tx; + $localtax1_type=$object->lines[$i]->localtax1_type; + $localtax2_type=$object->lines[$i]->localtax2_type; + + if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100; + if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100; + if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100; + + $vatrate=(string) $object->lines[$i]->tva_tx; + + // Retrieve type from database for backward compatibility with old records + if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined + && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax + { + $localtaxtmp_array=getLocalTaxesFromRate($vatrate,0,$object->thirdparty,$mysoc); + $localtax1_type = $localtaxtmp_array[0]; + $localtax2_type = $localtaxtmp_array[2]; + } + + // retrieve global local tax + if ($localtax1_type && $localtax1ligne != 0) + $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne; + if ($localtax2_type && $localtax2ligne != 0) + $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne; + + if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*'; + if (! isset($this->tva[$vatrate])) $this->tva[$vatrate]=0; + $this->tva[$vatrate] += $tvaligne; + + // Add line + if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1)) + { + $pdf->setPage($pageposafter); + $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80))); + //$pdf->SetDrawColor(190,190,200); + $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1); + $pdf->SetLineStyle(array('dash'=>0)); + } + + $nexY+=2; // Passe espace entre les lignes + + // Detect if some page were added automatically and output _tableau for past pages + while ($pagenb < $pageposafter) + { + $pdf->setPage($pagenb); + if ($pagenb == $pageposbeforeprintlines) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + $pagenb++; + $pdf->setPage($pagenb); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak) + { + if ($pagenb == $pageposafter) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + } + + // Show square + if ($pagenb == $pageposbeforeprintlines) + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code); + else + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + + // Affiche zone infos + $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); + + // Affiche zone totaux + $posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); + + // Affiche zone versements + /* + if ($deja_regle) + { + $posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs); + } + */ + + // Pied de page + $this->_pagefoot($pdf, $object, $outputlangs); + if (method_exists($pdf, 'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->Close(); + + $pdf->Output($file, 'F'); + + // Add pdfgeneration hook + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('afterPDFCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $this->result = array('fullpath'=>$file); + + return 1; // Pas d'erreur + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + else + { + $this->error=$langs->transnoentities("ErrorConstantNotDefined","COMMANDE_OUTPUTDIR"); + return 0; + } + } + + /** + * Show payments table + * + * @param TCPDF $pdf Object PDF + * @param Object $object Object order + * @param int $posy Position y in PDF + * @param Translate $outputlangs Object langs for output + * @return int <0 if KO, >0 if OK + */ + function _tableau_versements(&$pdf, $object, $posy, $outputlangs) + { + + } + + + /** + * Show miscellaneous information (payment mode, payment term, ...) + * + * @param TCPDF $pdf Object PDF + * @param Object $object Object to show + * @param int $posy Y + * @param Translate $outputlangs Langs object + * @return void + */ + function _tableau_info(&$pdf, $object, $posy, $outputlangs) + { + global $conf; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $pdf->SetFont('','', $default_font_size - 1); + + // If France, show VAT mention if not applicable + if ($this->emetteur->country_code == 'FR' && $this->franchise == 1) + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + + $posy=$pdf->GetY()+4; + } + + $posxval=52; + + // Show payments conditions + if ($object->cond_reglement_code || $object->cond_reglement) + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentConditions").':'; + $pdf->MultiCell(43, 4, $titre, 0, 'L'); + + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc); + $lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement); + $pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L'); + + $posy=$pdf->GetY()+3; + } + + // Check a payment mode is defined + /* Not used with orders + if (empty($object->mode_reglement_code) + && ! $conf->global->FACTURE_CHQ_NUMBER + && ! $conf->global->FACTURE_RIB_NUMBER) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell(80, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0); + $pdf->SetTextColor(0,0,0); + + $posy=$pdf->GetY()+1; + } + */ + /* TODO + else if (! empty($object->availability_code)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell(80, 3, $outputlangs->transnoentities("AvailabilityPeriod").': '.,0,'L',0); + $pdf->SetTextColor(0,0,0); + + $posy=$pdf->GetY()+1; + }*/ + + // Show planed date of delivery + if (! empty($object->date_livraison)) + { + $outputlangs->load("sendings"); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':'; + $pdf->MultiCell(80, 4, $titre, 0, 'L'); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $dlp=dol_print_date($object->date_livraison,"daytext",false,$outputlangs,true); + $pdf->MultiCell(80, 4, $dlp, 0, 'L'); + + $posy=$pdf->GetY()+1; + } + elseif ($object->availability_code || $object->availability) // Show availability conditions + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("AvailabilityPeriod").':'; + $pdf->MultiCell(80, 4, $titre, 0, 'L'); + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_availability=$outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset(isset($object->availability)?$object->availability:''); + $lib_availability=str_replace('\n',"\n",$lib_availability); + $pdf->MultiCell(80, 4, $lib_availability, 0, 'L'); + + $posy=$pdf->GetY()+1; + } + + // Show payment mode + if ($object->mode_reglement_code + && $object->mode_reglement_code != 'CHQ' + && $object->mode_reglement_code != 'VIR') + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentMode").':'; + $pdf->MultiCell(80, 5, $titre, 0, 'L'); + + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement); + $pdf->MultiCell(80, 5, $lib_mode_reg,0,'L'); + + $posy=$pdf->GetY()+2; + } + + // Show payment mode CHQ + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') + { + // Si mode reglement non force ou si force a CHQ + if (! empty($conf->global->FACTURE_CHQ_NUMBER)) + { + if ($conf->global->FACTURE_CHQ_NUMBER > 0) + { + $account = new Account($this->db); + $account->fetch($conf->global->FACTURE_CHQ_NUMBER); + + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','B', $default_font_size - 3); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0); + $posy=$pdf->GetY()+1; + + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','', $default_font_size - 3); + $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); + $posy=$pdf->GetY()+2; + } + } + if ($conf->global->FACTURE_CHQ_NUMBER == -1) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','B', $default_font_size - 3); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0); + $posy=$pdf->GetY()+1; + + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','', $default_font_size - 3); + $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); + $posy=$pdf->GetY()+2; + } + } + } + } + + // If payment mode not forced or forced to VIR, show payment with BAN + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') + { + if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER)) + { + $bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account); + if (! empty($object->fk_bank)) $bankid=$object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank + $account = new Account($this->db); + $account->fetch($bankid); + + $curx=$this->marge_gauche; + $cury=$posy; + + $posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size); + + $posy+=2; + } + } + + return $posy; + } + + + /** + * Show total to pay + * + * @param TCPDF $pdf Object PDF + * @param Facture $object Object invoice + * @param int $deja_regle Montant deja regle + * @param int $posy Position depart + * @param Translate $outputlangs Objet langs + * @return int Position pour suite + */ + function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs) + { + global $conf,$mysoc; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $tab2_top = $posy; + $tab2_hl = 4; + $pdf->SetFont('','', $default_font_size - 1); + + // Tableau total + $col1x = 120; $col2x = 170; + if ($this->page_largeur < 210) // To work with US executive format + { + $col2x-=20; + } + $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); + + $useborder=0; + $index = 0; + + // Total HT + $pdf->SetFillColor(255,255,255); + $pdf->SetXY($col1x, $tab2_top + 0); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1); + + $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); + $pdf->SetXY($col2x, $tab2_top + 0); + $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0), 0, $outputlangs), 0, 'R', 1); + + // Show VAT by rates and total + $pdf->SetFillColor(248,248,248); + + $total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc; + + $this->atleastoneratenotnull=0; + if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) + { + $tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false); + if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull) + { + // Nothing to do + } + else + { + //Local tax 1 before VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on') + //{ + foreach( $this->localtax1 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('1','3','5'))) continue; + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey!=0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' '; + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + } + //} + //Local tax 2 before VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on') + //{ + foreach( $this->localtax2 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('1','3','5'))) continue; + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey!=0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' '; + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + + } + } + } + //} + // VAT + foreach($this->tva as $tvakey => $tvaval) + { + if ($tvakey != 0) // On affiche pas taux 0 + { + $this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' '; + $totalvat.=vatrate($tvakey,1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + + //Local tax 1 after VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on') + //{ + foreach( $this->localtax1 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('2','4','6'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey != 0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' '; + + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + } + //} + //Local tax 2 after VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on') + //{ + foreach( $this->localtax2 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('2','4','6'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey != 0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' '; + + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + } + //} + + // Total TTC + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->SetTextColor(0,0,60); + $pdf->SetFillColor(224,224,224); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1); + } + } + + $pdf->SetTextColor(0,0,0); + + $creditnoteamount=0; + $depositsamount=0; + //$creditnoteamount=$object->getSumCreditNotesUsed(); + //$depositsamount=$object->getSumDepositsUsed(); + //print "x".$creditnoteamount."-".$depositsamount;exit; + $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT'); + if (! empty($object->paye)) $resteapayer=0; + + if ($deja_regle > 0) + { + // Already paid + Deposits + $index++; + + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0); + + $index++; + $pdf->SetTextColor(0,0,60); + $pdf->SetFillColor(224,224,224); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1); + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetTextColor(0,0,0); + } + + $index++; + return ($tab2_top + ($tab2_hl * $index)); + } + + /** + * Show table for lines + * + * @param PDF $pdf Object PDF + * @param string $tab_top Top position of table + * @param string $tab_height Height of table (rectangle) + * @param int $nexY Y (not used) + * @param Translate $outputlangs Langs object + * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title + * @param int $hidebottom Hide bottom bar of array + * @param string $currency Currency code + * @return void + */ + function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='') + { + global $conf; + + // Force to disable hidetop and hidebottom + $hidebottom=0; + if ($hidetop) $hidetop=-1; + + $currency = !empty($currency) ? $currency : $conf->currency; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Amount in (at tab_top - 1) + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + + if (empty($hidetop)) + { + $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency)); + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + + //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; + if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)); + } + + $pdf->SetDrawColor(128,128,128); + $pdf->SetFont('','', $default_font_size - 1); + + // Output Rect + $this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param + + + foreach ($this->cols as $colKey => $colDef) + { + if(!$this->getColumnStatus($colKey)) continue; + + // get title label + $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']); + + // Add column separator + if(!empty($colDef['border-left'])){ + $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height); + } + + if (empty($hidetop)) + { + $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] ); + + $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1]; + $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']); + } + } + + if (empty($hidetop)){ + $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line prend une position y en 2eme param et 4eme param + } + + + } + + /** + * Show top header of page. + * + * @param TCPDF $pdf Object PDF + * @param Object $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @param string $titlekey Translation key to show as title of document + * @return void + */ + function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey="PdfOrderTitle") + { + global $conf,$langs,$hookmanager; + + // Translations + $outputlangs->loadLangs(array("main", "bills", "propal", "orders", "companies")); + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); + + // Show Draft Watermark + if($object->statut==0 && (! empty($conf->global->COMMANDE_DRAFT_WATERMARK)) ) + { + pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->COMMANDE_DRAFT_WATERMARK); + } + + $pdf->SetTextColor(0,0,60); + $pdf->SetFont('','B', $default_font_size + 3); + + $posy=$this->marge_haute; + $posx=$this->page_largeur-$this->marge_droite-100; + + $pdf->SetXY($this->marge_gauche,$posy); + + // Logo + $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; + if ($this->emetteur->logo) + { + if (is_readable($logo)) + { + $height=pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } + else + { + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size -2); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } + } + else + { + $text=$this->emetteur->name; + $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); + } + + $pdf->SetFont('','B', $default_font_size + 3); + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $title=$outputlangs->transnoentities($titlekey); + $pdf->MultiCell(100, 3, $title, '', 'R'); + + $pdf->SetFont('','B',$default_font_size); + + $posy+=5; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref), '', 'R'); + + $posy+=1; + $pdf->SetFont('','', $default_font_size - 1); + + if ($object->ref_client) + { + $posy+=5; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R'); + } + + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("OrderDate")." : " . dol_print_date($object->date,"%d %b %Y",false,$outputlangs,true), '', 'R'); + + // Get contact + if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) + { + $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL'); + if (count($arrayidcontact) > 0) + { + $usertmp=new User($this->db); + $usertmp->fetch($arrayidcontact[0]); + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R'); + } + } + + $posy+=2; + + $top_shift = 0; + // Show list of linked objects + $current_y = $pdf->getY(); + $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); + if ($current_y < $pdf->getY()) + { + $top_shift = $pdf->getY() - $current_y; + } + + if ($showaddress) + { + // Sender properties + $carac_emetteur=''; + // Add internal contact of proposal if defined + $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL'); + if (count($arrayidcontact) > 0) + { + $object->fetch_user($arrayidcontact[0]); + $labelbeforecontactname=($outputlangs->transnoentities("FromContactName")!='FromContactName'?$outputlangs->transnoentities("FromContactName"):$outputlangs->transnoentities("Name")); + $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n"; + } + + $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); + + // Show sender + $posy=42+$top_shift; + $posx=$this->marge_gauche; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80; + $hautcadre=40; + + // Show sender frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx,$posy-5); + $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L'); + $pdf->SetXY($posx,$posy); + $pdf->SetFillColor(230,230,230); + $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0,0,60); + + // Show sender name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); + $posy=$pdf->getY(); + + // Show sender information + $pdf->SetXY($posx+2,$posy); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); + + + + // If CUSTOMER contact defined on order, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','CUSTOMER'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + //Recipient name + // On peut utiliser le nom de la societe du contact + if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) { + $thirdparty = $object->contact; + } else { + $thirdparty = $object->thirdparty; + } + + $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs); + + $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target', $object); + + // Show recipient + $widthrecbox=100; + if ($this->page_largeur < 210) $widthrecbox=84; // To work with US executive format + $posy=42+$top_shift; + $posx=$this->page_largeur-$this->marge_droite-$widthrecbox; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche; + + // Show recipient frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx+2,$posy-5); + $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":",0,'L'); + $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre); + + // Show recipient name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + + $posy = $pdf->getY(); + + // Show recipient information + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); + } + + $pdf->SetTextColor(0,0,0); + return $top_shift; + } + + /** + * Show footer of page. Need this->emetteur object + * + * @param TCPDF $pdf PDF + * @param Object $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return int Return height of bottom margin including footer text + */ + function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) + { + global $conf; + $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf,$outputlangs,'ORDER_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext); + } + + + + /** + * Define Array Column Field + * + * @param object $object common object + * @param outputlangs $outputlangs langs + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return null + */ + function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){ + + global $conf, $hookmanager; + + // Default field style for content + $this->defaultContentsFieldsStyle = array( + 'align' => 'R', // R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + // Default field style for content + $this->defaultTitlesFieldsStyle = array( + 'align' => 'C', // R,C,L + 'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + /* + * For exemple + $this->cols['theColKey'] = array( + 'rank' => $rank, // int : use for ordering columns + 'width' => 20, // the column width in mm + 'title' => array( + 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + 'label' => ' ', // the final label : used fore final generated text + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + */ + + $rank=0; // do not use negative rank + $this->cols['desc'] = array( + 'rank' => $rank, + 'width' => false, // only for desc + 'status' => true, + 'title' => array( + 'textkey' => 'Designation', // use lang key is usefull in somme case with module + 'align' => 'L', + // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + // 'label' => ' ', // the final label + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', + ), + ); + + $rank = $rank + 10; + $this->cols['photo'] = array( + 'rank' => $rank, + 'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Photo', + 'label' => ' ' + ), + 'content' => array( + 'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'border-left' => false, // remove left line separator + ); + + if (! empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE)) + { + $this->cols['photo']['status'] = true; + } + + + $rank = $rank + 10; + $this->cols['vat'] = array( + 'rank' => $rank, + 'status' => false, + 'width' => 16, // in mm + 'title' => array( + 'textkey' => 'VAT' + ), + 'border-left' => true, // add left line separator + ); + + if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) + { + $this->cols['vat']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['subprice'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'PriceUHT' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['qty'] = array( + 'rank' => $rank, + 'width' => 16, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'Qty' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['progress'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Progress' + ), + 'border-left' => false, // add left line separator + ); + + if($this->situationinvoice) + { + $this->cols['progress']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['unit'] = array( + 'rank' => $rank, + 'width' => 11, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Unit' + ), + 'border-left' => true, // add left line separator + ); + if($conf->global->PRODUCT_USE_UNITS){ + $this->cols['unit']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['discount'] = array( + 'rank' => $rank, + 'width' => 13, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'ReductionShort' + ), + 'border-left' => true, // add left line separator + ); + if ($this->atleastonediscount){ + $this->cols['discount']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['totalexcltax'] = array( + 'rank' => $rank, + 'width' => 26, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'TotalHT' + ), + 'border-left' => true, // add left line separator + ); + + + $parameters=array( + 'object' => $object, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails, + 'hidedesc' => $hidedesc, + 'hideref' => $hideref + ); + + $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this); // Note that $object may have been modified by hook + if ($reshook < 0) + { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + elseif (empty($reshook)) + { + $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys + } + else + { + $this->cols = $hookmanager->resArray; + } + + } + +} diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php new file mode 100644 index 00000000000..72c2a5aaca6 --- /dev/null +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -0,0 +1,2030 @@ + + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2014 Juanjo Menent + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cédric Salvador + * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2015 Marcos García + * Copyright (C) 2017 Ferran Marcet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/facture/doc/pdf_sponge.modules.php + * \ingroup facture + * \brief File of class to generate customers invoices from sponge model + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/facture/modules_facture.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; + + +/** + * Class to manage PDF invoice template sponge + */ +class pdf_sponge extends ModelePDFFactures +{ + /** + * @var DoliDb Database handler + */ + public $db; + + /** + * @var string model name + */ + public $name; + + /** + * @var string model description (short text) + */ + public $description; + + /** + * @var int Save the name of generated file as the main doc when generating a doc with this template + */ + public $update_main_doc_field; + + /** + * @var string document type + */ + public $type; + + /** + * @var array() Minimum version of PHP required by module. + * e.g.: PHP ≥ 5.3 = array(5, 3) + */ + public $phpmin = array(5, 2); + + /** + * Dolibarr version of the loaded document + * @public string + */ + public $version = 'dolibarr'; + + public $page_largeur; + public $page_hauteur; + public $format; + public $marge_gauche; + public $marge_droite; + public $marge_haute; + public $marge_basse; + + public $emetteur; // Objet societe qui emet + + /** + * @var bool Situation invoice type + */ + public $situationinvoice; + + /** + * @var float X position for the situation progress column + */ + public $posxprogress; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + // Translations + $langs->loadLangs(array("main", "bills")); + + $this->db = $db; + $this->name = "sponge"; + $this->description = $langs->trans('PDFSpongeDescription'); + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + + // Dimensiont page + $this->type = 'pdf'; + $formatarray=pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10; + $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10; + $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10; + $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION + $this->option_modereg = 1; // Affiche mode reglement + $this->option_condreg = 1; // Affiche conditions reglement + $this->option_codeproduitservice = 1; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 1; // Affiche si il y a eu escompte + $this->option_credit_note = 1; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 1; // Support add of a watermark on drafts + + $this->franchise=!$mysoc->tva_assuj; + + // Get source company + $this->emetteur=$mysoc; + if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined + + // Define position of columns + $this->posxdesc=$this->marge_gauche+1; // used for notes ans other stuff + + // Use new system for position of columns, view $this->defineColumnField() + + $this->tva=array(); + $this->localtax1=array(); + $this->localtax2=array(); + $this->atleastoneratenotnull=0; + $this->atleastonediscount=0; + $this->situationinvoice=false; + } + + + /** + * Function to build pdf onto disk + * + * @param Object $object Object to generate + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1=OK, 0=KO + */ + function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0) + { + global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes; + + if (! is_object($outputlangs)) $outputlangs=$langs; + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1'; + + // Translations + $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies")); + + $nblignes = count($object->lines); + + // Loop on each lines to detect if there is at least one image to show + $realpatharray=array(); + $this->atleastonephoto = false; + if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE)) + { + $objphoto = new Product($this->db); + + for ($i = 0 ; $i < $nblignes ; $i++) + { + if (empty($object->lines[$i]->fk_product)) continue; + + $objphoto->fetch($object->lines[$i]->fk_product); + //var_dump($objphoto->ref);exit; + if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { + $pdir[0] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/"; + $pdir[1] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/'; + } + else + { + $pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/'; // default + $pdir[1] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/"; // alternative + } + + $arephoto = false; + foreach ($pdir as $midir) + { + if (! $arephoto) + { + $dir = $conf->product->dir_output.'/'.$midir; + + foreach ($objphoto->liste_photos($dir,1) as $key => $obj) + { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + { + if ($obj['photo_vignette']) + { + $filename= $obj['photo_vignette']; + } + else + { + $filename=$obj['photo']; + } + } + else + { + $filename=$obj['photo']; + } + + $realpath = $dir.$filename; + $arephoto = true; + $this->atleastonephoto = true; + } + } + } + + if ($realpath && $arephoto) $realpatharray[$i]=$realpath; + } + } + + //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva; + + if ($conf->facture->dir_output) + { + $object->fetch_thirdparty(); + + $deja_regle = $object->getSommePaiement(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); + $amount_credit_notes_included = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); + $amount_deposits_included = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); + + // Definition of $dir and $file + if ($object->specimen) + { + $dir = $conf->facture->dir_output; + $file = $dir . "/SPECIMEN.pdf"; + } + else + { + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->facture->dir_output . "/" . $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + } + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + + if (file_exists($dir)) + { + // Add pdfgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + + // Set nblignes with the new facture lines content after hook + $nblignes = count($object->lines); + $nbpayments = count($object->getListOfPayments()); + + // Create pdf instance + $pdf=pdf_getInstance($this->format); + $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance + $pdf->SetAutoPageBreak(1,0); + + $heightforinfotot = 50+(4*$nbpayments); // Height reserved to output the info and total part and payment part + $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5); // Height reserved to output the free text on last page + $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22); // Height reserved to output the footer (value include bottom margin) + + if (class_exists('TCPDF')) + { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + + // Set path to the background PDF File + if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { + $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + $pdf->Open(); + $pagenb=0; + $pdf->SetDrawColor(128,128,128); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + + // Does we have at least one line with discount $this->atleastonediscount + foreach ($object->lines as $line) { + if ($line->remise_percent){ + $this->atleastonediscount = true; + break; + } + } + + + // Situation invoice handling + if ($object->situation_cycle_ref) + { + $this->situationinvoice = true; + } + + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + + $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + $tab_top = 90+$top_shift; + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10); + $tab_height = 130-$top_shift; + $tab_height_newpage = 150; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift; + + // Incoterm + $height_incoterms = 0; + if ($conf->incoterm->enabled) + { + $desc_incoterms = $object->getIncotermsForPDF(); + if ($desc_incoterms) + { + $tab_top -= 2; + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1); + $nexY = max($pdf->GetY(),$nexY); + $height_incoterms=$nexY-$tab_top; + + // Rect prend une longueur en 3eme param + $pdf->SetDrawColor(192,192,192); + $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1); + + $tab_top = $nexY+6; + $height_incoterms += 4; + } + } + + // Affiche notes + $notetoshow=empty($object->note_public)?'':$object->note_public; + if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) + { + // Get first sale rep + if (is_object($object->thirdparty)) + { + $salereparray=$object->thirdparty->getSalesRepresentatives($user); + $salerepobj=new User($this->db); + $salerepobj->fetch($salereparray[0]['id']); + if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature); + } + } + + $pagenb = $pdf->getPage(); + if ($notetoshow) + { + $tab_top -= 2; + + $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite; + $pageposbeforenote = $pagenb; + + $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs); + + + $pdf->startTransaction(); + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + // Description + $pageposafternote=$pdf->getPage(); + $posyafter = $pdf->GetY(); + + if($pageposafternote>$pageposbeforenote ) + { + $pdf->rollbackTransaction(true); + + // prepar pages to receive notes + while ($pagenb < $pageposafternote) { + $pdf->AddPage(); + $pagenb++; + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + // $this->_pagefoot($pdf,$object,$outputlangs,1); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + } + + // back to start + $pdf->setPage($pageposbeforenote); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + $pageposafternote=$pdf->getPage(); + + $posyafter = $pdf->GetY(); + + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20))) // There is no space left for total+free text + { + $pdf->AddPage('','',true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + //$posyafter = $tab_top_newpage; + } + + + // apply note frame to previus pages + $i = $pageposbeforenote; + while ($i < $pageposafternote) { + $pdf->setPage($i); + + + $pdf->SetDrawColor(128,128,128); + // Draw note frame + if($i>$pageposbeforenote){ + $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1); + } + else{ + $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1); + } + + // Add footer + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $this->_pagefoot($pdf,$object,$outputlangs,1); + + $i++; + } + + // apply note frame to last page + $pdf->setPage($pageposafternote); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $height_note=$posyafter-$tab_top_newpage; + $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1); + + } + else // No pagebreak + { + $pdf->commitTransaction(); + $posyafter = $pdf->GetY(); + $height_note=$posyafter-$tab_top; + $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1); + + + if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) ) + { + // not enough space, need to add page + $pdf->AddPage('','',true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + + $posyafter = $tab_top_newpage; + } + + } + + $tab_height = $tab_height - $height_note; + $tab_top = $posyafter +6; + } + else + { + $height_note=0; + } + + $iniY = $tab_top + 7; + $curY = $tab_top + 7; + $nexY = $tab_top + 7; + + // Use new auto collum system + $this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref); + + // Loop on each lines + $pageposbeforeprintlines=$pdf->getPage(); + $pagenb = $pageposbeforeprintlines; + for ($i = 0; $i < $nblignes; $i++) + { + + $curY = $nexY; + $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0,0,0); + + // Define size of image if we need it + $imglinesize=array(); + if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]); + + $pdf->setTopMargin($tab_top_newpage); + $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pageposbefore=$pdf->getPage(); + + $showpricebeforepagebreak=1; + $posYAfterImage=0; + $posYAfterDescription=0; + + if($this->getColumnStatus('photo')) + { + // We start with Photo of product line + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur-($heightforfooter+$heightforfreetext+$heightforinfotot))) // If photo too high, we moved completely on new page + { + $pdf->AddPage('','',true); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pdf->setPage($pageposbefore+1); + + $curY = $tab_top_newpage; + $showpricebeforepagebreak=0; + } + + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) + { + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + // $pdf->Image does not increase value return by getY, so we save it manually + $posYAfterImage=$curY+$imglinesize['height']; + } + } + + // Description of product line + if ($this->getColumnStatus('desc')) + { + $pdf->startTransaction(); + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc); + $pageposafter=$pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak + { + $pdf->rollbackTransaction(true); + $pageposafter=$pageposbefore; + //print $pageposafter.'-'.$pageposbefore;exit; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc); + $pageposafter=$pdf->getPage(); + $posyafter=$pdf->GetY(); + //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new page + { + $pdf->AddPage('','',true); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pdf->setPage($pageposafter+1); + } + } + else + { + // We found a page break + $showpricebeforepagebreak=0; + } + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + $posYAfterDescription=$pdf->GetY(); + } + + $nexY = $pdf->GetY(); + $pageposafter=$pdf->getPage(); + $pdf->setPage($pageposbefore); + $pdf->setTopMargin($this->marge_haute); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // We suppose that a too long description or photo were moved completely on next page + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut + + // VAT Rate + if ($this->getColumnStatus('vat')) + { + $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); + $nexY = max($pdf->GetY(),$nexY); + } + + // Unit price before discount + if ($this->getColumnStatus('subprice')) + { + $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax); + $nexY = max($pdf->GetY(),$nexY); + } + + // Quantity + // Enough for 6 chars + if ($this->getColumnStatus('qty')) + { + $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'qty', $qty); + $nexY = max($pdf->GetY(),$nexY); + } + + // Situation progress + if ($this->getColumnStatus('progress')) + { + $progress = pdf_getlineprogress($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'progress', $progress); + $nexY = max($pdf->GetY(),$nexY); + } + + // Unit + if ($this->getColumnStatus('unit')) + { + $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); + $this->printStdColumnContent($pdf, $curY, 'unit', $unit); + $nexY = max($pdf->GetY(),$nexY); + } + + // Discount on line + if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) + { + $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); + $nexY = max($pdf->GetY(),$nexY); + } + + // Total HT line + if ($this->getColumnStatus('totalexcltax')) + { + $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax); + $nexY = max($pdf->GetY(),$nexY); + } + + + $parameters=array( + 'object' => $object, + 'i' => $i, + 'pdf' =>& $pdf, + 'curY' =>& $curY, + 'nexY' =>& $nexY, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails + ); + $reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this); // Note that $object may have been modified by hook + + + + $sign=1; + if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1; + // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva + $prev_progress = $object->lines[$i]->get_prev_progress($object->id); + if ($prev_progress > 0 && !empty($object->lines[$i]->situation_percent)) // Compute progress from previous situation + { + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne = $sign * $object->lines[$i]->multicurrency_total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent; + else $tvaligne = $sign * $object->lines[$i]->total_tva * ($object->lines[$i]->situation_percent - $prev_progress) / $object->lines[$i]->situation_percent; + } else { + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne= $sign * $object->lines[$i]->multicurrency_total_tva; + else $tvaligne= $sign * $object->lines[$i]->total_tva; + } + + $localtax1ligne=$object->lines[$i]->total_localtax1; + $localtax2ligne=$object->lines[$i]->total_localtax2; + $localtax1_rate=$object->lines[$i]->localtax1_tx; + $localtax2_rate=$object->lines[$i]->localtax2_tx; + $localtax1_type=$object->lines[$i]->localtax1_type; + $localtax2_type=$object->lines[$i]->localtax2_type; + + if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100; + if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100; + if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100; + + $vatrate=(string) $object->lines[$i]->tva_tx; + + // Retrieve type from database for backward compatibility with old records + if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined + && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax + { + $localtaxtmp_array=getLocalTaxesFromRate($vatrate,0, $object->thirdparty, $mysoc); + $localtax1_type = $localtaxtmp_array[0]; + $localtax2_type = $localtaxtmp_array[2]; + } + + // retrieve global local tax + if ($localtax1_type && $localtax1ligne != 0) + $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne; + if ($localtax2_type && $localtax2ligne != 0) + $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne; + + if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*'; + if (! isset($this->tva[$vatrate])) $this->tva[$vatrate]=0; + $this->tva[$vatrate] += $tvaligne; + + $nexY = max($nexY,$posYAfterImage); + + // Add line + if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1)) + { + $pdf->setPage($pageposafter); + $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80))); + //$pdf->SetDrawColor(190,190,200); + $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1); + $pdf->SetLineStyle(array('dash'=>0)); + } + + $nexY+=2; // Passe espace entre les lignes + + // Detect if some page were added automatically and output _tableau for past pages + while ($pagenb < $pageposafter) + { + $pdf->setPage($pagenb); + if ($pagenb == $pageposbeforeprintlines) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + $pagenb++; + $pdf->setPage($pagenb); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + + if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak) + { + if ($pagenb == $pageposafter) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + + } + + // Show square + if ($pagenb == $pageposbeforeprintlines) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; + } + + // Affiche zone infos + $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); + + // Affiche zone totaux + $posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs); + + // 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); + } + + // Pied de page + $this->_pagefoot($pdf,$object,$outputlangs); + if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); + + $pdf->Close(); + + $pdf->Output($file,'F'); + + // Add pdfgeneration hook + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $this->result = array('fullpath'=>$file); + + return 1; // No error + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + else + { + $this->error=$langs->transnoentities("ErrorConstantNotDefined","FAC_OUTPUTDIR"); + return 0; + } + } + + + /** + * Show payments table + * + * @param PDF $pdf Object PDF + * @param Object $object Object invoice + * @param int $posy Position y in PDF + * @param Translate $outputlangs Object langs for output + * @return int <0 if KO, >0 if OK + */ + function _tableau_versements(&$pdf, $object, $posy, $outputlangs) + { + global $conf; + + $sign=1; + if ($object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1; + + $tab3_posx = 120; + $tab3_top = $posy + 8; + $tab3_width = 80; + $tab3_height = 4; + if ($this->page_largeur < 210) // To work with US executive format + { + $tab3_posx -= 20; + } + + $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); + + $y=0; + + $pdf->SetFont('','', $default_font_size - 4); + + + // Loop on each deposits and credit notes included + $sql = "SELECT re.rowid, re.amount_ht, re.multicurrency_amount_ht, re.amount_tva, re.multicurrency_amount_tva, re.amount_ttc, re.multicurrency_amount_ttc,"; + $sql.= " re.description, re.fk_facture_source,"; + $sql.= " f.type, f.datef"; + $sql.= " FROM ".MAIN_DB_PREFIX ."societe_remise_except as re, ".MAIN_DB_PREFIX ."facture as f"; + $sql.= " WHERE re.fk_facture_source = f.rowid AND re.fk_facture = ".$object->id; + $resql=$this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i=0; + $invoice=new Facture($this->db); + while ($i < $num) + { + $y+=3; + $obj = $this->db->fetch_object($resql); + + if ($obj->type == 2) $text=$outputlangs->trans("CreditNote"); + elseif ($obj->type == 3) $text=$outputlangs->trans("Deposit"); + else $text=$outputlangs->trans("UnknownType"); + + $invoice->fetch($obj->fk_facture_source); + + $pdf->SetXY($tab3_posx, $tab3_top+$y); + $pdf->MultiCell(20, 3, dol_print_date($obj->datef,'day',false,$outputlangs,true), 0, 'L', 0); + $pdf->SetXY($tab3_posx+21, $tab3_top+$y); + $pdf->MultiCell(20, 3, price(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $obj->multicurrency_amount_ttc : $obj->amount_ttc, 0, $outputlangs), 0, 'L', 0); + $pdf->SetXY($tab3_posx+40, $tab3_top+$y); + $pdf->MultiCell(20, 3, $text, 0, 'L', 0); + $pdf->SetXY($tab3_posx+58, $tab3_top+$y); + $pdf->MultiCell(20, 3, $invoice->ref, 0, 'L', 0); + + $pdf->line($tab3_posx, $tab3_top+$y+3, $tab3_posx+$tab3_width, $tab3_top+$y+3); + + $i++; + } + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + + // Loop on each payment + // TODO Call getListOfPaymentsgetListOfPayments instead of hard coded sql + $sql = "SELECT p.datep as date, p.fk_paiement, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,"; + $sql.= " cp.code"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id"; + $sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = ".$object->id; + //$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = 1"; + $sql.= " ORDER BY p.datep"; + + $resql=$this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i=0; + while ($i < $num) { + $y+=3; + $row = $this->db->fetch_object($resql); + + $pdf->SetXY($tab3_posx, $tab3_top+$y); + $pdf->MultiCell(20, 3, dol_print_date($this->db->jdate($row->date),'day',false,$outputlangs,true), 0, 'L', 0); + $pdf->SetXY($tab3_posx+21, $tab3_top+$y); + $pdf->MultiCell(20, 3, price($sign * (($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $row->multicurrency_amount : $row->amount), 0, $outputlangs), 0, 'L', 0); + $pdf->SetXY($tab3_posx+40, $tab3_top+$y); + $oper = $outputlangs->transnoentitiesnoconv("PaymentTypeShort" . $row->code); + + $pdf->MultiCell(20, 3, $oper, 0, 'L', 0); + $pdf->SetXY($tab3_posx+58, $tab3_top+$y); + $pdf->MultiCell(30, 3, $row->num, 0, 'L', 0); + + $pdf->line($tab3_posx, $tab3_top+$y+3, $tab3_posx+$tab3_width, $tab3_top+$y+3); + + $i++; + } + } + else + { + $this->error=$this->db->lasterror(); + return -1; + } + + } + + + /** + * Show miscellaneous information (payment mode, payment term, ...) + * + * @param PDF $pdf Object PDF + * @param Object $object Object to show + * @param int $posy Y + * @param Translate $outputlangs Langs object + * @return void + */ + function _tableau_info(&$pdf, $object, $posy, $outputlangs) + { + global $conf; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $pdf->SetFont('','', $default_font_size - 1); + + // If France, show VAT mention if not applicable + if ($this->emetteur->country_code == 'FR' && $this->franchise == 1) + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + + $posy=$pdf->GetY()+4; + } + + $posxval=52; + + // Show payments conditions + if ($object->type != 2 && ($object->cond_reglement_code || $object->cond_reglement)) + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentConditions").':'; + $pdf->MultiCell(43, 4, $titre, 0, 'L'); + + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc); + $lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement); + $pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L'); + + $posy=$pdf->GetY()+3; + } + + if ($object->type != 2) + { + // Check a payment mode is defined + if (empty($object->mode_reglement_code) + && empty($conf->global->FACTURE_CHQ_NUMBER) + && empty($conf->global->FACTURE_RIB_NUMBER)) + { + $this->error = $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"); + } + // Avoid having any valid PDF with setup that is not complete + elseif (($object->mode_reglement_code == 'CHQ' && empty($conf->global->FACTURE_CHQ_NUMBER) && empty($object->fk_account) && empty($object->fk_bank)) + || ($object->mode_reglement_code == 'VIR' && empty($conf->global->FACTURE_RIB_NUMBER) && empty($object->fk_account) && empty($object->fk_bank))) + { + $outputlangs->load("errors"); + + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $this->error = $outputlangs->transnoentities("ErrorPaymentModeDefinedToWithoutSetup",$object->mode_reglement_code); + $pdf->MultiCell(80, 3, $this->error,0,'L',0); + $pdf->SetTextColor(0,0,0); + + $posy=$pdf->GetY()+1; + } + + // Show payment mode + if ($object->mode_reglement_code + && $object->mode_reglement_code != 'CHQ' + && $object->mode_reglement_code != 'VIR') + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentMode").':'; + $pdf->MultiCell(80, 5, $titre, 0, 'L'); + + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement); + $pdf->MultiCell(80, 5, $lib_mode_reg,0,'L'); + + $posy=$pdf->GetY()+2; + } + + // Show payment mode CHQ + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') + { + // Si mode reglement non force ou si force a CHQ + if (! empty($conf->global->FACTURE_CHQ_NUMBER)) + { + $diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE); + + if ($conf->global->FACTURE_CHQ_NUMBER > 0) + { + $account = new Account($this->db); + $account->fetch($conf->global->FACTURE_CHQ_NUMBER); + + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','B', $default_font_size - $diffsizetitle); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0); + $posy=$pdf->GetY()+1; + + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','', $default_font_size - $diffsizetitle); + $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); + $posy=$pdf->GetY()+2; + } + } + if ($conf->global->FACTURE_CHQ_NUMBER == -1) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','B', $default_font_size - $diffsizetitle); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0); + $posy=$pdf->GetY()+1; + + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','', $default_font_size - $diffsizetitle); + $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); + $posy=$pdf->GetY()+2; + } + } + } + } + + // If payment mode not forced or forced to VIR, show payment with BAN + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') + { + if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER)) + { + $bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account); + if (! empty($object->fk_bank)) $bankid=$object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank + $account = new Account($this->db); + $account->fetch($bankid); + + $curx=$this->marge_gauche; + $cury=$posy; + + $posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size); + + $posy+=2; + } + } + } + + return $posy; + } + + + /** + * Show total to pay + * + * @param PDF $pdf Object PDF + * @param Facture $object Object invoice + * @param int $deja_regle Montant deja regle + * @param int $posy Position depart + * @param Translate $outputlangs Objet langs + * @return int Position pour suite + */ + function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs) + { + global $conf,$mysoc; + + $sign=1; + if ($object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1; + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $tab2_top = $posy; + $tab2_hl = 4; + $pdf->SetFont('','', $default_font_size - 1); + + // Tableau total + $col1x = 120; $col2x = 170; + if ($this->page_largeur < 210) // To work with US executive format + { + $col2x-=20; + } + $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); + + $useborder=0; + $index = 0; + + // Total HT + $pdf->SetFillColor(255,255,255); + $pdf->SetXY($col1x, $tab2_top + 0); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1); + + $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); + $pdf->SetXY($col2x, $tab2_top + 0); + $pdf->MultiCell($largcol2, $tab2_hl, price($sign * ($total_ht + (! empty($object->remise)?$object->remise:0)), 0, $outputlangs), 0, 'R', 1); + + // Show VAT by rates and total + $pdf->SetFillColor(248,248,248); + + $total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc; + + $this->atleastoneratenotnull=0; + if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) + { + $tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false); + if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull) + { + // Nothing to do + } + else + { + // FIXME amount of vat not supported with multicurrency + + //Local tax 1 before VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on') + //{ + foreach( $this->localtax1 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('1','3','5'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey!=0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + + $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' '; + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + } + //} + //Local tax 2 before VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on') + //{ + foreach( $this->localtax2 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('1','3','5'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey!=0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' '; + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + + } + } + } + + //} + + // VAT + // Situations totals migth be wrong on huge amounts + if ($object->situation_cycle_ref && $object->situation_counter > 1) { + + $sum_pdf_tva = 0; + foreach($this->tva as $tvakey => $tvaval){ + $sum_pdf_tva+=$tvaval; // sum VAT amounts to compare to object + } + + if($sum_pdf_tva!=$object->total_tva) { // apply coef to recover the VAT object amount (the good one) + $coef_fix_tva = $object->total_tva / $sum_pdf_tva; + + foreach($this->tva as $tvakey => $tvaval) { + $this->tva[$tvakey]=$tvaval * $coef_fix_tva; + } + } + + } + + foreach($this->tva as $tvakey => $tvaval) + { + if ($tvakey != 0) // On affiche pas taux 0 + { + $this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' '; + $totalvat.=vatrate($tvakey,1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + + //Local tax 1 after VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on') + //{ + foreach( $this->localtax1 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('2','4','6'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey != 0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' '; + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + } + //} + //Local tax 2 after VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on') + //{ + foreach( $this->localtax2 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('2','4','6'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + // retrieve global local tax + if ($tvakey != 0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' '; + + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + //} + } + + // Revenue stamp + if (price2num($object->revenuestamp) != 0) + { + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RevenueStamp"), $useborder, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($sign * $object->revenuestamp), $useborder, 'R', 1); + } + + // Total TTC + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->SetTextColor(0,0,60); + $pdf->SetFillColor(224,224,224); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($sign * $total_ttc, 0, $outputlangs), $useborder, 'R', 1); + } + } + + $pdf->SetTextColor(0,0,0); + + $creditnoteamount=$object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); + $depositsamount=$object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0); + //print "x".$creditnoteamount."-".$depositsamount;exit; + $resteapayer = price2num($total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 'MT'); + if ($object->paye) $resteapayer=0; + + if (($deja_regle > 0 || $creditnoteamount > 0 || $depositsamount > 0) && empty($conf->global->INVOICE_NO_PAYMENT_DETAILS)) + { + // Already paid + Deposits + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("Paid"), 0, 'L', 0); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle + $depositsamount, 0, $outputlangs), 0, 'R', 0); + + // Credit note + if ($creditnoteamount) + { + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("CreditNotes"), 0, 'L', 0); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($creditnoteamount, 0, $outputlangs), 0, 'R', 0); + } + + // Escompte + if ($object->close_code == Facture::CLOSECODE_DISCOUNTVAT) + { + $index++; + $pdf->SetFillColor(255,255,255); + + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle - $creditnoteamount - $depositsamount, 0, $outputlangs), $useborder, 'R', 1); + + $resteapayer=0; + } + + $index++; + $pdf->SetTextColor(0,0,60); + $pdf->SetFillColor(224,224,224); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1); + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetTextColor(0,0,0); + } + + $index++; + return ($tab2_top + ($tab2_hl * $index)); + } + + /** + * Show table for lines + * + * @param PDF $pdf Object PDF + * @param string $tab_top Top position of table + * @param string $tab_height Height of table (rectangle) + * @param int $nexY Y (not used) + * @param Translate $outputlangs Langs object + * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title + * @param int $hidebottom Hide bottom bar of array + * @param string $currency Currency code + * @return void + */ + function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='') + { + global $conf; + + // Force to disable hidetop and hidebottom + $hidebottom=0; + if ($hidetop) $hidetop=-1; + + $currency = !empty($currency) ? $currency : $conf->currency; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Amount in (at tab_top - 1) + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + + if (empty($hidetop)) + { + $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency)); + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + + //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; + if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)); + } + + $pdf->SetDrawColor(128,128,128); + $pdf->SetFont('','', $default_font_size - 1); + + // Output Rect + $this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param + + + foreach ($this->cols as $colKey => $colDef) + { + if(!$this->getColumnStatus($colKey)) continue; + + // get title label + $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']); + + // Add column separator + if(!empty($colDef['border-left'])){ + $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height); + } + + if (empty($hidetop)) + { + $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] ); + + $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1]; + $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']); + } + } + + if (empty($hidetop)){ + $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line prend une position y en 2eme param et 4eme param + } + + + } + + /** + * Show top header of page. + * + * @param PDF $pdf Object PDF + * @param Object $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @return void + */ + function _pagehead(&$pdf, $object, $showaddress, $outputlangs) + { + global $conf, $langs; + + // Translations + $outputlangs->loadLangs(array("main", "bills", "propal", "companies")); + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); + + // Show Draft Watermark + if($object->statut==Facture::STATUS_DRAFT && (! empty($conf->global->FACTURE_DRAFT_WATERMARK)) ) + { + pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->FACTURE_DRAFT_WATERMARK); + } + + $pdf->SetTextColor(0,0,60); + $pdf->SetFont('','B', $default_font_size + 3); + + $w = 110; + + $posy=$this->marge_haute; + $posx=$this->page_largeur-$this->marge_droite-$w; + + $pdf->SetXY($this->marge_gauche,$posy); + + // Logo + $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; + if ($this->emetteur->logo) + { + if (is_readable($logo)) + { + $height=pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } + else + { + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B',$default_font_size - 2); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } + } + else + { + $text=$this->emetteur->name; + $pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); + } + + $pdf->SetFont('','B', $default_font_size + 3); + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $title=$outputlangs->transnoentities("PdfInvoiceTitle"); + if ($object->type == 1) $title=$outputlangs->transnoentities("InvoiceReplacement"); + if ($object->type == 2) $title=$outputlangs->transnoentities("InvoiceAvoir"); + if ($object->type == 3) $title=$outputlangs->transnoentities("InvoiceDeposit"); + if ($object->type == 4) $title=$outputlangs->transnoentities("InvoiceProForma"); + if ($this->situationinvoice) $title=$outputlangs->transnoentities("InvoiceSituation"); + $pdf->MultiCell($w, 3, $title, '', 'R'); + + $pdf->SetFont('','B',$default_font_size); + + $posy+=5; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $textref=$outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref); + if ($object->statut == Facture::STATUS_DRAFT) + { + $pdf->SetTextColor(128,0,0); + $textref.=' - '.$outputlangs->transnoentities("NotValidated"); + } + $pdf->MultiCell($w, 4, $textref, '', 'R'); + + $posy+=1; + $pdf->SetFont('','', $default_font_size - 2); + + if ($object->ref_client) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R'); + } + + $objectidnext=$object->getIdReplacingInvoice('validated'); + if ($object->type == 0 && $objectidnext) + { + $objectreplacing=new Facture($this->db); + $objectreplacing->fetch($objectidnext); + + $posy+=3; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementByInvoice").' : '.$outputlangs->convToOutputCharset($objectreplacing->ref), '', 'R'); + } + if ($object->type == 1) + { + $objectreplaced=new Facture($this->db); + $objectreplaced->fetch($object->fk_facture_source); + + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("ReplacementInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R'); + } + if ($object->type == 2 && !empty($object->fk_facture_source)) + { + $objectreplaced=new Facture($this->db); + $objectreplaced->fetch($object->fk_facture_source); + + $posy+=3; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CorrectionInvoice").' : '.$outputlangs->convToOutputCharset($objectreplaced->ref), '', 'R'); + } + + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateInvoice")." : " . dol_print_date($object->date,"day",false,$outputlangs), '', 'R'); + + if (! empty($conf->global->INVOICE_POINTOFTAX_DATE)) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DatePointOfTax")." : " . dol_print_date($object->date_pointoftax,"day",false,$outputlangs), '', 'R'); + } + + if ($object->type != 2) + { + $posy+=3; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("DateDue")." : " . dol_print_date($object->date_lim_reglement,"day",false,$outputlangs,true), '', 'R'); + } + + if ($object->thirdparty->code_client) + { + $posy+=3; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_client), '', 'R'); + } + + // Get contact + if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) + { + $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL'); + if (count($arrayidcontact) > 0) + { + $usertmp=new User($this->db); + $usertmp->fetch($arrayidcontact[0]); + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell($w, 3, $langs->transnoentities("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R'); + } + } + + $posy+=1; + + $top_shift = 0; + // Show list of linked objects + $current_y = $pdf->getY(); + $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, $w, 3, 'R', $default_font_size); + if ($current_y < $pdf->getY()) + { + $top_shift = $pdf->getY() - $current_y; + } + + if ($showaddress) + { + // Sender properties + $carac_emetteur = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); + + // Show sender + $posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posy+=$top_shift; + $posx=$this->marge_gauche; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80; + + $hautcadre=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 38 : 40; + $widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 82; + + + // Show sender frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx,$posy-5); + $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L'); + $pdf->SetXY($posx,$posy); + $pdf->SetFillColor(230,230,230); + $pdf->MultiCell($widthrecbox, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0,0,60); + + // Show sender name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell($widthrecbox-2, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); + $posy=$pdf->getY(); + + // Show sender information + $pdf->SetXY($posx+2,$posy); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell($widthrecbox-2, 4, $carac_emetteur, 0, 'L'); + + // If BILLING contact defined on invoice, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','BILLING'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + //Recipient name + // On peut utiliser le nom de la societe du contact + if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) { + $thirdparty = $object->contact; + } else { + $thirdparty = $object->thirdparty; + } + + $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs); + + $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target',$object); + + // Show recipient + $widthrecbox=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 92 : 100; + if ($this->page_largeur < 210) $widthrecbox=84; // To work with US executive format + $posy=!empty($conf->global->MAIN_PDF_USE_ISO_LOCATION) ? 40 : 42; + $posy+=$top_shift; + $posx=$this->page_largeur-$this->marge_droite-$widthrecbox; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche; + + // Show recipient frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx+2,$posy-5); + $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":",0,'L'); + $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre); + + // Show recipient name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L'); + + $posy = $pdf->getY(); + + // Show recipient information + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); + } + + $pdf->SetTextColor(0,0,0); + return $top_shift; + } + + /** + * Show footer of page. Need this->emetteur object + * + * @param PDF $pdf PDF + * @param Object $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return int Return height of bottom margin including footer text + */ + function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) + { + global $conf; + $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf,$outputlangs,'INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext); + } + + + + + /** + * Define Array Column Field + * + * @param object $object common object + * @param outputlangs $outputlangs langs + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return null + */ + function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){ + + global $conf, $hookmanager; + + // Default field style for content + $this->defaultContentsFieldsStyle = array( + 'align' => 'R', // R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + // Default field style for content + $this->defaultTitlesFieldsStyle = array( + 'align' => 'C', // R,C,L + 'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + /* + * For exemple + $this->cols['theColKey'] = array( + 'rank' => $rank, // int : use for ordering columns + 'width' => 20, // the column width in mm + 'title' => array( + 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + 'label' => ' ', // the final label : used fore final generated text + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + */ + + $rank=0; // do not use negative rank + $this->cols['desc'] = array( + 'rank' => $rank, + 'width' => false, // only for desc + 'status' => true, + 'title' => array( + 'textkey' => 'Designation', // use lang key is usefull in somme case with module + 'align' => 'L', + // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + // 'label' => ' ', // the final label + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', + ), + ); + + // PHOTO + $rank = $rank + 10; + $this->cols['photo'] = array( + 'rank' => $rank, + 'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Photo', + 'label' => ' ' + ), + 'content' => array( + 'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'border-left' => false, // remove left line separator + ); + + if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto)) + { + $this->cols['photo']['status'] = true; + } + + + $rank = $rank + 10; + $this->cols['vat'] = array( + 'rank' => $rank, + 'status' => false, + 'width' => 16, // in mm + 'title' => array( + 'textkey' => 'VAT' + ), + 'border-left' => true, // add left line separator + ); + + if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) + { + $this->cols['vat']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['subprice'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'PriceUHT' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['qty'] = array( + 'rank' => $rank, + 'width' => 16, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'Qty' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['progress'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Progress' + ), + 'border-left' => true, // add left line separator + ); + + if($this->situationinvoice) + { + $this->cols['progress']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['unit'] = array( + 'rank' => $rank, + 'width' => 11, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Unit' + ), + 'border-left' => true, // add left line separator + ); + if($conf->global->PRODUCT_USE_UNITS){ + $this->cols['unit']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['discount'] = array( + 'rank' => $rank, + 'width' => 13, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'ReductionShort' + ), + 'border-left' => true, // add left line separator + ); + if ($this->atleastonediscount){ + $this->cols['discount']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['totalexcltax'] = array( + 'rank' => $rank, + 'width' => 26, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'TotalHT' + ), + 'border-left' => true, // add left line separator + ); + + + $parameters=array( + 'object' => $object, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails, + 'hidedesc' => $hidedesc, + 'hideref' => $hideref + ); + + $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this); // Note that $object may have been modified by hook + if ($reshook < 0) + { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + elseif (empty($reshook)) + { + $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys + } + else + { + $this->cols = $hookmanager->resArray; + } + + } + + +} diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php new file mode 100644 index 00000000000..383f34acebd --- /dev/null +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -0,0 +1,1891 @@ + + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2015 Juanjo Menent + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2015 Marcos García + * Copyright (C) 2017 Ferran Marcet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/propale/doc/pdf_cyan.modules.php + * \ingroup propale + * \brief Fichier de la classe permettant de generer les propales au modele Cyan + */ +require_once DOL_DOCUMENT_ROOT.'/core/modules/propale/modules_propale.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; + + +/** + * Class to generate PDF proposal Cyan + */ +class pdf_cyan extends ModelePDFPropales +{ + var $db; + var $name; + var $description; + var $update_main_doc_field; // Save the name of generated file as the main doc when generating a doc with this template + var $type; + + var $phpmin = array(4,3,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + var $page_largeur; + var $page_hauteur; + var $format; + var $marge_gauche; + var $marge_droite; + var $marge_haute; + var $marge_basse; + + var $emetteur; // Objet societe qui emet + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + // Translations + $langs->loadLangs(array("main", "bills")); + + $this->db = $db; + $this->name = "cyan"; + $this->description = $langs->trans('DocModelCyanDescription'); + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + + // Dimension page + $this->type = 'pdf'; + $formatarray=pdf_getFormat(); + $this->page_largeur = $formatarray['width']; + $this->page_hauteur = $formatarray['height']; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=isset($conf->global->MAIN_PDF_MARGIN_LEFT)?$conf->global->MAIN_PDF_MARGIN_LEFT:10; + $this->marge_droite=isset($conf->global->MAIN_PDF_MARGIN_RIGHT)?$conf->global->MAIN_PDF_MARGIN_RIGHT:10; + $this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10; + $this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 1; // Gere option tva FACTURE_TVAOPTION + $this->option_modereg = 1; // Affiche mode reglement + $this->option_condreg = 1; // Affiche conditions reglement + $this->option_codeproduitservice = 1; // Affiche code produit-service + $this->option_multilang = 1; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 1; //Support add of a watermark on drafts + + $this->franchise=!$mysoc->tva_assuj; + + // Get source company + $this->emetteur=$mysoc; + if (empty($this->emetteur->country_code)) $this->emetteur->country_code=substr($langs->defaultlang,-2); // By default, if was not defined + + // Define position of columns + $this->posxdesc=$this->marge_gauche+1; + + + + $this->tva=array(); + $this->localtax1=array(); + $this->localtax2=array(); + $this->atleastoneratenotnull=0; + $this->atleastonediscount=0; + } + + /** + * Function to build pdf onto disk + * + * @param Object $object Object to generate + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return int 1=OK, 0=KO + */ + function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0) + { + global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes; + + if (! is_object($outputlangs)) $outputlangs=$langs; + // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO + if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("bills"); + $outputlangs->load("propal"); + $outputlangs->load("products"); + + $nblignes = count($object->lines); + + // Loop on each lines to detect if there is at least one image to show + $realpatharray=array(); + $this->atleastonephoto = false; + if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE)) + { + $objphoto = new Product($this->db); + + for ($i = 0 ; $i < $nblignes ; $i++) + { + if (empty($object->lines[$i]->fk_product)) continue; + + $objphoto->fetch($object->lines[$i]->fk_product); + //var_dump($objphoto->ref);exit; + if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { + $pdir[0] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/"; + $pdir[1] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/'; + } + else + { + $pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/'; // default + $pdir[1] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/"; // alternative + } + + $arephoto = false; + foreach ($pdir as $midir) + { + if (! $arephoto) + { + $dir = $conf->product->dir_output.'/'.$midir; + + foreach ($objphoto->liste_photos($dir,1) as $key => $obj) + { + if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES)) // If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo + { + if ($obj['photo_vignette']) + { + $filename= $obj['photo_vignette']; + } + else + { + $filename=$obj['photo']; + } + } + else + { + $filename=$obj['photo']; + } + + $realpath = $dir.$filename; + $arephoto = true; + $this->atleastonephoto = true; + } + } + } + + if ($realpath && $arephoto) $realpatharray[$i]=$realpath; + } + } + + if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva; + + if ($conf->propal->multidir_output[$conf->entity]) + { + $object->fetch_thirdparty(); + + $deja_regle = 0; + + // Definition of $dir and $file + if ($object->specimen) + { + $dir = $conf->propal->multidir_output[$conf->entity]; + $file = $dir . "/SPECIMEN.pdf"; + } + else + { + $objectref = dol_sanitizeFileName($object->ref); + $dir = $conf->propal->multidir_output[$object->entity] . "/" . $objectref; + $file = $dir . "/" . $objectref . ".pdf"; + } + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return 0; + } + } + + if (file_exists($dir)) + { + // Add pdfgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks + + // Create pdf instance + $pdf=pdf_getInstance($this->format); + $default_font_size = pdf_getPDFFontSize($outputlangs); // Must be after pdf_getInstance + $pdf->SetAutoPageBreak(1,0); + + if (class_exists('TCPDF')) + { + $pdf->setPrintHeader(false); + $pdf->setPrintFooter(false); + } + $pdf->SetFont(pdf_getPDFFont($outputlangs)); + // Set path to the background PDF File + if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND)) + { + $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND); + $tplidx = $pdf->importPage(1); + } + + $pdf->Open(); + $pagenb=0; + $pdf->SetDrawColor(128,128,128); + + $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); + $pdf->SetSubject($outputlangs->transnoentities("PdfCommercialProposalTitle")); + $pdf->SetCreator("Dolibarr ".DOL_VERSION); + $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfCommercialProposalTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); + + $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite); // Left, Top, Right + + // Does we have at least one line with discount $this->atleastonediscount + foreach ($object->lines as $line) { + if ($line->remise_percent){ + $this->atleastonediscount = true; + break; + } + } + + + + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + + $heightforinfotot = 40; // Height reserved to output the info and total part + $heightforsignature = empty($conf->global->PROPAL_DISABLE_SIGNATURE)?(pdfGetHeightForHtmlContent($pdf, $outputlangs->transnoentities("ProposalCustomerSignature"))+10):0; + $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5); // Height reserved to output the free text on last page + $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22); // Height reserved to output the footer (value include bottom margin) + //print $heightforinfotot + $heightforsignature + $heightforfreetext + $heightforfooter;exit; + + $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(0, 3, ''); // Set interline to 3 + $pdf->SetTextColor(0,0,0); + + + $tab_top = 90+$top_shift; + $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10); + + + // Incoterm + $height_incoterms = 0; + if ($conf->incoterm->enabled) + { + $desc_incoterms = $object->getIncotermsForPDF(); + if ($desc_incoterms) + { + $tab_top -= 2; + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1); + $nexY = $pdf->GetY(); + $height_incoterms=$nexY-$tab_top; + + // Rect prend une longueur en 3eme param + $pdf->SetDrawColor(192,192,192); + $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1); + + $tab_top = $nexY+6; + } + } + + // Affiche notes + $notetoshow=empty($object->note_public)?'':$object->note_public; + if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE)) + { + // Get first sale rep + if (is_object($object->thirdparty)) + { + $salereparray=$object->thirdparty->getSalesRepresentatives($user); + $salerepobj=new User($this->db); + $salerepobj->fetch($salereparray[0]['id']); + if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature); + } + } + if (! empty($conf->global->MAIN_ADD_CREATOR_IN_NOTE) && $object->user_author_id > 0) + { + $tmpuser=new User($this->db); + $tmpuser->fetch($object->user_author_id); + $notetoshow.='Affaire suivi par '.$tmpuser->getFullName($langs); + if ($tmpuser->email) $notetoshow.=', Mail: '.$tmpuser->email; + if ($tmpuser->office_phone) $notetoshow.=', Tel: '.$tmpuser->office_phone; + } + + $pagenb = $pdf->getPage(); + if ($notetoshow) + { + $tab_top -= 2; + + $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite; + $pageposbeforenote = $pagenb; + + $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs); + + + $pdf->startTransaction(); + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + // Description + $pageposafternote=$pdf->getPage(); + $posyafter = $pdf->GetY(); + + if($pageposafternote>$pageposbeforenote ) + { + $pdf->rollbackTransaction(true); + + // prepar pages to receive notes + while ($pagenb < $pageposafternote) { + $pdf->AddPage(); + $pagenb++; + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + // $this->_pagefoot($pdf,$object,$outputlangs,1); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + } + + // back to start + $pdf->setPage($pageposbeforenote); + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1); + $pageposafternote=$pdf->getPage(); + + $posyafter = $pdf->GetY(); + + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20))) // There is no space left for total+free text + { + $pdf->AddPage('','',true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + $pdf->setTopMargin($tab_top_newpage); + // The only function to edit the bottom margin of current page to set it. + $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext); + //$posyafter = $tab_top_newpage; + } + + + // apply note frame to previus pages + $i = $pageposbeforenote; + while ($i < $pageposafternote) { + $pdf->setPage($i); + + + $pdf->SetDrawColor(128,128,128); + // Draw note frame + if($i>$pageposbeforenote){ + $height_note = $this->page_hauteur - ($tab_top_newpage + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note + 1); + } + else{ + $height_note = $this->page_hauteur - ($tab_top + $heightforfooter); + $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1); + } + + // Add footer + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + $this->_pagefoot($pdf,$object,$outputlangs,1); + + $i++; + } + + // apply note frame to last page + $pdf->setPage($pageposafternote); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + $height_note=$posyafter-$tab_top_newpage; + $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1); + + } + else // No pagebreak + { + $pdf->commitTransaction(); + $posyafter = $pdf->GetY(); + $height_note=$posyafter-$tab_top; + $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1); + + + if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) ) + { + // not enough space, need to add page + $pdf->AddPage('','',true); + $pagenb++; + $pageposafternote++; + $pdf->setPage($pageposafternote); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + + $posyafter = $tab_top_newpage; + } + + } + + $tab_height = $tab_height - $height_note; + $tab_top = $posyafter +6; + } + else + { + $height_note=0; + } + + $iniY = $tab_top + 7; + $curY = $tab_top + 7; + $nexY = $tab_top + 7; + + // Use new auto collum system + $this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref); + + // Loop on each lines + $pageposbeforeprintlines=$pdf->getPage(); + $pagenb = $pageposbeforeprintlines; + for ($i = 0; $i < $nblignes; $i++) + { + $curY = $nexY; + $pdf->SetFont('','', $default_font_size - 1); // Into loop to work with multipage + $pdf->SetTextColor(0,0,0); + + // Define size of image if we need it + $imglinesize=array(); + if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]); + + $pdf->setTopMargin($tab_top_newpage); + $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot); // The only function to edit the bottom margin of current page to set it. + $pageposbefore=$pdf->getPage(); + + $showpricebeforepagebreak=1; + $posYAfterImage=0; + $posYAfterDescription=0; + + if($this->getColumnStatus('photo')) + { + // We start with Photo of product line + if (isset($imglinesize['width']) && isset($imglinesize['height']) && ($curY + $imglinesize['height']) > ($this->page_hauteur-($heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot))) // If photo too high, we moved completely on new 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($pageposbefore+1); + + $curY = $tab_top_newpage; + $showpricebeforepagebreak=0; + } + + + if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) + { + $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300); // Use 300 dpi + // $pdf->Image does not increase value return by getY, so we save it manually + $posYAfterImage=$curY+$imglinesize['height']; + } + } + + // Description of product line + if($this->getColumnStatus('desc')) + { + $pdf->startTransaction(); + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc); + $pageposafter=$pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak + { + $pdf->rollbackTransaction(true); + $pageposafter=$pageposbefore; + //print $pageposafter.'-'.$pageposbefore;exit; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. + pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc); + + $pageposafter=$pdf->getPage(); + $posyafter=$pdf->GetY(); + //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; + if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforsignature+$heightforinfotot))) // There is no space left for total+free text + { + if ($i == ($nblignes-1)) // No more lines, and no space left to show total, so we create a new 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($pageposafter+1); + } + } + else + { + // We found a page break + $showpricebeforepagebreak=0; + } + } + else // No pagebreak + { + $pdf->commitTransaction(); + } + $posYAfterDescription=$pdf->GetY(); + } + + $nexY = $pdf->GetY(); + $pageposafter=$pdf->getPage(); + + $pdf->setPage($pageposbefore); + $pdf->setTopMargin($this->marge_haute); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + + // We suppose that a too long description or photo were moved completely on next page + if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) { + $pdf->setPage($pageposafter); $curY = $tab_top_newpage; + } + + $pdf->SetFont('','', $default_font_size - 1); // On repositionne la police par defaut + + // VAT Rate + if ($this->getColumnStatus('vat')) + { + $vat_rate = pdf_getlinevatrate($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate); + $nexY = max($pdf->GetY(),$nexY); + } + + // Unit price before discount + if ($this->getColumnStatus('subprice')) + { + $up_excl_tax = pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax); + $nexY = max($pdf->GetY(),$nexY); + } + + // Quantity + // Enough for 6 chars + if ($this->getColumnStatus('qty')) + { + $qty = pdf_getlineqty($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'qty', $qty); + $nexY = max($pdf->GetY(),$nexY); + } + + + // Unit + if ($this->getColumnStatus('unit')) + { + $unit = pdf_getlineunit($object, $i, $outputlangs, $hidedetails, $hookmanager); + $this->printStdColumnContent($pdf, $curY, 'unit', $unit); + $nexY = max($pdf->GetY(),$nexY); + } + + // Discount on line + if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent) + { + $remise_percent = pdf_getlineremisepercent($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent); + $nexY = max($pdf->GetY(),$nexY); + } + + // Total HT line + if ($this->getColumnStatus('totalexcltax')) + { + $total_excl_tax = pdf_getlinetotalexcltax($object, $i, $outputlangs, $hidedetails); + $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax); + $nexY = max($pdf->GetY(),$nexY); + } + + + $parameters=array( + 'object' => $object, + 'i' => $i, + 'pdf' =>& $pdf, + 'curY' =>& $curY, + 'nexY' =>& $nexY, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails + ); + $reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this); // Note that $object may have been modified by hook + + + + // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva + if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva; + else $tvaligne=$object->lines[$i]->total_tva; + + $localtax1ligne=$object->lines[$i]->total_localtax1; + $localtax2ligne=$object->lines[$i]->total_localtax2; + $localtax1_rate=$object->lines[$i]->localtax1_tx; + $localtax2_rate=$object->lines[$i]->localtax2_tx; + $localtax1_type=$object->lines[$i]->localtax1_type; + $localtax2_type=$object->lines[$i]->localtax2_type; + + if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100; + if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100; + if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100; + + $vatrate=(string) $object->lines[$i]->tva_tx; + + // Retrieve type from database for backward compatibility with old records + if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined + && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax + { + $localtaxtmp_array=getLocalTaxesFromRate($vatrate,0,$object->thirdparty,$mysoc); + $localtax1_type = $localtaxtmp_array[0]; + $localtax2_type = $localtaxtmp_array[2]; + } + + // retrieve global local tax + if ($localtax1_type && $localtax1ligne != 0) + $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne; + if ($localtax2_type && $localtax2ligne != 0) + $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne; + + if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*'; + if (! isset($this->tva[$vatrate])) $this->tva[$vatrate]=0; + $this->tva[$vatrate] += $tvaligne; + + if ($posYAfterImage > $posYAfterDescription) $nexY=$posYAfterImage; + + // Add line + if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1)) + { + $pdf->setPage($pageposafter); + $pdf->SetLineStyle(array('dash'=>'1,1','color'=>array(80,80,80))); + //$pdf->SetDrawColor(190,190,200); + $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1); + $pdf->SetLineStyle(array('dash'=>0)); + } + + $nexY+=2; // Passe espace entre les lignes + + // Detect if some page were added automatically and output _tableau for past pages + while ($pagenb < $pageposafter) + { + $pdf->setPage($pagenb); + if ($pagenb == $pageposbeforeprintlines) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + $pagenb++; + $pdf->setPage($pagenb); + $pdf->setPageOrientation('', 1, 0); // The only function to edit the bottom margin of current page to set it. + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak) + { + if ($pagenb == $pageposafter) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, 0, 1, $object->multicurrency_code); + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + } + $this->_pagefoot($pdf,$object,$outputlangs,1); + // New page + $pdf->AddPage(); + if (! empty($tplidx)) $pdf->useTemplate($tplidx); + $pagenb++; + if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs); + } + } + + // Show square + if ($pagenb == $pageposbeforeprintlines) + { + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 0, 0, $object->multicurrency_code); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1; + } + else + { + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); + $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforsignature - $heightforfooter + 1; + } + + // Affiche zone infos + $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs); + + // Affiche zone totaux + $posy=$this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs); + + // Affiche zone versements + /* + if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included) + { + $posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs); + } + */ + + // Customer signature area + if (empty($conf->global->PROPAL_DISABLE_SIGNATURE)) + { + $posy=$this->_signature_area($pdf, $object, $posy, $outputlangs); + } + + // Pied de page + $this->_pagefoot($pdf,$object,$outputlangs); + if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages(); + + //If propal merge product PDF is active + if (!empty($conf->global->PRODUIT_PDF_MERGE_PROPAL)) + { + require_once DOL_DOCUMENT_ROOT.'/product/class/propalmergepdfproduct.class.php'; + + $already_merged = array (); + foreach ( $object->lines as $line ) { + if (! empty($line->fk_product) && ! (in_array($line->fk_product, $already_merged))) { + // Find the desire PDF + $filetomerge = new Propalmergepdfproduct($this->db); + + if ($conf->global->MAIN_MULTILANGS) { + $filetomerge->fetch_by_product($line->fk_product, $outputlangs->defaultlang); + } else { + $filetomerge->fetch_by_product($line->fk_product); + } + + $already_merged[] = $line->fk_product; + + $product = new Product($this->db); + $product->fetch($line->fk_product); + + if ($product->entity!=$conf->entity) { + $entity_product_file=$product->entity; + } else { + $entity_product_file=$conf->entity; + } + + // If PDF is selected and file is not empty + if (count($filetomerge->lines) > 0) { + foreach ( $filetomerge->lines as $linefile ) { + if (! empty($linefile->id) && ! empty($linefile->file_name)) { + + + if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { + if (! empty($conf->product->enabled)) { + $filetomerge_dir = $conf->product->multidir_output[$entity_product_file] . '/' . get_exdir($product->id,2,0,0,$product,'product') . $product->id ."/photos"; + } elseif (! empty($conf->service->enabled)) { + $filetomerge_dir = $conf->service->multidir_output[$entity_product_file] . '/' . get_exdir($product->id,2,0,0,$product,'product') . $product->id ."/photos"; + } + } + else + { + if (! empty($conf->product->enabled)) { + $filetomerge_dir = $conf->product->multidir_output[$entity_product_file] . '/' . get_exdir(0,0,0,0,$product,'product') . dol_sanitizeFileName($product->ref); + } elseif (! empty($conf->service->enabled)) { + $filetomerge_dir = $conf->service->multidir_output[$entity_product_file] . '/' . get_exdir(0,0,0,0,$product,'product') . dol_sanitizeFileName($product->ref); + } + } + + dol_syslog(get_class($this) . ':: upload_dir=' . $filetomerge_dir, LOG_DEBUG); + + $infile = $filetomerge_dir . '/' . $linefile->file_name; + if (file_exists($infile) && is_readable($infile)) { + $pagecount = $pdf->setSourceFile($infile); + for($i = 1; $i <= $pagecount; $i ++) { + $tplIdx = $pdf->importPage($i); + if ($tplIdx!==false) { + $s = $pdf->getTemplatesize($tplIdx); + $pdf->AddPage($s['h'] > $s['w'] ? 'P' : 'L'); + $pdf->useTemplate($tplIdx); + } else { + setEventMessages(null, array($infile.' cannot be added, probably protected PDF'),'warnings'); + } + } + } + } + } + } + } + } + } + + $pdf->Close(); + + $pdf->Output($file,'F'); + + //Add pdfgeneration hook + $hookmanager->initHooks(array('pdfgeneration')); + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + global $action; + $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $this->result = array('fullpath'=>$file); + + return 1; // Pas d'erreur + } + else + { + $this->error=$langs->trans("ErrorCanNotCreateDir",$dir); + return 0; + } + } + else + { + $this->error=$langs->trans("ErrorConstantNotDefined","PROP_OUTPUTDIR"); + return 0; + } + } + + /** + * Show payments table + * + * @param TCPDF $pdf Object PDF + * @param Object $object Object proposal + * @param int $posy Position y in PDF + * @param Translate $outputlangs Object langs for output + * @return int <0 if KO, >0 if OK + */ + function _tableau_versements(&$pdf, $object, $posy, $outputlangs) + { + + } + + + /** + * Show miscellaneous information (payment mode, payment term, ...) + * + * @param TCPDF $pdf Object PDF + * @param Object $object Object to show + * @param int $posy Y + * @param Translate $outputlangs Langs object + * @return void + */ + function _tableau_info(&$pdf, $object, $posy, $outputlangs) + { + global $conf; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $pdf->SetFont('','', $default_font_size - 1); + + // If France, show VAT mention if not applicable + if ($this->emetteur->country_code == 'FR' && $this->franchise == 1) + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("VATIsNotUsedForInvoice"), 0, 'L', 0); + + $posy=$pdf->GetY()+4; + } + + $posxval=52; + + // Show shipping date + if (! empty($object->date_livraison)) + { + $outputlangs->load("sendings"); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("DateDeliveryPlanned").':'; + $pdf->MultiCell(80, 4, $titre, 0, 'L'); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $dlp=dol_print_date($object->date_livraison,"daytext",false,$outputlangs,true); + $pdf->MultiCell(80, 4, $dlp, 0, 'L'); + + $posy=$pdf->GetY()+1; + } + elseif ($object->availability_code || $object->availability) // Show availability conditions + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("AvailabilityPeriod").':'; + $pdf->MultiCell(80, 4, $titre, 0, 'L'); + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_availability=$outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset($object->availability); + $lib_availability=str_replace('\n',"\n",$lib_availability); + $pdf->MultiCell(80, 4, $lib_availability, 0, 'L'); + + $posy=$pdf->GetY()+1; + } + + // Show payments conditions + if (empty($conf->global->PROPALE_PDF_HIDE_PAYMENTTERMCOND) && ($object->cond_reglement_code || $object->cond_reglement)) + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentConditions").':'; + $pdf->MultiCell(43, 4, $titre, 0, 'L'); + + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_condition_paiement=$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code)!=('PaymentCondition'.$object->cond_reglement_code)?$outputlangs->transnoentities("PaymentCondition".$object->cond_reglement_code):$outputlangs->convToOutputCharset($object->cond_reglement_doc); + $lib_condition_paiement=str_replace('\n',"\n",$lib_condition_paiement); + $pdf->MultiCell(67, 4, $lib_condition_paiement,0,'L'); + + $posy=$pdf->GetY()+3; + } + + if (empty($conf->global->PROPALE_PDF_HIDE_PAYMENTTERMMODE)) + { + // Check a payment mode is defined + /* Not required on a proposal + if (empty($object->mode_reglement_code) + && ! $conf->global->FACTURE_CHQ_NUMBER + && ! $conf->global->FACTURE_RIB_NUMBER) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->MultiCell(90, 3, $outputlangs->transnoentities("ErrorNoPaiementModeConfigured"),0,'L',0); + $pdf->SetTextColor(0,0,0); + + $posy=$pdf->GetY()+1; + } + */ + + // Show payment mode + if ($object->mode_reglement_code + && $object->mode_reglement_code != 'CHQ' + && $object->mode_reglement_code != 'VIR') + { + $pdf->SetFont('','B', $default_font_size - 2); + $pdf->SetXY($this->marge_gauche, $posy); + $titre = $outputlangs->transnoentities("PaymentMode").':'; + $pdf->MultiCell(80, 5, $titre, 0, 'L'); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posxval, $posy); + $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement); + $pdf->MultiCell(80, 5, $lib_mode_reg,0,'L'); + + $posy=$pdf->GetY()+2; + } + + // Show payment mode CHQ + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') + { + // Si mode reglement non force ou si force a CHQ + if (! empty($conf->global->FACTURE_CHQ_NUMBER)) + { + $diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE); + + if ($conf->global->FACTURE_CHQ_NUMBER > 0) + { + $account = new Account($this->db); + $account->fetch($conf->global->FACTURE_CHQ_NUMBER); + + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','B', $default_font_size - $diffsizetitle); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$account->proprio),0,'L',0); + $posy=$pdf->GetY()+1; + + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','', $default_font_size - $diffsizetitle); + $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($account->owner_address), 0, 'L', 0); + $posy=$pdf->GetY()+2; + } + } + if ($conf->global->FACTURE_CHQ_NUMBER == -1) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','B', $default_font_size - $diffsizetitle); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities('PaymentByChequeOrderedTo',$this->emetteur->name),0,'L',0); + $posy=$pdf->GetY()+1; + + if (empty($conf->global->MAIN_PDF_HIDE_CHQ_ADDRESS)) + { + $pdf->SetXY($this->marge_gauche, $posy); + $pdf->SetFont('','', $default_font_size - $diffsizetitle); + $pdf->MultiCell(100, 3, $outputlangs->convToOutputCharset($this->emetteur->getFullAddress()), 0, 'L', 0); + $posy=$pdf->GetY()+2; + } + } + } + } + + // If payment mode not forced or forced to VIR, show payment with BAN + if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') + { + if (! empty($object->fk_account) || ! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER)) + { + $bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account); + if (! empty($object->fk_bank)) $bankid=$object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank + $account = new Account($this->db); + $account->fetch($bankid); + + $curx=$this->marge_gauche; + $cury=$posy; + + $posy=pdf_bank($pdf,$outputlangs,$curx,$cury,$account,0,$default_font_size); + + $posy+=2; + } + } + } + + return $posy; + } + + + /** + * Show total to pay + * + * @param PDF $pdf Object PDF + * @param Facture $object Object invoice + * @param int $deja_regle Montant deja regle + * @param int $posy Position depart + * @param Translate $outputlangs Objet langs + * @return int Position pour suite + */ + function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs) + { + global $conf,$mysoc; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + $tab2_top = $posy; + $tab2_hl = 4; + $pdf->SetFont('','', $default_font_size - 1); + + // Tableau total + $col1x = 120; $col2x = 170; + if ($this->page_largeur < 210) // To work with US executive format + { + $col2x-=20; + } + $largcol2 = ($this->page_largeur - $this->marge_droite - $col2x); + + $useborder=0; + $index = 0; + + // Total HT + $pdf->SetFillColor(255,255,255); + $pdf->SetXY($col1x, $tab2_top + 0); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalHT"), 0, 'L', 1); + + $total_ht = ($conf->multicurrency->enabled && $object->mylticurrency_tx != 1 ? $object->multicurrency_total_ht : $object->total_ht); + $pdf->SetXY($col2x, $tab2_top + 0); + $pdf->MultiCell($largcol2, $tab2_hl, price($total_ht + (! empty($object->remise)?$object->remise:0), 0, $outputlangs), 0, 'R', 1); + + // Show VAT by rates and total + $pdf->SetFillColor(248,248,248); + + $total_ttc = ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? $object->multicurrency_total_ttc : $object->total_ttc; + + $this->atleastoneratenotnull=0; + if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT)) + { + $tvaisnull=((! empty($this->tva) && count($this->tva) == 1 && isset($this->tva['0.000']) && is_float($this->tva['0.000'])) ? true : false); + if (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL) && $tvaisnull) + { + // Nothing to do + } + else + { + //Local tax 1 before VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on') + //{ + foreach( $this->localtax1 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('1','3','5'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey!=0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' '; + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + } + //} + //Local tax 2 before VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on') + //{ + foreach( $this->localtax2 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('1','3','5'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey!=0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' '; + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + + } + } + } + //} + // VAT + foreach($this->tva as $tvakey => $tvaval) + { + if ($tvakey != 0) // On affiche pas taux 0 + { + $this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat =$outputlangs->transcountrynoentities("TotalVAT",$mysoc->country_code).' '; + $totalvat.=vatrate($tvakey,1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + + //Local tax 1 after VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on') + //{ + foreach( $this->localtax1 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('2','4','6'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + if ($tvakey != 0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT1",$mysoc->country_code).' '; + + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + } + //} + //Local tax 2 after VAT + //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on') + //{ + foreach( $this->localtax2 as $localtax_type => $localtax_rate ) + { + if (in_array((string) $localtax_type, array('2','4','6'))) continue; + + foreach( $localtax_rate as $tvakey => $tvaval ) + { + // retrieve global local tax + if ($tvakey != 0) // On affiche pas taux 0 + { + //$this->atleastoneratenotnull++; + + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + + $tvacompl=''; + if (preg_match('/\*/',$tvakey)) + { + $tvakey=str_replace('*','',$tvakey); + $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; + } + $totalvat = $outputlangs->transcountrynoentities("TotalLT2",$mysoc->country_code).' '; + + $totalvat.=vatrate(abs($tvakey),1).$tvacompl; + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); + } + } + } + //} + + // Total TTC + $index++; + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->SetTextColor(0,0,60); + $pdf->SetFillColor(224,224,224); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("TotalTTC"), $useborder, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($total_ttc, 0, $outputlangs), $useborder, 'R', 1); + } + } + + $pdf->SetTextColor(0,0,0); + + /* + $resteapayer = $object->total_ttc - $deja_regle; + if (! empty($object->paye)) $resteapayer=0; + */ + + if ($deja_regle > 0) + { + $index++; + + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("AlreadyPaid"), 0, 'L', 0); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($deja_regle, 0, $outputlangs), 0, 'R', 0); + + /* + if ($object->close_code == 'discount_vat') + { + $index++; + $pdf->SetFillColor(255,255,255); + + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("EscompteOfferedShort"), $useborder, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($object->total_ttc - $deja_regle, 0, $outputlangs), $useborder, 'R', 1); + + $resteapayer=0; + } + */ + + $index++; + $pdf->SetTextColor(0,0,60); + $pdf->SetFillColor(224,224,224); + $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($col2x-$col1x, $tab2_hl, $outputlangs->transnoentities("RemainderToPay"), $useborder, 'L', 1); + + $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); + $pdf->MultiCell($largcol2, $tab2_hl, price($resteapayer, 0, $outputlangs), $useborder, 'R', 1); + + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetTextColor(0,0,0); + } + + $index++; + return ($tab2_top + ($tab2_hl * $index)); + } + + /** + * Show table for lines + * + * @param PDF $pdf Object PDF + * @param string $tab_top Top position of table + * @param string $tab_height Height of table (rectangle) + * @param int $nexY Y (not used) + * @param Translate $outputlangs Langs object + * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title + * @param int $hidebottom Hide bottom bar of array + * @param string $currency Currency code + * @return void + */ + function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='') + { + global $conf; + + // Force to disable hidetop and hidebottom + $hidebottom=0; + if ($hidetop) $hidetop=-1; + + $currency = !empty($currency) ? $currency : $conf->currency; + $default_font_size = pdf_getPDFFontSize($outputlangs); + + // Amount in (at tab_top - 1) + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + + if (empty($hidetop)) + { + $titre = $outputlangs->transnoentities("AmountInCurrency",$outputlangs->transnoentitiesnoconv("Currency".$currency)); + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top-4); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + + //$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR='230,230,230'; + if (! empty($conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)) $pdf->Rect($this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_droite-$this->marge_gauche, 5, 'F', null, explode(',',$conf->global->MAIN_PDF_TITLE_BACKGROUND_COLOR)); + } + + $pdf->SetDrawColor(128,128,128); + $pdf->SetFont('','', $default_font_size - 1); + + // Output Rect + $this->printRect($pdf,$this->marge_gauche, $tab_top, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $tab_height, $hidetop, $hidebottom); // Rect prend une longueur en 3eme param et 4eme param + + + foreach ($this->cols as $colKey => $colDef) + { + if(!$this->getColumnStatus($colKey)) continue; + + // get title label + $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']); + + // Add column separator + if(!empty($colDef['border-left'])){ + $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height); + } + + if (empty($hidetop)) + { + $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] ); + + $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1]; + $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']); + } + } + + if (empty($hidetop)){ + $pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5); // line prend une position y en 2eme param et 4eme param + } + + + } + + /** + * Show top header of page. + * + * @param PDF $pdf Object PDF + * @param Object $object Object to show + * @param int $showaddress 0=no, 1=yes + * @param Translate $outputlangs Object lang for output + * @return void + */ + function _pagehead(&$pdf, $object, $showaddress, $outputlangs) + { + global $conf,$langs; + + $outputlangs->load("main"); + $outputlangs->load("bills"); + $outputlangs->load("propal"); + $outputlangs->load("companies"); + + $default_font_size = pdf_getPDFFontSize($outputlangs); + + pdf_pagehead($pdf,$outputlangs,$this->page_hauteur); + + // Show Draft Watermark + if($object->statut==0 && (! empty($conf->global->PROPALE_DRAFT_WATERMARK)) ) + { + pdf_watermark($pdf,$outputlangs,$this->page_hauteur,$this->page_largeur,'mm',$conf->global->PROPALE_DRAFT_WATERMARK); + } + + $pdf->SetTextColor(0,0,60); + $pdf->SetFont('','B', $default_font_size + 3); + + $posy=$this->marge_haute; + $posx=$this->page_largeur-$this->marge_droite-100; + + $pdf->SetXY($this->marge_gauche,$posy); + + // Logo + $logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo; + if ($this->emetteur->logo) + { + if (is_readable($logo)) + { + $height=pdf_getHeightForLogo($logo); + $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height); // width=0 (auto) + } + else + { + $pdf->SetTextColor(200,0,0); + $pdf->SetFont('','B',$default_font_size - 2); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L'); + } + } + else + { + $text=$this->emetteur->name; + $pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L'); + } + + $pdf->SetFont('','B',$default_font_size + 3); + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $title=$outputlangs->transnoentities("PdfCommercialProposalTitle"); + $pdf->MultiCell(100, 4, $title, '', 'R'); + + $pdf->SetFont('','B',$default_font_size); + + $posy+=5; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 4, $outputlangs->transnoentities("Ref")." : " . $outputlangs->convToOutputCharset($object->ref), '', 'R'); + + $posy+=1; + $pdf->SetFont('','', $default_font_size - 2); + + if ($object->ref_client) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : " . $outputlangs->convToOutputCharset($object->ref_client), '', 'R'); + } + + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Date")." : " . dol_print_date($object->date,"day",false,$outputlangs,true), '', 'R'); + + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DateEndPropal")." : " . dol_print_date($object->fin_validite,"day",false,$outputlangs,true), '', 'R'); + + if ($object->thirdparty->code_client) + { + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("CustomerCode")." : " . $outputlangs->transnoentities($object->thirdparty->code_client), '', 'R'); + } + + // Get contact + if (!empty($conf->global->DOC_SHOW_FIRST_SALES_REP)) + { + $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL'); + if (count($arrayidcontact) > 0) + { + $usertmp=new User($this->db); + $usertmp->fetch($arrayidcontact[0]); + $posy+=4; + $pdf->SetXY($posx,$posy); + $pdf->SetTextColor(0,0,60); + $pdf->MultiCell(100, 3, $langs->trans("SalesRepresentative")." : ".$usertmp->getFullName($langs), '', 'R'); + } + } + + $posy+=2; + + $top_shift = 0; + // Show list of linked objects + $current_y = $pdf->getY(); + $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); + if ($current_y < $pdf->getY()) + { + $top_shift = $pdf->getY() - $current_y; + } + + if ($showaddress) + { + // Sender properties + $carac_emetteur=''; + // Add internal contact of proposal if defined + $arrayidcontact=$object->getIdContact('internal','SALESREPFOLL'); + if (count($arrayidcontact) > 0) + { + $object->fetch_user($arrayidcontact[0]); + $labelbeforecontactname=($outputlangs->transnoentities("FromContactName")!='FromContactName'?$outputlangs->transnoentities("FromContactName"):$outputlangs->transnoentities("Name")); + $carac_emetteur .= ($carac_emetteur ? "\n" : '' ).$labelbeforecontactname." ".$outputlangs->convToOutputCharset($object->user->getFullName($outputlangs))."\n"; + } + + $carac_emetteur .= pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, '', 0, 'source', $object); + + // Show sender + $posy=42+$top_shift; + $posx=$this->marge_gauche; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->page_largeur-$this->marge_droite-80; + $hautcadre=40; + + // Show sender frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx,$posy-5); + $pdf->MultiCell(66,5, $outputlangs->transnoentities("BillFrom").":", 0, 'L'); + $pdf->SetXY($posx,$posy); + $pdf->SetFillColor(230,230,230); + $pdf->MultiCell(82, $hautcadre, "", 0, 'R', 1); + $pdf->SetTextColor(0,0,60); + + // Show sender name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell(80, 4, $outputlangs->convToOutputCharset($this->emetteur->name), 0, 'L'); + $posy=$pdf->getY(); + + // Show sender information + $pdf->SetXY($posx+2,$posy); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->MultiCell(80, 4, $carac_emetteur, 0, 'L'); + + + // If CUSTOMER contact defined, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','CUSTOMER'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } + + //Recipient name + // On peut utiliser le nom de la societe du contact + if ($usecontact && !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) { + $thirdparty = $object->contact; + } else { + $thirdparty = $object->thirdparty; + } + + $carac_client_name= pdfBuildThirdpartyName($thirdparty, $outputlangs); + + $carac_client=pdf_build_address($outputlangs,$this->emetteur,$object->thirdparty,($usecontact?$object->contact:''),$usecontact,'target',$object); + + // Show recipient + $widthrecbox=100; + if ($this->page_largeur < 210) $widthrecbox=84; // To work with US executive format + $posy=42+$top_shift; + $posx=$this->page_largeur-$this->marge_droite-$widthrecbox; + if (! empty($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) $posx=$this->marge_gauche; + + // Show recipient frame + $pdf->SetTextColor(0,0,0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->SetXY($posx+2,$posy-5); + $pdf->MultiCell($widthrecbox, 5, $outputlangs->transnoentities("BillTo").":", 0, 'L'); + $pdf->Rect($posx, $posy, $widthrecbox, $hautcadre); + + // Show recipient name + $pdf->SetXY($posx+2,$posy+3); + $pdf->SetFont('','B', $default_font_size); + $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + + $posy = $pdf->getY(); + + // Show recipient information + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); + } + + $pdf->SetTextColor(0,0,0); + return $top_shift; + } + + /** + * Show footer of page. Need this->emetteur object + * + * @param PDF $pdf PDF + * @param Object $object Object to show + * @param Translate $outputlangs Object lang for output + * @param int $hidefreetext 1=Hide free text + * @return int Return height of bottom margin including footer text + */ + function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0) + { + global $conf; + $showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS; + return pdf_pagefoot($pdf,$outputlangs,'PROPOSAL_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext); + } + + /** + * Show area for the customer to sign + * + * @param PDF $pdf Object PDF + * @param Facture $object Object invoice + * @param int $posy Position depart + * @param Translate $outputlangs Objet langs + * @return int Position pour suite + */ + function _signature_area(&$pdf, $object, $posy, $outputlangs) + { + global $conf; + $default_font_size = pdf_getPDFFontSize($outputlangs); + $tab_top = $posy + 4; + $tab_hl = 4; + + $posx = 120; + $largcol = ($this->page_largeur - $this->marge_droite - $posx); + $useborder=0; + $index = 0; + // Total HT + $pdf->SetFillColor(255,255,255); + $pdf->SetXY($posx, $tab_top + 0); + $pdf->SetFont('','', $default_font_size - 2); + $pdf->MultiCell($largcol, $tab_hl, $outputlangs->transnoentities("ProposalCustomerSignature"), 0, 'L', 1); + + $pdf->SetXY($posx, $tab_top + $tab_hl); + $pdf->MultiCell($largcol, $tab_hl*3, '', 1, 'R'); + if (! empty($conf->global->MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING)) { + $pdf->addEmptySignatureAppearance($posx, $tab_top + $tab_hl, $largcol, $tab_hl*3); + } + + return ($tab_hl*7); + } + + + /** + * Define Array Column Field + * + * @param object $object common object + * @param outputlangs $outputlangs langs + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref + * @return null + */ + function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){ + + global $conf, $hookmanager; + + // Default field style for content + $this->defaultContentsFieldsStyle = array( + 'align' => 'R', // R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + // Default field style for content + $this->defaultTitlesFieldsStyle = array( + 'align' => 'C', // R,C,L + 'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ); + + /* + * For exemple + $this->cols['theColKey'] = array( + 'rank' => $rank, // int : use for ordering columns + 'width' => 20, // the column width in mm + 'title' => array( + 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + 'label' => ' ', // the final label : used fore final generated text + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', // text alignement : R,C,L + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + ); + */ + + $rank=0; // do not use negative rank + $this->cols['desc'] = array( + 'rank' => $rank, + 'width' => false, // only for desc + 'status' => true, + 'title' => array( + 'textkey' => 'Designation', // use lang key is usefull in somme case with module + 'align' => 'L', + // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label + // 'label' => ' ', // the final label + 'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'content' => array( + 'align' => 'L', + ), + ); + + $rank = $rank + 10; + $this->cols['photo'] = array( + 'rank' => $rank, + 'width' => (empty($conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH)?20:$conf->global->MAIN_DOCUMENTS_WITH_PICTURE_WIDTH), // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Photo', + 'label' => ' ' + ), + 'content' => array( + 'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + ), + 'border-left' => false, // remove left line separator + ); + + if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE) && !empty($this->atleastonephoto)) + { + $this->cols['photo']['status'] = true; + } + + + $rank = $rank + 10; + $this->cols['vat'] = array( + 'rank' => $rank, + 'status' => false, + 'width' => 16, // in mm + 'title' => array( + 'textkey' => 'VAT' + ), + 'border-left' => true, // add left line separator + ); + + if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN)) + { + $this->cols['vat']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['subprice'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'PriceUHT' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['qty'] = array( + 'rank' => $rank, + 'width' => 16, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'Qty' + ), + 'border-left' => true, // add left line separator + ); + + $rank = $rank + 10; + $this->cols['progress'] = array( + 'rank' => $rank, + 'width' => 19, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Progress' + ), + 'border-left' => false, // add left line separator + ); + + if($this->situationinvoice) + { + $this->cols['progress']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['unit'] = array( + 'rank' => $rank, + 'width' => 11, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'Unit' + ), + 'border-left' => true, // add left line separator + ); + if($conf->global->PRODUCT_USE_UNITS){ + $this->cols['unit']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['discount'] = array( + 'rank' => $rank, + 'width' => 13, // in mm + 'status' => false, + 'title' => array( + 'textkey' => 'ReductionShort' + ), + 'border-left' => true, // add left line separator + ); + if ($this->atleastonediscount){ + $this->cols['discount']['status'] = true; + } + + $rank = $rank + 10; + $this->cols['totalexcltax'] = array( + 'rank' => $rank, + 'width' => 26, // in mm + 'status' => true, + 'title' => array( + 'textkey' => 'TotalHT' + ), + 'border-left' => true, // add left line separator + ); + + + $parameters=array( + 'object' => $object, + 'outputlangs' => $outputlangs, + 'hidedetails' => $hidedetails, + 'hidedesc' => $hidedesc, + 'hideref' => $hideref + ); + + $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this); // Note that $object may have been modified by hook + if ($reshook < 0) + { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + elseif (empty($reshook)) + { + $this->cols = array_replace($this->cols, $hookmanager->resArray); // array_replace is used to preserve keys + } + else + { + $this->cols = $hookmanager->resArray; + } + + } + +} diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index d06b1512cc6..3b60256c3ef 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -486,7 +486,8 @@ RevenueStamp=Revenue stamp YouMustCreateInvoiceFromThird=This option is only available when creating invoice from tab "customer" of third party YouMustCreateInvoiceFromSupplierThird=This option is only available when creating invoice from tab "supplier" of third party YouMustCreateStandardInvoiceFirstDesc=You have to create a standard invoice first and convert it to "template" to create a new template invoice -PDFCrabeDescription=Invoice PDF template Crabe. A complete invoice template (recommended Template) +PDFCrabeDescription=Invoice PDF template Crabe. A complete invoice template (deprecated Template) +PDFSpongeDescription=Invoice PDF template Sponge. A complete invoice template (recommended Template) PDFCrevetteDescription=Invoice PDF template Crevette. A complete invoice template for situation invoices TerreNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 MarsNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices, %syymm-nnnn for replacement invoices, %syymm-nnnn for down payment invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 diff --git a/htdocs/langs/en_US/orders.lang b/htdocs/langs/en_US/orders.lang index 06191d9f7b7..30fb0aa1320 100644 --- a/htdocs/langs/en_US/orders.lang +++ b/htdocs/langs/en_US/orders.lang @@ -140,7 +140,8 @@ OrderByEMail=EMail OrderByWWW=Online OrderByPhone=Phone # Documents models -PDFEinsteinDescription=A complete order model (logo...) +PDFEinsteinDescription=A complete order model (logo...)(deprecated Template) +PDFEratostheneDescription=A complete order model (logo...)(recommended Template) PDFEdisonDescription=A simple order model PDFProformaDescription=A complete proforma invoice (logo…) CreateInvoiceForThisCustomer=Bill orders diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index 5a7169ac925..55fb6372d74 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -77,7 +77,8 @@ TypeContact_propal_external_BILLING=Customer invoice contact TypeContact_propal_external_CUSTOMER=Customer contact following-up proposal TypeContact_propal_external_SHIPPING=Customer contact for delivery # Document models -DocModelAzurDescription=A complete proposal model (logo...) +DocModelAzurDescription=A complete proposal model (logo...)(deprecated Template) +DocModelCyanDescription=A complete proposal model (logo...)(recommended Template) DefaultModelPropalCreate=Default model creation DefaultModelPropalToBill=Default template when closing a business proposal (to be invoiced) DefaultModelPropalClosed=Default template when closing a business proposal (unbilled) From 523b03e1324984a073b84666dd1149b6ec7655ed Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Tue, 28 Aug 2018 13:32:38 +0200 Subject: [PATCH 008/433] Fix for new stripe API 2018-08-23 Fix break with change API --- .../triggers/interface_80_modStripe_Stripe.class.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php index ab0cd62eb82..f9985461df8 100644 --- a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php +++ b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php @@ -136,7 +136,6 @@ class InterfaceStripe $service = 'StripeLive'; $servicestatus = 1; } - // If customer is linked to Strip, we update/delete Stripe too if ($action == 'COMPANY_MODIFY') { dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); @@ -148,19 +147,22 @@ class InterfaceStripe if ($customer) { $namecleaned = $object->name ? $object->name : null; - $vatcleaned = $object->tva_intra ? $object->tva_intra : null; // We force data to "null" if empty as expected by Stripe + $vatcleaned = array( + "tax_id" => $object->tva_intra ? $object->tva_intra : null, // We force data to "null" if empty as expected by Stripe + "type" => 'vat', + ); // Detect if we change a Stripe info (email, description, vat id) $changerequested = 0; if (! empty($object->email) && $object->email != $customer->email) $changerequested++; if ($namecleaned != $customer->description) $changerequested++; - if ($vatcleaned != $customer->business_vat_id) $changerequested++; + if ($vatcleaned != $customer->tax_info) $changerequested++; if ($changerequested) { if (! empty($object->email)) $customer->email = $object->email; $customer->description = $namecleaned; - $customer->business_vat_id = $vatcleaned; + $customer->tax_info = $vatcleaned; $customer->save(); } From 90de2698c3668bc50e75eb34a5b3597963b39748 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Tue, 28 Aug 2018 13:34:59 +0200 Subject: [PATCH 009/433] Fix for new stripe API 2018-08-23 Fix break of change API --- htdocs/stripe/class/stripe.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index b8472d0b821..bf4103e51a8 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -166,7 +166,10 @@ class Stripe extends CommonObject { $dataforcustomer = array( "email" => $object->email, - "business_vat_id" => $object->tva_intra, + "tax_info" => array( + "tax_id" => $object->tva_intra ? $object->tva_intra : null, // We force data to "null" if empty as expected by Stripe + "type" => 'vat', + ), "description" => $object->name, "metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR'])) ); From 289dfc7fbeeab2c5269324f81fa0c9357c57ceac Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Tue, 28 Aug 2018 13:37:17 +0200 Subject: [PATCH 010/433] update API version We need to downgrade this change to V8 because some breaks occur if Stripe API is updated in dashboard to 2018-08-23 --- htdocs/stripe/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php index 7aa22678d7a..802dad47737 100644 --- a/htdocs/stripe/config.php +++ b/htdocs/stripe/config.php @@ -55,4 +55,4 @@ else \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']); \Stripe\Stripe::setAppInfo("Dolibarr Stripe", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version -\Stripe\Stripe::setApiVersion("2018-07-27"); // force version API +\Stripe\Stripe::setApiVersion("2018-08-23"); // force version API From 25be9f59896ebe323a034abd0255a2db87580cc3 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Wed, 29 Aug 2018 13:19:03 +0200 Subject: [PATCH 011/433] fix if null --- htdocs/stripe/class/stripe.class.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index bf4103e51a8..e8c0d7a3f12 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -166,13 +166,16 @@ class Stripe extends CommonObject { $dataforcustomer = array( "email" => $object->email, - "tax_info" => array( - "tax_id" => $object->tva_intra ? $object->tva_intra : null, // We force data to "null" if empty as expected by Stripe - "type" => 'vat', - ), "description" => $object->name, "metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR'])) ); + + if ($object->tva_intra!=null) + { + $dataforcustomer["tax_info"] = array( + "tax_id" => $object->tva_intra, + "type" => 'vat'); + } //$a = \Stripe\Stripe::getApiKey(); //var_dump($a);var_dump($key);exit; From ff44e65c38c640f5097e5570791af6d759e46995 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Mon, 10 Sep 2018 12:31:34 +0200 Subject: [PATCH 012/433] update api changelog 2018-09-06 introduce no change for dolibarr with 2018-08-23 --- htdocs/stripe/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php index 802dad47737..1c15b547fad 100644 --- a/htdocs/stripe/config.php +++ b/htdocs/stripe/config.php @@ -55,4 +55,4 @@ else \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']); \Stripe\Stripe::setAppInfo("Dolibarr Stripe", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version -\Stripe\Stripe::setApiVersion("2018-08-23"); // force version API +\Stripe\Stripe::setApiVersion("2018-09-06"); // force version API From 477acb2e4c6267971ca11c7a36889b6c5adf0204 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Fri, 14 Sep 2018 09:48:15 +0200 Subject: [PATCH 013/433] change new PDF version --- htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php | 2 +- htdocs/core/modules/propale/doc/pdf_azur.modules.php | 2 +- htdocs/core/modules/propale/doc/pdf_cyan.modules.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index 58129bea6e2..039f29fa379 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -76,7 +76,7 @@ class pdf_eratosthene extends ModelePDFCommandes * Dolibarr version of the loaded document * @public string */ - public $version = 'dolibarr'; + public $version = 'development'; public $page_largeur; public $page_hauteur; diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index 6e72e757fb6..e25abd5bc9e 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -47,7 +47,7 @@ class pdf_azur extends ModelePDFPropales var $type; var $phpmin = array(4,3,0); // Minimum version of PHP required by module - var $version = 'dolibarr'; + var $version = 'development'; var $page_largeur; var $page_hauteur; diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index 383f34acebd..c9bce8b07a4 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -47,7 +47,7 @@ class pdf_cyan extends ModelePDFPropales var $type; var $phpmin = array(4,3,0); // Minimum version of PHP required by module - var $version = 'dolibarr'; + var $version = 'development'; var $page_largeur; var $page_hauteur; From d1321e5a7b21ad5fa83ed03b494384d72a7487e5 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Fri, 14 Sep 2018 09:54:39 +0200 Subject: [PATCH 014/433] change new PDF version --- htdocs/core/modules/facture/doc/pdf_sponge.modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 72c2a5aaca6..74f4bf34acf 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -77,7 +77,7 @@ class pdf_sponge extends ModelePDFFactures * Dolibarr version of the loaded document * @public string */ - public $version = 'dolibarr'; + public $version = 'development'; public $page_largeur; public $page_hauteur; From 3fb2d4c159bb3dd62b143ca3ca9584bb25cb2849 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Tue, 18 Sep 2018 15:52:57 +0200 Subject: [PATCH 015/433] remove change on text --- htdocs/langs/en_US/bills.lang | 4 ++-- htdocs/langs/en_US/orders.lang | 4 ++-- htdocs/langs/en_US/propal.lang | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index ab2adf33441..95114c96446 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -488,8 +488,8 @@ RevenueStamp=Revenue stamp YouMustCreateInvoiceFromThird=This option is only available when creating invoice from tab "customer" of third party YouMustCreateInvoiceFromSupplierThird=This option is only available when creating invoice from tab "supplier" of third party YouMustCreateStandardInvoiceFirstDesc=You have to create a standard invoice first and convert it to "template" to create a new template invoice -PDFCrabeDescription=Invoice PDF template Crabe. A complete invoice template (deprecated Template) -PDFSpongeDescription=Invoice PDF template Sponge. A complete invoice template (recommended Template) +PDFCrabeDescription=Invoice PDF template Crabe. A complete invoice template (recommended Template) +PDFSpongeDescription=Invoice PDF template Sponge. A complete invoice template PDFCrevetteDescription=Invoice PDF template Crevette. A complete invoice template for situation invoices TerreNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 MarsNumRefModelDesc1=Return number with format %syymm-nnnn for standard invoices, %syymm-nnnn for replacement invoices, %syymm-nnnn for down payment invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequence with no break and no return to 0 diff --git a/htdocs/langs/en_US/orders.lang b/htdocs/langs/en_US/orders.lang index 1d286cc5ebd..77d2eda19a3 100644 --- a/htdocs/langs/en_US/orders.lang +++ b/htdocs/langs/en_US/orders.lang @@ -140,8 +140,8 @@ OrderByEMail=EMail OrderByWWW=Online OrderByPhone=Phone # Documents models -PDFEinsteinDescription=A complete order model (logo...)(deprecated Template) -PDFEratostheneDescription=A complete order model (logo...)(recommended Template) +PDFEinsteinDescription=A complete order model (logo...) +PDFEratostheneDescription=A complete order model (logo...) PDFEdisonDescription=A simple order model PDFProformaDescription=A complete proforma invoice (logo…) CreateInvoiceForThisCustomer=Bill orders diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index 44157780ce7..f336daa242d 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -77,8 +77,8 @@ TypeContact_propal_external_BILLING=Customer invoice contact TypeContact_propal_external_CUSTOMER=Customer contact following-up proposal TypeContact_propal_external_SHIPPING=Customer contact for delivery # Document models -DocModelAzurDescription=A complete proposal model (logo...)(deprecated Template) -DocModelCyanDescription=A complete proposal model (logo...)(recommended Template) +DocModelAzurDescription=A complete proposal model (logo...) +DocModelCyanDescription=A complete proposal model (logo...) DefaultModelPropalCreate=Default model creation DefaultModelPropalToBill=Default template when closing a business proposal (to be invoiced) DefaultModelPropalClosed=Default template when closing a business proposal (unbilled) From 95989019335d08499c8b33e1e1ca7d78e12d49b6 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Thu, 27 Sep 2018 09:43:43 +0200 Subject: [PATCH 016/433] Update config.php --- htdocs/stripe/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php index 1c15b547fad..6141c2a32f8 100644 --- a/htdocs/stripe/config.php +++ b/htdocs/stripe/config.php @@ -55,4 +55,4 @@ else \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']); \Stripe\Stripe::setAppInfo("Dolibarr Stripe", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version -\Stripe\Stripe::setApiVersion("2018-09-06"); // force version API +\Stripe\Stripe::setApiVersion("2018-09-24"); // force version API From 78b8881c4451305decf42592e5624aaaec9b47a8 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Thu, 27 Sep 2018 10:43:43 +0200 Subject: [PATCH 017/433] Prepare for more stripe function support refund, dispute, capture.... --- htdocs/install/mysql/tables/llx_paiement.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/install/mysql/tables/llx_paiement.sql b/htdocs/install/mysql/tables/llx_paiement.sql index 2a287ac7e89..ca4c2fe9a90 100644 --- a/htdocs/install/mysql/tables/llx_paiement.sql +++ b/htdocs/install/mysql/tables/llx_paiement.sql @@ -31,6 +31,8 @@ create table llx_paiement fk_paiement integer NOT NULL, num_paiement varchar(50), note text, + key_charge varchar(128), -- key of external charge + site varchar(128), -- name of external paymentmode fk_bank integer NOT NULL DEFAULT 0, fk_user_creat integer, -- utilisateur qui a cree l'info fk_user_modif integer, -- utilisateur qui a modifie l'info From a05bdccb06b5c65f98f76e4a90ea93af28575e7f Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Thu, 27 Sep 2018 10:47:58 +0200 Subject: [PATCH 018/433] Prepare for more stripe function --- htdocs/install/mysql/migration/8.0.0-9.0.0.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql index 9d7479591d8..801d878b509 100644 --- a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql +++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql @@ -70,6 +70,9 @@ ALTER TABLE llx_payment_salary ADD COLUMN fk_projet integer DEFAULT NULL after a ALTER TABLE llx_categorie ADD COLUMN ref_ext varchar(255); +ALTER TABLE llx_paiement ADD COLUMN key_charge varchar(128); +ALTER TABLE llx_paiement ADD COLUMN site varchar(128); + ALTER TABLE llx_societe ADD COLUMN twitter varchar(255) after skype; ALTER TABLE llx_societe ADD COLUMN facebook varchar(255) after skype; ALTER TABLE llx_societe ADD COLUMN instagram varchar(255) after skype; From 06fe172669500d3e5b8d5fd0163695da58c35205 Mon Sep 17 00:00:00 2001 From: Philippe Date: Thu, 27 Sep 2018 20:06:00 +0200 Subject: [PATCH 019/433] FIX Product marge tabs on product card Credit note are not negative so the grand total are false --- htdocs/margin/tabs/productMargins.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/margin/tabs/productMargins.php b/htdocs/margin/tabs/productMargins.php index 9175736d5db..f899d112a2d 100644 --- a/htdocs/margin/tabs/productMargins.php +++ b/htdocs/margin/tabs/productMargins.php @@ -138,9 +138,9 @@ if ($id > 0 || ! empty($ref)) $sql.= " f.datef, f.paye, f.fk_statut as statut, f.type,"; if (!$user->rights->societe->client->voir && !$socid) $sql.= " sc.fk_soc, sc.fk_user,"; $sql.= " sum(d.total_ht) as selling_price,"; // may be negative or positive - $sql.= " sum(d.qty) as qty,"; - $sql.= " sum(d.qty * d.buy_price_ht) as buying_price,"; // always positive - $sql.= " sum(abs(d.total_ht) - (d.buy_price_ht * d.qty)) as marge" ; // always positive + $sql.= " IF(f.type = 2, -1, 1) * sum(d.qty) as qty,"; // not always positive in case of Credit note + $sql.= " IF(f.type = 2, -1, 1) * sum(d.qty * d.buy_price_ht) as buying_price,"; // not always positive in case of Credit note + $sql.= " IF(f.type = 2, -1, 1) * sum(abs(d.total_ht) - (d.buy_price_ht * d.qty)) as marge" ; // not always positive in case of Credit note $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql.= ", ".MAIN_DB_PREFIX."facture as f"; $sql.= ", ".MAIN_DB_PREFIX."facturedet as d"; From af66a8971a323ba43448a1d01b747e9a7bea9ba5 Mon Sep 17 00:00:00 2001 From: John BOTELLA Date: Tue, 2 Oct 2018 15:51:17 +0200 Subject: [PATCH 020/433] NEW Hidden conf INVOICE_USE_DEFAULT_DOCUMENT --- htdocs/admin/facture.php | 75 +++++++++++++++++----------------- htdocs/compta/facture/card.php | 66 ++++++++++++++++-------------- 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index 71fa035ee00..6e0f4bf681d 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -610,47 +610,48 @@ foreach ($dirmodels as $reldir) } print '
'; print $desc; print '
'; include_once DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php'; $liste = ModelePDFFactures::liste_modeles($db); - print $form->selectarray('model', $liste, $conf->global->FACTURE_ADDON_PDF); + $curent = !empty($conf->global->{'FACTURE_ADDON_PDF_'.$object->type})?$conf->global->{'FACTURE_ADDON_PDF_'.$object->type}:$conf->global->FACTURE_ADDON_PDF; + print $form->selectarray('model', $liste, $curent); print "
'.$trans.''.$form->selectarray('invoicetypemodels['.$type.']', ModelePDFFactures::liste_modeles($db) , $curent ,0,0, 0).''.$form->selectarray('invoicetypemodels['.$type.']', ModelePDFFactures::liste_modeles($db), $current,0,0, 0).'
'; include_once DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php'; $liste = ModelePDFFactures::liste_modeles($db); - $curent = !empty($conf->global->{'FACTURE_ADDON_PDF_'.$object->type})?$conf->global->{'FACTURE_ADDON_PDF_'.$object->type}:$conf->global->FACTURE_ADDON_PDF; + $paramkey='FACTURE_ADDON_PDF_'.$object->type; + $curent = !empty($conf->global->$paramkey)?$conf->global->$paramkey:$conf->global->FACTURE_ADDON_PDF; print $form->selectarray('model', $liste, $curent); print "
'; - -/* - * Document templates generators - */ -print '
'; -print load_fiche_titre($langs->trans("BillsPDFModulesAccordindToInvoiceType"),'',''); -print '
'; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print "\n"; - -$listtype=array( - Facture::TYPE_STANDARD=>$langs->trans("InvoiceStandard"), - Facture::TYPE_REPLACEMENT=>$langs->trans("InvoiceReplacement"), - Facture::TYPE_CREDIT_NOTE=>$langs->trans("InvoiceAvoir"), - Facture::TYPE_DEPOSIT=>$langs->trans("InvoiceDeposit"), -); -if (! empty($conf->global->INVOICE_USE_SITUATION)) +if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)) // Hidden conf { - $listtype[Facture::TYPE_SITUATION] = $langs->trans("InvoiceSituation"); -} - -foreach ($listtype as $type => $trans) -{ - $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type; - $current = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF; - print ''; - print ''; - print ''; + /* + * Document templates generators + */ + print '
'; + print load_fiche_titre($langs->trans("BillsPDFModulesAccordindToInvoiceType"),'',''); + print ''; + print ''; + print ''; + print '
'.$langs->trans("Type").''.$langs->trans("Name").'
'.$trans.''.$form->selectarray('invoicetypemodels['.$type.']', ModelePDFFactures::liste_modeles($db), $current,0,0, 0).'
'; + print ''; + print ''; + print ''; + print ''; print "\n"; + + $listtype=array( + Facture::TYPE_STANDARD=>$langs->trans("InvoiceStandard"), + Facture::TYPE_REPLACEMENT=>$langs->trans("InvoiceReplacement"), + Facture::TYPE_CREDIT_NOTE=>$langs->trans("InvoiceAvoir"), + Facture::TYPE_DEPOSIT=>$langs->trans("InvoiceDeposit"), + ); + if (! empty($conf->global->INVOICE_USE_SITUATION)) + { + $listtype[Facture::TYPE_SITUATION] = $langs->trans("InvoiceSituation"); + } + + foreach ($listtype as $type => $trans) + { + $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type; + $current = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF; + print ''; + print ''; + print ''; + print "\n"; + } + + print '
'.$langs->trans("Type").''.$langs->trans("Name").'
'.$trans.''.$form->selectarray('invoicetypemodels['.$type.']', ModelePDFFactures::liste_modeles($db), $current,0,0, 0).'
'; + print "
"; } -print ''; -print ""; - - /* * Modes de reglement */ diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index ecd9ad09bbf..074558fd4ac 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2779,37 +2779,38 @@ if ($action == 'create') print ''; - - // Add auto select default document model - $listtType=array(Facture::TYPE_STANDARD,Facture::TYPE_REPLACEMENT,Facture::TYPE_CREDIT_NOTE,Facture::TYPE_DEPOSIT,Facture::TYPE_SITUATION); - $jsListType=''; - foreach ($listtType as $type) + if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)) // Hidden conf { - $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type; - $curent = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF; - $jsListType.=(!empty($jsListType)?',':'').'"'.$type.'":"'.$curent.'"'; + // Add auto select default document model + $listtType=array(Facture::TYPE_STANDARD,Facture::TYPE_REPLACEMENT,Facture::TYPE_CREDIT_NOTE,Facture::TYPE_DEPOSIT,Facture::TYPE_SITUATION); + $jsListType=''; + foreach ($listtType as $type) + { + $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type; + $curent = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF; + $jsListType.=(!empty($jsListType)?',':'').'"'.$type.'":"'.$curent.'"'; + } + + print ''; } - print ''; - - print ''; @@ -2902,8 +2903,13 @@ if ($action == 'create') print ''; include_once DOL_DOCUMENT_ROOT . '/core/modules/facture/modules_facture.php'; $liste = ModelePDFFactures::liste_modeles($db); - $paramkey='FACTURE_ADDON_PDF_'.$object->type; - $curent = !empty($conf->global->$paramkey)?$conf->global->$paramkey:$conf->global->FACTURE_ADDON_PDF; + if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)){ // Hidden conf + $paramkey='FACTURE_ADDON_PDF_'.$object->type; + $curent = !empty($conf->global->$paramkey)?$conf->global->$paramkey:$conf->global->FACTURE_ADDON_PDF; + } + else{ + $curent = $conf->global->FACTURE_ADDON_PDF; + } print $form->selectarray('model', $liste, $curent); print ""; From b578913d2b3de8b48b11111f859bcf56f64a2880 Mon Sep 17 00:00:00 2001 From: Chl Date: Thu, 23 Aug 2018 15:02:13 +0200 Subject: [PATCH 021/433] FIX correct migration of old postgresql unique key --- htdocs/install/mysql/migration/7.0.0-8.0.0.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql index 18b6440f45b..44c2854baa0 100644 --- a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -60,7 +60,7 @@ DROP TABLE llx_c_accountancy_category; DROP TABLE llx_c_accountingaccount; -- drop old postgresql unique key --- VPGSQL8.2 DROP INDEX llx_usergroup_rights_fk_usergroup_fk_id_key; +-- VPGSQL8.2 ALTER TABLE llx_usergroup_rights DROP CONSTRAINT llx_usergroup_rights_fk_usergroup_fk_id_key; update llx_propal set fk_statut = 1 where fk_statut = -1; From 2acd69033cf233d7716cdc1001f2b5ae9db419b0 Mon Sep 17 00:00:00 2001 From: atm-ph Date: Wed, 3 Oct 2018 22:48:29 +0200 Subject: [PATCH 022/433] Fix minor error in dom --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1797617a26d..f760dd32cc1 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2806,7 +2806,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ if ($picto == 'off') { $fakey = 'fa-square-o'; $fasize='1.3em'; } if ($picto == 'on') { $fakey = 'fa-check-square-o'; $fasize='1.3em'; } $enabledisablehtml=''; - $enabledisablehtml.=''; + $enabledisablehtml.=''; if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $enabledisablehtml.=$titlealt; $enabledisablehtml.=''; return $enabledisablehtml; From 292dab192b5f9547e86127fbcfda26b4a842fa0b Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 4 Oct 2018 09:42:11 +0200 Subject: [PATCH 023/433] FIX : #9161 --- htdocs/core/lib/company.lib.php | 40 ++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 2dd4cf090f5..9440f911eeb 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1213,6 +1213,8 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= global $param; + dol_include_once('/comm/action/class/actioncomm.class.php'); + // Check parameters if (! is_object($filterobj) && ! is_object($objcon)) dol_print_error('','BadParameter'); @@ -1261,6 +1263,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'product'"; if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; } + //TODO check how ot work with new table actioncomm_resources and multiple contact affectation if (is_object($objcon) && $objcon->id) $sql.= " AND a.fk_contact = ".$objcon->id; // Condition on actioncode if (! empty($actioncode)) @@ -1297,6 +1300,14 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= { $obj = $db->fetch_object($resql); + $contactaction = new ActionComm($db); + $contactaction->id=$obj->id; + $result = $contactaction->fetchResources(); + if ($result<0) { + dol_print_error($db); + setEventMessage("company.lib::show_actions_done Error fetch ressource"); + } + //if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))"; //if ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))"; $tododone=''; @@ -1318,6 +1329,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= 'userphoto'=>$obj->user_photo, 'contact_id'=>$obj->fk_contact, + 'socpeopleassigned' => $contactaction->socpeopleassigned, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'fk_element'=>$obj->fk_element, @@ -1470,7 +1482,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $out.=getTitleFieldOfList($langs->trans("Label"), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder); $out.=getTitleFieldOfList($langs->trans("Date"), 0, $_SERVER["PHP_SELF"], 'a.datep,a.id', '', $param, 'align="center"', $sortfield, $sortorder); $out.=getTitleFieldOfList(''); - $out.=getTitleFieldOfList($langs->trans("ActionOnContact"), 0, $_SERVER["PHP_SELF"], 'a.fk_contact', '', $param, '', $sortfield, $sortorder); + $out.=getTitleFieldOfList($langs->trans("ActionOnContact"), 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder); $out.=getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], 'a.percent', '', $param, 'align="center"', $sortfield, $sortorder); $out.=getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'maxwidthsearch '); $out.=''; @@ -1616,11 +1628,33 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $contactstatic->lastname=$histo[$key]['lastname']; $contactstatic->firstname=$histo[$key]['firstname']; $contactstatic->id=$histo[$key]['contact_id']; + var_dump($histo[$key]['contact_id']); $out.=''.$contactstatic->getNomUrl(1,'',10).''; } - else + elseif (isset($histo[$key]['socpeopleassigned']) && is_array($histo[$key]['socpeopleassigned']) && count($histo[$key]['socpeopleassigned'])>0) { - $out.=' '; + $out.=''; + foreach ($histo[$key]['socpeopleassigned'] as $cid => $Tab) + { + $contact = new Contact($db); + $result = $contact->fetch($cid); + + if ($result < 0) dol_print_error($db,$contact->error); + + if ($result > 0) + { + $out.= $contact->getNomUrl(1); + if ($object->type_code == 'AC_TEL') + { + if (!empty($contact->phone_pro)) $out.= '('.dol_print_phone($contact->phone_pro).')'; + } + $out.= '
'; + } + } + $out.=''; + } + else { + $out.=' '; } // Status From 7f4f27ebfec407b419ed2e782881d4b0d05691de Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 4 Oct 2018 09:45:12 +0200 Subject: [PATCH 024/433] indent --- htdocs/core/lib/company.lib.php | 41 +++++++++++++++------------------ 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 9440f911eeb..4dfbe47e9e3 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1305,7 +1305,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $result = $contactaction->fetchResources(); if ($result<0) { dol_print_error($db); - setEventMessage("company.lib::show_actions_done Error fetch ressource"); + setEventMessage("company.lib::show_actions_done Error fetch ressource",'errors'); } //if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))"; @@ -1630,29 +1630,26 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $contactstatic->id=$histo[$key]['contact_id']; var_dump($histo[$key]['contact_id']); $out.=''.$contactstatic->getNomUrl(1,'',10).''; - } - elseif (isset($histo[$key]['socpeopleassigned']) && is_array($histo[$key]['socpeopleassigned']) && count($histo[$key]['socpeopleassigned'])>0) - { - $out.=''; - foreach ($histo[$key]['socpeopleassigned'] as $cid => $Tab) - { - $contact = new Contact($db); - $result = $contact->fetch($cid); + } elseif (isset($histo[$key]['socpeopleassigned']) && is_array($histo[$key]['socpeopleassigned']) && count($histo[$key]['socpeopleassigned']) > 0) { + $out .= ''; + foreach ( $histo[$key]['socpeopleassigned'] as $cid => $Tab ) { + $contact = new Contact($db); + $result = $contact->fetch($cid); - if ($result < 0) dol_print_error($db,$contact->error); + if ($result < 0) + dol_print_error($db, $contact->error); - if ($result > 0) - { - $out.= $contact->getNomUrl(1); - if ($object->type_code == 'AC_TEL') - { - if (!empty($contact->phone_pro)) $out.= '('.dol_print_phone($contact->phone_pro).')'; - } - $out.= '
'; - } - } - $out.=''; - } + if ($result > 0) { + $out .= $contact->getNomUrl(1); + if ($object->type_code == 'AC_TEL') { + if (! empty($contact->phone_pro)) + $out .= '(' . dol_print_phone($contact->phone_pro) . ')'; + } + $out .= '
'; + } + } + $out .= ''; + } else { $out.=' '; } From e95921eb934d8d3f3d891978ad0cf489269777fc Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 4 Oct 2018 09:47:04 +0200 Subject: [PATCH 025/433] better test --- htdocs/core/lib/company.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 4dfbe47e9e3..02652892305 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1641,7 +1641,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= if ($result > 0) { $out .= $contact->getNomUrl(1); - if ($object->type_code == 'AC_TEL') { + if (isset($histo[$key]['acode']) && $histo[$key]['acode'] == 'AC_TEL') { if (! empty($contact->phone_pro)) $out .= '(' . dol_print_phone($contact->phone_pro) . ')'; } From c048f515624098ad0e8c19a66949cc3aa560aafc Mon Sep 17 00:00:00 2001 From: ATM-Nicolas Date: Thu, 4 Oct 2018 09:54:40 +0200 Subject: [PATCH 026/433] FIX : Wrong variable name --- htdocs/compta/facture/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 139fe355d3d..6c9822fd8a3 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -451,7 +451,7 @@ if ($search_month > 0) if ($search_year > 0 && empty($search_day)) $sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,$search_month,false))."' AND '".$db->idate(dol_get_last_day($search_year,$search_month,false))."'"; else if ($search_year > 0 && ! empty($search_day)) - $sql.= " AND f.datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $serch_year))."'"; + $sql.= " AND f.datef BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month, $search_day, $search_year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month, $search_day, $search_year))."'"; else $sql.= " AND date_format(f.datef, '%m') = '".$month."'"; } From 58d1ac427e1af794e662327b999291319e70a142 Mon Sep 17 00:00:00 2001 From: atm-ph Date: Thu, 4 Oct 2018 10:57:22 +0200 Subject: [PATCH 027/433] Fix missing hook on sellsjournal --- htdocs/accountancy/journal/sellsjournal.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index b10e0d37c75..2c0ab7c1a2f 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -59,11 +59,15 @@ $now = dol_now(); if ($user->societe_id > 0) accessforbidden(); +$hookmanager->initHooks(array('sellsjournal')); +$parameters=array(); /* * Actions */ +$reshook=$hookmanager->executeHooks('doActions',$parameters,$user,$action); // Note that $action and $object may have been modified by some hooks + // Get informations of journal $accountingjournalstatic = new AccountingJournal($db); $accountingjournalstatic->fetch($id_journal); From bfaf25ca2a0ace725b58ae45f92768dc7caded3e Mon Sep 17 00:00:00 2001 From: atm-ph Date: Thu, 4 Oct 2018 16:55:16 +0200 Subject: [PATCH 028/433] Fix wrong value for module part and return access denied --- htdocs/comm/action/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 890996bddce..4afde1e0ac4 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1611,7 +1611,7 @@ if ($id > 0) $var=true; - print $formfile->showdocuments('agenda',$object->id,$filedir,$urlsource,$genallowed,$delallowed,'',0,0,0,0,0,'','','',$object->default_lang); + print $formfile->showdocuments('actions',$object->id,$filedir,$urlsource,$genallowed,$delallowed,'',0,0,0,0,0,'','','',$object->default_lang); print '
'; From 68c99d01a7a545ec91965e2f717c2437d717733a Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 5 Oct 2018 10:35:32 +0200 Subject: [PATCH 029/433] OMG!!!! var_dump.... --- htdocs/core/lib/company.lib.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 02652892305..db6ef2de6cb 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -1628,7 +1628,6 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= $contactstatic->lastname=$histo[$key]['lastname']; $contactstatic->firstname=$histo[$key]['firstname']; $contactstatic->id=$histo[$key]['contact_id']; - var_dump($histo[$key]['contact_id']); $out.=''.$contactstatic->getNomUrl(1,'',10).''; } elseif (isset($histo[$key]['socpeopleassigned']) && is_array($histo[$key]['socpeopleassigned']) && count($histo[$key]['socpeopleassigned']) > 0) { $out .= ''; From 82651cd920478b419d0677081be4a5fbd3e81b42 Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Fri, 5 Oct 2018 12:12:04 +0200 Subject: [PATCH 030/433] FIX: invoice stats: situation invoices were not counted --- htdocs/compta/facture/class/facturestats.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/class/facturestats.class.php b/htdocs/compta/facture/class/facturestats.class.php index b6874862286..484d6447878 100644 --- a/htdocs/compta/facture/class/facturestats.class.php +++ b/htdocs/compta/facture/class/facturestats.class.php @@ -84,8 +84,8 @@ class FactureStats extends Stats $this->where.=" AND f.fk_soc = ".$this->socid; } if ($this->userid > 0) $this->where.=' AND f.fk_user_author = '.$this->userid; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $this->where.= " AND f.type IN (0,1,2)"; - else $this->where.= " AND f.type IN (0,1,2,3)"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $this->where.= " AND f.type IN (0,1,2,5)"; + else $this->where.= " AND f.type IN (0,1,2,3,5)"; } From c7c3780400a49107701414d05596bd37b4649ba1 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Fri, 5 Oct 2018 15:34:32 +0200 Subject: [PATCH 031/433] clean code --- htdocs/admin/prelevement.php | 2 -- htdocs/compta/index.php | 9 ++------- htdocs/core/boxes/modules_boxes.php | 1 - htdocs/fourn/commande/dispatch.php | 4 ---- htdocs/variants/card.php | 1 - htdocs/variants/combinations.php | 1 - 6 files changed, 2 insertions(+), 16 deletions(-) diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index c40eca7380e..cdfcd451f2c 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -465,7 +465,6 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION)) { $num = $db->num_rows($resql); $i = 0; - $var = false; while ($i < $num) { $obj = $db->fetch_object($resql); @@ -511,7 +510,6 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION)) { $num = $db->num_rows($resql); $i = 0; - $var = false; while ($i < $num) { $obj = $db->fetch_object($resql); diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index ea43c270b5f..eec0c640b67 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -162,7 +162,6 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire) if ( $resql ) { - $var = false; $num = $db->num_rows($resql); print ''; @@ -350,7 +349,6 @@ if (! empty($conf->facture->enabled) && $user->rights->facture->lire) $resql = $db->query($sql); if ($resql) { - $var=false; $num = $db->num_rows($resql); $i = 0; @@ -473,7 +471,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- $resql=$db->query($sql); if ($resql) { - $var=false; $num = $db->num_rows($resql); print '
'; @@ -520,7 +517,6 @@ if (! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture- $total_ttc += $obj->total_ttc; $totalam += $obj->am; $i++; - $var = !$var; } } else @@ -1069,7 +1065,7 @@ if ($resql) $obj = $db->fetch_object($resql); - print ""; + print ''; print ''; $i++; } @@ -1080,7 +1076,6 @@ if ($resql) print ''; - +// End of page llxFooter(); - $db->close(); diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 4377b90d17a..47646a0facf 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -213,7 +213,6 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" box require_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php'; $MAXLENGTHBOX=60; // Mettre 0 pour pas de limite - $var = false; $cachetime = 900; // 900 : 15mn $cachedir = DOL_DATA_ROOT.'/boxes/temp'; diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 44b10bf6f88..7f2e5ba4139 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -533,7 +533,6 @@ if ($id > 0 || ! empty($ref)) { $nbproduct = 0; // Nb of predefined product lines to dispatch (already done or not) if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is off (default) // or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on. - $var = false; while ( $i < $num ) { $objp = $db->fetch_object($resql); @@ -794,8 +793,6 @@ if ($id > 0 || ! empty($ref)) { print ''; print "\n"; - $var = false; - while ( $i < $num ) { $objp = $db->fetch_object($resql); @@ -869,7 +866,6 @@ if ($id > 0 || ! empty($ref)) { print "\n"; $i ++; - $var = ! $var; } $db->free($resql); diff --git a/htdocs/variants/card.php b/htdocs/variants/card.php index be73db1fff0..8cb4e13b33e 100644 --- a/htdocs/variants/card.php +++ b/htdocs/variants/card.php @@ -133,7 +133,6 @@ if ($confirm == 'yes') { $langs->load('products'); $title = $langs->trans('ProductAttributeName', dol_htmlentities($object->label)); -$var = false; llxHeader('', $title); diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 0d1ea7af03b..f5c0d813995 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -27,7 +27,6 @@ require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination2ValuePair.cla $langs->loadLangs(array("products", "other")); -$var = false; $id = GETPOST('id', 'int'); $valueid = GETPOST('valueid', 'int'); $ref = GETPOST('ref'); From 94df8d297d70818bf14a8850865e92d1047eab65 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Fri, 5 Oct 2018 15:44:57 +0200 Subject: [PATCH 032/433] Standardize code --- htdocs/asset/class/asset.class.php | 3 +++ htdocs/compta/facture/class/facture-rec.class.php | 4 ++++ htdocs/core/class/events.class.php | 5 +++++ htdocs/core/class/fiscalyear.class.php | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/htdocs/asset/class/asset.class.php b/htdocs/asset/class/asset.class.php index 8aee71b4926..54d263dce6d 100644 --- a/htdocs/asset/class/asset.class.php +++ b/htdocs/asset/class/asset.class.php @@ -106,6 +106,9 @@ class Asset extends CommonObject */ public $ref; + /** + * @var int Entity + */ public $entity; /** diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 1c97b82d926..ad33432484f 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -64,7 +64,11 @@ class FactureRec extends CommonInvoice */ public $picto='bill'; + /** + * @var int Entity + */ public $entity; + public $number; public $date; public $amount; diff --git a/htdocs/core/class/events.class.php b/htdocs/core/class/events.class.php index d8d71513cd9..020998fa37a 100644 --- a/htdocs/core/class/events.class.php +++ b/htdocs/core/class/events.class.php @@ -61,7 +61,12 @@ class Events // extends CommonObject public $tms; public $type; + + /** + * @var int Entity + */ public $entity; + public $dateevent; /** diff --git a/htdocs/core/class/fiscalyear.class.php b/htdocs/core/class/fiscalyear.class.php index c4ab50179d9..4bdcf54b59a 100644 --- a/htdocs/core/class/fiscalyear.class.php +++ b/htdocs/core/class/fiscalyear.class.php @@ -64,6 +64,10 @@ class Fiscalyear extends CommonObject public $date_end; public $datec; public $statut; // 0=open, 1=closed + + /** + * @var int Entity + */ public $entity; public $statuts=array(); From da560289e3f1126a74b030d36e734604215947f8 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Fri, 5 Oct 2018 15:48:38 +0200 Subject: [PATCH 033/433] Standardize code --- htdocs/accountancy/class/accountingaccount.class.php | 4 ++++ htdocs/asset/class/asset.class.php | 4 ++++ htdocs/comm/action/class/actioncommreminder.class.php | 5 +++++ htdocs/cron/class/cronjob.class.php | 10 ++++++++++ htdocs/product/class/productcustomerprice.class.php | 8 ++++++++ 5 files changed, 31 insertions(+) diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index 4929e118a3b..07918488636 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -86,6 +86,10 @@ class AccountingAccount extends CommonObject public $account_number; public $account_parent; public $account_category; + + /** + * @var int Status + */ public $status; /** diff --git a/htdocs/asset/class/asset.class.php b/htdocs/asset/class/asset.class.php index 54d263dce6d..3f35c063fe9 100644 --- a/htdocs/asset/class/asset.class.php +++ b/htdocs/asset/class/asset.class.php @@ -135,6 +135,10 @@ class Asset extends CommonObject public $fk_user_creat; public $fk_user_modif; public $import_key; + + /** + * @var int Status + */ public $status; // If this object has a subtable with lines diff --git a/htdocs/comm/action/class/actioncommreminder.class.php b/htdocs/comm/action/class/actioncommreminder.class.php index 6c9632d83e5..15a318b0343 100644 --- a/htdocs/comm/action/class/actioncommreminder.class.php +++ b/htdocs/comm/action/class/actioncommreminder.class.php @@ -92,7 +92,12 @@ class ActionCommReminder extends CommonObject public $offsetvalue; public $offsetunit; + + /** + * @var int Status + */ public $status; + // END MODULEBUILDER PROPERTIES diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index a0db4a1f572..26b17016a5f 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -76,7 +76,12 @@ class Cronjob extends CommonObject public $lastoutput; public $unitfrequency; public $frequency; + + /** + * @var int Status + */ public $status; + public $processing; public $fk_user_author; public $fk_user_mod; @@ -1379,7 +1384,12 @@ class Cronjobline public $lastoutput; public $unitfrequency; public $frequency; + + /** + * @var int Status + */ public $status; + public $fk_user_author; public $fk_user_mod; public $note; diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php index 7f9e5a0b383..5aaa2c079ea 100644 --- a/htdocs/product/class/productcustomerprice.class.php +++ b/htdocs/product/class/productcustomerprice.class.php @@ -38,7 +38,11 @@ class Productcustomerprice extends CommonObject */ public $table_element = 'product_customer_price'; + /** + * @var int Entity + */ public $entity; + public $datec = ''; public $tms = ''; public $fk_product; @@ -976,7 +980,11 @@ class PriceByCustomerLine */ public $id; + /** + * @var int Entity + */ public $entity; + public $datec = ''; public $tms = ''; public $fk_product; From 073ec85208cd305199066e3c07ce6bf3c132670c Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Fri, 5 Oct 2018 15:51:08 +0200 Subject: [PATCH 034/433] Standardize code --- htdocs/fourn/class/fournisseur.commande.dispatch.class.php | 5 +++++ htdocs/hrm/class/establishment.class.php | 6 +++++- htdocs/modulebuilder/template/class/myobject.class.php | 5 +++++ htdocs/product/inventory/class/inventory.class.php | 5 +++++ htdocs/societe/class/companypaymentmode.class.php | 5 +++++ htdocs/societe/class/societeaccount.class.php | 5 +++++ htdocs/website/class/websitepage.class.php | 5 +++++ 7 files changed, 35 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php index 309c5f2deff..76d3e6e0d96 100644 --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php @@ -78,7 +78,12 @@ class CommandeFournisseurDispatch extends CommonObject public $datec=''; public $comment; + + /** + * @var int Status + */ public $status; + public $tms=''; public $batch; public $eatby=''; diff --git a/htdocs/hrm/class/establishment.class.php b/htdocs/hrm/class/establishment.class.php index 457fca3ac21..68ab8f38872 100644 --- a/htdocs/hrm/class/establishment.class.php +++ b/htdocs/hrm/class/establishment.class.php @@ -71,7 +71,11 @@ class Establishment extends CommonObject public $address; public $zip; public $town; - public $status; // 0=open, 1=closed + + /** + * @var int Status 0=open, 1=closed + */ + public $status; /** * @var int Entity diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 0439f78f3a5..b04dd735e49 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -122,7 +122,12 @@ class MyObject extends CommonObject public $label; public $amount; + + /** + * @var int Status + */ public $status; + public $date_creation; public $tms; public $fk_user_creat; diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php index 5b0bbb99a65..e1be589ac88 100644 --- a/htdocs/product/inventory/class/inventory.class.php +++ b/htdocs/product/inventory/class/inventory.class.php @@ -117,7 +117,12 @@ class Inventory extends CommonObject public $fk_warehouse; public $date_inventory; public $title; + + /** + * @var int Status + */ public $status; + public $date_creation; public $date_validation; public $tms; diff --git a/htdocs/societe/class/companypaymentmode.class.php b/htdocs/societe/class/companypaymentmode.class.php index f5ef70c2407..537fd5998eb 100644 --- a/htdocs/societe/class/companypaymentmode.class.php +++ b/htdocs/societe/class/companypaymentmode.class.php @@ -161,7 +161,12 @@ class CompanyPaymentMode extends CommonObject public $preapproval_key; public $total_amount_of_all_payments; public $stripe_card_ref; + + /** + * @var int Status + */ public $status; + public $starting_date; public $ending_date; public $datec; diff --git a/htdocs/societe/class/societeaccount.class.php b/htdocs/societe/class/societeaccount.class.php index 422dd4ddb8e..37195d01a66 100644 --- a/htdocs/societe/class/societeaccount.class.php +++ b/htdocs/societe/class/societeaccount.class.php @@ -126,7 +126,12 @@ class SocieteAccount extends CommonObject public $fk_user_creat; public $fk_user_modif; public $import_key; + + /** + * @var int Status + */ public $status; + // END MODULEBUILDER PROPERTIES diff --git a/htdocs/website/class/websitepage.class.php b/htdocs/website/class/websitepage.class.php index 97aba5e6ac2..4277a03167d 100644 --- a/htdocs/website/class/websitepage.class.php +++ b/htdocs/website/class/websitepage.class.php @@ -64,7 +64,12 @@ class WebsitePage extends CommonObject public $htmlheader; public $content; public $grabbed_from; + + /** + * @var int Status + */ public $status; + public $date_creation; public $date_modification; From bcfdeeea889e3cd22b735cea6f8637d2fad6f30a Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Fri, 5 Oct 2018 15:55:47 +0200 Subject: [PATCH 035/433] Standardize code --- htdocs/societe/class/companypaymentmode.class.php | 2 +- htdocs/stripe/class/stripe.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/companypaymentmode.class.php b/htdocs/societe/class/companypaymentmode.class.php index 537fd5998eb..83303a3a41d 100644 --- a/htdocs/societe/class/companypaymentmode.class.php +++ b/htdocs/societe/class/companypaymentmode.class.php @@ -127,7 +127,7 @@ class CompanyPaymentMode extends CommonObject /** * @var int Thirdparty ID */ - public $fk_soc; + public $fk_soc; /** * @var string company payment mode label diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 901997cef3b..3c07c9ae5f6 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -36,7 +36,7 @@ class Stripe extends CommonObject /** * @var int Thirdparty ID */ - public $fk_soc; + public $fk_soc; public $fk_key; From b3925dd2bda98e9e7976f0355ece1b9298b6d15c Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Fri, 5 Oct 2018 16:04:10 +0200 Subject: [PATCH 036/433] Standardize code --- htdocs/adherents/class/adherent.class.php | 9 +++++++++ htdocs/don/class/don.class.php | 7 ++++++- htdocs/hrm/class/establishment.class.php | 5 +++++ htdocs/product/stock/class/entrepot.class.php | 5 +++++ htdocs/societe/class/address.class.php | 10 ++++++++++ htdocs/societe/class/societe.class.php | 5 +++++ 6 files changed, 40 insertions(+), 1 deletion(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index a4e80d3b626..e1a510152f6 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -65,8 +65,17 @@ class Adherent extends CommonObject public $pass_indatabase_crypted; public $societe; + + /** + * @var Societe $company {@type Societe} + */ public $company; + + /** + * @var string Address + */ public $address; + public $zip; public $town; diff --git a/htdocs/don/class/don.class.php b/htdocs/don/class/don.class.php index 0723ecb659a..edcd05cca9c 100644 --- a/htdocs/don/class/don.class.php +++ b/htdocs/don/class/don.class.php @@ -59,7 +59,12 @@ class Don extends CommonObject public $date; public $amount; public $societe; - public $address; + + /** + * @var string Address + */ + public $address; + public $zip; public $town; public $email; diff --git a/htdocs/hrm/class/establishment.class.php b/htdocs/hrm/class/establishment.class.php index 68ab8f38872..034c4050db9 100644 --- a/htdocs/hrm/class/establishment.class.php +++ b/htdocs/hrm/class/establishment.class.php @@ -68,7 +68,12 @@ class Establishment extends CommonObject public $rowid; public $name; + + /** + * @var string Address + */ public $address; + public $zip; public $town; diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 59e3f2fb057..575aa2a705d 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -69,7 +69,12 @@ class Entrepot extends CommonObject public $statut; public $lieu; + + /** + * @var string Address + */ public $address; + //! Code Postal public $zip; public $town; diff --git a/htdocs/societe/class/address.class.php b/htdocs/societe/class/address.class.php index 37a350b81ff..63b23d42f9e 100644 --- a/htdocs/societe/class/address.class.php +++ b/htdocs/societe/class/address.class.php @@ -47,7 +47,12 @@ class Address public $socid; public $name; + + /** + * @var string Address + */ public $address; + public $zip; public $town; public $country_id; @@ -522,7 +527,12 @@ class AddressLine public $label; public $name; + + /** + * @var string Address + */ public $address; + public $zip; public $town; public $country_id; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 81a370dc2b9..eb8f00243eb 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -119,7 +119,12 @@ class Societe extends CommonObject public $name_alias; public $particulier; + + /** + * @var string Address + */ public $address; + public $zip; public $town; From 74c86f477c9655df7cfb622a6ffd81daac3108ce Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 6 Oct 2018 12:01:00 +0200 Subject: [PATCH 037/433] Standardize code --- htdocs/expedition/class/expedition.class.php | 3 +++ htdocs/expensereport/class/expensereport_ik.class.php | 3 +++ htdocs/expensereport/class/expensereport_rule.class.php | 7 +++++-- htdocs/holiday/class/holiday.class.php | 5 +++++ htdocs/user/class/user.class.php | 5 +++++ 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index dee8184ee18..7ed035a545f 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -50,6 +50,9 @@ class Expedition extends CommonObject */ public $element="shipping"; + /** + * @var int Field with ID of parent key if this field has a parent + */ public $fk_element="fk_expedition"; /** diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php index 425851cb6e4..9eaa8970a5b 100644 --- a/htdocs/expensereport/class/expensereport_ik.class.php +++ b/htdocs/expensereport/class/expensereport_ik.class.php @@ -39,6 +39,9 @@ class ExpenseReportIk extends CoreObject */ public $table_element='expensereport_ik'; + /** + * @var int Field with ID of parent key if this field has a parent + */ public $fk_element='fk_expense_ik'; /** diff --git a/htdocs/expensereport/class/expensereport_rule.class.php b/htdocs/expensereport/class/expensereport_rule.class.php index 8599cfcc810..6d2a99d2101 100644 --- a/htdocs/expensereport/class/expensereport_rule.class.php +++ b/htdocs/expensereport/class/expensereport_rule.class.php @@ -33,12 +33,15 @@ class ExpenseReportRule extends CoreObject * @var string ID to identify managed object */ public $element='expenserule'; - + /** * @var string Name of table without prefix where object is stored */ public $table_element='expensereport_rules'; - + + /** + * @var int Field with ID of parent key if this field has a parent + */ public $fk_element='fk_expense_rule'; /** diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 5107ffb09ab..39eb2b023de 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -43,7 +43,12 @@ class Holiday extends CommonObject public $table_element='holiday'; public $ismultientitymanaged = 0; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + + /** + * @var int Field with ID of parent key if this field has a parent + */ public $fk_element = 'fk_holiday'; + public $picto = 'holiday'; /** diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 9020cd3a4bc..97172214dc6 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -64,7 +64,12 @@ class User extends CommonObject public $skype; public $job; // job position public $signature; + + /** + * @var string Address + */ public $address; + public $zip; public $town; public $state_id; // The state/department From 5890647afd301a64084abef4f22f265c37b2d0bd Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 6 Oct 2018 12:04:17 +0200 Subject: [PATCH 038/433] Standardize code --- htdocs/supplier_proposal/class/supplier_proposal.class.php | 3 +++ htdocs/user/class/user.class.php | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index ecd940fea96..688f6aa1276 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -60,6 +60,9 @@ class SupplierProposal extends CommonObject */ public $table_element_line='supplier_proposaldet'; + /** + * @var int Field with ID of parent key if this field has a parent + */ public $fk_element='fk_supplier_proposal'; public $picto='propal'; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 97172214dc6..603c73fa33a 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -50,7 +50,11 @@ class User extends CommonObject */ public $table_element='user'; + /** + * @var int Field with ID of parent key if this field has a parent + */ public $fk_element='fk_user'; + public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $id=0; From dd9af92020ca661ae671d07d3f250bf505904ff6 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 6 Oct 2018 12:07:24 +0200 Subject: [PATCH 039/433] Standardize code --- htdocs/accountancy/class/accountingjournal.class.php | 6 +++++- htdocs/adherents/class/adherent.class.php | 6 +++++- htdocs/adherents/class/adherent_type.class.php | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index 058bdb3dddb..9bd21a4a5c4 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -41,7 +41,11 @@ class AccountingJournal extends CommonObject */ public $fk_element = ''; - public $ismultientitymanaged = 0; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 0; /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index e1a510152f6..342fcd19796 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -51,7 +51,11 @@ class Adherent extends CommonObject */ public $table_element='adherent'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; public $mesgs; diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index dffd1446af0..20a85c7bf3e 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -47,7 +47,11 @@ class AdherentType extends CommonObject */ public $picto = 'group'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; /** * @var string From 83db36f9b25ae25981c787b27fef14711f2f5143 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 6 Oct 2018 12:11:48 +0200 Subject: [PATCH 040/433] Standardize code --- htdocs/asset/class/asset_type.class.php | 6 +++- htdocs/bookmarks/class/bookmark.class.php | 29 ++++++++++++------- .../deplacement/class/deplacement.class.php | 6 +++- htdocs/contact/class/contact.class.php | 6 +++- htdocs/core/class/fiscalyear.class.php | 6 +++- 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/htdocs/asset/class/asset_type.class.php b/htdocs/asset/class/asset_type.class.php index f1c6f9d771b..8eb915f95eb 100644 --- a/htdocs/asset/class/asset_type.class.php +++ b/htdocs/asset/class/asset_type.class.php @@ -44,7 +44,11 @@ class AssetType extends CommonObject */ public $picto = 'group'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; /** * @var string Asset type label diff --git a/htdocs/bookmarks/class/bookmark.class.php b/htdocs/bookmarks/class/bookmark.class.php index b7846cd0864..5422e7d7190 100644 --- a/htdocs/bookmarks/class/bookmark.class.php +++ b/htdocs/bookmarks/class/bookmark.class.php @@ -29,21 +29,25 @@ class Bookmark extends CommonObject { /** - * @var string ID to identify managed object - */ - public $element='bookmark'; + * @var string ID to identify managed object + */ + public $element='bookmark'; /** * @var string Name of table without prefix where object is stored */ public $table_element='bookmark'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; /** - * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png - */ - public $picto = 'bookmark'; + * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png + */ + public $picto = 'bookmark'; /** * @var DoliDB Database handler. @@ -56,15 +60,20 @@ class Bookmark extends CommonObject public $id; /** - * @var int User ID - */ - public $fk_user; + * @var int User ID + */ + public $fk_user; public $datec; + public $url; + public $target; // 0=replace, 1=new window + public $title; + public $position; + public $favicon; diff --git a/htdocs/compta/deplacement/class/deplacement.class.php b/htdocs/compta/deplacement/class/deplacement.class.php index 403988052bd..cf08960d99e 100644 --- a/htdocs/compta/deplacement/class/deplacement.class.php +++ b/htdocs/compta/deplacement/class/deplacement.class.php @@ -51,7 +51,11 @@ class Deplacement extends CommonObject */ public $fk_element = ''; - public $ismultientitymanaged = 0; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 0; public $datec; // Creation date public $dated; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index b8cadaa4632..7f0dbebaed4 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -47,7 +47,11 @@ class Contact extends CommonObject */ public $table_element='socpeople'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png diff --git a/htdocs/core/class/fiscalyear.class.php b/htdocs/core/class/fiscalyear.class.php index 4bdcf54b59a..985d67d5cae 100644 --- a/htdocs/core/class/fiscalyear.class.php +++ b/htdocs/core/class/fiscalyear.class.php @@ -48,7 +48,11 @@ class Fiscalyear extends CommonObject */ public $fk_element = ''; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; /** * @var int ID From 596dba9ce18abbd14769d57f2cc4edf05aad0253 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 6 Oct 2018 12:14:47 +0200 Subject: [PATCH 041/433] Standardize code --- htdocs/don/class/don.class.php | 6 +++++- htdocs/expedition/class/expedition.class.php | 6 +++++- htdocs/holiday/class/holiday.class.php | 6 +++++- htdocs/hrm/class/establishment.class.php | 7 ++++++- htdocs/product/class/product.class.php | 7 ++++++- htdocs/product/stock/class/productlot.class.php | 4 ++++ 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/htdocs/don/class/don.class.php b/htdocs/don/class/don.class.php index edcd05cca9c..ed9c629a50d 100644 --- a/htdocs/don/class/don.class.php +++ b/htdocs/don/class/don.class.php @@ -49,7 +49,11 @@ class Don extends CommonObject */ public $fk_element = 'fk_donation'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 7ed035a545f..7b764e32093 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -65,7 +65,11 @@ class Expedition extends CommonObject */ public $table_element_line="expeditiondet"; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 39eb2b023de..fe90f85b6a4 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -42,7 +42,11 @@ class Holiday extends CommonObject */ public $table_element='holiday'; - public $ismultientitymanaged = 0; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 0; /** * @var int Field with ID of parent key if this field has a parent diff --git a/htdocs/hrm/class/establishment.class.php b/htdocs/hrm/class/establishment.class.php index 034c4050db9..4153972d27c 100644 --- a/htdocs/hrm/class/establishment.class.php +++ b/htdocs/hrm/class/establishment.class.php @@ -49,7 +49,12 @@ class Establishment extends CommonObject */ public $fk_element = 'fk_establishment'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + public $picto='building'; /** diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 12ddfb9e6d7..050d756ad82 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -59,7 +59,12 @@ class Product extends CommonObject public $fk_element='fk_product'; protected $childtables=array('supplier_proposaldet', 'propaldet','commandedet','facturedet','contratdet','facture_fourn_det','commande_fournisseurdet'); // To test if we can delete object - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; /** * {@inheritdoc} diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php index 7eb3593de35..d7b77cd83ee 100644 --- a/htdocs/product/stock/class/productlot.class.php +++ b/htdocs/product/stock/class/productlot.class.php @@ -47,6 +47,10 @@ class Productlot extends CommonObject public $picto='barcode'; + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ public $ismultientitymanaged = 1; /** From 956c7b21e2340f18cf4a9c65c76a40c32da55d41 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 6 Oct 2018 12:18:03 +0200 Subject: [PATCH 042/433] Standardize code --- htdocs/projet/class/project.class.php | 7 ++++++- htdocs/societe/class/societe.class.php | 1 + htdocs/user/class/user.class.php | 6 +++++- htdocs/user/class/usergroup.class.php | 6 +++++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 9af52721787..a8b34e9c57d 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -53,7 +53,12 @@ class Project extends CommonObject */ public $fk_element = 'fk_projet'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + public $picto = 'projectpub'; /** diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index eb8f00243eb..74bda3d3afc 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -66,6 +66,7 @@ class Societe extends CommonObject * @var int */ public $ismultientitymanaged = 1; + /** * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user * @var integer diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 603c73fa33a..f3fa431daa0 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -55,7 +55,11 @@ class User extends CommonObject */ public $fk_element='fk_user'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; public $id=0; public $statut; diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index e3ada6efcac..6f3e333f6f5 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -45,7 +45,11 @@ class UserGroup extends CommonObject */ public $table_element='usergroup'; - public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; public $picto='group'; From 61daff6cb611870ce463aee642a9fd9680d81306 Mon Sep 17 00:00:00 2001 From: Philippe GRAND Date: Sat, 6 Oct 2018 12:34:51 +0200 Subject: [PATCH 043/433] Standardize code --- htdocs/core/class/commondocgenerator.class.php | 3 +++ htdocs/core/class/google.class.php | 4 ++-- htdocs/core/class/html.form.class.php | 14 +++++++------- htdocs/core/class/notify.class.php | 10 +++++----- htdocs/core/modules/mailings/modules_mailings.php | 2 +- htdocs/mailmanspip/class/mailmanspip.class.php | 8 ++++---- htdocs/resource/class/html.formresource.class.php | 5 +++-- 7 files changed, 25 insertions(+), 21 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 3792aaf9327..f75ced719a1 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -38,6 +38,9 @@ abstract class CommonDocGenerator */ public $error=''; + /** + * @var DoliDB Database handler. + */ protected $db; diff --git a/htdocs/core/class/google.class.php b/htdocs/core/class/google.class.php index 5756acd90e0..615729ba9c3 100644 --- a/htdocs/core/class/google.class.php +++ b/htdocs/core/class/google.class.php @@ -30,13 +30,13 @@ class GoogleAPI * @var DoliDB Database handler. */ public $db; - + /** * @var string Error code (or message) */ public $error=''; - var $key; + public $key; /** * Constructor diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 16f0a0158a9..a12e496b587 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -58,15 +58,15 @@ class Form */ public $error=''; - var $num; + public $num; // Cache arrays - var $cache_types_paiements=array(); - var $cache_conditions_paiements=array(); - var $cache_availability=array(); - var $cache_demand_reason=array(); - var $cache_types_fees=array(); - var $cache_vatrates=array(); + public $cache_types_paiements=array(); + public $cache_conditions_paiements=array(); + public $cache_availability=array(); + public $cache_demand_reason=array(); + public $cache_types_fees=array(); + public $cache_vatrates=array(); /** diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index d52166659ea..5736fcba681 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -51,11 +51,11 @@ class Notify */ public $errors = array(); - var $author; - var $ref; - var $date; - var $duree; - var $note; + public $author; + public $ref; + public $date; + public $duree; + public $note; /** * @var int Project ID diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php index e0316a75390..f7136d4aa63 100644 --- a/htdocs/core/modules/mailings/modules_mailings.php +++ b/htdocs/core/modules/mailings/modules_mailings.php @@ -41,7 +41,7 @@ class MailingTargets // This can't be abstract as it is used for some method */ public $error=''; - var $tooltip=''; + public $tooltip=''; /** diff --git a/htdocs/mailmanspip/class/mailmanspip.class.php b/htdocs/mailmanspip/class/mailmanspip.class.php index 139183e0375..de075eb2dc5 100644 --- a/htdocs/mailmanspip/class/mailmanspip.class.php +++ b/htdocs/mailmanspip/class/mailmanspip.class.php @@ -48,10 +48,10 @@ class MailmanSpip */ public $error=''; - var $mladded_ok; - var $mladded_ko; - var $mlremoved_ok; - var $mlremoved_ko; + public $mladded_ok; + public $mladded_ko; + public $mlremoved_ok; + public $mlremoved_ko; /** diff --git a/htdocs/resource/class/html.formresource.class.php b/htdocs/resource/class/html.formresource.class.php index f541a7728cb..c118643aa7d 100644 --- a/htdocs/resource/class/html.formresource.class.php +++ b/htdocs/resource/class/html.formresource.class.php @@ -38,8 +38,9 @@ class FormResource */ public $db; - var $substit=array(); - var $param=array(); + public $substit=array(); + + public $param=array(); /** * @var string Error code (or message) From de17977bff3124f262477c0d59f13d60cc92d78b Mon Sep 17 00:00:00 2001 From: ias-ceo Date: Sat, 6 Oct 2018 15:09:06 +0300 Subject: [PATCH 044/433] new malay lang tag --- htdocs/langs/ar_SA/languages.lang | 3 ++- htdocs/langs/en_US/languages.lang | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/ar_SA/languages.lang b/htdocs/langs/ar_SA/languages.lang index 7b27cc35010..4519ef6078d 100644 --- a/htdocs/langs/ar_SA/languages.lang +++ b/htdocs/langs/ar_SA/languages.lang @@ -1,6 +1,6 @@ # Dolibarr language file - Source file is en_US - languages Language_ar_AR=العربية -Language_ar_EG=Arabic (Egypt) +Language_ar_EG=العربيه مصر Language_ar_SA=العربية Language_bn_BD=بنغالي Language_bg_BG=البلغارية @@ -86,3 +86,4 @@ Language_uz_UZ=الأوزبكي Language_vi_VN=الفيتنامية Language_zh_CN=الصينية Language_zh_TW=الصينية (التقليدية) +Language_bh_MY=الماليزية diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang index a062883d667..99c9b6486e0 100644 --- a/htdocs/langs/en_US/languages.lang +++ b/htdocs/langs/en_US/languages.lang @@ -86,3 +86,4 @@ Language_uz_UZ=Uzbek Language_vi_VN=Vietnamese Language_zh_CN=Chinese Language_zh_TW=Chinese (Traditional) +Language_bh_MY=Malay From 320ca3db673a9b8098ea3ffaadd1b460dc0b5780 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 6 Oct 2018 22:53:28 +0200 Subject: [PATCH 045/433] Fix request on project overview Fixes #9220 --- htdocs/projet/element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 3263309187a..713e5ec74f1 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -291,7 +291,7 @@ $listofreferent=array( 'title'=>"ListSupplierProposalsAssociatedProject", 'class'=>'SupplierProposal', 'table'=>'supplier_proposal', - 'datefieldname'=>'date', + 'datefieldname'=>'datec', 'urlnew'=>DOL_URL_ROOT.'/supplier_proposal/card.php?action=create&projectid='.$id.'&socid='.$socid, 'lang'=>'supplier_proposal', 'buttonnew'=>'AddSupplierProposal', From d776fc423e4066901d231ec4c7f5e0ffe48e287b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Oct 2018 00:51:08 +0200 Subject: [PATCH 046/433] Fix search criterai of contract --- htdocs/contrat/list.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 18e78c7ff0a..b4255046ad4 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -107,7 +107,6 @@ $fieldstosearchall = array( 'c.ref_customer'=>'RefCustomer', 'c.ref_supplier'=>'RefSupplier', 's.nom'=>"ThirdParty", - 'cd.description'=>'Description', 'c.note_public'=>'NotePublic', ); if (empty($user->socid)) $fieldstosearchall["c.note_private"]="NotePrivate"; @@ -252,7 +251,7 @@ else if ($year > 0) $sql.= " AND c.date_contrat BETWEEN '".$db->idate(dol_get_first_day($year,1,false))."' AND '".$db->idate(dol_get_last_day($year,12,false))."'"; } if ($search_name) $sql .= natural_search('s.nom', $search_name); -if ($search_email) $sql .= natural_search('s.email', $search_name); +if ($search_email) $sql .= natural_search('s.email', $search_email); if ($search_contract) $sql .= natural_search(array('c.rowid', 'c.ref'), $search_contract); if (!empty($search_ref_customer)) $sql .= natural_search(array('c.ref_customer'), $search_ref_customer); if (!empty($search_ref_supplier)) $sql .= natural_search(array('c.ref_supplier'), $search_ref_supplier); From 7be9b6d94e353da111e813d2575c4ca884495b07 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Oct 2018 14:04:22 +0200 Subject: [PATCH 047/433] Fix translation of source of proposals --- htdocs/core/class/html.form.class.php | 8 ++++++-- htdocs/langs/en_US/dict.lang | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 89c45ec2bfc..6f331c42896 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2971,7 +2971,10 @@ class Form $obj = $this->db->fetch_object($resql); // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut - $label=($langs->trans("DemandReasonType".$obj->code)!=("DemandReasonType".$obj->code)?$langs->trans("DemandReasonType".$obj->code):($obj->label!='-'?$obj->label:'')); + $label=($obj->label!='-'?$obj->label:''); + if ($langs->trans("DemandReasonType".$obj->code) != ("DemandReasonType".$obj->code)) $label = $langs->trans("DemandReasonType".$obj->code); // So translation key DemandReasonTypeSRC_XXX will work + if ($langs->trans($obj->code) != $obj->code) $label=$langs->trans($obj->code); // So translation key SRC_XXX will work + $tmparray[$obj->rowid]['id'] =$obj->rowid; $tmparray[$obj->rowid]['code'] =$obj->code; $tmparray[$obj->rowid]['label']=$label; @@ -3020,7 +3023,8 @@ class Form { print ''; } print ''; diff --git a/htdocs/langs/en_US/dict.lang b/htdocs/langs/en_US/dict.lang index 81f62469896..bb79cd59d7d 100644 --- a/htdocs/langs/en_US/dict.lang +++ b/htdocs/langs/en_US/dict.lang @@ -295,7 +295,7 @@ CurrencyCentINR=paisa CurrencyCentSingINR=paise CurrencyThousandthSingTND=thousandth #### Input reasons ##### -DemandReasonTypeSRC_INTE=Internet +DemandReasonTypeSRC_INTE=Internetaaa DemandReasonTypeSRC_CAMP_MAIL=Mailing campaign DemandReasonTypeSRC_CAMP_EMAIL=EMailing campaign DemandReasonTypeSRC_CAMP_PHO=Phone campaign From 0c7b7ed7f46b8fa2d1954ec733dbf44802d8f3d8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Oct 2018 14:26:18 +0200 Subject: [PATCH 048/433] FIX Required extrafield value numeric should accept '0' --- htdocs/core/class/extrafields.class.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 200c869f5e8..ae859181f67 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1847,11 +1847,16 @@ class ExtraFields if (empty($enabled)) continue; if (empty($perms)) continue; - if ($this->attributes[$object->table_element]['required'][$key] && empty($_POST["options_".$key])) // Check if empty without GETPOST, value can be alpha, int, array, etc... + if ($this->attributes[$object->table_element]['required'][$key]) // Value is required { - //print 'ccc'.$value.'-'.$this->attributes[$object->table_element]['required'][$key]; - $nofillrequired++; - $error_field_required[] = $langs->transnoentitiesnoconv($value); + // Check if empty without using GETPOST, value can be alpha, int, array, etc... + if ((! is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $_POST["options_".$key] != '0') + || (is_array($_POST["options_".$key]) && empty($_POST["options_".$key]))) + { + //print 'ccc'.$value.'-'.$this->attributes[$object->table_element]['required'][$key]; + $nofillrequired++; + $error_field_required[] = $langs->transnoentitiesnoconv($value); + } } if (in_array($key_type,array('date'))) From 021f9552dd91fb017d3ff403f3722d2bcc143365 Mon Sep 17 00:00:00 2001 From: gauthier Date: Mon, 8 Oct 2018 15:41:31 +0200 Subject: [PATCH 049/433] FIX : when we're just admin and not super admin, if we create new user with transverse mode, we don't see it then we can't add him in usergroup --- htdocs/user/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/user/index.php b/htdocs/user/index.php index 704c04d2593..813d1e5ad05 100644 --- a/htdocs/user/index.php +++ b/htdocs/user/index.php @@ -194,7 +194,7 @@ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u2 ON u.fk_user = u2.rowid"; // TODO add hook if (! empty($conf->multicompany->enabled)) { if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { - if (! empty($user->admin) && empty($user->entity)) { + if (! empty($user->admin)) { if ($conf->entity == 1) { $sql.= " WHERE u.entity IS NOT NULL"; } else { From c26fe00362b37f97cb781db73154e59f23a79cd8 Mon Sep 17 00:00:00 2001 From: Nicolas Aupetit Date: Tue, 9 Oct 2018 02:15:38 +1100 Subject: [PATCH 050/433] fix bank ref override "bordereau cheque" ref --- htdocs/compta/paiement/cheque/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/paiement/cheque/index.php b/htdocs/compta/paiement/cheque/index.php index 527bd05e3a1..826a4333147 100644 --- a/htdocs/compta/paiement/cheque/index.php +++ b/htdocs/compta/paiement/cheque/index.php @@ -91,7 +91,7 @@ $max=10; $sql = "SELECT bc.rowid, bc.date_bordereau as db, bc.amount, bc.ref as ref,"; $sql.= " bc.statut, bc.nbcheque,"; -$sql.= " ba.ref, ba.label, ba.rowid as bid, ba.number, ba.currency_code, ba.account_number, ba.fk_accountancy_journal,"; +$sql.= " ba.ref as bref, ba.label, ba.rowid as bid, ba.number, ba.currency_code, ba.account_number, ba.fk_accountancy_journal,"; $sql.= " aj.code"; $sql.= " FROM ".MAIN_DB_PREFIX."bordereau_cheque as bc, ".MAIN_DB_PREFIX."bank_account as ba"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_journal as aj ON aj.rowid = ba.fk_accountancy_journal"; @@ -120,7 +120,7 @@ if ($resql) $checkdepositstatic->statut=$objp->statut; $accountstatic->id=$objp->bid; - $accountstatic->ref=$objp->ref; + $accountstatic->ref=$objp->bref; $accountstatic->label=$objp->label; $accountstatic->number=$objp->number; $accountstatic->currency_code=$objp->currency_code; From c930218dd28f9d9e73dc07cea0ab5891cd204926 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Oct 2018 17:40:17 +0200 Subject: [PATCH 051/433] FIX Missing transaction around action --- htdocs/comm/propal/card.php | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 802e255fb36..ee48650ef04 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -609,12 +609,23 @@ if (empty($reshook)) // Classify billed else if ($action == 'classifybilled' && $usercanclose) { + $db->begin(); + $result=$object->cloture($user, 4, ''); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; } + + if (! $error) + { + $db->commit(); + } + else + { + $db->rollback(); + } } // Close proposal @@ -627,12 +638,23 @@ if (empty($reshook)) // prevent browser refresh from closing proposal several times if ($object->statut == Propal::STATUS_VALIDATED) { + $db->begin(); + $result=$object->cloture($user, GETPOST('statut','int'), GETPOST('note_private','none')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; } + + if (! $error) + { + $db->commit(); + } + else + { + $db->rollback(); + } } } } @@ -643,12 +665,23 @@ if (empty($reshook)) // prevent browser refresh from reopening proposal several times if ($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED) { + $db->begin(); + $result=$object->reopen($user, 1); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); $error++; } + + if (! $error) + { + $db->commit(); + } + else + { + $db->rollback(); + } } } From 91038af84d2f0c5c178d60607ddc4f0a388175c7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Oct 2018 18:15:46 +0200 Subject: [PATCH 052/433] FIX properties on proposal must not be modified if error --- htdocs/comm/propal/class/propal.class.php | 28 +++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index bd6a85a06ad..fabb43ce846 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2420,16 +2420,16 @@ class Propal extends CommonObject if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) - { - $outputlangs = new Translate("",$conf); - $newlang=(GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $this->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - //$ret=$object->fetch($id); // Reload to get new records - $this->generateDocument($modelpdf, $outputlangs); + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) + { + $outputlangs = new Translate("",$conf); + $newlang=(GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $this->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + //$ret=$object->fetch($id); // Reload to get new records + $this->generateDocument($modelpdf, $outputlangs); } if (! $error) @@ -2437,7 +2437,7 @@ class Propal extends CommonObject $this->oldcopy= clone $this; $this->statut = $statut; $this->date_cloture = $now; - $this->note_private = $note; + $this->note_private = $newprivatenote; } if (! $notrigger && empty($error)) @@ -2448,13 +2448,17 @@ class Propal extends CommonObject // End call triggers } - if ( ! $error ) + if (! $error) { $this->db->commit(); return 1; } else { + $this->statut = $this->oldcopy->statut; + $this->date_cloture = $this->oldcopy->date_cloture; + $this->note_private = $this->oldcopy->note_private; + $this->db->rollback(); return -1; } From 923b561aff06be4bdbe9e98d9dff223758af9f96 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Oct 2018 20:01:45 +0200 Subject: [PATCH 053/433] FIX Option for prof id mandatory not working with custom type of company --- htdocs/langs/en_US/admin.lang | 2 +- htdocs/langs/en_US/companies.lang | 2 +- htdocs/langs/fr_FR/admin.lang | 2 +- htdocs/langs/fr_FR/companies.lang | 2 +- htdocs/societe/class/societe.class.php | 8 ++++++-- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index aade72a64bb..cbe085f3149 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1207,7 +1207,7 @@ WatermarkOnDraft=Watermark on draft document JSOnPaimentBill=Activate feature to autofill payment lines on payment form CompanyIdProfChecker=Rules for Professional IDs MustBeUnique=Must be unique? -MustBeMandatory=Mandatory to create third parties? +MustBeMandatory=Mandatory to create third parties (if vat number or type of company defined) ? MustBeInvoiceMandatory=Mandatory to validate invoices? TechnicalServicesProvided=Technical services provided #####DAV ##### diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index 19cc993876c..78762e542e2 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -38,7 +38,7 @@ ThirdPartyCustomers=Customers ThirdPartyCustomersStats=Customers ThirdPartyCustomersWithIdProf12=Customers with %s or %s ThirdPartySuppliers=Vendors -ThirdPartyType=Third Party Type +ThirdPartyType=Type of company Individual=Private individual ToCreateContactWithSameName=Will create automatically a contact/address with same information than third party under the third party. In most cases, even if your third party is a physical people, creating a third party alone is enough. ParentCompany=Parent company diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index cd048e908f8..58cd1d09b11 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -1207,7 +1207,7 @@ WatermarkOnDraft=Filigrane sur les documents brouillons JSOnPaimentBill=Activer la fonctionnalité de remplissage automatique des lignes de paiement sur le formulaire de paiement CompanyIdProfChecker=Règles sur les Identifiants professionnels MustBeUnique=Doit être unique ? -MustBeMandatory=Obligatoire pour créer des tiers ? +MustBeMandatory=Obligatoire pour créer des tiers (si num tva ou type de société défini) ? MustBeInvoiceMandatory=Obligatoire pour valider des factures ? TechnicalServicesProvided=Services techniques fournis #####DAV ##### diff --git a/htdocs/langs/fr_FR/companies.lang b/htdocs/langs/fr_FR/companies.lang index fbd8bb87e4e..548a7f6e0dd 100644 --- a/htdocs/langs/fr_FR/companies.lang +++ b/htdocs/langs/fr_FR/companies.lang @@ -38,7 +38,7 @@ ThirdPartyCustomers=Clients ThirdPartyCustomersStats=Clients ThirdPartyCustomersWithIdProf12=Clients avec %s ou %s ThirdPartySuppliers=Fournisseurs -ThirdPartyType=Type du tiers +ThirdPartyType=Type du société Individual=Individu privé ToCreateContactWithSameName=Crée automatiquement un contact/adresse, sous le tiers, avec la même information que le tiers. Dans la plupart des cas, même si votre tiers est une personne physique, la création d'un tiers seul suffit. ParentCompany=Maison mère diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 2125d0e6627..bae4a0a4495 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -3127,8 +3127,12 @@ class Societe extends CommonObject // Define if third party is treated as company (or not) when nature is unknown $isacompany=empty($conf->global->MAIN_UNKNOWN_CUSTOMERS_ARE_COMPANIES)?0:1; // 0 by default if (! empty($this->tva_intra)) $isacompany=1; - else if (! empty($this->typent_code) && in_array($this->typent_code,array('TE_PRIVATE'))) $isacompany=0; - else if (! empty($this->typent_code) && in_array($this->typent_code,array('TE_SMALL','TE_MEDIUM','TE_LARGE','TE_GROUP'))) $isacompany=1; + else if (! empty($this->typent_code) && $this->typent_code != 'TE_UNKNOWN') + { + // TODO Add a field is_a_company into dictionary + if (preg_match('/^TE_PRIVATE/', $this->typent_code)) $isacompany=0; + else $isacompany=1; + } return $isacompany; } From 75b9862c1421d9ccc8fbb06be25412544eb4c90e Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 8 Oct 2018 21:01:21 +0200 Subject: [PATCH 054/433] New : Add FEC Export in accountancy --- .../class/accountancyexport.class.php | 181 +++++++++++++----- .../accountancy/class/bookkeeping.class.php | 8 + .../tables/llx_accounting_bookkeeping.sql | 4 +- htdocs/langs/en_US/accountancy.lang | 1 + 4 files changed, 143 insertions(+), 51 deletions(-) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 40427d68034..83c16e43a72 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -54,6 +54,7 @@ class AccountancyExport public static $EXPORT_TYPE_COGILOG = 8; public static $EXPORT_TYPE_AGIRIS = 9; public static $EXPORT_TYPE_CONFIGURABLE = 10; + public static $EXPORT_TYPE_FEC = 11; /** @@ -78,8 +79,8 @@ class AccountancyExport * * @param DoliDb $db Database handler */ - public function __construct(DoliDB &$db) - { + public function __construct(DoliDB &$db) + { global $conf; $this->db = &$db; @@ -92,8 +93,8 @@ class AccountancyExport * * @return array of type */ - public static function getType() - { + public static function getType() + { global $langs; return array ( @@ -107,6 +108,7 @@ class AccountancyExport self::$EXPORT_TYPE_COGILOG => $langs->trans('Modelcsv_cogilog'), self::$EXPORT_TYPE_AGIRIS => $langs->trans('Modelcsv_agiris'), self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'), + self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'), ); } @@ -115,8 +117,8 @@ class AccountancyExport * * @return array of type */ - public static function getTypeConfig() - { + public static function getTypeConfig() + { global $conf, $langs; return array ( @@ -161,6 +163,10 @@ class AccountancyExport 'ACCOUNTING_EXPORT_ENDLINE' => empty($conf->global->ACCOUNTING_EXPORT_ENDLINE)?1:$conf->global->ACCOUNTING_EXPORT_ENDLINE, 'ACCOUNTING_EXPORT_DATE' => empty($conf->global->ACCOUNTING_EXPORT_DATE)?'%d%m%Y':$conf->global->ACCOUNTING_EXPORT_DATE, ), + self::$EXPORT_TYPE_FEC => array( + 'label' => $langs->trans('Modelcsv_FEC'), + 'ACCOUNTING_EXPORT_FORMAT' => 'txt', + ), ), 'cr'=> array ( '1' => $langs->trans("Unix"), @@ -178,8 +184,8 @@ class AccountancyExport * * @return void */ - public static function downloadFile() - { + public static function downloadFile() + { global $conf; $filename = 'general_ledger'; include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php'; @@ -189,10 +195,10 @@ class AccountancyExport * Function who chose which export to use with the default config * * @param unknown $TData data - * @return void + * @return void */ - public function export(&$TData) - { + public function export(&$TData) + { global $conf, $langs; self::downloadFile(); @@ -228,6 +234,9 @@ class AccountancyExport case self::$EXPORT_TYPE_CONFIGURABLE : $this->exportConfigurable($TData); break; + case self::$EXPORT_TYPE_FEC : + $this->exportFEC($TData); + break; default: $this->errors[] = $langs->trans('accountancy_error_modelnotfound'); break; @@ -241,8 +250,8 @@ class AccountancyExport * * @return void */ - public function exportNormal($objectLines) - { + public function exportNormal($objectLines) + { global $conf; foreach ( $objectLines as $line ) { @@ -266,8 +275,8 @@ class AccountancyExport * * @return void */ - public function exportCegid($objectLines) - { + public function exportCegid($objectLines) + { foreach ( $objectLines as $line ) { $date = dol_print_date($line->doc_date, '%d%m%Y'); $separator = ";"; @@ -292,8 +301,8 @@ class AccountancyExport * * @return void */ - public function exportCogilog($objectLines) - { + public function exportCogilog($objectLines) + { foreach ( $objectLines as $line ) { $date = dol_print_date($line->doc_date, '%d%m%Y'); $separator = ";"; @@ -326,8 +335,8 @@ class AccountancyExport * * @return void */ - public function exportCoala($objectLines) - { + public function exportCoala($objectLines) + { // Coala export $separator = ";"; $end_line = "\n"; @@ -354,8 +363,8 @@ class AccountancyExport * * @return void */ - public function exportBob50($objectLines) - { + public function exportBob50($objectLines) + { // Bob50 $separator = ";"; @@ -393,8 +402,8 @@ class AccountancyExport * * @return void */ - public function exportCiel(&$TData) - { + public function exportCiel(&$TData) + { global $conf; $end_line ="\r\n"; @@ -434,13 +443,13 @@ class AccountancyExport * * @return void */ - public function exportQuadratus(&$TData) - { + public function exportQuadratus(&$TData) + { global $conf; $end_line ="\r\n"; - //We should use dol_now function not time however this is wrong date to transfert in accounting + //We should use dol_now function not time however this is wrong date to transfert in accounting //$date_ecriture = dol_print_date(dol_now(), $conf->global->ACCOUNTING_EXPORT_DATE); // format must be ddmmyy //$date_ecriture = dol_print_date(time(), $conf->global->ACCOUNTING_EXPORT_DATE); // format must be ddmmyy foreach ( $TData as $data ) { @@ -454,8 +463,8 @@ class AccountancyExport $Tab['code_journal'] = str_pad(self::trunc($data->code_journal, 2), 2); $Tab['folio'] = '000'; - //We use invoice date $data->doc_date not $date_ecriture which is the transfert date - //maybe we should set an option for customer who prefer to keep in accounting software the tranfert date instead of invoice date ? + //We use invoice date $data->doc_date not $date_ecriture which is the transfert date + //maybe we should set an option for customer who prefer to keep in accounting software the tranfert date instead of invoice date ? //$Tab['date_ecriture'] = $date_ecriture; $Tab['date_ecriture'] = dol_print_date($data->doc_date, '%d%m%y'); $Tab['filler'] = ' '; @@ -463,25 +472,25 @@ class AccountancyExport $Tab['sens'] = $data->sens; // C or D $Tab['signe_montant'] = '+'; - //elarifr le montant doit etre en centimes sans point decimal ! + //elarifr le montant doit etre en centimes sans point decimal ! $Tab['montant'] = str_pad(abs($data->montant*100), 12, '0', STR_PAD_LEFT); // TODO manage negative amount - // $Tab['montant'] = str_pad(abs($data->montant), 12, '0', STR_PAD_LEFT); // TODO manage negative amount + // $Tab['montant'] = str_pad(abs($data->montant), 12, '0', STR_PAD_LEFT); // TODO manage negative amount $Tab['contrepartie'] = str_repeat(' ', 8); - // elarifr: date format must be fixed format : 6 char ddmmyy = %d%m%yand not defined by user / dolibarr setting + // elarifr: date format must be fixed format : 6 char ddmmyy = %d%m%yand not defined by user / dolibarr setting if (! empty($data->date_echeance)) //$Tab['date_echeance'] = dol_print_date($data->date_echeance, $conf->global->ACCOUNTING_EXPORT_DATE); - $Tab['date_echeance'] = dol_print_date($data->date_echeance, '%d%m%y' ); // elarifr: format must be ddmmyy + $Tab['date_echeance'] = dol_print_date($data->date_echeance, '%d%m%y' ); // elarifr: format must be ddmmyy else $Tab['date_echeance'] = '000000'; - //elarifr please keep quadra named field lettrage(2) + codestat(3) instead of fake lettrage(5) + //elarifr please keep quadra named field lettrage(2) + codestat(3) instead of fake lettrage(5) //$Tab['lettrage'] = str_repeat(' ', 5); $Tab['lettrage'] = str_repeat(' ', 2); $Tab['codestat'] = str_repeat(' ', 3); $Tab['num_piece'] = str_pad(self::trunc($data->piece_num, 5), 5); - //elarifr keep correct quadra named field instead of anon filler + //elarifr keep correct quadra named field instead of anon filler //$Tab['filler2'] = str_repeat(' ', 20); $Tab['affaire'] = str_repeat(' ', 10); $Tab['quantity1'] = str_repeat(' ', 10); @@ -490,16 +499,16 @@ class AccountancyExport $Tab['code_journal2'] = str_pad(self::trunc($data->code_journal, 3), 3); $Tab['filler3'] = str_repeat(' ', 3); - //elarifr keep correct quadra named field instead of anon filler libelle_ecriture2 is 30 char not 32 !!!! - //as we use utf8, we must remove accent to have only one ascii char instead of utf8 2 chars for specials that report wrong line size that will exceed import format spec - //todo we should filter more than only accent to avoid wrong line size - //TODO: remove invoice number doc_ref in libelle, - //TODO: we should offer an option for customer to build the libelle using invoice number / name / date in accounting software + //elarifr keep correct quadra named field instead of anon filler libelle_ecriture2 is 30 char not 32 !!!! + //as we use utf8, we must remove accent to have only one ascii char instead of utf8 2 chars for specials that report wrong line size that will exceed import format spec + //todo we should filter more than only accent to avoid wrong line size + //TODO: remove invoice number doc_ref in libelle, + //TODO: we should offer an option for customer to build the libelle using invoice number / name / date in accounting software //$Tab['libelle_ecriture2'] = str_pad(self::trunc(dol_string_unaccent($data->doc_ref) . ' ' . dol_string_unaccent($data->label_operation), 30), 30); $Tab['libelle_ecriture2'] = str_pad(self::trunc(dol_string_unaccent($data->label_operation), 30), 30); $Tab['codetva'] = str_repeat(' ', 2); - //elarifr we need to keep the 10 lastest number of invoice doc_ref not the beginning part that is the unusefull almost same part + //elarifr we need to keep the 10 lastest number of invoice doc_ref not the beginning part that is the unusefull almost same part //$Tab['num_piece3'] = str_pad(self::trunc($data->piece_num, 10), 10); $Tab['num_piece3'] = substr(self::trunc($data->doc_ref, 20), -10); $Tab['filler4'] = str_repeat(' ', 73); @@ -518,8 +527,8 @@ class AccountancyExport * * @return void */ - public function exportEbp($objectLines) - { + public function exportEbp($objectLines) + { $separator = ','; $end_line = "\n"; @@ -551,8 +560,8 @@ class AccountancyExport * * @return void */ - public function exportAgiris($objectLines) - { + public function exportAgiris($objectLines) + { $separator = ';'; $end_line = "\n"; @@ -589,8 +598,8 @@ class AccountancyExport * * @return void */ - public function exportConfigurable($objectLines) - { + public function exportConfigurable($objectLines) + { global $conf; foreach ($objectLines as $line) { @@ -613,15 +622,89 @@ class AccountancyExport } } + /** + * Export format : FEC + * + * @param array $objectLines data + * + * @return void + */ + public function exportFEC($objectLines) + { + $separator = ';'; + $end_line = "\n"; + + foreach ( $objectLines as $line ) { + $date_creation = dol_print_date($line->date_creation, '%d%m%Y'); + $date_doc = dol_print_date($line->doc_date, '%d%m%Y'); + $date_valid = dol_print_date($line->date_validated, '%d%m%Y'); + + // FEC:JournalCode + print $line->code_journal; + + // FEC:JournalLib + print $line->journal_label; + + // FEC:EcritureNum + print $line->piece_num . $separator; + + // FEC:EcritureDate + print $date_creation . $separator; + + // FEC:CompteNum + print $line->numero_compte . $separator + + // FEC:CompteLib + print $line->label_compte . $separator; + + // FEC:CompAuxNum + print $line->subledger_account . $separator; + + // FEC:CompAuxLib + print $line->subledger_label . $separator; + + // FEC:PieceRef + print $line->doc_ref . $separator; + + // FEC:PieceDate + print $date_doc . $separator; + + // FEC:EcritureLib + print $line->label_operation . $separator; + + // FEC:Debit + print price($line->debit) . $separator; + + // FEC:Credit + print price($line->credit) . $separator; + + // FEC:EcritureLet + print $line->lettering_code . $separator; + + // FEC:DateLet + print $line->date_lettering . $separator; + + // FEC:ValidDate + print $date_valid . $separator; + + // FEC:Montantdevise + print $line->multicurrency_amount . $separator; + + // FEC:Idevise + print $line->multicurrency_code; + + print $end_line; + } + } /** * * @param unknown $str data * @param integer $size data - * @return string + * @return string */ - public static function trunc($str, $size) - { + public static function trunc($str, $size) + { return dol_trunc($str, $size, 'right', 'UTF-8', 1); } } diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 5d9572da684..ab6061689e3 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -718,6 +718,10 @@ class BookKeeping extends CommonObject $sql .= " t.credit,"; $sql .= " t.montant,"; $sql .= " t.sens,"; + $sql .= " t.multicurrency_amount,"; + $sql .= " t.multicurrency_code,"; + $sql .= " t.lettering_code,"; + $sql .= " t.date_lettering,"; $sql .= " t.fk_user_author,"; $sql .= " t.import_key,"; $sql .= " t.code_journal,"; @@ -786,6 +790,10 @@ class BookKeeping extends CommonObject $line->credit = $obj->credit; $line->montant = $obj->montant; $line->sens = $obj->sens; + $line->multicurrency_amount = $obj->multicurrency_amount; + $line->multicurrency_code = $obj->multicurrency_code; + $line->lettering_code = $obj->lettering_code; + $line->date_lettering = $obj->date_lettering; $line->fk_user_author = $obj->fk_user_author; $line->import_key = $obj->import_key; $line->code_journal = $obj->code_journal; diff --git a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql index 4169b858536..af6cd66826d 100644 --- a/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql +++ b/htdocs/install/mysql/tables/llx_accounting_bookkeeping.sql @@ -22,8 +22,8 @@ CREATE TABLE llx_accounting_bookkeeping rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY, entity integer DEFAULT 1 NOT NULL, -- | multi company id doc_date date NOT NULL, -- FEC:PieceDate - doc_type varchar(30) NOT NULL, -- FEC:PieceRef | facture_client/reglement_client/facture_fournisseur/reglement_fournisseur - doc_ref varchar(300) NOT NULL, -- | facture_client/reglement_client/... reference number + doc_type varchar(30) NOT NULL, -- | facture_client/reglement_client/facture_fournisseur/reglement_fournisseur + doc_ref varchar(300) NOT NULL, -- FEC:PieceRef | facture_client/reglement_client/... reference number fk_doc integer NOT NULL, -- | facture_client/reglement_client/... rowid fk_docdet integer NOT NULL, -- | facture_client/reglement_client/... line rowid thirdparty_code varchar(32), -- Third party code (customer or supplier) when record is saved (may help debug) diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index e1fe73d0383..7a7c730f05b 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -263,6 +263,7 @@ Modelcsv_ebp=Export towards EBP Modelcsv_cogilog=Export towards Cogilog Modelcsv_agiris=Export towards Agiris Modelcsv_configurable=Export Configurable +Modelcsv_FEC=Export FEC (Art. L47 A) (Test) ChartofaccountsId=Chart of accounts Id ## Tools - Init accounting account on product / service From 41f2289ffaabbf7992436cf4f56511644e91a2f8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Oct 2018 22:28:30 +0200 Subject: [PATCH 055/433] Save pos station into invoice --- htdocs/cashdesk/validation_verif.php | 1 + htdocs/compta/facture/class/facture.class.php | 5 ++++- htdocs/install/mysql/migration/8.0.0-9.0.0.sql | 1 + htdocs/install/mysql/tables/llx_facture.sql | 1 + htdocs/takepos/invoice.php | 3 ++- 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/htdocs/cashdesk/validation_verif.php b/htdocs/cashdesk/validation_verif.php index 05da0bdebe1..b42bc90d8fb 100644 --- a/htdocs/cashdesk/validation_verif.php +++ b/htdocs/cashdesk/validation_verif.php @@ -216,6 +216,7 @@ switch ($action) $invoice->cond_reglement_id=$cond_reglement_id; $invoice->mode_reglement_id=$mode_reglement_id; $invoice->module_source = 'cashdesk'; + $invoice->pos_source = '0'; //print "c=".$invoice->cond_reglement_id." m=".$invoice->mode_reglement_id; exit; // Si paiement differe ... diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index dd207af57ec..a0013593390 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -128,6 +128,8 @@ class Facture extends CommonInvoice public $paye; //! key of module source when invoice generated from a dedicated module ('cashdesk', 'takepos', ...) public $module_source; + //! key of pos source ('0', '1', ...) + public $pos_source; //! id of template invoice when generated from a template invoice public $fk_fac_rec_source; //! id of source invoice if replacement invoice or credit note @@ -447,7 +449,7 @@ class Facture extends CommonInvoice $sql.= ", note_public"; $sql.= ", ref_client, ref_int"; $sql.= ", fk_account"; - $sql.= ", module_source, fk_fac_rec_source, fk_facture_source, fk_user_author, fk_projet"; + $sql.= ", module_source, pos_source, fk_fac_rec_source, fk_facture_source, fk_user_author, fk_projet"; $sql.= ", fk_cond_reglement, fk_mode_reglement, date_lim_reglement, model_pdf"; $sql.= ", situation_cycle_ref, situation_counter, situation_final"; $sql.= ", fk_incoterms, location_incoterms"; @@ -472,6 +474,7 @@ class Facture extends CommonInvoice $sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); $sql.= ", ".($this->module_source ? "'".$this->db->escape($this->module_source)."'" : "null"); + $sql.= ", ".($this->pos_source ? "'".$this->db->escape($this->pos_source)."'" : "null"); $sql.= ", ".($this->fk_fac_rec_source?"'".$this->db->escape($this->fk_fac_rec_source)."'":"null"); $sql.= ", ".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null"); $sql.= ", ".($user->id > 0 ? "'".$user->id."'":"null"); diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql index 0d3f823cb52..476eac1c4d9 100644 --- a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql +++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql @@ -35,6 +35,7 @@ ALTER TABLE llx_accounting_system MODIFY COLUMN pcg_version varchar(32) NOT NULL ALTER TABLE llx_accounting_account ADD CONSTRAINT fk_accounting_account_fk_pcg_version FOREIGN KEY (fk_pcg_version) REFERENCES llx_accounting_system (pcg_version); ALTER TABLE llx_facture ADD COLUMN module_source varchar(32); +ALTER TABLE llx_facture ADD COLUMN pos_source varchar(32); create table llx_facture_rec_extrafields ( diff --git a/htdocs/install/mysql/tables/llx_facture.sql b/htdocs/install/mysql/tables/llx_facture.sql index 6f326450f7f..c001d459b48 100644 --- a/htdocs/install/mysql/tables/llx_facture.sql +++ b/htdocs/install/mysql/tables/llx_facture.sql @@ -64,6 +64,7 @@ create table llx_facture fk_user_valid integer, -- user validating module_source varchar(32), -- name of module when invoice generated by a dedicated module (POS, ...) + pos_source varchar(32), -- name of POS station when invoice is generated by a POS module fk_fac_rec_source integer, -- facture rec source fk_facture_source integer, -- facture origin if credit notes or replacement invoice fk_projet integer DEFAULT NULL, -- project invoice is linked to diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 939d1ea2189..165a128b9e5 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -83,9 +83,10 @@ if (($action=="addline" || $action=="freezone") and $placeid==0) $invoice->date=dol_now(); $invoice->ref="(PROV-POS)"; $invoice->module_source = 'takepos'; + $invoice->pos_source = (string) $place; $placeid=$invoice->create($user); - $sql="UPDATE ".MAIN_DB_PREFIX."facture set facnumber='(PROV-POS-".$place.")' where rowid=".$placeid; + $sql="UPDATE ".MAIN_DB_PREFIX."facture set facnumber='(PROV-POS-".$placeid.")' where rowid=".$placeid; $db->query($sql); } } From 35d5a495de889b1bccdbdea7ce42761419242f30 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 8 Oct 2018 22:51:20 +0200 Subject: [PATCH 056/433] Save pos_source with id of POS station --- htdocs/compta/facture/class/facture.class.php | 2 +- htdocs/takepos/invoice.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index a0013593390..98222fafc00 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -474,7 +474,7 @@ class Facture extends CommonInvoice $sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); $sql.= ", ".($this->fk_account>0?$this->fk_account:'NULL'); $sql.= ", ".($this->module_source ? "'".$this->db->escape($this->module_source)."'" : "null"); - $sql.= ", ".($this->pos_source ? "'".$this->db->escape($this->pos_source)."'" : "null"); + $sql.= ", ".($this->pos_source != '' ? "'".$this->db->escape($this->pos_source)."'" : "null"); $sql.= ", ".($this->fk_fac_rec_source?"'".$this->db->escape($this->fk_fac_rec_source)."'":"null"); $sql.= ", ".($this->fk_facture_source?"'".$this->db->escape($this->fk_facture_source)."'":"null"); $sql.= ", ".($user->id > 0 ? "'".$user->id."'":"null"); diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 165a128b9e5..cdfe47a756f 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -77,16 +77,17 @@ if ($action == 'valid' && $user->rights->facture->creer){ if (($action=="addline" || $action=="freezone") and $placeid==0) { + // $place is id of POS, $placeid is id of invoice if ($placeid==0) { $invoice = new Facture($db); $invoice->socid=$conf->global->CASHDESK_ID_THIRDPARTY; $invoice->date=dol_now(); $invoice->ref="(PROV-POS)"; $invoice->module_source = 'takepos'; - $invoice->pos_source = (string) $place; + $invoice->pos_source = (string) (empty($place)?'0':$place); $placeid=$invoice->create($user); - $sql="UPDATE ".MAIN_DB_PREFIX."facture set facnumber='(PROV-POS-".$placeid.")' where rowid=".$placeid; + $sql="UPDATE ".MAIN_DB_PREFIX."facture set facnumber='(PROV-POS-".$place.")' where rowid=".$placeid; $db->query($sql); } } From 1e706c2e6b4368d2abf5a2eb94945fb3081e314e Mon Sep 17 00:00:00 2001 From: Abbes Bahfir Date: Mon, 8 Oct 2018 23:17:44 +0100 Subject: [PATCH 057/433] Fix: users categories type is Categorie::TYPE_USER --- htdocs/user/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index dc2437af825..888550a6408 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -2285,7 +2285,7 @@ else { print ''; print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; print ''; print ''; + print ''; - print ''; + print ''; print ''; diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index b5fec4a0e7c..fb604988582 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -212,7 +212,8 @@ $sql = "SELECT f.rowid as facid, f.facnumber as ref, f.datef, f.type as ftype,"; $sql.= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,"; $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_sell as code_sell, p.tva_tx as tva_tx_prod,"; $sql.= " aa.rowid as aarowid,"; -$sql.= " co.label as country, s.tva_intra"; +$sql.= " co.code as country_code, co.label as country,"; +$sql.= " s.tva_intra"; $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook $sql.=$hookmanager->resPrint; @@ -265,7 +266,7 @@ else if ($search_year > 0) $sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'"; } if (strlen(trim($search_country))) { - $sql .= natural_search("co.label", $search_country); + $sql .= natural_search("co.code", $search_country); } if (strlen(trim($search_tvaintra))) { $sql .= natural_search("s.tva_intra", $search_tvaintra); @@ -371,7 +372,10 @@ if ($result) { print ''; print ''; print ''; - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index ae368a20de1..b328cf73455 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -236,8 +236,6 @@ if ($result) { if ($search_day) $param .= '&search_day='.urlencode($search_day); if ($search_month) $param .= '&search_month='.urlencode($search_month); if ($search_year) $param .= '&search_year='.urlencode($search_year); - if ($search_country) $param .= "&search_country=" . urlencode($search_country); - if ($search_tvaintra) $param .= "&search_tvaintra=" . urlencode($search_tvaintra); print '' . "\n"; print ''; diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index 326d249f86d..48bde2dfb87 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -172,7 +172,9 @@ print ' - - - -

Limitations of APS Support in the Panel

-

About This Document

-

This document is addressed to independent software -vendors who plan to distribute web applications among the Panel users. -The aim of the document is to help vendors find out whether they can -package their applications to APS to make them available through the -Panel.

-

The document does not contain information about -Application Packaging Standard itself or give application packaging -instructions. It focuses on how the Panel implements APS and what APS -packages are not supported by this implementation.

-

-

APS Support in the Panel

-

Application Packaging Standard (APS) - is a set of rules that defines a web application packaging format. This - standard is designed to ease the integration of applications in a -service provider's infrastructure. It covers provisioning, management, -and integration of cloud-based services and applications.

-

The Panel uses APS to offer third-party applications to hosting customers. These applications are presented in APS catalog, where the customers can buy or download them.

-

Currently, the Panel does not support all aspects of - APS. Therefore, customers may have problems trying to install certain -applications. To find out whether your application is compatible with -the Panel, see section Plesk Panel Restrictions.

-

You can find more information about APS at http://www.apsstandard.org/.

-

APS specification and supporting documents are available at http://www.apsstandard.org/isv/documentation/.

-

-

Restrictions on Packages Processing

-

The current Panel version has restrictions on APS -applications processing. If an application requires performing -restricted actions, the Panel will not install it. Particularly, these -actions are the following:

-
  • Sending e-mails or processing incoming mail.

    See Mail aspect of APS in APS Format Specification v1.2, section 8.8. Mail at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.aspects.mail

    -
  • Changing the DNS resource records of an environment where the application works.

    See DNS aspect in APS Format Specification v1.2, section 8.10. DNS Zone at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.aspects.dns

    -
  • Installing third-party dynamic libraries (*.dll, *.so).

    See DLL aspect in APS Format Specification v1.2, section 8.11. DLL Content Processing Method at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.aspects.dll

    -
  • Updating older version of application with -complex changes in application settings or deployment logic. According -to APS, such updates are called upgrades. For more information on the application updates, see the APS Format Specification v1.2, section 5.1.15 Updates at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.metadata.common.update

If - you need you application to perform these actions, consider other ways -of integration with the Panel: API RPC, modules or Panel Notifications.

-

Also, the Panel does not support the following actions defined in the application package:

-
  • Checking application settings for consistency via verification script. For more information on verification scripts, see the APS Format Specification v1.2, section 5.3.3 Verification Script at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.metadata.provision.verification-script
  • Processing application resource usage reports defined by resource counters and passed by resource script . For more information on resource counters and resource scripts, see the APS Format Specification v1.2, section 5.2.6. Resources at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.metadata.service.resources and 5.3.3 Resources Script at http://www.apsstandard.org/r/doc/package-format-specification-1.2/index.html#s.metadata.provision.resource-script
  • - -

    Copyright Notice

    - - - - - - - - - - - - - - - - - - - -

    -Please send us your feedback on this help page.

    - - - - -
- \ No newline at end of file diff --git a/build/aps/Limitations of APS Support in the Panel_fichiers/highlight.js b/build/aps/Limitations of APS Support in the Panel_fichiers/highlight.js deleted file mode 100644 index 10056e95fd4..00000000000 --- a/build/aps/Limitations of APS Support in the Panel_fichiers/highlight.js +++ /dev/null @@ -1,64 +0,0 @@ -function last(href) -{ - var ret = href.split("/"); - return ret[ret.length-1]; -} - -function StopProcess() -{ -LeftFrame = parent.TOC.document.location.href; -LeftFrame = last(LeftFrame); -if (LeftFrame == "dhtml_search.htm") return 1 -else return 0; -} - - - -function highlightTOC(str) { - - - - - - if (StopProcess()) return; - try { - - str = str || parent.BODY.document.location.href; - uri = last(str); - list = parent.TOC.document.getElementsByTagName("a"); - for(i=0; i - * - * For a fairly comprehensive set of languages see the - * README - * file that came with this source. At a minimum, the lexer should work on a - * number of languages including C and friends, Java, Python, Bash, SQL, HTML, - * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk - * and a subset of Perl, but, because of commenting conventions, doesn't work on - * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. - *

- * Usage:

    - *
  1. include this source file in an html page via - * {@code } - *
  2. define style rules. See the example page for examples. - *
  3. mark the {@code
    } and {@code } tags in your source with
    - *    {@code class=prettyprint.}
    - *    You can also use the (html deprecated) {@code } tag, but the pretty
    - *    printer needs to do more substantial DOM manipulations to support that, so
    - *    some css styles may not be preserved.
    - * </ol>
    - * That's it.  I wanted to keep the API as simple as possible, so there's no
    - * need to specify which language the code is in, but if you wish, you can add
    - * another class to the {@code <pre>} or {@code <code>} element to specify the
    - * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    - * starts with "lang-" followed by a file extension, specifies the file type.
    - * See the "lang-*.js" files in this directory for code that implements
    - * per-language file handlers.
    - * <p>
    - * Change log:<br>
    - * cbeust, 2006/08/22
    - * <blockquote>
    - *   Java annotations (start with "@") are now captured as literals ("lit")
    - * </blockquote>
    - * @requires console
    - */
    -
    -// JSLint declarations
    -/*global console, document, navigator, setTimeout, window */
    -
    -/**
    - * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    - * UI events.
    - * If set to {@code false}, {@code prettyPrint()} is synchronous.
    - */
    -window['PR_SHOULD_USE_CONTINUATION'] = true;
    -
    -/** the number of characters between tab columns */
    -window['PR_TAB_WIDTH'] = 8;
    -
    -/** Walks the DOM returning a properly escaped version of innerHTML.
    -  * @param {Node} node
    -  * @param {Array.<string>} out output buffer that receives chunks of HTML.
    -  */
    -window['PR_normalizedHtml']
    -
    -/** Contains functions for creating and registering new language handlers.
    -  * @type {Object}
    -  */
    -  = window['PR']
    -
    -/** Pretty print a chunk of code.
    -  *
    -  * @param {string} sourceCodeHtml code as html
    -  * @return {string} code as html, but prettier
    -  */
    -  = window['prettyPrintOne']
    -/** Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    -  * {@code class=prettyprint} and prettify them.
    -  * @param {Function?} opt_whenDone if specified, called when the last entry
    -  *     has been finished.
    -  */
    -  = window['prettyPrint'] = void 0;
    -
    -/** browser detection. @extern @returns false if not IE, otherwise the major version. */
    -window['_pr_isIE6'] = function () {
    -  var ieVersion = navigator && navigator.userAgent &&
    -      navigator.userAgent.match(/\bMSIE ([678])\./);
    -  ieVersion = ieVersion ? +ieVersion[1] : false;
    -  window['_pr_isIE6'] = function () { return ieVersion; };
    -  return ieVersion;
    -};
    -
    -
    -(function () {
    -  // Keyword lists for various languages.
    -  var FLOW_CONTROL_KEYWORDS =
    -      "break continue do else for if return while ";
    -  var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " +
    -      "double enum extern float goto int long register short signed sizeof " +
    -      "static struct switch typedef union unsigned void volatile ";
    -  var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " +
    -      "new operator private protected public this throw true try typeof ";
    -  var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " +
    -      "concept concept_map const_cast constexpr decltype " +
    -      "dynamic_cast explicit export friend inline late_check " +
    -      "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
    -      "template typeid typename using virtual wchar_t where ";
    -  var JAVA_KEYWORDS = COMMON_KEYWORDS +
    -      "abstract boolean byte extends final finally implements import " +
    -      "instanceof null native package strictfp super synchronized throws " +
    -      "transient ";
    -  var CSHARP_KEYWORDS = JAVA_KEYWORDS +
    -      "as base by checked decimal delegate descending event " +
    -      "fixed foreach from group implicit in interface internal into is lock " +
    -      "object out override orderby params partial readonly ref sbyte sealed " +
    -      "stackalloc string select uint ulong unchecked unsafe ushort var ";
    -  var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
    -      "debugger eval export function get null set undefined var with " +
    -      "Infinity NaN ";
    -  var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " +
    -      "goto if import last local my next no our print package redo require " +
    -      "sub undef unless until use wantarray while BEGIN END ";
    -  var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
    -      "elif except exec finally from global import in is lambda " +
    -      "nonlocal not or pass print raise try with yield " +
    -      "False True None ";
    -  var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
    -      " defined elsif end ensure false in module next nil not or redo rescue " +
    -      "retry self super then true undef unless until when yield BEGIN END ";
    -  var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " +
    -      "function in local set then until ";
    -  var ALL_KEYWORDS = (
    -      CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +
    -      PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);
    -
    -  // token style names.  correspond to css classes
    -  /** token style for PHP variables */
    -  var PR_VAR = 'vr';
    -  /** token style for a string literal */
    -  var PR_STRING = 'str';
    -  /** token style for a keyword */
    -  var PR_KEYWORD = 'kwd';
    -  /** token style for a comment */
    -  var PR_COMMENT = 'com';
    -  /** token style for a type */
    -  var PR_TYPE = 'typ';
    -  /** token style for a literal value.  e.g. 1, null, true. */
    -  var PR_LITERAL = 'lit';
    -  /** token style for a punctuation string. */
    -  var PR_PUNCTUATION = 'pun';
    -  /** token style for a punctuation string. */
    -  var PR_PLAIN = 'pln';
    -
    -  /** token style for an sgml tag. */
    -  var PR_TAG = 'tag';
    -  /** token style for a markup declaration such as a DOCTYPE. */
    -  var PR_DECLARATION = 'dec';
    -  /** token style for embedded source. */
    -  var PR_SOURCE = 'src';
    -  /** token style for an sgml attribute name. */
    -  var PR_ATTRIB_NAME = 'atn';
    -  /** token style for an sgml attribute value. */
    -  var PR_ATTRIB_VALUE = 'atv';
    -
    -  /**
    -   * A class that indicates a section of markup that is not code, e.g. to allow
    -   * embedding of line numbers within code listings.
    -   */
    -  var PR_NOCODE = 'nocode';
    -
    -  /** A set of tokens that can precede a regular expression literal in
    -    * javascript.
    -    * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full
    -    * list, but I've removed ones that might be problematic when seen in
    -    * languages that don't support regular expression literals.
    -    *
    -    * <p>Specifically, I've removed any keywords that can't precede a regexp
    -    * literal in a syntactically legal javascript program, and I've removed the
    -    * "in" keyword since it's not a keyword in many languages, and might be used
    -    * as a count of inches.
    -    *
    -    * <p>The link a above does not accurately describe EcmaScript rules since
    -    * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    -    * very well in practice.
    -    *
    -    * @private
    -    */
    -  var REGEXP_PRECEDER_PATTERN = function () {
    -      var preceders = [
    -          "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=",
    -          "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=",
    -          "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";",
    -          "<", "<<", "<<=", "<=", "=", "==", "===", ">",
    -          ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
    -          "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
    -          "||=", "~" /* handles =~ and !~ */,
    -          "break", "case", "continue", "delete",
    -          "do", "else", "finally", "instanceof",
    -          "return", "throw", "try", "typeof"
    -          ];
    -      var pattern = '(?:^^|[+-]';
    -      for (var i = 0; i < preceders.length; ++i) {
    -        pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1');
    -      }
    -      pattern += ')\\s*';  // matches at end, and matches empty string
    -      return pattern;
    -      // CAVEAT: this does not properly handle the case where a regular
    -      // expression immediately follows another since a regular expression may
    -      // have flags for case-sensitivity and the like.  Having regexp tokens
    -      // adjacent is not valid in any language I'm aware of, so I'm punting.
    -      // TODO: maybe style special characters inside a regexp as punctuation.
    -    }();
    -
    -  // Define regexps here so that the interpreter doesn't have to create an
    -  // object each time the function containing them is called.
    -  // The language spec requires a new object created even if you don't access
    -  // the $1 members.
    -  var pr_amp = /&/g;
    -  var pr_lt = /</g;
    -  var pr_gt = />/g;
    -  var pr_quot = /\"/g;
    -  /** like textToHtml but escapes double quotes to be attribute safe. */
    -  function attribToHtml(str) {
    -    return str.replace(pr_amp, '&amp;')
    -        .replace(pr_lt, '&lt;')
    -        .replace(pr_gt, '&gt;')
    -        .replace(pr_quot, '&quot;');
    -  }
    -
    -  /** escapest html special characters to html. */
    -  function textToHtml(str) {
    -    return str.replace(pr_amp, '&amp;')
    -        .replace(pr_lt, '&lt;')
    -        .replace(pr_gt, '&gt;');
    -  }
    -
    -
    -  var pr_ltEnt = /&lt;/g;
    -  var pr_gtEnt = /&gt;/g;
    -  var pr_aposEnt = /&apos;/g;
    -  var pr_quotEnt = /&quot;/g;
    -  var pr_ampEnt = /&amp;/g;
    -  var pr_nbspEnt = /&nbsp;/g;
    -  /** unescapes html to plain text. */
    -  function htmlToText(html) {
    -    var pos = html.indexOf('&');
    -    if (pos < 0) { return html; }
    -    // Handle numeric entities specially.  We can't use functional substitution
    -    // since that doesn't work in older versions of Safari.
    -    // These should be rare since most browsers convert them to normal chars.
    -    for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0;) {
    -      var end = html.indexOf(';', pos);
    -      if (end >= 0) {
    -        var num = html.substring(pos + 3, end);
    -        var radix = 10;
    -        if (num && num.charAt(0) === 'x') {
    -          num = num.substring(1);
    -          radix = 16;
    -        }
    -        var codePoint = parseInt(num, radix);
    -        if (!isNaN(codePoint)) {
    -          html = (html.substring(0, pos) + String.fromCharCode(codePoint) +
    -                  html.substring(end + 1));
    -        }
    -      }
    -    }
    -
    -    return html.replace(pr_ltEnt, '<')
    -        .replace(pr_gtEnt, '>')
    -        .replace(pr_aposEnt, "'")
    -        .replace(pr_quotEnt, '"')
    -        .replace(pr_nbspEnt, ' ')
    -        .replace(pr_ampEnt, '&');
    -  }
    -
    -  /** is the given node's innerHTML normally unescaped? */
    -  function isRawContent(node) {
    -    return 'XMP' === node.tagName;
    -  }
    -
    -  var newlineRe = /[\r\n]/g;
    -  /**
    -   * Are newlines and adjacent spaces significant in the given node's innerHTML?
    -   */
    -  function isPreformatted(node, content) {
    -    // PRE means preformatted, and is a very common case, so don't create
    -    // unnecessary computed style objects.
    -    if ('PRE' === node.tagName) { return true; }
    -    if (!newlineRe.test(content)) { return true; }  // Don't care
    -    var whitespace = '';
    -    // For disconnected nodes, IE has no currentStyle.
    -    if (node.currentStyle) {
    -      whitespace = node.currentStyle.whiteSpace;
    -    } else if (window.getComputedStyle) {
    -      // Firefox makes a best guess if node is disconnected whereas Safari
    -      // returns the empty string.
    -      whitespace = window.getComputedStyle(node, null).whiteSpace;
    -    }
    -    return !whitespace || whitespace === 'pre';
    -  }
    -
    -  function normalizedHtml(node, out, opt_sortAttrs) {
    -    switch (node.nodeType) {
    -      case 1:  // an element
    -        var name = node.tagName.toLowerCase();
    -
    -        out.push('<', name);
    -        var attrs = node.attributes;
    -        var n = attrs.length;
    -        if (n) {
    -          if (opt_sortAttrs) {
    -            var sortedAttrs = [];
    -            for (var i = n; --i >= 0;) { sortedAttrs[i] = attrs[i]; }
    -            sortedAttrs.sort(function (a, b) {
    -                return (a.name < b.name) ? -1 : a.name === b.name ? 0 : 1;
    -              });
    -            attrs = sortedAttrs;
    -          }
    -          for (var i = 0; i < n; ++i) {
    -            var attr = attrs[i];
    -            if (!attr.specified) { continue; }
    -            out.push(' ', attr.name.toLowerCase(),
    -                     '="', attribToHtml(attr.value), '"');
    -          }
    -        }
    -        out.push('>');
    -        for (var child = node.firstChild; child; child = child.nextSibling) {
    -          normalizedHtml(child, out, opt_sortAttrs);
    -        }
    -        if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {
    -          out.push('<\/', name, '>');
    -        }
    -        break;
    -      case 3: case 4: // text
    -        out.push(textToHtml(node.nodeValue));
    -        break;
    -    }
    -  }
    -
    -  /**
    -   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    -   * matches the union o the sets o strings matched d by the input RegExp.
    -   * Since it matches globally, if the input strings have a start-of-input
    -   * anchor (/^.../), it is ignored for the purposes of unioning.
    -   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    -   * @return {RegExp} a global regex.
    -   */
    -  function combinePrefixPatterns(regexs) {
    -    var capturedGroupIndex = 0;
    -
    -    var needToFoldCase = false;
    -    var ignoreCase = false;
    -    for (var i = 0, n = regexs.length; i < n; ++i) {
    -      var regex = regexs[i];
    -      if (regex.ignoreCase) {
    -        ignoreCase = true;
    -      } else if (/[a-z]/i.test(regex.source.replace(
    -                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    -        needToFoldCase = true;
    -        ignoreCase = false;
    -        break;
    -      }
    -    }
    -
    -    function decodeEscape(charsetPart) {
    -      if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); }
    -      switch (charsetPart.charAt(1)) {
    -        case 'b': return 8;
    -        case 't': return 9;
    -        case 'n': return 0xa;
    -        case 'v': return 0xb;
    -        case 'f': return 0xc;
    -        case 'r': return 0xd;
    -        case 'u': case 'x':
    -          return parseInt(charsetPart.substring(2), 16)
    -              || charsetPart.charCodeAt(1);
    -        case '0': case '1': case '2': case '3': case '4':
    -        case '5': case '6': case '7':
    -          return parseInt(charsetPart.substring(1), 8);
    -        default: return charsetPart.charCodeAt(1);
    -      }
    -    }
    -
    -    function encodeEscape(charCode) {
    -      if (charCode < 0x20) {
    -        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    -      }
    -      var ch = String.fromCharCode(charCode);
    -      if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
    -        ch = '\\' + ch;
    -      }
    -      return ch;
    -    }
    -
    -    function caseFoldCharset(charSet) {
    -      var charsetParts = charSet.substring(1, charSet.length - 1).match(
    -          new RegExp(
    -              '\\\\u[0-9A-Fa-f]{4}'
    -              + '|\\\\x[0-9A-Fa-f]{2}'
    -              + '|\\\\[0-3][0-7]{0,2}'
    -              + '|\\\\[0-7]{1,2}'
    -              + '|\\\\[\\s\\S]'
    -              + '|-'
    -              + '|[^-\\\\]',
    -              'g'));
    -      var groups = [];
    -      var ranges = [];
    -      var inverse = charsetParts[0] === '^';
    -      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    -        var p = charsetParts[i];
    -        switch (p) {
    -          case '\\B': case '\\b':
    -          case '\\D': case '\\d':
    -          case '\\S': case '\\s':
    -          case '\\W': case '\\w':
    -            groups.push(p);
    -            continue;
    -        }
    -        var start = decodeEscape(p);
    -        var end;
    -        if (i + 2 < n && '-' === charsetParts[i + 1]) {
    -          end = decodeEscape(charsetParts[i + 2]);
    -          i += 2;
    -        } else {
    -          end = start;
    -        }
    -        ranges.push([start, end]);
    -        // If the range might intersect letters, then expand it.
    -        if (!(end < 65 || start > 122)) {
    -          if (!(end < 65 || start > 90)) {
    -            ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    -          }
    -          if (!(end < 97 || start > 122)) {
    -            ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    -          }
    -        }
    -      }
    -
    -      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    -      // -> [[1, 12], [14, 14], [16, 17]]
    -      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    -      var consolidatedRanges = [];
    -      var lastRange = [NaN, NaN];
    -      for (var i = 0; i < ranges.length; ++i) {
    -        var range = ranges[i];
    -        if (range[0] <= lastRange[1] + 1) {
    -          lastRange[1] = Math.max(lastRange[1], range[1]);
    -        } else {
    -          consolidatedRanges.push(lastRange = range);
    -        }
    -      }
    -
    -      var out = ['['];
    -      if (inverse) { out.push('^'); }
    -      out.push.apply(out, groups);
    -      for (var i = 0; i < consolidatedRanges.length; ++i) {
    -        var range = consolidatedRanges[i];
    -        out.push(encodeEscape(range[0]));
    -        if (range[1] > range[0]) {
    -          if (range[1] + 1 > range[0]) { out.push('-'); }
    -          out.push(encodeEscape(range[1]));
    -        }
    -      }
    -      out.push(']');
    -      return out.join('');
    -    }
    -
    -    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    -      // Split into character sets, escape sequences, punctuation strings
    -      // like ('(', '(?:', ')', '^'), and runs of characters that do not
    -      // include any of the above.
    -      var parts = regex.source.match(
    -          new RegExp(
    -              '(?:'
    -              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    -              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    -              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    -              + '|\\\\[0-9]+'  // a back-reference or octal escape
    -              + '|\\\\[^ux0-9]'  // other escape sequence
    -              + '|\\(\\?[:!=]'  // start of a non-capturing group
    -              + '|[\\(\\)\\^]'  // start/emd of a group, or line start
    -              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    -              + ')',
    -              'g'));
    -      var n = parts.length;
    -
    -      // Maps captured group numbers to the number they will occupy in
    -      // the output or to -1 if that has not been determined, or to
    -      // undefined if they need not be capturing in the output.
    -      var capturedGroups = [];
    -
    -      // Walk over and identify back references to build the capturedGroups
    -      // mapping.
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        var p = parts[i];
    -        if (p === '(') {
    -          // groups are 1-indexed, so max group index is count of '('
    -          ++groupIndex;
    -        } else if ('\\' === p.charAt(0)) {
    -          var decimalValue = +p.substring(1);
    -          if (decimalValue && decimalValue <= groupIndex) {
    -            capturedGroups[decimalValue] = -1;
    -          }
    -        }
    -      }
    -
    -      // Renumber groups and reduce capturing groups to non-capturing groups
    -      // where possible.
    -      for (var i = 1; i < capturedGroups.length; ++i) {
    -        if (-1 === capturedGroups[i]) {
    -          capturedGroups[i] = ++capturedGroupIndex;
    -        }
    -      }
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        var p = parts[i];
    -        if (p === '(') {
    -          ++groupIndex;
    -          if (capturedGroups[groupIndex] === undefined) {
    -            parts[i] = '(?:';
    -          }
    -        } else if ('\\' === p.charAt(0)) {
    -          var decimalValue = +p.substring(1);
    -          if (decimalValue && decimalValue <= groupIndex) {
    -            parts[i] = '\\' + capturedGroups[groupIndex];
    -          }
    -        }
    -      }
    -
    -      // Remove any prefix anchors so that the output will match anywhere.
    -      // ^^ really does mean an anchored match though.
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    -      }
    -
    -      // Expand letters to groupts to handle mixing of case-sensitive and
    -      // case-insensitive patterns if necessary.
    -      if (regex.ignoreCase && needToFoldCase) {
    -        for (var i = 0; i < n; ++i) {
    -          var p = parts[i];
    -          var ch0 = p.charAt(0);
    -          if (p.length >= 2 && ch0 === '[') {
    -            parts[i] = caseFoldCharset(p);
    -          } else if (ch0 !== '\\') {
    -            // TODO: handle letters in numeric escapes.
    -            parts[i] = p.replace(
    -                /[a-zA-Z]/g,
    -                function (ch) {
    -                  var cc = ch.charCodeAt(0);
    -                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    -                });
    -          }
    -        }
    -      }
    -
    -      return parts.join('');
    -    }
    -
    -    var rewritten = [];
    -    for (var i = 0, n = regexs.length; i < n; ++i) {
    -      var regex = regexs[i];
    -      if (regex.global || regex.multiline) { throw new Error('' + regex); }
    -      rewritten.push(
    -          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    -    }
    -
    -    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    -  }
    -
    -  var PR_innerHtmlWorks = null;
    -  function getInnerHtml(node) {
    -    // inner html is hopelessly broken in Safari 2.0.4 when the content is
    -    // an html description of well formed XML and the containing tag is a PRE
    -    // tag, so we detect that case and emulate innerHTML.
    -    if (null === PR_innerHtmlWorks) {
    -      var testNode = document.createElement('PRE');
    -      testNode.appendChild(
    -          document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));
    -      PR_innerHtmlWorks = !/</.test(testNode.innerHTML);
    -    }
    -
    -    if (PR_innerHtmlWorks) {
    -      var content = node.innerHTML;
    -      // XMP tags contain unescaped entities so require special handling.
    -      if (isRawContent(node)) {
    -        content = textToHtml(content);
    -      } else if (!isPreformatted(node, content)) {
    -        content = content.replace(/(<br\s*\/?>)[\r\n]+/g, '$1')
    -            .replace(/(?:[\r\n]+[ \t]*)+/g, ' ');
    -      }
    -      return content;
    -    }
    -
    -    var out = [];
    -    for (var child = node.firstChild; child; child = child.nextSibling) {
    -      normalizedHtml(child, out);
    -    }
    -    return out.join('');
    -  }
    -
    -  /** returns a function that expand tabs to spaces.  This function can be fed
    -    * successive chunks of text, and will maintain its own internal state to
    -    * keep track of how tabs are expanded.
    -    * @return {function (string) : string} a function that takes
    -    *   plain text and return the text with tabs expanded.
    -    * @private
    -    */
    -  function makeTabExpander(tabWidth) {
    -    var SPACES = '                ';
    -    var charInLine = 0;
    -
    -    return function (plainText) {
    -      // walk over each character looking for tabs and newlines.
    -      // On tabs, expand them.  On newlines, reset charInLine.
    -      // Otherwise increment charInLine
    -      var out = null;
    -      var pos = 0;
    -      for (var i = 0, n = plainText.length; i < n; ++i) {
    -        var ch = plainText.charAt(i);
    -
    -        switch (ch) {
    -          case '\t':
    -            if (!out) { out = []; }
    -            out.push(plainText.substring(pos, i));
    -            // calculate how much space we need in front of this part
    -            // nSpaces is the amount of padding -- the number of spaces needed
    -            // to move us to the next column, where columns occur at factors of
    -            // tabWidth.
    -            var nSpaces = tabWidth - (charInLine % tabWidth);
    -            charInLine += nSpaces;
    -            for (; nSpaces >= 0; nSpaces -= SPACES.length) {
    -              out.push(SPACES.substring(0, nSpaces));
    -            }
    -            pos = i + 1;
    -            break;
    -          case '\n':
    -            charInLine = 0;
    -            break;
    -          default:
    -            ++charInLine;
    -        }
    -      }
    -      if (!out) { return plainText; }
    -      out.push(plainText.substring(pos));
    -      return out.join('');
    -    };
    -  }
    -
    -  var pr_chunkPattern = new RegExp(
    -      '[^<]+'  // A run of characters other than '<'
    -      + '|<\!--[\\s\\S]*?--\>'  // an HTML comment
    -      + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>'  // a CDATA section
    -      // a probable tag that should not be highlighted
    -      + '|<\/?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>'
    -      + '|<',  // A '<' that does not begin a larger chunk
    -      'g');
    -  var pr_commentPrefix = /^<\!--/;
    -  var pr_cdataPrefix = /^<!\[CDATA\[/;
    -  var pr_brPrefix = /^<br\b/i;
    -  var pr_tagNameRe = /^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/;
    -
    -  /** split markup into chunks of html tags (style null) and
    -    * plain text (style {@link #PR_PLAIN}), converting tags which are
    -    * significant for tokenization (<br>) into their textual equivalent.
    -    *
    -    * @param {string} s html where whitespace is considered significant.
    -    * @return {Object} source code and extracted tags.
    -    * @private
    -    */
    -  function extractTags(s) {
    -    // since the pattern has the 'g' modifier and defines no capturing groups,
    -    // this will return a list of all chunks which we then classify and wrap as
    -    // PR_Tokens
    -    var matches = s.match(pr_chunkPattern);
    -    var sourceBuf = [];
    -    var sourceBufLen = 0;
    -    var extractedTags = [];
    -    if (matches) {
    -      for (var i = 0, n = matches.length; i < n; ++i) {
    -        var match = matches[i];
    -        if (match.length > 1 && match.charAt(0) === '<') {
    -          if (pr_commentPrefix.test(match)) { continue; }
    -          if (pr_cdataPrefix.test(match)) {
    -            // strip CDATA prefix and suffix.  Don't unescape since it's CDATA
    -            sourceBuf.push(match.substring(9, match.length - 3));
    -            sourceBufLen += match.length - 12;
    -          } else if (pr_brPrefix.test(match)) {
    -            // <br> tags are lexically significant so convert them to text.
    -            // This is undone later.
    -            sourceBuf.push('\n');
    -            ++sourceBufLen;
    -          } else {
    -            if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) {
    -              // A <span class="nocode"> will start a section that should be
    -              // ignored.  Continue walking the list until we see a matching end
    -              // tag.
    -              var name = match.match(pr_tagNameRe)[2];
    -              var depth = 1;
    -              var j;
    -              end_tag_loop:
    -              for (j = i + 1; j < n; ++j) {
    -                var name2 = matches[j].match(pr_tagNameRe);
    -                if (name2 && name2[2] === name) {
    -                  if (name2[1] === '/') {
    -                    if (--depth === 0) { break end_tag_loop; }
    -                  } else {
    -                    ++depth;
    -                  }
    -                }
    -              }
    -              if (j < n) {
    -                extractedTags.push(
    -                    sourceBufLen, matches.slice(i, j + 1).join(''));
    -                i = j;
    -              } else {  // Ignore unclosed sections.
    -                extractedTags.push(sourceBufLen, match);
    -              }
    -            } else {
    -              extractedTags.push(sourceBufLen, match);
    -            }
    -          }
    -        } else {
    -          var literalText = htmlToText(match);
    -          sourceBuf.push(literalText);
    -          sourceBufLen += literalText.length;
    -        }
    -      }
    -    }
    -    return { source: sourceBuf.join(''), tags: extractedTags };
    -  }
    -
    -  /** True if the given tag contains a class attribute with the nocode class. */
    -  function isNoCodeTag(tag) {
    -    return !!tag
    -        // First canonicalize the representation of attributes
    -        .replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,
    -                 ' $1="$2$3$4"')
    -        // Then look for the attribute we want.
    -        .match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/);
    -  }
    -
    -  /**
    -   * Apply the given language handler to sourceCode and add the resulting
    -   * decorations to out.
    -   * @param {number} basePos the index of sourceCode within the chunk of source
    -   *    whose decorations are already present on out.
    -   */
    -  function appendDecorations(basePos, sourceCode, langHandler, out) {
    -    if (!sourceCode) { return; }
    -    var job = {
    -      source: sourceCode,
    -      basePos: basePos
    -    };
    -    langHandler(job);
    -    out.push.apply(out, job.decorations);
    -  }
    -
    -  /** Given triples of [style, pattern, context] returns a lexing function,
    -    * The lexing function interprets the patterns to find token boundaries and
    -    * returns a decoration list of the form
    -    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    -    * where index_n is an index into the sourceCode, and style_n is a style
    -    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    -    * all characters in sourceCode[index_n-1:index_n].
    -    *
    -    * The stylePatterns is a list whose elements have the form
    -    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    -    *
    -    * Style is a style constant like PR_PLAIN, or can be a string of the
    -    * form 'lang-FOO', where FOO is a language extension describing the
    -    * language of the portion of the token in $1 after pattern executes.
    -    * E.g., if style is 'lang-lisp', and group 1 contains the text
    -    * '(hello (world))', then that portion of the token will be passed to the
    -    * registered lisp handler for formatting.
    -    * The text before and after group 1 will be restyled using this decorator
    -    * so decorators should take care that this doesn't result in infinite
    -    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    -    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    -    * '<script>foo()<\/script>', which would cause the current decorator to
    -    * be called with '<script>' which would not match the same rule since
    -    * group 1 must not be empty, so it would be instead styled as PR_TAG by
    -    * the generic tag rule.  The handler registered for the 'js' extension would
    -    * then be called with 'foo()', and finally, the current decorator would
    -    * be called with '<\/script>' which would not match the original rule and
    -    * so the generic tag rule would identify it as a tag.
    -    *
    -    * Pattern must only match prefixes, and if it matches a prefix, then that
    -    * match is considered a token with the same style.
    -    *
    -    * Context is applied to the last non-whitespace, non-comment token
    -    * recognized.
    -    *
    -    * Shortcut is an optional string of characters, any of which, if the first
    -    * character, gurantee that this pattern and only this pattern matches.
    -    *
    -    * @param {Array} shortcutStylePatterns patterns that always start with
    -    *   a known character.  Must have a shortcut string.
    -    * @param {Array} fallthroughStylePatterns patterns that will be tried in
    -    *   order if the shortcut ones fail.  May have shortcuts.
    -    *
    -    * @return {function (Object)} a
    -    *   function that takes source code and returns a list of decorations.
    -    */
    -  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    -    var shortcuts = {};
    -    var tokenizer;
    -    (function () {
    -      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    -      var allRegexs = [];
    -      var regexKeys = {};
    -      for (var i = 0, n = allPatterns.length; i < n; ++i) {
    -        var patternParts = allPatterns[i];
    -        var shortcutChars = patternParts[3];
    -        if (shortcutChars) {
    -          for (var c = shortcutChars.length; --c >= 0;) {
    -            shortcuts[shortcutChars.charAt(c)] = patternParts;
    -          }
    -        }
    -        var regex = patternParts[1];
    -        var k = '' + regex;
    -        if (!regexKeys.hasOwnProperty(k)) {
    -          allRegexs.push(regex);
    -          regexKeys[k] = null;
    -        }
    -      }
    -      allRegexs.push(/[\0-\uffff]/);
    -      tokenizer = combinePrefixPatterns(allRegexs);
    -    })();
    -
    -    var nPatterns = fallthroughStylePatterns.length;
    -    var notWs = /\S/;
    -
    -    /**
    -     * Lexes job.source and produces an output array job.decorations of style
    -     * classes preceded by the position at which they start in job.source in
    -     * order.
    -     *
    -     * @param {Object} job an object like {@code
    -     *    source: {string} sourceText plain text,
    -     *    basePos: {int} position of job.source in the larger chunk of
    -     *        sourceCode.
    -     * }
    -     */
    -    var decorate = function (job) {
    -      var sourceCode = job.source, basePos = job.basePos;
    -      /** Even entries are positions in source in ascending order.  Odd enties
    -        * are style markers (e.g., PR_COMMENT) that run from that position until
    -        * the end.
    -        * @type {Array.<number|string>}
    -        */
    -      var decorations = [basePos, PR_PLAIN];
    -      var pos = 0;  // index into sourceCode
    -      var tokens = sourceCode.match(tokenizer) || [];
    -      var styleCache = {};
    -
    -      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    -        var token = tokens[ti];
    -        var style = styleCache[token];
    -        var match = void 0;
    -
    -        var isEmbedded;
    -        if (typeof style === 'string') {
    -          isEmbedded = false;
    -        } else {
    -          var patternParts = shortcuts[token.charAt(0)];
    -          if (patternParts) {
    -            match = token.match(patternParts[1]);
    -            style = patternParts[0];
    -          } else {
    -            for (var i = 0; i < nPatterns; ++i) {
    -              patternParts = fallthroughStylePatterns[i];
    -              match = token.match(patternParts[1]);
    -              if (match) {
    -                style = patternParts[0];
    -                break;
    -              }
    -            }
    -
    -            if (!match) {  // make sure that we make progress
    -              style = PR_PLAIN;
    -            }
    -          }
    -
    -          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    -          if (isEmbedded && !(match && typeof match[1] === 'string')) {
    -            isEmbedded = false;
    -            style = PR_SOURCE;
    -          }
    -
    -          if (!isEmbedded) { styleCache[token] = style; }
    -        }
    -
    -        var tokenStart = pos;
    -        pos += token.length;
    -
    -        if (!isEmbedded) {
    -          decorations.push(basePos + tokenStart, style);
    -        } else {  // Treat group 1 as an embedded block of source code.
    -          var embeddedSource = match[1];
    -          var embeddedSourceStart = token.indexOf(embeddedSource);
    -          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    -          if (match[2]) {
    -            // If embeddedSource can be blank, then it would match at the
    -            // beginning which would cause us to infinitely recurse on the
    -            // entire token, so we catch the right context in match[2].
    -            embeddedSourceEnd = token.length - match[2].length;
    -            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    -          }
    -          var lang = style.substring(5);
    -          // Decorate the left of the embedded source
    -          appendDecorations(
    -              basePos + tokenStart,
    -              token.substring(0, embeddedSourceStart),
    -              decorate, decorations);
    -          // Decorate the embedded source
    -          appendDecorations(
    -              basePos + tokenStart + embeddedSourceStart,
    -              embeddedSource,
    -              langHandlerForExtension(lang, embeddedSource),
    -              decorations);
    -          // Decorate the right of the embedded section
    -          appendDecorations(
    -              basePos + tokenStart + embeddedSourceEnd,
    -              token.substring(embeddedSourceEnd),
    -              decorate, decorations);
    -        }
    -      }
    -      job.decorations = decorations;
    -    };
    -    return decorate;
    -  }
    -
    -  /** returns a function that produces a list of decorations from source text.
    -    *
    -    * This code treats ", ', and ` as string delimiters, and \ as a string
    -    * escape.  It does not recognize perl's qq() style strings.
    -    * It has no special handling for double delimiter escapes as in basic, or
    -    * the tripled delimiters used in python, but should work on those regardless
    -    * although in those cases a single string literal may be broken up into
    -    * multiple adjacent string literals.
    -    *
    -    * It recognizes C, C++, and shell style comments.
    -    *
    -    * @param {Object} options a set of optional parameters.
    -    * @return {function (Object)} a function that examines the source code
    -    *     in the input job and builds the decoration list.
    -    */
    -  function sourceDecorator(options) {
    -    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    -    if (options['tripleQuotedStrings']) {
    -      // '''multi-line-string''', 'single-line-string', and double-quoted
    -      shortcutStylePatterns.push(
    -          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    -           null, '\'"']);
    -    } else if (options['multiLineStrings']) {
    -      // 'multi-line-string', "multi-line-string"
    -      shortcutStylePatterns.push(
    -          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    -           null, '\'"`']);
    -    } else {
    -      // 'single-line-string', "single-line-string"
    -      shortcutStylePatterns.push(
    -          [PR_STRING,
    -           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    -           null, '"\'']);
    -    }
    -    if (options['verbatimStrings']) {
    -      // verbatim-string-literal production from the C# grammar.  See issue 93.
    -      fallthroughStylePatterns.push(
    -          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    -    }
    -    if (options['hashComments']) {
    -      if (options['cStyleComments']) {
    -        // Stop C preprocessor declarations at an unclosed open comment
    -        shortcutStylePatterns.push(
    -            [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
    -             null, '#']);
    -        fallthroughStylePatterns.push(
    -            [PR_STRING,
    -             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
    -             null]);
    -      } else {
    -        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    -      }
    -    }
    -    if (options['cStyleComments']) {
    -      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    -      fallthroughStylePatterns.push(
    -          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    -    }
    -    if (options['regexLiterals']) {
    -      var REGEX_LITERAL = (
    -          // A regular expression literal starts with a slash that is
    -          // not followed by * or / so that it is not confused with
    -          // comments.
    -          '/(?=[^/*])'
    -          // and then contains any number of raw characters,
    -          + '(?:[^/\\x5B\\x5C]'
    -          // escape sequences (\x5C),
    -          +    '|\\x5C[\\s\\S]'
    -          // or non-nesting character sets (\x5B\x5D);
    -          +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
    -          // finally closed by a /.
    -          + '/');
    -      fallthroughStylePatterns.push(
    -          ['lang-regex',
    -           new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    -           ]);
    -    }
    -
    -    var keywords = options['keywords'].replace(/^\s+|\s+$/g, '');
    -    if (keywords.length) {
    -      fallthroughStylePatterns.push(
    -          [PR_KEYWORD,
    -           new RegExp('^(?:' + keywords.replace(/\s+/g, '|') + ')\\b'), null]);
    -    }
    -
    -    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    -    fallthroughStylePatterns.push(
    -        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    -        [PR_COMMENT,     /^.*?\*.*/],
    -		[PR_VAR, /^\$[a-z]{1}[a-z_]+/i, null],
    -		[PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    -        [PR_TYPE,        /^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, null],
    -        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    -        [PR_LITERAL,
    -         new RegExp(
    -             '^(?:'
    -             // A hex number
    -             + '0x[a-f0-9]+'
    -             // or an octal or decimal number,
    -             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    -             // possibly in scientific notation
    -             + '(?:e[+\\-]?\\d+)?'
    -             + ')'
    -             // with an optional modifier like UL for unsigned long
    -             + '[a-z]*', 'i'),
    -         null, '0123456789'],
    -        [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#]*/, null]);
    -
    -    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
    -  }
    -
    -  var decorateSource = sourceDecorator({
    -        'keywords': ALL_KEYWORDS,
    -        'hashComments': true,
    -        'cStyleComments': true,
    -        'multiLineStrings': true,
    -        'regexLiterals': true
    -      });
    -
    -  /** Breaks {@code job.source} around style boundaries in
    -    * {@code job.decorations} while re-interleaving {@code job.extractedTags},
    -    * and leaves the result in {@code job.prettyPrintedHtml}.
    -    * @param {Object} job like {
    -    *    source: {string} source as plain text,
    -    *    extractedTags: {Array.<number|string>} extractedTags chunks of raw
    -    *                   html preceded by their position in {@code job.source}
    -    *                   in order
    -    *    decorations: {Array.<number|string} an array of style classes preceded
    -    *                 by the position at which they start in job.source in order
    -    * }
    -    * @private
    -    */
    -  function recombineTagsAndDecorations(job) {
    -    var sourceText = job.source;
    -    var extractedTags = job.extractedTags;
    -    var decorations = job.decorations;
    -
    -    var html = [];
    -    // index past the last char in sourceText written to html
    -    var outputIdx = 0;
    -
    -    var openDecoration = null;
    -    var currentDecoration = null;
    -    var tagPos = 0;  // index into extractedTags
    -    var decPos = 0;  // index into decorations
    -    var tabExpander = makeTabExpander(window['PR_TAB_WIDTH']);
    -
    -    var adjacentSpaceRe = /([\r\n ]) /g;
    -    var startOrSpaceRe = /(^| ) /gm;
    -    var newlineRe = /\r\n?|\n/g;
    -    var trailingSpaceRe = /[ \r\n]$/;
    -    var lastWasSpace = true;  // the last text chunk emitted ended with a space.
    -
    -    // See bug 71 and http://stackoverflow.com/questions/136443/why-doesnt-ie7-
    -    var isIE678 = window['_pr_isIE6']();
    -    var lineBreakHtml = (
    -        isIE678
    -        ? (job.sourceNode.tagName === 'PRE'
    -           // Use line feeds instead of <br>s so that copying and pasting works
    -           // on IE.
    -           // Doing this on other browsers breaks lots of stuff since \r\n is
    -           // treated as two newlines on Firefox.
    -           ? (isIE678 === 6 ? '&#160;\r\n' :
    -              isIE678 === 7 ? '&#160;<br>\r' : '&#160;\r')
    -           // IE collapses multiple adjacent <br>s into 1 line break.
    -           // Prefix every newline with '&#160;' to prevent such behavior.
    -           // &nbsp; is the same as &#160; but works in XML as well as HTML.
    -           : '&#160;<br />')
    -        : '<br />');
    -
    -    // Look for a class like linenums or linenums:<n> where <n> is the 1-indexed
    -    // number of the first line.
    -    var numberLines = job.sourceNode.className.match(/\blinenums\b(?::(\d+))?/);
    -    var lineBreaker;
    -    if (numberLines) {
    -      var lineBreaks = [];
    -      for (var i = 0; i < 10; ++i) {
    -        lineBreaks[i] = lineBreakHtml + '</li><li class="L' + i + '">';
    -      }
    -      var lineNum = numberLines[1] && numberLines[1].length
    -          ? numberLines[1] - 1 : 0;  // Lines are 1-indexed
    -      html.push('<ol class="linenums"><li class="L', (lineNum) % 10, '"');
    -      if (lineNum) {
    -        html.push(' value="', lineNum + 1, '"');
    -      }
    -      html.push('>');
    -      lineBreaker = function () {
    -        var lb = lineBreaks[++lineNum % 10];
    -        // If a decoration is open, we need to close it before closing a list-item
    -        // and reopen it on the other side of the list item.
    -        return openDecoration
    -            ? ('</span>' + lb + '<span class="' + openDecoration + '">') : lb;
    -      };
    -    } else {
    -      lineBreaker = lineBreakHtml;
    -    }
    -
    -    // A helper function that is responsible for opening sections of decoration
    -    // and outputing properly escaped chunks of source
    -    function emitTextUpTo(sourceIdx) {
    -      if (sourceIdx > outputIdx) {
    -        if (openDecoration && openDecoration !== currentDecoration) {
    -          // Close the current decoration
    -          html.push('</span>');
    -          openDecoration = null;
    -        }
    -        if (!openDecoration && currentDecoration) {
    -          openDecoration = currentDecoration;
    -          html.push('<span class="', openDecoration, '">');
    -        }
    -        // This interacts badly with some wikis which introduces paragraph tags
    -        // into pre blocks for some strange reason.
    -        // It's necessary for IE though which seems to lose the preformattedness
    -        // of <pre> tags when their innerHTML is assigned.
    -        // http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html
    -        // and it serves to undo the conversion of <br>s to newlines done in
    -        // chunkify.
    -        var htmlChunk = textToHtml(
    -            tabExpander(sourceText.substring(outputIdx, sourceIdx)))
    -            .replace(lastWasSpace
    -                     ? startOrSpaceRe
    -                     : adjacentSpaceRe, '$1&#160;');
    -        // Keep track of whether we need to escape space at the beginning of the
    -        // next chunk.
    -        lastWasSpace = trailingSpaceRe.test(htmlChunk);
    -        html.push(htmlChunk.replace(newlineRe, lineBreaker));
    -        outputIdx = sourceIdx;
    -      }
    -    }
    -
    -    while (true) {
    -      // Determine if we're going to consume a tag this time around.  Otherwise
    -      // we consume a decoration or exit.
    -      var outputTag;
    -      if (tagPos < extractedTags.length) {
    -        if (decPos < decorations.length) {
    -          // Pick one giving preference to extractedTags since we shouldn't open
    -          // a new style that we're going to have to immediately close in order
    -          // to output a tag.
    -          outputTag = extractedTags[tagPos] <= decorations[decPos];
    -        } else {
    -          outputTag = true;
    -        }
    -      } else {
    -        outputTag = false;
    -      }
    -      // Consume either a decoration or a tag or exit.
    -      if (outputTag) {
    -        emitTextUpTo(extractedTags[tagPos]);
    -        if (openDecoration) {
    -          // Close the current decoration
    -          html.push('</span>');
    -          openDecoration = null;
    -        }
    -        html.push(extractedTags[tagPos + 1]);
    -        tagPos += 2;
    -      } else if (decPos < decorations.length) {
    -        emitTextUpTo(decorations[decPos]);
    -        currentDecoration = decorations[decPos + 1];
    -        decPos += 2;
    -      } else {
    -        break;
    -      }
    -    }
    -    emitTextUpTo(sourceText.length);
    -    if (openDecoration) {
    -      html.push('</span>');
    -    }
    -    if (numberLines) { html.push('</li></ol>'); }
    -    job.prettyPrintedHtml = html.join('');
    -  }
    -
    -  /** Maps language-specific file extensions to handlers. */
    -  var langHandlerRegistry = {};
    -  /** Register a language handler for the given file extensions.
    -    * @param {function (Object)} handler a function from source code to a list
    -    *      of decorations.  Takes a single argument job which describes the
    -    *      state of the computation.   The single parameter has the form
    -    *      {@code {
    -    *        source: {string} as plain text.
    -    *        decorations: {Array.<number|string>} an array of style classes
    -    *                     preceded by the position at which they start in
    -    *                     job.source in order.
    -    *                     The language handler should assigned this field.
    -    *        basePos: {int} the position of source in the larger source chunk.
    -    *                 All positions in the output decorations array are relative
    -    *                 to the larger source chunk.
    -    *      } }
    -    * @param {Array.<string>} fileExtensions
    -    */
    -  function registerLangHandler(handler, fileExtensions) {
    -    for (var i = fileExtensions.length; --i >= 0;) {
    -      var ext = fileExtensions[i];
    -      if (!langHandlerRegistry.hasOwnProperty(ext)) {
    -        langHandlerRegistry[ext] = handler;
    -      } else if ('console' in window) {
    -        console['warn']('cannot override language handler %s', ext);
    -      }
    -    }
    -  }
    -  function langHandlerForExtension(extension, source) {
    -    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    -      // Treat it as markup if the first non whitespace character is a < and
    -      // the last non-whitespace character is a >.
    -      extension = /^\s*</.test(source)
    -          ? 'default-markup'
    -          : 'default-code';
    -    }
    -    return langHandlerRegistry[extension];
    -  }
    -  registerLangHandler(decorateSource, ['default-code']);
    -  registerLangHandler(
    -      createSimpleLexer(
    -          [],
    -          [
    -		   [PR_PLAIN,       /^[^<?]+/],
    -           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    -           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    -           // Unescaped content in an unknown language
    -           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    -           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    -           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    -           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    -           // Unescaped content in javascript.  (Or possibly vbscript).
    -           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    -           // Contains unescaped stylesheet content
    -           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    -           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    -          ]),
    -      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    -  registerLangHandler(
    -      createSimpleLexer(
    -          [
    -		   [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    -           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    -           ],
    -          [
    -		  [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    -           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    -           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    -           [PR_PUNCTUATION,  /^[=<>\/]+/],
    -           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    -           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    -           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    -           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    -           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    -           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    -           ]),
    -      ['in.tag']);
    -  registerLangHandler(
    -      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': CPP_KEYWORDS,
    -          'hashComments': true,
    -          'cStyleComments': true
    -        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': 'null true false'
    -        }), ['json']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': CSHARP_KEYWORDS,
    -          'hashComments': true,
    -          'cStyleComments': true,
    -          'verbatimStrings': true
    -        }), ['cs']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': JAVA_KEYWORDS,
    -          'cStyleComments': true
    -        }), ['java']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': SH_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true
    -        }), ['bsh', 'csh', 'sh']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': PYTHON_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'tripleQuotedStrings': true
    -        }), ['cv', 'py']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': PERL_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'regexLiterals': true
    -        }), ['perl', 'pl', 'pm']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': RUBY_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'regexLiterals': true
    -        }), ['rb']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': JSCRIPT_KEYWORDS,
    -          'cStyleComments': true,
    -          'regexLiterals': true
    -        }), ['js']);
    -  registerLangHandler(
    -      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    -
    -  function applyDecorator(job) {
    -    var sourceCodeHtml = job.sourceCodeHtml;
    -    var opt_langExtension = job.langExtension;
    -
    -    // Prepopulate output in case processing fails with an exception.
    -    job.prettyPrintedHtml = sourceCodeHtml;
    -
    -    try {
    -      // Extract tags, and convert the source code to plain text.
    -      var sourceAndExtractedTags = extractTags(sourceCodeHtml);
    -      /** Plain text. @type {string} */
    -      var source = sourceAndExtractedTags.source;
    -      job.source = source;
    -      job.basePos = 0;
    -
    -      /** Even entries are positions in source in ascending order.  Odd entries
    -        * are tags that were extracted at that position.
    -        * @type {Array.<number|string>}
    -        */
    -      job.extractedTags = sourceAndExtractedTags.tags;
    -
    -      // Apply the appropriate language handler
    -      langHandlerForExtension(opt_langExtension, source)(job);
    -      // Integrate the decorations and tags back into the source code to produce
    -      // a decorated html string which is left in job.prettyPrintedHtml.
    -      recombineTagsAndDecorations(job);
    -    } catch (e) {
    -      if ('console' in window) {
    -        console['log'](e && e['stack'] ? e['stack'] : e);
    -      }
    -    }
    -  }
    -
    -  function prettyPrintOne(sourceCodeHtml, opt_langExtension) {
    -    var job = {
    -      sourceCodeHtml: sourceCodeHtml,
    -      langExtension: opt_langExtension
    -    };
    -    applyDecorator(job);
    -    return job.prettyPrintedHtml;
    -  }
    -
    -  function prettyPrint(opt_whenDone) {
    -    function byTagName(tn) { return document.getElementsByTagName(tn); }
    -    // fetch a list of nodes to rewrite
    -    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
    -    var elements = [];
    -    for (var i = 0; i < codeSegments.length; ++i) {
    -      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    -        elements.push(codeSegments[i][j]);
    -      }
    -    }
    -    codeSegments = null;
    -
    -    var clock = Date;
    -    if (!clock['now']) {
    -      clock = { 'now': function () { return (new Date).getTime(); } };
    -    }
    -
    -    // The loop is broken into a series of continuations to make sure that we
    -    // don't make the browser unresponsive when rewriting a large page.
    -    var k = 0;
    -    var prettyPrintingJob;
    -
    -    function doWork() {
    -      var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?
    -                     clock.now() + 250 /* ms */ :
    -                     Infinity);
    -      for (; k < elements.length && clock.now() < endTime; k++) {
    -        var cs = elements[k];
    -        if (cs.className && cs.className.indexOf('preformatted') >= 0) {
    -          // If the classes includes a language extensions, use it.
    -          // Language extensions can be specified like
    -          //     <pre class="prettyprint lang-cpp">
    -          // the language extension "cpp" is used to find a language handler as
    -          // passed to PR_registerLangHandler.
    -          var langExtension = cs.className.match(/\blang-(\w+)\b/);
    -          if (langExtension) { langExtension = langExtension[1]; }
    -
    -          // make sure this is not nested in an already prettified element
    -          var nested = false;
    -          for (var p = cs.parentNode; p; p = p.parentNode) {
    -            if ((p.tagName === 'pre' || p.tagName === 'code' ||
    -                 p.tagName === 'xmp') &&
    -                p.className && p.className.indexOf('preformatted') >= 0) {
    -              nested = true;
    -              break;
    -            }
    -          }
    -          if (!nested) {
    -            // fetch the content as a snippet of properly escaped HTML.
    -            // Firefox adds newlines at the end.
    -            var content = getInnerHtml(cs);
    -            content = content.replace(/(?:\r\n?|\n)$/, '');
    -
    -            // do the pretty printing
    -            prettyPrintingJob = {
    -              sourceCodeHtml: content,
    -              langExtension: langExtension,
    -              sourceNode: cs
    -            };
    -            applyDecorator(prettyPrintingJob);
    -            replaceWithPrettyPrintedHtml();
    -          }
    -        }
    -      }
    -      if (k < elements.length) {
    -        // finish up in a continuation
    -        setTimeout(doWork, 250);
    -      } else if (opt_whenDone) {
    -        opt_whenDone();
    -      }
    -    }
    -
    -    function replaceWithPrettyPrintedHtml() {
    -      var newContent = prettyPrintingJob.prettyPrintedHtml;
    -      if (!newContent) { return; }
    -      var cs = prettyPrintingJob.sourceNode;
    -
    -      // push the prettified html back into the tag.
    -      if (!isRawContent(cs)) {
    -        // just replace the old html with the new
    -        cs.innerHTML = newContent;
    -      } else {
    -        // we need to change the tag to a <pre> since <xmp>s do not allow
    -        // embedded tags such as the span tags used to attach styles to
    -        // sections of source code.
    -        var pre = document.createElement('PRE');
    -        for (var i = 0; i < cs.attributes.length; ++i) {
    -          var a = cs.attributes[i];
    -          if (a.specified) {
    -            var aname = a.name.toLowerCase();
    -            if (aname === 'class') {
    -              pre.className = a.value;  // For IE 6
    -            } else {
    -              pre.setAttribute(a.name, a.value);
    -            }
    -          }
    -        }
    -        pre.innerHTML = newContent;
    -
    -        // remove the old
    -        cs.parentNode.replaceChild(pre, cs);
    -        cs = pre;
    -      }
    -    }
    -
    -    doWork();
    -  }
    -
    -  window['PR_normalizedHtml'] = normalizedHtml;
    -  window['prettyPrintOne'] = prettyPrintOne;
    -  window['prettyPrint'] = prettyPrint;
    -  window['PR'] = {
    -        'combinePrefixPatterns': combinePrefixPatterns,
    -        'createSimpleLexer': createSimpleLexer,
    -        'registerLangHandler': registerLangHandler,
    -        'sourceDecorator': sourceDecorator,
    -        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    -        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    -        'PR_COMMENT': PR_COMMENT,
    -        'PR_DECLARATION': PR_DECLARATION,
    -        'PR_KEYWORD': PR_KEYWORD,
    -        'PR_LITERAL': PR_LITERAL,
    -        'PR_NOCODE': PR_NOCODE,
    -        'PR_PLAIN': PR_PLAIN,
    -        'PR_PUNCTUATION': PR_PUNCTUATION,
    -        'PR_SOURCE': PR_SOURCE,
    -        'PR_STRING': PR_STRING,
    -        'PR_TAG': PR_TAG,
    -        'PR_TYPE': PR_TYPE
    -      };
    -})();
    diff --git a/build/aps/Limitations of APS Support in the Panel_fichiers/stylesheet.css b/build/aps/Limitations of APS Support in the Panel_fichiers/stylesheet.css
    deleted file mode 100644
    index b7ce63f17b3..00000000000
    --- a/build/aps/Limitations of APS Support in the Panel_fichiers/stylesheet.css	
    +++ /dev/null
    @@ -1,1571 +0,0 @@
    -body
    -{
    -background: #FFFFFF
    -}
    -
    -/*ol.listalfa
    -{
    -        list-style-type: lower-alpha;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }*/
    -li.listalpha {
    -        list-style-type: lower-alpha;
    -		font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: 10pt;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -/*ol.listalfa2
    -{
    -        list-style-type: lower-alpha;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }*/
    -li.listalpha2 {
    -        list-style-type: lower-alpha;
    -		font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #13152d;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -		  line-height: 10pt;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -/*ol.listalfa3
    -{
    -        list-style-type: lower-alpha;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }*/
    -li.listalpha3 {
    -        list-style-type: lower-alpha;
    -		font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #13152d;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -/*li.listalpha2, li.listalpha, li.listalpha3
    -{
    -list-style-type: lower-alpha;
    -} */
    -
    -
    -li.tablelistbullet {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: 10pt;
    -        margin: 0px;
    -        padding: 5px;
    -	vertical-align: top;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -
    -p.centered {
    -
    -        text-align: center;
    -}
    -
    -p.listcontinue3 {
    -    margin-left: 30pt;
    -  }
    -
    -.preformattedbold2ndlvl {
    -  display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: bold;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 20pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -
    -}
    -
    -
    -.preformattedseclevel {
    -        display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 20pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -}
    -
    -.prcontinuous
    -{font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -       }
    -
    -.prefblue
    -{display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-size: 10pt;
    -        color: #0000FF;
    -        background-color: #f4f4f4;
    -        vertical-align: baseline;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.prefred
    -{display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-size: 10pt;
    -        color: #FF0000;
    -        background-color: #f4f4f4;
    -        vertical-align: baseline;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.prefdarkblue
    -{display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-weight: bold;
    -        font-size: 10pt;
    -        color: #000080;
    -        background-color: #f4f4f4;
    -        vertical-align: baseline;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.prefgrey
    -{display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-size: 10pt;
    -        color: #EA8110;
    -        background-color: #f4f4f4;
    -        vertical-align: baseline;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -
    -.expandingblock
    -{font-family: "Tahoma", verdana, arial, helvetica, sans-serif;
    -        border-color: #AFAFAF;
    -        border-top-style: dotted;
    -        border-top-width: 1px;
    -        border-top-color: #AFAFAF;
    -        border-bottom-style: dotted;
    -        border-bottom-width: 1px;
    -        border-bottom-color: #AFAFAF;
    -        border-left-style: dotted;
    -        border-left-width: 1px;
    -        border-left-color: #AFAFAF;
    -        border-right-style: dotted;
    -        border-right-width: 1px;
    -        border-right-color: #AFAFAF;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -	padding-left: 3px;
    -	padding-right: 3px;
    -	padding-top: 3px;
    -	padding-bottom: 3px;
    -
    -       }
    -
    -
    -
    -.copyright {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        font-style: italic;
    -        color: #000000;
    -        margin: 9px 0px 9px 0px;
    -        padding: 0px;
    -}
    -
    -/* Nov-14 begin */
    -
    -.pagenavigation {
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	white-space: nowrap;
    -	vertical-align: middle;
    -	margin: 0px;
    -	margin-right: 2px;
    -	padding: 3px;
    -	padding-right: 4px;
    -	background-color: #f0f1f5;
    -}
    -*html .pagenavigation {
    -	margin-top: -7px;
    -	position: relative;
    -}
    -
    -.pagenavigation a, .pagenavigation a:link, .pagenavigation a:visited {
    -	color: #000000;
    -	text-decoration: none;
    -}
    -.pagenavigation a:hover {
    -	text-decoration: none;
    -	color: #666666;
    -}
    -
    -/* end */
    -
    -
    -
    -.topBody {
    -	background: #eeeeee;
    -}
    -.nav {
    -	vertical-align: middle;
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	padding-left: 7px;
    -	padding-right: 5px;
    -	padding-top: 4px;
    -}
    -.nav a, .nav a:link, .nav a:visited {
    -	color: #000000;
    -	text-decoration: none;
    -}
    -.nav a:hover {
    -	text-decoration: none;
    -	color: #666666;
    -}
    -
    -td.navTabActive {
    -	color: #1f202c;
    -	text-decoration: none;
    -	vertical-align: middle;
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	padding-top: 4px;
    -	padding-bottom: 0px;
    -	padding-left: 8px;
    -	padding-right: 8px;
    -	font-weight: bold;
    -	background-image: url('nav_bg_active.gif');
    -	background-repeat: repeat-x;
    -}
    -td.navTab {
    -	padding-top: 3px;
    -}
    -.navTab a, .navTab a:link, .navTab a:visited {
    -	color: #000000;
    -	text-decoration: none;
    -	vertical-align: middle;
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	padding-top: 4px;
    -	padding-bottom: 0px;
    -	padding-left: 8px;
    -	padding-right: 8px;
    -}
    -.navTab a:hover {
    -	color: #1f202c;
    -	text-decoration: none;
    -	vertical-align: middle;
    -	font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -	font-size: 8pt;
    -	padding-top: 5px;
    -	padding-bottom: 7px;
    -	padding-left: 8px;
    -	padding-right: 8px;
    -	background-image: url('nav_bg_active.gif');
    -	background-repeat: repeat-x;
    -}
    -
    -.navDiv {
    -	vertical-align: middle;
    -}
    -
    -.topFrameTable {
    -	width: 100%;
    -	/*height: 23px;*/
    -	margin: 0px;
    -	padding: 0px;
    -	border-bottom: 2px solid #d6d6d6;
    -   background-image: url('nav_bg.gif');
    -	background-repeat: repeat-x;
    -}
    -.topFrameTabs {
    -	margin-left: 3px;
    -	margin-top: 0px;
    -}
    -
    -.headerTable {
    -	width: 100%;
    -	vertical-align: top;
    -	height: 23px;
    -	background: #588cc7;
    -}
    -.headerTd {
    -	vertical-align: middle;
    -	font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -	color: #ffffff;
    -	font-size: 12px;
    -	padding-top: 2px;
    -	padding-bottom: 3px;
    -	padding-left: 7px;
    -	padding-right: 5px;
    -}
    -
    -.tocTable {
    -	width: 100%;
    -	vertical-align: top;
    -}
    -.tocLevel1 {
    -	margin: -14px 0 0 0;
    -	padding: 0px;
    -}
    -
    -a.itemActive,
    -a.itemActive:link,
    -a.itemActive:visited,
    -a.itemActive:active {
    -	color: #ffffff;
    -	line-height: 16px;
    -	padding-top: 1px;
    -	padding-bottom: 2px;
    -	padding-left: 3px;
    -	padding-right: 3px;
    -	background-color:#6697cc;
    -}
    -
    -a, a:link,
    -.relateditem a, .relateditem a:link,
    -.tocLevel1 a, .tocLevel1 a:link {
    -	color: #0049b7;
    -	text-decoration: none;
    -}
    -a:hover,
    -.relateditem a:hover,
    -.tocLevel1 a:hover {
    -	text-decoration: underline;
    -}
    -a:visited,
    -.relateditem a:visited,
    -.tocLevel1 a:visited {
    -	color: #003380;
    -}
    -.relateditem a {
    -	text-decoration: none;
    -}
    -
    -.table {
    -	margin-top: 5px;
    -}
    -.tableDescription {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -		  font-weight: bold;
    -        color: #444444;
    -        margin-top: 15px;
    -        margin-bottom: 7px;
    -        margin-left: 0px;
    -        margin-right: 0px;
    -        padding: 0px;
    -		  text-align: left;
    -}
    -
    -.relatedheading {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-weight: bold;
    -        font-size: 8pt;
    -        color: #ffffff;
    -        background-color: #729ecf;
    -        margin-top: 25px;
    -        margin-bottom: 2px;
    -        margin-left: 0px;
    -        margin-right: 0px;
    -        padding-top: 2px;
    -        padding-bottom: 2px;
    -        padding-left: 4px;
    -        padding-right: 4px;
    -        border-color: #FFFFFF;
    -        border-right-style: solid;
    -        border-right-width: 1px;
    -        border-right-color: #FFFFFF;
    -}
    -.relateditem {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #f3f8fc;
    -        margin-top: 0px;
    -        margin-bottom: 0px;
    -        margin-left: 0px;
    -        margin-right: 0px;
    -        padding-top: 2px;
    -        padding-bottom: 3px;
    -        padding-left: 12px;
    -        padding-right: 15px;
    -        border-color: #FFFFFF;
    -        border-right-style: solid;
    -        border-right-width: 1px;
    -        border-right-color: #FFFFFF;
    -	     border-bottom-style: solid;
    -        border-bottom-width: 2px;
    -        border-bottom-color: #ffffff;
    -}
    -.bodytext {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        margin: 9px 0px 9px 0px;
    -        padding: 0px;
    -}
    -
    -.tableheading {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -		  font-weight: bold;
    -        font-size: 8pt;
    -		  line-height: 12px;
    -        color: #2f739b;
    -		  line-height: 11px;
    -        margin: 0px;
    -        padding: 3px;
    -        text-align: center;
    -		  background-color: #f5f8fc;/*eef2f9;*/
    -}
    -.tablebodytext {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        padding: 5px;
    -		  padding-top: 7px;
    -		  vertical-align: top;
    -}
    -
    -.preformatted {
    -        display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -}
    -
    -
    -.prefcleanxml {
    -        display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -}
    -
    -
    -
    -
    -.preformatedbold2ndlvl, .preformattedbold {
    -        display: block;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: bold;
    -        font-size: 10pt;
    -        color: #000000;
    -        background-color: #f4f4f4;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 0pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 1pt;
    -        padding-bottom: 1pt;
    -        padding-left: 5pt;
    -        padding-right: 5pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -}
    -.specialbold {
    -        display: inline;
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-weight: bold;
    -        font-size: 8pt;
    -        color: #e64a00;
    -        background-color: inherit;
    -        word-spacing: 0pt;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        }
    -.emphasis {
    -        display: inline;
    -        font-style: italic;
    -        color: inherit;
    -        background-color: inherit;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.monospace {
    -        display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        color: inherit;
    -		  font-size: 10pt;
    -        background-color: inherit;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -.monospaceitalics {
    -        display: inline;
    -        font-family: "Courier New", verdana, arial, helvetica, sans-serif;
    -        font-style: italic;
    -        color: inherit;
    -		  font-size: 10pt;
    -        background-color: inherit;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -ul.listbullet {
    -        list-style-type: disk;
    -        list-style-image: none;
    -        list-style-position: outside;
    -        margin-top: 7px;
    -        margin-bottom: 0px;
    -        }
    -li.listbullet {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: 10pt;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.note {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #fffdec;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0cm;
    -        margin-right: 0pt;
    -        padding-top: 4pt;
    -        padding-bottom: 4pt;
    -        padding-left: 4pt;
    -        padding-right: 4pt;
    -        border: 2px solid #f8c701;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: 97%;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.buttons {
    -        display: inline;
    -        font-weight: bold;
    -        color: #444444;
    -        background-color: inherit;
    -        vertical-align: baseline;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -       }
    -ol.listnumber {
    -        list-style-type: Decimal;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }
    -li.listnumber {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.procedureheading {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-variant: normal;
    -        font-weight: bold;
    -        font-size: 9pt;
    -        color: #266fa4; /* 266fa4 1b64a0 */
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 12pt;
    -        margin-bottom: 0px;
    -        margin-left: 0px;
    -        margin-right: 0px;
    -        padding-top: 0px;
    -        padding-bottom: 5px;
    -        padding-left: 0px;
    -        padding-right: 0px;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -ol.procedurelistnumber {
    -        list-style-type: Decimal;
    -        list-style-position: outside;
    -        margin-top: 7px;
    -        margin-bottom: 10px;
    -        }
    -li.procedurelistnumber {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6px;
    -        margin-bottom: 0px;
    -        margin-left: 0px;
    -        margin-right: 0pxt;
    -        padding: 0px;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.listcontinue {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 5pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -ul.listbullet2 {
    -        list-style-type: disk;
    -        list-style-image: none;
    -        list-style-position: outside;
    -        margin-top: 7px;
    -        margin-bottom: 0px;
    -        }
    -li.listbullet2 {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #13152d;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -		  line-height: 10pt;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.listnote {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #fffdec;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 4pt;
    -        padding-bottom: 4pt;
    -        padding-left: 4pt;
    -        padding-right: 4pt;
    -        border: 2px solid #f8c701;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: 97%;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.widegraphic {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: center;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.listcontinue2 {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 10pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -.listcontinue3 {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 10pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -ul.listbullet3 {
    -        list-style-type: Square;
    -        list-style-image: none;
    -        list-style-position: outside;
    -        margin-top: 7px;
    -        margin-bottom: 0px;
    -        }
    -li.listbullet3 {
    -	     font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #13152d;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin: 0px;
    -        padding: 0 0 6px 0;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -ol.procedurelistnumber2 {
    -        list-style-type: lower-alpha;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }
    -li.procedurelistnumber2 {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding: 0px;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.listnote2 {
    -        display: block;
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #fffdec;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0pt;
    -        margin-right: 6pt;
    -        padding-top: 4pt;
    -        padding-bottom: 4pt;
    -        padding-left: 4pt;
    -        padding-right: 4pt;
    -        border: 2px solid #f8c701;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: 97%;
    -        height: auto;
    -        white-space: normal;
    -       }
    -ol.listnumber2 {
    -        list-style-type: Decimal;
    -        list-style-position: outside;
    -        margin-top: 7pt;
    -        margin-bottom: 0pt;
    -        }
    -li.listnumber2 {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 0pt;
    -        margin-left: 0pt;
    -        margin-right: 0pt;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.warning {
    -        font-family: verdana, tahoma, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -        color: #000000;
    -        background-color: #fff5f0;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 6pt;
    -        margin-bottom: 6pt;
    -        margin-left: 0cm;
    -        margin-right: 6pt;
    -        padding-top: 4pt;
    -        padding-bottom: 4pt;
    -        padding-left: 4pt;
    -        padding-right: 4pt;
    -        border: 2px solid #e64a00;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -.heading1 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -
    -.heading2 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -		  font-size: 12pt;
    -        color: #5c5b64;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.heading3 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.heading4 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -		  font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.heading5 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-variant: normal;
    -		  font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.heading6 {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-variant: normal;
    - 		  font-size: 12pt;
    -        color: #6a6a6a;
    -        background-color: inherit;
    -        word-spacing: normal;
    -        letter-spacing: normal;
    -        vertical-align: baseline;
    -        text-decoration: none;
    -        text-transform: none;
    -        line-height: normal;
    -        margin-top: 18px;
    -        margin-bottom: 18px;
    -        margin-left: 0cm;
    -        margin-right: 0cm;
    -        padding-top: 0pt;
    -        padding-bottom: 0pt;
    -        padding-left: 0pt;
    -        padding-right: 0pt;
    -        float: none;
    -        clear: none;
    -        text-align: left;
    -        text-indent: 0cm;
    -        width: auto;
    -        height: auto;
    -        white-space: normal;
    -       }
    -.indexatoz {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-style: normal;
    -        font-weight: bold;
    -        font-size: 12px;
    -        color: #adadad;
    -        background-color: #f4f4f4;
    -        border: 1px solid #CFCFCF;
    -        margin: -15px -2px 0 -2px;
    -        padding: 6px;
    -		  position: relative;
    -		  z-index:99;
    -       }
    -
    -.indexatoz a:hover {
    -      background-color: #6697cc;
    -      text-decoration: none;
    -      color: #ffffff;
    -      padding: 1px 0;
    -}
    -.indexLetter {
    -	 	  padding-left: 2px;
    -}
    -
    -.indexheading, .indexheading a {
    -        font-family: arial, helvetica, sans-serif, tahoma, verdana;
    -        font-weight: bold;
    -        font-size: 12pt;
    -        color: #e64a00;
    -		  text-decoration: none;
    -        margin: 0px;
    -        padding: 0px;
    -		  padding-top: 10px;
    -		  margin-top: 12px;
    -		  margin-bottom: 2px;
    -		  margin-right: 2px;
    -		  border-bottom: 1px solid #cfcfcf;
    -}
    -.index1, .index2, .index3 {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        text-decoration: none;
    -        margin: 0px;
    -        padding-top: 3px;
    -        padding-bottom: 0px;
    -        padding-left: 0px;
    -        padding-right: 0px;
    -}
    -.indexlink, .index1link {
    -        padding: 0px;
    -		  padding-top: 3px;
    -		  margin: 0px;
    -}
    -.index1link {
    -		  padding-left: 18px;
    -}
    -.toc {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-style: normal;
    -        font-variant: normal;
    -        font-weight: normal;
    -        font-size: 8pt;
    -		  padding-left: 8px;
    -		  padding-right: 5px;
    -        vertical-align: top;
    -       }
    -span.toc {
    -	line-height: 19px;
    -}
    -
    -.searchDetails {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 11px;
    -        color: #666666;
    -        background-color: #ffffff;
    -		  border: 1px solid #CFCFCF;
    -        margin: 5px;
    -		  padding-left: 10px;
    - 		  padding-right: 10px;
    -		  padding-top: 3px;
    -		  padding-bottom: 9px;
    -		  line-height: 20px;
    -}
    -.inputText {
    -		  width: 60%;
    -		  height: 16px;
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 12px;
    -        color: #000000;
    -}
    -form {
    -	margin: 0px;
    -}
    -.search {
    -        font-family: tahoma, verdana, arial, helvetica, sans-serif;
    -        font-size: 8pt;
    -        color: #000000;
    -        vertical-align: top;
    -        margin: 0px;
    -        padding: 0px 10px;
    -       }
    -.searchFound {
    -	font-weight: bold;
    -	color: #1f202c;
    -	padding-top: 5px;
    -	padding-bottom: 10px;
    -	margin: 0px;
    -}
    -.searchResults {
    -	padding-bottom: 10px;
    -	padding-top: 5px;
    -	margin: 0px;
    -	border-top: 1px solid #cfcfcf;
    -}
    -.searchResults a {
    -	font-weight: bold;
    -}
    -.searchFoundWord {
    -	background-color: #fffdce;
    -}
    -.searchToTop {
    -	text-align: left;
    -	border-top: 1px solid #cfcfcf;
    -	padding: 7px 0px 15px 0px;
    -	margin: 0px;
    -}
    diff --git a/build/aps/README b/build/aps/README
    deleted file mode 100644
    index 6d9b8098977..00000000000
    --- a/build/aps/README
    +++ /dev/null
    @@ -1,20 +0,0 @@
    -README (English)
    -##################################################
    -This directory is dedicated to APS package building
    -##################################################
    -
    -Docs for APS format 1.1:
    -http://www.apsstandard.org/r/doc/aps-format-1.1-packaging-guide/index.htm
    -
    -Docs for APS format 1.2 (need APP-LIST.xml):
    -http://www.apsstandard.org/r/doc/aps-format-1.2-packaging-guide/index.htm
    -
    -
    -To check an APS package on Debian:
    -* Install libgdiplus with 
    -apt-get install libgdiplus
    -* Install apslint.exe (http://www.apsstandard.org/r/doc/aps-format-1.2-packaging-guide/57414.htm)
    -tar -xvf xxxx.tgz 
    -* Go into directory of apslint and run command
    -mono ./apslint.exe '/media/DATA/Mes Developpements/dolibarr/build/dolibarr-3.1.0-dev.app.zip' 
    -
    diff --git a/build/aps/configure.php b/build/aps/configure.php
    deleted file mode 100755
    index 1b2565e3dc8..00000000000
    --- a/build/aps/configure.php
    +++ /dev/null
    @@ -1,151 +0,0 @@
    -#!/usr/bin/env php
    -<?php
    -/*-----------------------------------------------------
    - *
    - *----------------------------------------------------- */
    -
    -// This is list of predefined variables when script is ran
    -// We have to set them manually to run script outside context.
    -/*putenv('SETTINGS_admin_name=admin');
    -putenv('SETTINGS_admin_password=admin-ad');
    -putenv('BASE_URL_SCHEME=http');
    -putenv('BASE_URL_HOST=localhost');
    -putenv('BASE_URL_PORT=0');
    -putenv('BASE_URL_PATH=/');
    -//putenv('WEB___DIR=/var/wwww/dolibarr/htdocs');      // WEB___DIR is dir to htdocs
    -putenv('WEB___DIR=../htdocs');      // WEB___DIR is dir to htdocs
    -putenv('DB_main_NAME=dolibarr');
    -putenv('DB_main_HOST=localhost');
    -putenv('DB_main_PORT=3306');
    -putenv('DB_main_LOGIN=root');
    -putenv('DB_main_PASSWORD=root');
    -*/
    -
    -// Check parameters
    -if(count($_SERVER['argv']) < 2)
    -{
    -    print "Usage: configure.php (install | upgrade <version> | configure | remove)\n";
    -    exit(1);
    -}
    -$command = $_SERVER['argv'][1]; //$command stores the argument with which the script was invoked.
    -
    -
    -if($command == "install")
    -{
    -    $db_id = 'main';
    -
    -    $rootdir = getenv("WEB___DIR");
    -    if ($rootdir != '/') $rootdir = preg_replace('/\/$/','',$rootdir);  // Remove last /
    -    $datadir = $rootdir.'/dolibarr_documents';
    -
    -    //List of database-related variables that are passed to the configuration
    -    //script. See the 6.3.1.1.1. Environment variables section of the
    -    //Specification for details.
    -    $db_address = getenv("DB_${db_id}_HOST");
    -    $db_port = getenv("DB_${db_id}_PORT");
    -    $dblogin = getenv("DB_${db_id}_LOGIN");
    -    $dbpassword = getenv("DB_${db_id}_PASSWORD");
    -    $dbname = getenv("DB_${db_id}_NAME");
    -
    -
    -    //PHP functions for connecting to the mysql server and
    -    //executing SQL queries.
    -    //mysql_connect($dbaddress, $dblogin, $dbpassword);
    -    //mysql_select_db($dbname);
    -    /*
    -     $sql_queries = file($query_file);
    -     foreach ($sql_queries as $query) mysql_query($query);
    -     */
    -
    -
    -    //Other code to be executed on invoking configure with
    -    //the install argument.
    -
    -    // Create empty config file
    -    $file=$rootdir.'/conf/conf.php';
    -    print "Create conf file ".$file."\n";
    -    $fp = fopen($file, 'wb');
    -    if ($fp)
    -    {
    -        fclose($fp);
    -        chmod($file,0775);
    -    }
    -    else
    -    {
    -        print "configure.php install: Unable to write file $file.\n";
    -        exit(1);
    -    }
    -
    -    // Create empty directory that will be used by software to store uploaded documents
    -    print "Create directory ".$datadir."\n";
    -    @mkdir($datadir);
    -    chmod($datadir,0775);
    -
    -    // Create install.forced.php into htdocs/install directory with value.
    -    // This will set parameters of install for web installer wizard.
    -    $file_source=$rootdir.'/../build/aps/install.forced.php.install';
    -    $file=$rootdir.'/install/install.forced.php';
    -    print "Create file ".$file.' from '.$file_source."\n";
    -
    -    $modify_hash=array(
    -    'WEB___DIR'=>$rootdir,
    -    'DB_'.$db_id.'_HOST'=>$db_address,
    -    'DB_'.$db_id.'_PORT'=>$db_port,
    -    'DB_'.$db_id.'_LOGIN'=>$dblogin,
    -    'DB_'.$db_id.'_PASSWORD'=>$dbpassword,
    -    'DB_'.$db_id.'_NAME'=>$dbname
    -    );
    -
    -    $file_content = fread(fopen($file_source, 'r'), filesize($file_source));
    -    foreach($modify_hash as $param => $val){
    -        $file_content = str_replace($param, php_quote($val), $file_content);
    -    }
    -    $fp = fopen($file, 'wb');
    -    if ($fp)
    -    {
    -        fputs($fp, $file_content);
    -        fputs($fp, "\n");
    -        fclose($fp);
    -        chmod($file,0775);
    -    }
    -    else
    -    {
    -        print "configure.php install: Unable to write file $file.\n";
    -        exit(2);
    -    }
    -
    -    exit(0);
    -}
    -
    -if($command == "remove")
    -{
    -    //Code to be executed on invoking configure with the remove argument
    -    exit(0);
    -}
    -
    -if($command == "upgrade")
    -{
    -    //Code to be executed on invoking configure with the upgrade argument
    -    exit(0);
    -}
    -
    -if($command == "configure")
    -{
    -    //Code to be executed on invoking configure with the configure argument
    -    exit(0);
    -}
    -
    -print "configure.php: Error: unknown command $command.\n";
    -exit(1);
    -
    -
    -
    -// Content of file-util.php we need
    -
    -function php_quote($val)
    -{
    -    $res_val = str_replace("\\", "\\\\", $val);
    -    $res_val = str_replace("'", "\\'", $res_val);
    -    return $res_val;
    -}
    -
    diff --git a/build/aps/install.forced.php.install b/build/aps/install.forced.php.install
    deleted file mode 100644
    index a7a3f03c14c..00000000000
    --- a/build/aps/install.forced.php.install
    +++ /dev/null
    @@ -1,23 +0,0 @@
    -<?php
    -// File to force Dolibarr wizard installer choices.
    -//
    -// This file must be present into htdocs/install directory
    -// during install process to be used.
    -//
    -//
    -$force_install_noedit=1;
    -$force_install_message='KeepDefaultValuesDeb';
    -$force_install_main_data_root='WEB___DIR/dolibarr_documents';
    -$force_install_type='mysqli';
    -$force_install_dbserver='DB_main_HOST';
    -$force_install_port='DB_main_PORT';
    -$force_install_database='DB_main_NAME';
    -$force_install_createdatabase='0';
    -$force_install_databaselogin='DB_main_LOGIN';
    -$force_install_databasepass='DB_main_PASSWORD';
    -$force_install_createuser='0';
    -$force_install_databaserootlogin='';
    -$force_install_databaserootpass='';
    -$force_install_dolibarrlogin='admin';
    -$force_install_nophpinfo='1';
    -$force_install_lockinstall='444';
    diff --git a/build/flatpack/org.flatpak.Dolibarr.json b/build/flatpack/org.flatpak.Dolibarr.json
    new file mode 100644
    index 00000000000..9e2135cf0a3
    --- /dev/null
    +++ b/build/flatpack/org.flatpak.Dolibarr.json
    @@ -0,0 +1 @@
    +Help wanted...
    \ No newline at end of file
    diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl
    index 1ab3269d0de..01e282aa492 100755
    --- a/build/makepack-dolibarr.pl
    +++ b/build/makepack-dolibarr.pl
    @@ -22,7 +22,7 @@ $PUBLISHSTABLE="eldy,dolibarr\@frs.sourceforge.net:/home/frs/project/dolibarr";
     $PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/dolibarr.org/httpdocs/files";
     
     
    -#@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","APS","EXEDOLIWAMP","SNAPSHOT");   # Possible packages
    +#@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT");   # Possible packages
     @LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT");   # Possible packages
     %REQUIREMENTPUBLISH=(
     "SF"=>"git ssh rsync",
    @@ -37,7 +37,7 @@ $PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/dolibarr.org/httpd
     "RPM_MANDRIVA"=>"rpmbuild",
     "RPM_OPENSUSE"=>"rpmbuild",
     "DEB"=>"dpkg",
    -"APS"=>"zip",
    +"FLATPACK"=>"flatpack",
     "EXEDOLIWAMP"=>"ISCC.exe",
     "SNAPSHOT"=>"tar"
     );
    @@ -142,7 +142,6 @@ $FILENAMETGZ         = "$PROJECT-$MAJOR.$MINOR.$BUILD";
     $FILENAMEZIP         = "$PROJECT-$MAJOR.$MINOR.$BUILD";
     $FILENAMEXZ          = "$PROJECT-$MAJOR.$MINOR.$BUILD";
     $FILENAMEDEB         = "see later";
    -$FILENAMEAPS         = "$PROJECT-$MAJOR.$MINOR.$BUILD.app";
     $FILENAMEEXEDOLIWAMP = "DoliWamp-$MAJOR.$MINOR.$BUILD";
     # For RPM
     $ARCH='noarch';
    @@ -692,7 +691,7 @@ if ($nboftargetok) {
     			print "Go to directory $BUILDROOT\n";
     			$olddir=getcwd();
     			chdir("$BUILDROOT");
    -			$cmd= "xz -9 -r $BUILDROOT/$FILENAMEAPS.xz \*";
    +			$cmd= "xz -9 -r $BUILDROOT/$FILENAMEXZ.xz \*";
     			print $cmd."\n";
     			$ret= `$cmd`;
     			chdir("$olddir");
    @@ -1033,92 +1032,6 @@ if ($nboftargetok) {
     			next;
     		}
     		
    -		if ($target eq 'APS') 
    -		{
    -			$NEWDESTI=$DESTI;
    -			if ($NEWDESTI =~ /stable/)
    -			{
    -				mkdir($DESTI.'/package_aps');
    -				if (-d $DESTI.'/package_aps') { $NEWDESTI=$DESTI.'/package_aps'; }
    -			} 
    -			
    -			$newbuild = $BUILD;
    -			$newbuild =~ s/(dev|alpha)/0/gi;                # dev
    -			$newbuild =~ s/beta/1/gi;                       # beta
    -			$newbuild =~ s/rc./2/gi;                        # rc
    -			if ($newbuild !~ /-/) { $newbuild.='-3'; }      # finale
    -			# now newbuild is 0-0 or 0-3 for example
    -			$REL1 = $newbuild; $REL1 =~ s/-.*$//gi;
    -			if ($RPMSUBVERSION eq 'auto') { $RPMSUBVERSION = $newbuild; $RPMSUBVERSION =~ s/^.*-//gi; }
    -			print "Version is $MAJOR.$MINOR.$REL1-$RPMSUBVERSION\n";
    -			
    -			print "Remove target $FILENAMEAPS.zip...\n";
    -			unlink "$NEWDESTI/$FILENAMEAPS.zip";
    -
    -			#rmdir "$BUILDROOT/$PROJECT.tmp";
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp`;
    -			print "Create directory $BUILDROOT/$PROJECT.tmp\n";
    -			$ret=`mkdir -p "$BUILDROOT/$PROJECT.tmp"`;
    -			print "Copy $BUILDROOT/$PROJECT to $BUILDROOT/$PROJECT.tmp\n";
    -			$cmd="cp -pr \"$BUILDROOT/$PROJECT\" \"$BUILDROOT/$PROJECT.tmp\"";
    -			$ret=`$cmd`;
    -
    -			print "Remove other files\n";
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/deb`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/dmg`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/doap`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/exe`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/live`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/patch`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/rpm`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/zip`;
    -			$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/build/perl`;
    -
    -            $APSVERSION="1.2";
    -            print "Create APS files $BUILDROOT/$PROJECT.tmp/$PROJECT/APP-META.xml\n";
    -            open (SPECFROM,"<$BUILDROOT/$PROJECT/build/aps/APP-META-$APSVERSION.xml") || die "Error";
    -            open (SPECTO,">$BUILDROOT/$PROJECT.tmp/$PROJECT/APP-META.xml") || die "Error";
    -            while (<SPECFROM>) {
    -                $newbuild = $BUILD;
    -                $newbuild =~ s/(dev|alpha)/0/gi;                # dev
    -                $newbuild =~ s/beta/1/gi;                       # beta
    -                $newbuild =~ s/rc./2/gi;                        # rc
    -                if ($newbuild !~ /-/) { $newbuild.='-3'; }      # finale
    -                # now newbuild is 0-0 or 0-3 for example
    -                $_ =~ s/__VERSION__/$MAJOR.$MINOR.$REL1/;
    -                $_ =~ s/__RELEASE__/$RPMSUBVERSION/;
    -                print SPECTO $_;
    -            }
    -            close SPECFROM;
    -            close SPECTO;
    -            print "Version set to $MAJOR.$MINOR.$newbuild\n";
    -            $cmd="cp -pr \"$BUILDROOT/$PROJECT/build/aps/configure.php\" \"$BUILDROOT/$PROJECT.tmp/$PROJECT/scripts/configure.php\"";
    -            $ret=`$cmd`;
    -            $cmd="cp -pr \"$BUILDROOT/$PROJECT/doc/images\" \"$BUILDROOT/$PROJECT.tmp/$PROJECT/images\"";
    -            $ret=`$cmd`;
    - 
    -            print "Remove other files\n";
    -            $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/dev`;
    -            $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/$PROJECT/doc`;
    -            
    -            print "Build APP-LIST.xml files\n";
    -            
    -            print "Compress $BUILDROOT/$PROJECT.tmp/$PROJECT into $FILENAMEAPS.zip...\n";
    - 
    -            print "Go to directory $BUILDROOT/$PROJECT.tmp\/$PROJECT\n";
    -            $olddir=getcwd();
    -            chdir("$BUILDROOT\/$PROJECT.tmp\/$PROJECT");
    -            $cmd= "zip -9 -r $BUILDROOT/$FILENAMEAPS.zip \*";
    -            print $cmd."\n";
    -            $ret= `$cmd`;
    -            chdir("$olddir");
    -                        
    -    		# Move to final dir
    -            print "Move $BUILDROOT/$FILENAMEAPS.zip to $NEWDESTI/$FILENAMEAPS.zip\n";
    -            $ret=`mv "$BUILDROOT/$FILENAMEAPS.zip" "$NEWDESTI/$FILENAMEAPS.zip"`;
    -            next;
    -    	}
    -
     		if ($target eq 'EXEDOLIWAMP')
     		{
     			$NEWDESTI=$DESTI;
    
    From c2646886357468181cc36d6c1c39961659b96611 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Thu, 11 Oct 2018 09:53:36 +0200
    Subject: [PATCH 129/433] Standardize and update code
    
    ---
     htdocs/loan/class/loan.class.php | 16 ++++++++++++++++
     1 file changed, 16 insertions(+)
    
    diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php
    index dd066f0064c..e9f5fbfff72 100644
    --- a/htdocs/loan/class/loan.class.php
    +++ b/htdocs/loan/class/loan.class.php
    @@ -66,9 +66,25 @@ class Loan extends CommonObject
     	public $date_creation;
     	public $date_modification;
     	public $date_validation;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_bank;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_project;
     
     
    
    From ee225a2b8bc7f714e82ac8fb46e3b142a14cc433 Mon Sep 17 00:00:00 2001
    From: John BOTELLA <john.botella@atm-consulting.fr>
    Date: Thu, 11 Oct 2018 10:14:22 +0200
    Subject: [PATCH 130/433] FIX situation prev percent
    
    ---
     htdocs/compta/facture/card.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
    index 8834d93d162..bf84114129f 100644
    --- a/htdocs/compta/facture/card.php
    +++ b/htdocs/compta/facture/card.php
    @@ -1535,6 +1535,7 @@ if (empty($reshook))
     					{
     						$line->origin = $object->origin;
     						$line->origin_id = $line->id;
    +						$line->fk_prev_id = $line->id;
     						$line->fetch_optionals($line->id);
     						$line->situation_percent =  $line->get_prev_progress($object->id); // get good progress including credit note 
     						
    
    From 92686100b23d63c25865e49a4aac01b0d1ad74df Mon Sep 17 00:00:00 2001
    From: John BOTELLA <john.botella@atm-consulting.fr>
    Date: Thu, 11 Oct 2018 10:51:54 +0200
    Subject: [PATCH 131/433] Fix count on no countable object
    
    ---
     htdocs/compta/facture/card.php | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
    index 8834d93d162..aeb145a7ea2 100644
    --- a/htdocs/compta/facture/card.php
    +++ b/htdocs/compta/facture/card.php
    @@ -3250,8 +3250,7 @@ if ($action == 'create')
     		print '<tr><td>' . $langs->trans($newclassname) . '</td><td colspan="2">' . $objectsrc->getNomUrl(1);
     		// We check if Origin document (id and type is known) has already at least one invoice attached to it
     		$objectsrc->fetchObjectLinked($originid,$origin,'','facture');
    -		$cntinvoice=count($objectsrc->linkedObjects['facture']);
    -		if ($cntinvoice>=1)
    +		if(!empty($objectsrc->linkedObjects['facture']) && is_array($objectsrc->linkedObjects['facture']))
     		{
     			setEventMessages('WarningBillExist', null, 'warnings');
     			echo ' ('.$langs->trans('LatestRelatedBill').end($objectsrc->linkedObjects['facture'])->getNomUrl(1).')';
    
    From ced40384436d3c94e87910cce049c100a31bee49 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 11 Oct 2018 11:56:52 +0200
    Subject: [PATCH 132/433] FIX qty not visible for a lot when making shipment on
     a dedicated stock
    
    ---
     ChangeLog                                     |  2 +-
     htdocs/core/lib/pdf.lib.php                   |  2 +-
     htdocs/core/lib/sendings.lib.php              |  2 +-
     htdocs/expedition/card.php                    | 19 +++---
     htdocs/expedition/class/expedition.class.php  | 18 +++---
     .../class/expeditionbatch.class.php           | 58 +++++++++----------
     6 files changed, 51 insertions(+), 50 deletions(-)
    
    diff --git a/ChangeLog b/ChangeLog
    index 0d1bbfbf379..2449730bf8e 100644
    --- a/ChangeLog
    +++ b/ChangeLog
    @@ -86,7 +86,7 @@ NEW: Add a tab to specify accountant/auditor of the company
     NEW: Add Date delivery and Availability on Propals List
     NEW: Add date in goods reception supplier order table
     NEW: Add delivery_time_days of suppliers in export profile
    -NEW: Add Docments'tab to expedition module
    +NEW: Add Documents'tab to expedition module
     NEW: Use dol_print_phone in thirdparty list page to format phone
     NEW: Add entry for the GDPR contact
     NEW: Add extrafield type "html"
    diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php
    index 671a3d6cbc3..73de27cafac 100644
    --- a/htdocs/core/lib/pdf.lib.php
    +++ b/htdocs/core/lib/pdf.lib.php
    @@ -1376,7 +1376,7 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl
     			if ($detail->eatby) $dte[]=$outputlangs->transnoentitiesnoconv('printEatby',dol_print_date($detail->eatby, $format, false, $outputlangs));
     			if ($detail->sellby) $dte[]=$outputlangs->transnoentitiesnoconv('printSellby',dol_print_date($detail->sellby, $format, false, $outputlangs));
     			if ($detail->batch) $dte[]=$outputlangs->transnoentitiesnoconv('printBatch',$detail->batch);
    -			$dte[]=$outputlangs->transnoentitiesnoconv('printQty',$detail->dluo_qty);
    +			$dte[]=$outputlangs->transnoentitiesnoconv('printQty',$detail->qty);
     			$libelleproduitservice.= "__N__  ".implode(" - ", $dte);
     		}
     	}
    diff --git a/htdocs/core/lib/sendings.lib.php b/htdocs/core/lib/sendings.lib.php
    index 71c287f7119..b79b1d094da 100644
    --- a/htdocs/core/lib/sendings.lib.php
    +++ b/htdocs/core/lib/sendings.lib.php
    @@ -364,7 +364,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='')
     								$detail.= $langs->trans("Batch").': '.$dbatch->batch;
     								$detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day");
     								$detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day");
    -								$detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty;
    +								$detail.= ' - '.$langs->trans("Qty").': '.$dbatch->qty;
     								$detail.= '<br>';
     				            }
     				            print $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"),$detail);
    diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php
    index 49bded5a45b..0f45ca61804 100644
    --- a/htdocs/expedition/card.php
    +++ b/htdocs/expedition/card.php
    @@ -649,7 +649,7 @@ if (empty($reshook))
     						$qty = "qtyl".$detail_batch->fk_expeditiondet.'_'.$detail_batch->id;
     						$batch_id = GETPOST($batch,'int');
     						$batch_qty = GETPOST($qty, 'int');
    -						if (! empty($batch_id) && ($batch_id != $detail_batch->fk_origin_stock || $batch_qty != $detail_batch->dluo_qty))
    +						if (! empty($batch_id) && ($batch_id != $detail_batch->fk_origin_stock || $batch_qty != $detail_batch->qty))
     						{
     							if ($lotStock->fetch($batch_id) > 0 && $line->fetch($detail_batch->fk_expeditiondet) > 0)	// $line is ExpeditionLine
     							{
    @@ -666,7 +666,7 @@ if (empty($reshook))
     								$line->detail_batch->batch = $lotStock->batch;
     								$line->detail_batch->id = $detail_batch->id;
     								$line->detail_batch->entrepot_id = $lotStock->warehouseid;
    -								$line->detail_batch->dluo_qty = $batch_qty;
    +								$line->detail_batch->qty = $batch_qty;
     								if ($line->update($user) < 0) {
     									setEventMessages($line->error, $line->errors, 'errors');
     									$error++;
    @@ -720,7 +720,7 @@ if (empty($reshook))
     									$line->detail_batch->fk_origin_stock = $batch_id;
     									$line->detail_batch->batch = $lotStock->batch;
     									$line->detail_batch->entrepot_id = $lotStock->warehouseid;
    -									$line->detail_batch->dluo_qty = $batch_qty;
    +									$line->detail_batch->qty = $batch_qty;
     									if ($line->update($user) < 0) {
     										setEventMessages($line->error, $line->errors, 'errors');
     										$error++;
    @@ -741,7 +741,7 @@ if (empty($reshook))
     								$line->detail_batch[0]->fk_origin_stock = $batch_id;
     								$line->detail_batch[0]->batch = $lotStock->batch;
     								$line->detail_batch[0]->entrepot_id = $lotStock->warehouseid;
    -								$line->detail_batch[0]->dluo_qty = $batch_qty;
    +								$line->detail_batch[0]->qty = $batch_qty;
     								if ($object->create_line_batch($line, $line->array_options) < 0)
     								{
     									setEventMessages($object->error, $object->errors, 'errors');
    @@ -1306,6 +1306,7 @@ if ($action == 'create')
     					{
     					    // Product need lot
     						print '<td></td><td></td></tr>';	// end line and start a new one for lot/serial
    +						print '<!-- Case product need lot -->';
     
     						$staticwarehouse=new Entrepot($db);
     						if ($warehouse_id > 0) $staticwarehouse->fetch($warehouse_id);
    @@ -1323,7 +1324,7 @@ if ($action == 'create')
     						print '<input name="idl'.$indiceAsked.'" type="hidden" value="'.$line->id.'">';
     						if (is_object($product->stock_warehouse[$warehouse_id]) && count($product->stock_warehouse[$warehouse_id]->detail_batch))
     						{
    -							foreach ($product->stock_warehouse[$warehouse_id]->detail_batch as $dbatch)
    +							foreach ($product->stock_warehouse[$warehouse_id]->detail_batch as $dbatch)	// $dbatch is instance of Productbatch
     							{
     								//var_dump($dbatch);
     								$batchStock = + $dbatch->qty;		// To get a numeric
    @@ -1344,7 +1345,7 @@ if ($action == 'create')
     								$detail.= $langs->trans("Batch").': '.$dbatch->batch;
     								$detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day");
     								$detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day");
    -								$detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty;
    +								$detail.= ' - '.$langs->trans("Qty").': '.$dbatch->qty;
     								$detail.= '<br>';
     								print $detail;
     
    @@ -2242,7 +2243,7 @@ else if ($id || $ref)
     					{
     						print '<tr>';
     						// Qty to ship or shipped
    -						print '<td>' . '<input name="qtyl'.$detail_batch->fk_expeditiondet.'_'.$detail_batch->id.'" id="qtyl'.$line_id.'_'.$detail_batch->id.'" type="text" size="4" value="'.$detail_batch->dluo_qty.'">' . '</td>';
    +						print '<td>' . '<input name="qtyl'.$detail_batch->fk_expeditiondet.'_'.$detail_batch->id.'" id="qtyl'.$line_id.'_'.$detail_batch->id.'" type="text" size="4" value="'.$detail_batch->qty.'">' . '</td>';
     						// Batch number managment
     						if ($lines[$i]->entrepot_id == 0)
     						{
    @@ -2354,12 +2355,12 @@ else if ($id || $ref)
     						if ($lines[$i]->product_tobatch)
     						{
     							$detail = '';
    -							foreach ($lines[$i]->detail_batch as $dbatch)
    +							foreach ($lines[$i]->detail_batch as $dbatch)	// $dbatch is instance of ExpeditionLineBatch
     							{
     								$detail.= $langs->trans("Batch").': '.$dbatch->batch;
     								$detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day");
     								$detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day");
    -								$detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty;
    +								$detail.= ' - '.$langs->trans("Qty").': '.$dbatch->qty;
     								$detail.= '<br>';
     							}
     							print $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"),$detail);
    diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php
    index 5728d60932a..5848c1b9d9d 100644
    --- a/htdocs/expedition/class/expedition.class.php
    +++ b/htdocs/expedition/class/expedition.class.php
    @@ -415,7 +415,7 @@ class Expedition extends CommonObject
     		{
     			if ($detbatch->entrepot_id)
     			{
    -				$stockLocationQty[$detbatch->entrepot_id] += $detbatch->dluo_qty;
    +				$stockLocationQty[$detbatch->entrepot_id] += $detbatch->qty;
     			}
     		}
     		// create shipment lines
    @@ -931,7 +931,7 @@ class Expedition extends CommonObject
     						$this->error=$linebatch->error;
     						return -1;
     					}
    -					$linebatch->dluo_qty=$value['q'];
    +					$linebatch->qty=$value['q'];
     					$tab[]=$linebatch;
     
     					if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT)
    @@ -940,7 +940,7 @@ class Expedition extends CommonObject
     						$prod_batch = new Productbatch($this->db);
     						$prod_batch->fetch($value['id_batch']);
     
    -						if ($prod_batch->qty < $linebatch->dluo_qty)
    +						if ($prod_batch->qty < $linebatch->qty)
     						{
     							$langs->load("errors");
     							$this->errors[]=$langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $prod_batch->fk_product);
    @@ -1164,7 +1164,7 @@ class Expedition extends CommonObject
     						// We use warehouse selected for each line
     						foreach($lotArray as $lot)
     						{
    -							$result=$mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $lot->dluo_qty, 0, $langs->trans("ShipmentDeletedInDolibarr", $this->ref), $lot->eatby, $lot->sellby, $lot->batch);  // Price is set to 0, because we don't want to see WAP changed
    +							$result=$mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $lot->qty, 0, $langs->trans("ShipmentDeletedInDolibarr", $this->ref), $lot->eatby, $lot->sellby, $lot->batch);  // Price is set to 0, because we don't want to see WAP changed
     							if ($result < 0)
     							{
     								$error++;$this->errors=$this->errors + $mouvS->errors;
    @@ -2572,7 +2572,7 @@ class ExpeditionLigne extends CommonObjectLine
     					$this->errors[]='ErrorBadParameters';
     					$error++;
     				}
    -				$qty = price2num($this->detail_batch[0]->dluo_qty);
    +				$qty = price2num($this->detail_batch[0]->qty);
     			}
     		}
     		else if (! empty($this->detail_batch))
    @@ -2586,7 +2586,7 @@ class ExpeditionLigne extends CommonObjectLine
     				$this->errors[]='ErrorBadParameters';
     				$error++;
     			}
    -			$qty = price2num($this->detail_batch->dluo_qty);
    +			$qty = price2num($this->detail_batch->qty);
     		}
     
     		// check parameters
    @@ -2624,7 +2624,7 @@ class ExpeditionLigne extends CommonObjectLine
     				{
     					if ($expedition_batch_id != $lot->id)
     					{
    -						$remainingQty += $lot->dluo_qty;
    +						$remainingQty += $lot->qty;
     					}
     				}
     				$qty += $remainingQty;
    @@ -2652,7 +2652,7 @@ class ExpeditionLigne extends CommonObjectLine
     						$error++;
     					}
     				}
    -				if (! $error && $this->detail_batch->dluo_qty > 0)
    +				if (! $error && $this->detail_batch->qty > 0)
     				{
     					// create lot expedition line
     					if (isset($lot->id))
    @@ -2662,7 +2662,7 @@ class ExpeditionLigne extends CommonObjectLine
     						$shipmentLot->eatby = $lot->eatby;
     						$shipmentLot->sellby = $lot->sellby;
     						$shipmentLot->entrepot_id = $this->detail_batch->entrepot_id;
    -						$shipmentLot->dluo_qty = $this->detail_batch->dluo_qty;
    +						$shipmentLot->qty = $this->detail_batch->qty;
     						$shipmentLot->fk_origin_stock = $batch_id;
     						if ($shipmentLot->create($this->id) < 0)
     						{
    diff --git a/htdocs/expedition/class/expeditionbatch.class.php b/htdocs/expedition/class/expeditionbatch.class.php
    index d94baee2a43..227566d8382 100644
    --- a/htdocs/expedition/class/expeditionbatch.class.php
    +++ b/htdocs/expedition/class/expeditionbatch.class.php
    @@ -34,7 +34,7 @@ class ExpeditionLineBatch extends CommonObject
     	var $sellby;
     	var $eatby;
     	var $batch;
    -	var $dluo_qty;
    +	var $qty;
     	var $entrepot_id;
     	var $fk_origin_stock;
     	var $fk_expeditiondet;
    @@ -58,41 +58,41 @@ class ExpeditionLineBatch extends CommonObject
     	 */
     	function fetchFromStock($id_stockdluo)
     	{
    -        $sql = "SELECT";
    -	$sql.= " pb.batch,";
    -	$sql.= " pl.sellby,";
    -	$sql.= " pl.eatby,";
    -	$sql.= " ps.fk_entrepot";
    +		$sql = "SELECT";
    +		$sql.= " pb.batch,";
    +		$sql.= " pl.sellby,";
    +		$sql.= " pl.eatby,";
    +		$sql.= " ps.fk_entrepot";
     
    -        $sql.= " FROM ".MAIN_DB_PREFIX."product_batch as pb";
    -        $sql.= " JOIN ".MAIN_DB_PREFIX."product_stock as ps on pb.fk_product_stock=ps.rowid";
    -        $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."product_lot as pl on pl.batch = pb.batch AND pl.fk_product = ps.fk_product";
    -	$sql.= " WHERE pb.rowid = ".(int) $id_stockdluo;
    +		$sql.= " FROM ".MAIN_DB_PREFIX."product_batch as pb";
    +		$sql.= " JOIN ".MAIN_DB_PREFIX."product_stock as ps on pb.fk_product_stock=ps.rowid";
    +		$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."product_lot as pl on pl.batch = pb.batch AND pl.fk_product = ps.fk_product";
    +		$sql.= " WHERE pb.rowid = ".(int) $id_stockdluo;
     
    -    	dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
    -        $resql=$this->db->query($sql);
    -        if ($resql)
    -        {
    -            if ($this->db->num_rows($resql))
    -            {
    -                $obj = $this->db->fetch_object($resql);
    +		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
    +		$resql=$this->db->query($sql);
    +		if ($resql)
    +		{
    +			if ($this->db->num_rows($resql))
    +			{
    +				$obj = $this->db->fetch_object($resql);
     
     				$this->sellby = $this->db->jdate($obj->sellby);
     				$this->eatby = $this->db->jdate($obj->eatby);
     				$this->batch = $obj->batch;
     				$this->entrepot_id= $obj->fk_entrepot;
     				$this->fk_origin_stock=(int) $id_stockdluo;
    -            }
    -            $this->db->free($resql);
    +			}
    +			$this->db->free($resql);
     
    -            return 1;
    -        }
    -        else
    -        {
    -      	    $this->error="Error ".$this->db->lasterror();
    -            return -1;
    -        }
    -    }
    +			return 1;
    +		}
    +		else
    +		{
    +			$this->error="Error ".$this->db->lasterror();
    +			return -1;
    +		}
    +	}
     
     	/**
     	 * Create an expeditiondet_batch DB record link to an expedtiondet record
    @@ -118,7 +118,7 @@ class ExpeditionLineBatch extends CommonObject
     		$sql.= " ".(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':("'".$this->db->idate($this->sellby))."'").",";
     		$sql.= " ".(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':("'".$this->db->idate($this->eatby))."'").",";
     		$sql.= " ".(! isset($this->batch)?'NULL':("'".$this->db->escape($this->batch)."'")).",";
    -		$sql.= " ".(! isset($this->dluo_qty)?'NULL':$this->dluo_qty).",";
    +		$sql.= " ".(! isset($this->qty)?'NULL':$this->qty).",";
     		$sql.= " ".(! isset($this->fk_origin_stock)?'NULL':$this->fk_origin_stock);
     		$sql.= ")";
     
    @@ -218,7 +218,7 @@ class ExpeditionLineBatch extends CommonObject
     				$tmp->id = $obj->rowid;
     				$tmp->fk_origin_stock = $obj->fk_origin_stock;
     				$tmp->fk_expeditiondet = $obj->fk_expeditiondet;
    -				$tmp->dluo_qty = $obj->qty;
    +				$tmp->qty = $obj->qty;
     
     				$ret[]=$tmp;
     				$i++;
    
    From e1e1599a6d9ce293a223d2d8db4a712b652a8a97 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 11 Oct 2018 11:59:14 +0200
    Subject: [PATCH 133/433] FIX shared link ko on proposals
    
    ---
     htdocs/core/lib/files.lib.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php
    index 15e8c003417..210626f461c 100644
    --- a/htdocs/core/lib/files.lib.php
    +++ b/htdocs/core/lib/files.lib.php
    @@ -2496,7 +2496,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity,
     		//$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity;
     	}
     	// Wrapping pour les propales
    -	else if ($modulepart == 'propal' && !empty($conf->propal->multidir_output[$entity]))
    +	else if (($modulepart == 'propal' || $modulepart == 'propale') && !empty($conf->propal->multidir_output[$entity]))
     	{
     		if ($fuser->rights->propale->{$lire} || preg_match('/^specimen/i',$original_file))
     		{
    
    From 2ef0e95586410cf7bf840ccb25cd9fc5f4f1c372 Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Thu, 11 Oct 2018 12:08:50 +0200
    Subject: [PATCH 134/433] New: works with variants: - If product is parent
     showing stock of childs and not itself - Add function hasVariants for know if
     product has variants
    
    ---
     htdocs/product/class/product.class.php        |  19 +
     htdocs/product/stock/product.php              | 790 ++++++++++--------
     .../class/ProductCombination.class.php        |   2 +-
     3 files changed, 451 insertions(+), 360 deletions(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 050d756ad82..3257f9bbde5 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -3493,6 +3493,25 @@ class Product extends CommonObject
     		return $nb;
     	}
     
    +	/**
    +	 * Return if a product has variants or not
    +	 *
    +	 * @return 	int		Number of variants
    +	 */
    +	function hasVariants() {
    +		$nb = 0;
    +		$sql = "SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_parent = ".$this->id;
    +		$sql.= " AND entity IN (".getEntity('product').")";
    +
    +		$resql = $this->db->query($sql);
    +		if ($resql) {
    +			$obj = $this->db->fetch_object($resql);
    +			if ($obj) $nb = $obj->nb;
    +		}
    +
    +		return $nb;
    +	}
    +
     	/**
     	 *  Return all parent products for current product (first level only)
     	 *
    diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
    index 324e14047d4..51871736a3d 100644
    --- a/htdocs/product/stock/product.php
    +++ b/htdocs/product/stock/product.php
    @@ -45,6 +45,13 @@ if (! empty($conf->projet->enabled))
     	require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
     }
     
    +if (! empty($conf->variants->enabled)) {
    +	require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductAttribute.class.php';
    +	require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductAttributeValue.class.php';
    +	require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductCombination.class.php';
    +	require_once DOL_DOCUMENT_ROOT . '/variants/class/ProductCombination2ValuePair.class.php';
    +}
    +
     // Load translation files required by the page
     $langs->loadlangs(array('products', 'orders', 'bills', 'stocks', 'sendings'));
     if (! empty($conf->productbatch->enabled)) $langs->load("productbatch");
    @@ -518,6 +525,8 @@ if ($id > 0 || $ref)
     	$object = new Product($db);
     	$result = $object->fetch($id,$ref);
     
    +	$variants = $object->hasVariants();
    +
     	$object->load_stock();
     
     	$title = $langs->trans('ProductServiceCard');
    @@ -558,174 +567,161 @@ if ($id > 0 || $ref)
             print '<div class="underbanner clearboth"></div>';
             print '<table class="border tableforfield" width="100%">';
     
    -		if ($conf->productbatch->enabled)
    -		{
    -			print '<tr><td class="titlefield">'.$langs->trans("ManageLotSerial").'</td><td>';
    -			print $object->getLibStatut(0,2);
    -			print '</td></tr>';
    -		}
    +		if (! $variants) {
     
    -		// PMP
    -		print '<tr><td class="titlefield">'.$langs->trans("AverageUnitPricePMP").'</td>';
    -		print '<td>';
    -		if ($object->pmp > 0) print price($object->pmp).' '.$langs->trans("HT");
    -		print '</td>';
    -		print '</tr>';
    +			if ($conf->productbatch->enabled) {
    +				print '<tr><td class="titlefield">' . $langs->trans("ManageLotSerial") . '</td><td>';
    +				print $object->getLibStatut(0, 2);
    +				print '</td></tr>';
    +			}
     
    -		// Minimum Price
    -		print '<tr><td>'.$langs->trans("BuyingPriceMin").'</td>';
    -		print '<td>';
    -		$product_fourn = new ProductFournisseur($db);
    -		if ($product_fourn->find_min_price_product_fournisseur($object->id) > 0)
    -		{
    -			if ($product_fourn->product_fourn_price_id > 0) print $product_fourn->display_price_product_fournisseur();
    -			else print $langs->trans("NotDefined");
    -		}
    -		print '</td></tr>';
    +			// PMP
    +			print '<tr><td class="titlefield">' . $langs->trans("AverageUnitPricePMP") . '</td>';
    +			print '<td>';
    +			if ($object->pmp > 0) print price($object->pmp) . ' ' . $langs->trans("HT");
    +			print '</td>';
    +			print '</tr>';
     
    -		if (empty($conf->global->PRODUIT_MULTIPRICES))
    -		{
    -			// Price
    -			print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    -			if ($object->price_base_type == 'TTC') {
    -				print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type);
    -			} else {
    -				print price($object->price) . ' ' . $langs->trans($object->price_base_type);
    +			// Minimum Price
    +			print '<tr><td>' . $langs->trans("BuyingPriceMin") . '</td>';
    +			print '<td>';
    +			$product_fourn = new ProductFournisseur($db);
    +			if ($product_fourn->find_min_price_product_fournisseur($object->id) > 0) {
    +				if ($product_fourn->product_fourn_price_id > 0) print $product_fourn->display_price_product_fournisseur();
    +				else print $langs->trans("NotDefined");
     			}
     			print '</td></tr>';
     
    -			// Price minimum
    -			print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    -			if ($object->price_base_type == 'TTC') {
    -				print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type);
    +			if (empty($conf->global->PRODUIT_MULTIPRICES)) {
    +				// Price
    +				print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    +				if ($object->price_base_type == 'TTC') {
    +					print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type);
    +				} else {
    +					print price($object->price) . ' ' . $langs->trans($object->price_base_type);
    +				}
    +				print '</td></tr>';
    +
    +				// Price minimum
    +				print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    +				if ($object->price_base_type == 'TTC') {
    +					print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type);
    +				} else {
    +					print price($object->price_min) . ' ' . $langs->trans($object->price_base_type);
    +				}
    +				print '</td></tr>';
     			} else {
    -				print price($object->price_min) . ' ' . $langs->trans($object->price_base_type);
    +				// Price
    +				print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    +				print $langs->trans("Variable");
    +				print '</td></tr>';
    +
    +				// Price minimum
    +				print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    +				print $langs->trans("Variable");
    +				print '</td></tr>';
     			}
    -			print '</td></tr>';
    -		}
    -		else
    -		{
    -			// Price
    -			print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    -			print $langs->trans("Variable");
    +
    +			// Stock alert threshold
    +			print '<tr><td>' . $form->editfieldkey($form->textwithpicto($langs->trans("StockLimit"), $langs->trans("StockLimitDesc"), 1), 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer) . '</td><td>';
    +			print $form->editfieldval("StockLimit", 'seuil_stock_alerte', $object->seuil_stock_alerte, $object, $user->rights->produit->creer, 'string');
     			print '</td></tr>';
     
    -			// Price minimum
    -			print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    -			print $langs->trans("Variable");
    +			// Hook formObject
    +			$parameters = array();
    +			$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action);    // Note that $action and $object may have been modified by hook
    +			print $hookmanager->resPrint;
    +
    +			// Desired stock
    +			print '<tr><td>' . $form->editfieldkey($form->textwithpicto($langs->trans("DesiredStock"), $langs->trans("DesiredStockDesc"), 1), 'desiredstock', $object->desiredstock, $object, $user->rights->produit->creer);
    +			print '</td><td>';
    +			print $form->editfieldval("DesiredStock", 'desiredstock', $object->desiredstock, $object, $user->rights->produit->creer, 'string');
     			print '</td></tr>';
    +
    +			// Real stock
    +			$text_stock_options = $langs->trans("RealStockDesc") . '<br>';
    +			$text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen") . '<br>';
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) ? $langs->trans("DeStockOnShipment") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) ? $langs->trans("DeStockOnValidateOrder") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_BILL) ? $langs->trans("DeStockOnBill") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) ? $langs->trans("ReStockOnBill") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) ? $langs->trans("ReStockOnValidateOrder") . '<br>' : '');
    +			$text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) ? $langs->trans("ReStockOnDispatchOrder") . '<br>' : '');
    +			print '<tr><td>';
    +			print $form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1);
    +			print '</td>';
    +			print '<td>' . price2num($object->stock_reel, 'MS');
    +			if ($object->seuil_stock_alerte != '' && ($object->stock_reel < $object->seuil_stock_alerte)) print ' ' . img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte));
    +			print '</td>';
    +			print '</tr>';
    +
    +			$stocktheo = price2num($object->stock_theorique, 'MS');
    +
    +			$found = 0;
    +			$helpondiff = '<strong>' . $langs->trans("StockDiffPhysicTeoric") . ':</strong><br>';
    +			// Number of customer orders running
    +			if (!empty($conf->commande->enabled)) {
    +				if ($found) $helpondiff .= '<br>'; else $found = 1;
    +				$helpondiff .= $langs->trans("ProductQtyInCustomersOrdersRunning") . ': ' . $object->stats_commande['qty'];
    +				$result = $object->load_stats_commande(0, '0', 1);
    +				if ($result < 0) dol_print_error($db, $object->error);
    +				$helpondiff .= ' (' . $langs->trans("ProductQtyInDraft") . ': ' . $object->stats_commande['qty'] . ')';
    +			}
    +
    +			// Number of product from customer order already sent (partial shipping)
    +			if (!empty($conf->expedition->enabled)) {
    +				if ($found) $helpondiff .= '<br>'; else $found = 1;
    +				$result = $object->load_stats_sending(0, '2', 1);
    +				$helpondiff .= $langs->trans("ProductQtyInShipmentAlreadySent") . ': ' . $object->stats_expedition['qty'];
    +			}
    +
    +			// Number of supplier order running
    +			if (!empty($conf->fournisseur->enabled)) {
    +				if ($found) $helpondiff .= '<br>'; else $found = 1;
    +				$result = $object->load_stats_commande_fournisseur(0, '3,4', 1);
    +				$helpondiff .= $langs->trans("ProductQtyInSuppliersOrdersRunning") . ': ' . $object->stats_commande_fournisseur['qty'];
    +				$result = $object->load_stats_commande_fournisseur(0, '0,1,2', 1);
    +				if ($result < 0) dol_print_error($db, $object->error);
    +				$helpondiff .= ' (' . $langs->trans("ProductQtyInDraftOrWaitingApproved") . ': ' . $object->stats_commande_fournisseur['qty'] . ')';
    +			}
    +
    +			// Number of product from supplier order already received (partial receipt)
    +			if (!empty($conf->fournisseur->enabled)) {
    +				if ($found) $helpondiff .= '<br>'; else $found = 1;
    +				$helpondiff .= $langs->trans("ProductQtyInSuppliersShipmentAlreadyRecevied") . ': ' . $object->stats_reception['qty'];
    +			}
    +
    +			// Calculating a theorical value
    +			print '<tr><td>';
    +			print $form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc"));
    +			print '</td>';
    +			print "<td>";
    +			//print (empty($stocktheo)?0:$stocktheo);
    +			print $form->textwithpicto((empty($stocktheo) ? 0 : $stocktheo), $helpondiff);
    +			if ($object->seuil_stock_alerte != '' && ($object->stock_theorique < $object->seuil_stock_alerte)) print ' ' . img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte));
    +			print '</td>';
    +			print '</tr>';
    +
    +			// Last movement
    +			$sql = "SELECT max(m.datem) as datem";
    +			$sql .= " FROM " . MAIN_DB_PREFIX . "stock_mouvement as m";
    +			$sql .= " WHERE m.fk_product = '" . $object->id . "'";
    +			$resqlbis = $db->query($sql);
    +			if ($resqlbis) {
    +				$obj = $db->fetch_object($resqlbis);
    +				$lastmovementdate = $db->jdate($obj->datem);
    +			} else {
    +				dol_print_error($db);
    +			}
    +			print '<tr><td class="tdtop">' . $langs->trans("LastMovement") . '</td><td>';
    +			if ($lastmovementdate) {
    +				print dol_print_date($lastmovementdate, 'dayhour') . ' ';
    +				print '(<a href="' . DOL_URL_ROOT . '/product/stock/mouvement.php?idproduct=' . $object->id . '">' . $langs->trans("FullList") . '</a>)';
    +			} else {
    +				print '<a href="' . DOL_URL_ROOT . '/product/stock/mouvement.php?idproduct=' . $object->id . '">' . $langs->trans("None") . '</a>';
    +			}
    +			print "</td></tr>";
     		}
    -
    -        // Stock alert threshold
    -        print '<tr><td>'.$form->editfieldkey($form->textwithpicto($langs->trans("StockLimit"), $langs->trans("StockLimitDesc"), 1),'seuil_stock_alerte',$object->seuil_stock_alerte,$object,$user->rights->produit->creer).'</td><td>';
    -        print $form->editfieldval("StockLimit",'seuil_stock_alerte',$object->seuil_stock_alerte,$object,$user->rights->produit->creer,'string');
    -        print '</td></tr>';
    -
    -		// Hook formObject
    -		$parameters=array();
    -		$reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action);    // Note that $action and $object may have been modified by hook
    -		print $hookmanager->resPrint;
    -
    -        // Desired stock
    -        print '<tr><td>'.$form->editfieldkey($form->textwithpicto($langs->trans("DesiredStock"), $langs->trans("DesiredStockDesc"), 1),'desiredstock',$object->desiredstock,$object,$user->rights->produit->creer);
    -        print '</td><td>';
    -        print $form->editfieldval("DesiredStock",'desiredstock',$object->desiredstock,$object,$user->rights->produit->creer,'string');
    -        print '</td></tr>';
    -
    -        // Real stock
    -        $text_stock_options = $langs->trans("RealStockDesc").'<br>';
    -        $text_stock_options.= $langs->trans("RealStockWillAutomaticallyWhen").'<br>';
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)?$langs->trans("DeStockOnShipment").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)?$langs->trans("DeStockOnValidateOrder").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_BILL)?$langs->trans("DeStockOnBill").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)?$langs->trans("ReStockOnBill").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)?$langs->trans("ReStockOnValidateOrder").'<br>':'');
    -        $text_stock_options.= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)?$langs->trans("ReStockOnDispatchOrder").'<br>':'');
    -        print '<tr><td>';
    -        print $form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1);
    -        print '</td>';
    -		print '<td>'.price2num($object->stock_reel, 'MS');
    -		if ($object->seuil_stock_alerte != '' && ($object->stock_reel < $object->seuil_stock_alerte)) print ' '.img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte));
    -		print '</td>';
    -		print '</tr>';
    -
    -		$stocktheo = price2num($object->stock_theorique, 'MS');
    -
    -		$found=0;
    -		$helpondiff='<strong>'.$langs->trans("StockDiffPhysicTeoric").':</strong><br>';
    -		// Number of customer orders running
    -		if (! empty($conf->commande->enabled))
    -		{
    -		    if ($found) $helpondiff.='<br>'; else $found=1;
    -		    $helpondiff.=$langs->trans("ProductQtyInCustomersOrdersRunning").': '.$object->stats_commande['qty'];
    -		    $result=$object->load_stats_commande(0,'0', 1);
    -		    if ($result < 0) dol_print_error($db,$object->error);
    -		    $helpondiff.=' ('.$langs->trans("ProductQtyInDraft").': '.$object->stats_commande['qty'].')';
    -		}
    -
    -		// Number of product from customer order already sent (partial shipping)
    -		if (! empty($conf->expedition->enabled))
    -		{
    -		    if ($found) $helpondiff.='<br>'; else $found=1;
    -		    $result=$object->load_stats_sending(0,'2', 1);
    -		    $helpondiff.=$langs->trans("ProductQtyInShipmentAlreadySent").': '.$object->stats_expedition['qty'];
    -		}
    -
    -		// Number of supplier order running
    -		if (! empty($conf->fournisseur->enabled))
    -		{
    -		    if ($found) $helpondiff.='<br>'; else $found=1;
    -		    $result=$object->load_stats_commande_fournisseur(0,'3,4', 1);
    -		    $helpondiff.=$langs->trans("ProductQtyInSuppliersOrdersRunning").': '.$object->stats_commande_fournisseur['qty'];
    -		    $result=$object->load_stats_commande_fournisseur(0,'0,1,2', 1);
    -		    if ($result < 0) dol_print_error($db,$object->error);
    -		    $helpondiff.=' ('.$langs->trans("ProductQtyInDraftOrWaitingApproved").': '.$object->stats_commande_fournisseur['qty'].')';
    -		}
    -
    -		// Number of product from supplier order already received (partial receipt)
    -		if (! empty($conf->fournisseur->enabled))
    -		{
    -		    if ($found) $helpondiff.='<br>'; else $found=1;
    -		    $helpondiff.=$langs->trans("ProductQtyInSuppliersShipmentAlreadyRecevied").': '.$object->stats_reception['qty'];
    -		}
    -
    -        // Calculating a theorical value
    -        print '<tr><td>';
    -        print $form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc"));
    -        print '</td>';
    -        print "<td>";
    -        //print (empty($stocktheo)?0:$stocktheo);
    -        print $form->textwithpicto((empty($stocktheo)?0:$stocktheo), $helpondiff);
    -        if ($object->seuil_stock_alerte != '' && ($object->stock_theorique < $object->seuil_stock_alerte)) print ' '.img_warning($langs->trans("StockLowerThanLimit", $object->seuil_stock_alerte));
    -        print '</td>';
    -        print '</tr>';
    -
    -		// Last movement
    -		$sql = "SELECT max(m.datem) as datem";
    -		$sql.= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m";
    -		$sql.= " WHERE m.fk_product = '".$object->id."'";
    -		$resqlbis = $db->query($sql);
    -		if ($resqlbis)
    -		{
    -			$obj = $db->fetch_object($resqlbis);
    -			$lastmovementdate=$db->jdate($obj->datem);
    -		}
    -		else
    -		{
    -			dol_print_error($db);
    -		}
    -		print '<tr><td class="tdtop">'.$langs->trans("LastMovement").'</td><td>';
    -		if ($lastmovementdate)
    -		{
    -		    print dol_print_date($lastmovementdate,'dayhour').' ';
    -		    print '(<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$object->id.'">'.$langs->trans("FullList").'</a>)';
    -		}
    -		else
    -		{
    -		     print '<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$object->id.'">'.$langs->trans("None").'</a>';
    -		}
    -		print "</td></tr>";
    -
     		print "</table>";
     
             print '</div>';
    @@ -770,229 +766,305 @@ if (empty($reshook))
     	{
     	    print "<div class=\"tabsAction\">\n";
     
    -	    if ($user->rights->stock->mouvement->creer)
    -	    {
    -	        print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=correction">'.$langs->trans("CorrectStock").'</a>';
    -	    }
    +		if (! $variants) {
     
    -	    //if (($user->rights->stock->mouvement->creer) && ! $object->hasbatch())
    -	    if ($user->rights->stock->mouvement->creer)
    -		{
    -			print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=transfert">'.$langs->trans("TransferStock").'</a>';
    +			if ($user->rights->stock->mouvement->creer) {
    +				print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=correction">' . $langs->trans("CorrectStock") . '</a>';
    +			}
    +
    +			//if (($user->rights->stock->mouvement->creer) && ! $object->hasbatch())
    +			if ($user->rights->stock->mouvement->creer) {
    +				print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=transfert">' . $langs->trans("TransferStock") . '</a>';
    +			}
     		}
    -
     		print '</div>';
     	}
     
     }
     
     
    -/*
    - * Stock detail (by warehouse). May go down into batch details.
    - */
    +if (! $variants) {
    +	/*
    +	 * Stock detail (by warehouse). May go down into batch details.
    +	 */
     
    -print '<div class="div-table-responsive">';
    -print '<table class="noborder" width="100%">';
    -print '<tr class="liste_titre">';
    -print '<td colspan="4">'.$langs->trans("Warehouse").'</td>';
    -print '<td align="right">'.$langs->trans("NumberOfUnit").'</td>';
    -print '<td align="right">'.$langs->trans("AverageUnitPricePMPShort").'</td>';
    -print '<td align="right">'.$langs->trans("EstimatedStockValueShort").'</td>';
    -print '<td align="right">'.$langs->trans("SellPriceMin").'</td>';
    -print '<td align="right">'.$langs->trans("EstimatedStockValueSellShort").'</td>';
    -print '</tr>';
    -if ((! empty($conf->productbatch->enabled)) && $object->hasbatch())
    -{
    -	print '<tr class="liste_titre"><td width="10%"></td>';
    -	print '<td align="right" width="10%">'.$langs->trans("batch_number").'</td>';
    -	print '<td align="center" width="10%">'.$langs->trans("EatByDate").'</td>';
    -	print '<td align="center" width="10%">'.$langs->trans("SellByDate").'</td>';
    -	print '<td></td>';
    -	print '<td></td>';
    -	print '<td></td>';
    -	print '<td></td>';
    -	print '<td></td>';
    -	print '</tr>';
    -}
    -
    -$sql = "SELECT e.rowid, e.ref as label, e.lieu, ps.reel, ps.rowid as product_stock_id, p.pmp";
    -$sql.= " FROM ".MAIN_DB_PREFIX."entrepot as e,";
    -$sql.= " ".MAIN_DB_PREFIX."product_stock as ps";
    -$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = ps.fk_product";
    -$sql.= " WHERE ps.reel != 0";
    -$sql.= " AND ps.fk_entrepot = e.rowid";
    -$sql.= " AND e.entity IN (".getEntity('stock').")";
    -$sql.= " AND ps.fk_product = ".$object->id;
    -$sql.= " ORDER BY e.ref";
    -
    -$entrepotstatic=new Entrepot($db);
    -$product_lot_static=new Productlot($db);
    -
    -$total=0;
    -$totalvalue=$totalvaluesell=0;
    -
    -$resql=$db->query($sql);
    -if ($resql)
    -{
    -	$num = $db->num_rows($resql);
    -	$total=$totalwithpmp;
    -	$i=0; $var=false;
    -	while ($i < $num)
    -	{
    -		$obj = $db->fetch_object($resql);
    -		$entrepotstatic->id=$obj->rowid;
    -		$entrepotstatic->libelle=$obj->label;
    -		$entrepotstatic->lieu=$obj->lieu;
    -		$stock_real = price2num($obj->reel, 'MS');
    -		print '<tr class="oddeven">';
    -		print '<td colspan="4">'.$entrepotstatic->getNomUrl(1).'</td>';
    -		print '<td align="right">'.$stock_real.($stock_real < 0 ?' '.img_warning():'').'</td>';
    -		// PMP
    -		print '<td align="right">'.(price2num($object->pmp)?price2num($object->pmp,'MU'):'').'</td>';
    -		// Value purchase
    -		print '<td align="right">'.(price2num($object->pmp)?price(price2num($object->pmp*$obj->reel,'MT')):'').'</td>';
    -        // Sell price
    -		print '<td align="right">';
    -        if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price,'MU'),1);
    -        else print $langs->trans("Variable");
    -        print '</td>';
    -        // Value sell
    -        print '<td align="right">';
    -        if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price*$obj->reel,'MT'),1).'</td>';
    -        else print $langs->trans("Variable");
    -		print '</tr>'; ;
    -		$total += $obj->reel;
    -		if (price2num($object->pmp)) $totalwithpmp += $obj->reel;
    -		$totalvalue = $totalvalue + ($object->pmp*$obj->reel);
    -        $totalvaluesell = $totalvaluesell + ($object->price*$obj->reel);
    -		// Batch Detail
    -		if ((! empty($conf->productbatch->enabled)) && $object->hasbatch())
    -		{
    -			$details=Productbatch::findAll($db, $obj->product_stock_id, 0, $object->id);
    -			if ($details<0) dol_print_error($db);
    -			foreach ($details as $pdluo)
    -			{
    -				$product_lot_static->id = $pdluo->lotid;
    -				$product_lot_static->batch = $pdluo->batch;
    -				$product_lot_static->eatby = $pdluo->eatby;
    -				$product_lot_static->sellby = $pdluo->sellby;
    -
    -			    if ($action == 'editline' && GETPOST('lineid','int') == $pdluo->id)
    -			    { //Current line edit
    -			        print "\n".'<tr>';
    -			        print '<td colspan="9">';
    -			        print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
    -			        print '<input type="hidden" name="pdluoid" value="'.$pdluo->id.'"><input type="hidden" name="action" value="updateline"><input type="hidden" name="id" value="'.$id.'"><table class="noborder" width="100%"><tr><td width="10%"></td>';
    -			        print '<td align="right" width="10%"><input type="text" name="batch_number" value="'.$pdluo->batch.'"></td>';
    -			        print '<td align="center" width="10%">';
    -			        print $form->selectDate($pdluo->eatby,'eatby','','',1,'',1,0);
    -			        print '</td>';
    -			        print '<td align="center" width="10%">';
    -			        print $form->selectDate($pdluo->sellby,'sellby','','',1,'',1,0);
    -			        print '</td>';
    -			        print '<td align="right" width="10%">'.$pdluo->qty.($pdluo->qty<0?' '.img_warning():'').'</td>';
    -			        print '<td colspan="4"><input type="submit" class="button" id="savelinebutton" name="save" value="'.$langs->trans("Save").'">';
    -		            print '<input type="submit" class="button" id="cancellinebutton" name="Cancel" value="'.$langs->trans("Cancel").'"></td></tr>';
    -			        print '</table>';
    -			        print '</form>';
    -			        print '</td></tr>';
    -			    }
    -			    else
    -				{
    -                    print "\n".'<tr><td align="right">';
    -                    print img_picto($langs->trans("Tranfer"),'uparrow','class="hideonsmartphone"').' ';
    -					print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;id_entrepot='.$entrepotstatic->id.'&amp;action=transfert&amp;pdluoid='.$pdluo->id.'">'.$langs->trans("TransferStock").'</a>';
    -					// Disabled, because edition of stock content must use the "Correct stock menu".
    -					// Do not use this, or data will be wrong (bad tracking of movement label, inventory code, ...
    -                    //print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=editline&amp;lineid='.$pdluo->id.'#'.$pdluo->id.'">';
    -                    //print img_edit().'</a></td>';
    -                    print '<td align="right">';
    -                    print $product_lot_static->getNomUrl(1);
    -                    print '</td>';
    -                    print '<td align="center">'. dol_print_date($pdluo->eatby,'day') .'</td>';
    -                    print '<td align="center">'. dol_print_date($pdluo->sellby,'day') .'</td>';
    -                    print '<td align="right">'.$pdluo->qty.($pdluo->qty<0?' '.img_warning():'').'</td>';
    -                    print '<td colspan="4"></td></tr>';
    -			    }
    -			}
    -		}
    -		$i++;
    -
    -	}
    -}
    -else dol_print_error($db);
    -
    -print '<tr class="liste_total"><td align="right" class="liste_total" colspan="4">'.$langs->trans("Total").':</td>';
    -print '<td class="liste_total" align="right">'.price2num($total, 'MS').'</td>';
    -print '<td class="liste_total" align="right">';
    -print ($totalwithpmp?price(price2num($totalvalue/$totalwithpmp,'MU')):'&nbsp;');	// This value may have rounding errors
    -print '</td>';
    -// Value purchase
    -print '<td class="liste_total" align="right">';
    -print $totalvalue?price(price2num($totalvalue,'MT'),1):'&nbsp;';
    -print '</td>';
    -print '<td class="liste_total" align="right">';
    -if (empty($conf->global->PRODUIT_MULTIPRICES)) print ($total?price($totalvaluesell/$total,1):'&nbsp;');
    -else print $langs->trans("Variable");
    -print '</td>';
    -// Value to sell
    -print '<td class="liste_total" align="right">';
    -if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($totalvaluesell,'MT'),1);
    -else print $langs->trans("Variable");
    -print '</td>';
    -print "</tr>";
    -print "</table>";
    -print '</div>';
    -
    -if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE))
    -{
    -	print '<br><br>';
    -	print_titre($langs->trans('AddNewProductStockWarehouse'));
    -
    -	if (!empty($user->rights->produit->creer)){
    -		print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
    -		print '<input type="hidden" name="action" value="addlimitstockwarehouse">';
    -		print '<input type="hidden" name="id" value="'.$id.'">';
    -	}
    +	print '<div class="div-table-responsive">';
     	print '<table class="noborder" width="100%">';
    -	if (!empty($user->rights->produit->creer)){
    -		print '<tr class="liste_titre"><td width="40%">'.$formproduct->selectWarehouses('', 'fk_entrepot').'</td>';
    -		print '<td align="right"><input name="seuil_stock_alerte" type="text" placeholder="'.$langs->trans("StockLimit").'" /></td>';
    -		print '<td align="right"><input name="desiredstock" type="text" placeholder="'.$langs->trans("DesiredStock").'" /></td>';
    -		print '<td align="right"><input type="submit" value="'.$langs->trans('Save').'" class="button" /></td>';
    -		print '</tr>';
    -	}else{
    -		print '<tr class="liste_titre"><td width="40%">'.$langs->trans("Warehouse").'</td>';
    -		print '<td align="right">'.$langs->trans("StockLimit").'</td>';
    -		print '<td align="right">'.$langs->trans("DesiredStock").'</td>';
    +	print '<tr class="liste_titre">';
    +	print '<td colspan="4">' . $langs->trans("Warehouse") . '</td>';
    +	print '<td align="right">' . $langs->trans("NumberOfUnit") . '</td>';
    +	print '<td align="right">' . $langs->trans("AverageUnitPricePMPShort") . '</td>';
    +	print '<td align="right">' . $langs->trans("EstimatedStockValueShort") . '</td>';
    +	print '<td align="right">' . $langs->trans("SellPriceMin") . '</td>';
    +	print '<td align="right">' . $langs->trans("EstimatedStockValueSellShort") . '</td>';
    +	print '</tr>';
    +	if ((!empty($conf->productbatch->enabled)) && $object->hasbatch()) {
    +		print '<tr class="liste_titre"><td width="10%"></td>';
    +		print '<td align="right" width="10%">' . $langs->trans("batch_number") . '</td>';
    +		print '<td align="center" width="10%">' . $langs->trans("EatByDate") . '</td>';
    +		print '<td align="center" width="10%">' . $langs->trans("SellByDate") . '</td>';
    +		print '<td></td>';
    +		print '<td></td>';
    +		print '<td></td>';
    +		print '<td></td>';
    +		print '<td></td>';
     		print '</tr>';
     	}
     
    -	$pse = new ProductStockEntrepot($db);
    -	$lines = $pse->fetchAll($id);
    +	$sql = "SELECT e.rowid, e.ref as label, e.lieu, ps.reel, ps.rowid as product_stock_id, p.pmp";
    +	$sql .= " FROM " . MAIN_DB_PREFIX . "entrepot as e,";
    +	$sql .= " " . MAIN_DB_PREFIX . "product_stock as ps";
    +	$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = ps.fk_product";
    +	$sql .= " WHERE ps.reel != 0";
    +	$sql .= " AND ps.fk_entrepot = e.rowid";
    +	$sql .= " AND e.entity IN (" . getEntity('stock') . ")";
    +	$sql .= " AND ps.fk_product = " . $object->id;
    +	$sql .= " ORDER BY e.ref";
     
    -	if (!empty($lines))
    -	{
    -		$var=false;
    -		foreach($lines as $line)
    -		{
    -			$ent = new Entrepot($db);
    -			$ent->fetch($line['fk_entrepot']);
    -			print '<tr class="oddeven"><td width="40%">'.$ent->getNomUrl(3).'</td>';
    -			print '<td align="right">'.$line['seuil_stock_alerte'].'</td>';
    -			print '<td align="right">'.$line['desiredstock'].'</td>';
    -			if (!empty($user->rights->produit->creer)){
    -			    print '<td align="right"><a href="?id='.$id.'&fk_productstockwarehouse='.$line['id'].'&action=delete_productstockwarehouse">'.img_delete().'</a></td>';
    +	$entrepotstatic = new Entrepot($db);
    +	$product_lot_static = new Productlot($db);
    +
    +	$total = 0;
    +	$totalvalue = $totalvaluesell = 0;
    +
    +	$resql = $db->query($sql);
    +	if ($resql) {
    +		$num = $db->num_rows($resql);
    +		$total = $totalwithpmp;
    +		$i = 0;
    +		$var = false;
    +		while ($i < $num) {
    +			$obj = $db->fetch_object($resql);
    +			$entrepotstatic->id = $obj->rowid;
    +			$entrepotstatic->libelle = $obj->label;
    +			$entrepotstatic->lieu = $obj->lieu;
    +			$stock_real = price2num($obj->reel, 'MS');
    +			print '<tr class="oddeven">';
    +			print '<td colspan="4">' . $entrepotstatic->getNomUrl(1) . '</td>';
    +			print '<td align="right">' . $stock_real . ($stock_real < 0 ? ' ' . img_warning() : '') . '</td>';
    +			// PMP
    +			print '<td align="right">' . (price2num($object->pmp) ? price2num($object->pmp, 'MU') : '') . '</td>';
    +			// Value purchase
    +			print '<td align="right">' . (price2num($object->pmp) ? price(price2num($object->pmp * $obj->reel, 'MT')) : '') . '</td>';
    +			// Sell price
    +			print '<td align="right">';
    +			if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price, 'MU'), 1);
    +			else print $langs->trans("Variable");
    +			print '</td>';
    +			// Value sell
    +			print '<td align="right">';
    +			if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($object->price * $obj->reel, 'MT'), 1) . '</td>';
    +			else print $langs->trans("Variable");
    +			print '</tr>';;
    +			$total += $obj->reel;
    +			if (price2num($object->pmp)) $totalwithpmp += $obj->reel;
    +			$totalvalue = $totalvalue + ($object->pmp * $obj->reel);
    +			$totalvaluesell = $totalvaluesell + ($object->price * $obj->reel);
    +			// Batch Detail
    +			if ((!empty($conf->productbatch->enabled)) && $object->hasbatch()) {
    +				$details = Productbatch::findAll($db, $obj->product_stock_id, 0, $object->id);
    +				if ($details < 0) dol_print_error($db);
    +				foreach ($details as $pdluo) {
    +					$product_lot_static->id = $pdluo->lotid;
    +					$product_lot_static->batch = $pdluo->batch;
    +					$product_lot_static->eatby = $pdluo->eatby;
    +					$product_lot_static->sellby = $pdluo->sellby;
    +
    +					if ($action == 'editline' && GETPOST('lineid', 'int') == $pdluo->id) { //Current line edit
    +						print "\n" . '<tr>';
    +						print '<td colspan="9">';
    +						print '<form action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
    +						print '<input type="hidden" name="pdluoid" value="' . $pdluo->id . '"><input type="hidden" name="action" value="updateline"><input type="hidden" name="id" value="' . $id . '"><table class="noborder" width="100%"><tr><td width="10%"></td>';
    +						print '<td align="right" width="10%"><input type="text" name="batch_number" value="' . $pdluo->batch . '"></td>';
    +						print '<td align="center" width="10%">';
    +						print $form->selectDate($pdluo->eatby, 'eatby', '', '', 1, '', 1, 0);
    +						print '</td>';
    +						print '<td align="center" width="10%">';
    +						print $form->selectDate($pdluo->sellby, 'sellby', '', '', 1, '', 1, 0);
    +						print '</td>';
    +						print '<td align="right" width="10%">' . $pdluo->qty . ($pdluo->qty < 0 ? ' ' . img_warning() : '') . '</td>';
    +						print '<td colspan="4"><input type="submit" class="button" id="savelinebutton" name="save" value="' . $langs->trans("Save") . '">';
    +						print '<input type="submit" class="button" id="cancellinebutton" name="Cancel" value="' . $langs->trans("Cancel") . '"></td></tr>';
    +						print '</table>';
    +						print '</form>';
    +						print '</td></tr>';
    +					} else {
    +						print "\n" . '<tr><td align="right">';
    +						print img_picto($langs->trans("Tranfer"), 'uparrow', 'class="hideonsmartphone"') . ' ';
    +						print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;id_entrepot=' . $entrepotstatic->id . '&amp;action=transfert&amp;pdluoid=' . $pdluo->id . '">' . $langs->trans("TransferStock") . '</a>';
    +						// Disabled, because edition of stock content must use the "Correct stock menu".
    +						// Do not use this, or data will be wrong (bad tracking of movement label, inventory code, ...
    +						//print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&amp;action=editline&amp;lineid='.$pdluo->id.'#'.$pdluo->id.'">';
    +						//print img_edit().'</a></td>';
    +						print '<td align="right">';
    +						print $product_lot_static->getNomUrl(1);
    +						print '</td>';
    +						print '<td align="center">' . dol_print_date($pdluo->eatby, 'day') . '</td>';
    +						print '<td align="center">' . dol_print_date($pdluo->sellby, 'day') . '</td>';
    +						print '<td align="right">' . $pdluo->qty . ($pdluo->qty < 0 ? ' ' . img_warning() : '') . '</td>';
    +						print '<td colspan="4"></td></tr>';
    +					}
    +				}
     			}
    +			$i++;
    +
    +		}
    +	} else dol_print_error($db);
    +
    +	print '<tr class="liste_total"><td align="right" class="liste_total" colspan="4">' . $langs->trans("Total") . ':</td>';
    +	print '<td class="liste_total" align="right">' . price2num($total, 'MS') . '</td>';
    +	print '<td class="liste_total" align="right">';
    +	print ($totalwithpmp ? price(price2num($totalvalue / $totalwithpmp, 'MU')) : '&nbsp;');    // This value may have rounding errors
    +	print '</td>';
    +// Value purchase
    +	print '<td class="liste_total" align="right">';
    +	print $totalvalue ? price(price2num($totalvalue, 'MT'), 1) : '&nbsp;';
    +	print '</td>';
    +	print '<td class="liste_total" align="right">';
    +	if (empty($conf->global->PRODUIT_MULTIPRICES)) print ($total ? price($totalvaluesell / $total, 1) : '&nbsp;');
    +	else print $langs->trans("Variable");
    +	print '</td>';
    +// Value to sell
    +	print '<td class="liste_total" align="right">';
    +	if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($totalvaluesell, 'MT'), 1);
    +	else print $langs->trans("Variable");
    +	print '</td>';
    +	print "</tr>";
    +	print "</table>";
    +	print '</div>';
    +
    +	if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) {
    +		print '<br><br>';
    +		print_titre($langs->trans('AddNewProductStockWarehouse'));
    +
    +		if (!empty($user->rights->produit->creer)) {
    +			print '<form action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
    +			print '<input type="hidden" name="action" value="addlimitstockwarehouse">';
    +			print '<input type="hidden" name="id" value="' . $id . '">';
    +		}
    +		print '<table class="noborder" width="100%">';
    +		if (!empty($user->rights->produit->creer)) {
    +			print '<tr class="liste_titre"><td width="40%">' . $formproduct->selectWarehouses('', 'fk_entrepot') . '</td>';
    +			print '<td align="right"><input name="seuil_stock_alerte" type="text" placeholder="' . $langs->trans("StockLimit") . '" /></td>';
    +			print '<td align="right"><input name="desiredstock" type="text" placeholder="' . $langs->trans("DesiredStock") . '" /></td>';
    +			print '<td align="right"><input type="submit" value="' . $langs->trans('Save') . '" class="button" /></td>';
    +			print '</tr>';
    +		} else {
    +			print '<tr class="liste_titre"><td width="40%">' . $langs->trans("Warehouse") . '</td>';
    +			print '<td align="right">' . $langs->trans("StockLimit") . '</td>';
    +			print '<td align="right">' . $langs->trans("DesiredStock") . '</td>';
     			print '</tr>';
     		}
    -	}
     
    -	print "</table>";
    +		$pse = new ProductStockEntrepot($db);
    +		$lines = $pse->fetchAll($id);
     
    -	if (!empty($user->rights->produit->creer)){
    -	    print '</form>';
    +		if (!empty($lines)) {
    +			$var = false;
    +			foreach ($lines as $line) {
    +				$ent = new Entrepot($db);
    +				$ent->fetch($line['fk_entrepot']);
    +				print '<tr class="oddeven"><td width="40%">' . $ent->getNomUrl(3) . '</td>';
    +				print '<td align="right">' . $line['seuil_stock_alerte'] . '</td>';
    +				print '<td align="right">' . $line['desiredstock'] . '</td>';
    +				if (!empty($user->rights->produit->creer)) {
    +					print '<td align="right"><a href="?id=' . $id . '&fk_productstockwarehouse=' . $line['id'] . '&action=delete_productstockwarehouse">' . img_delete() . '</a></td>';
    +				}
    +				print '</tr>';
    +			}
    +		}
    +
    +		print "</table>";
    +
    +		if (!empty($user->rights->produit->creer)) {
    +			print '</form>';
    +		}
     	}
    +} else {
    +	// List of variants
    +
    +	$prodstatic = new Product($db);
    +	$prodcomb = new ProductCombination($db);
    +	$comb2val = new ProductCombination2ValuePair($db);
    +	$productCombinations = $prodcomb->fetchAllByFkProductParent($object->id);
    +
    +	print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
    +	print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
    +	print '<input type="hidden" name="action" value="massaction">';
    +	print '<input type="hidden" name="id" value="'.$id.'">';
    +	print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
    +
    +	// load variants
    +	$title = $langs->trans("ProductCombinations");
    +
    +	print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0);
    +
    +	print '<div class="div-table-responsive">';
    +	?>
    +	<table class="liste">
    +		<tr class="liste_titre">
    +			<td class="liste_titre"><?php echo $langs->trans('Product') ?></td>
    +			<td class="liste_titre"><?php echo $langs->trans('Combination') ?></td>
    +			<td class="liste_titre center"><?php echo $langs->trans('OnSell') ?></td>
    +			<td class="liste_titre center"><?php echo $langs->trans('OnBuy') ?></td>
    +			<td class="liste_titre right"><?php echo $langs->trans('Stock') ?></td>
    +			<td class="liste_titre"></td>
    +		</tr>
    +		<?php
    +
    +		if (count($productCombinations))
    +		{
    +			$stock_total= 0;
    +			foreach ($productCombinations as $currcomb)
    +			{
    +				$prodstatic->fetch($currcomb->fk_product_child);
    +				$prodstatic->load_stock();
    +				$stock_total+=$prodstatic->stock_reel;
    +				?>
    +				<tr class="oddeven">
    +					<td><?php echo $prodstatic->getNomUrl(1) ?></td>
    +					<td>
    +						<?php
    +
    +						$productCombination2ValuePairs = $comb2val->fetchByFkCombination($currcomb->id);
    +						$iMax = count($productCombination2ValuePairs);
    +
    +						for ($i = 0; $i < $iMax; $i++) {
    +							echo dol_htmlentities($productCombination2ValuePairs[$i]);
    +
    +							if ($i !== ($iMax - 1)) {
    +								echo ', ';
    +							}
    +						} ?>
    +					</td>
    +					<td style="text-align: center;"><?php echo $prodstatic->getLibStatut(2, 0) ?></td>
    +					<td style="text-align: center;"><?php echo $prodstatic->getLibStatut(2, 1) ?></td>
    +					<td class="right"><?php echo $prodstatic->stock_reel ?></td>
    +					<td class="right">
    +						<a class="paddingleft paddingright" href="<?php echo dol_buildpath('/product/stock/product.php?id='.$currcomb->fk_product_child, 2) ?>"><?php echo img_edit() ?></a>
    +					</td>
    +					<?php
    +					?>
    +				</tr>
    +				<?php
    +			}
    +
    +			print '<tr class="liste_total">';
    +			print '<td colspan="4" align="left">'.$langs->trans("Total").'</td>';
    +			print '<td align="right">'.$stock_total.'</td>';
    +			print '</tr>';
    +		}
    +		else
    +		{
    +			print '<tr><td colspan="8"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
    +		}
    +		?>
    +	</table>
    +
    +	<?php
    +	print '</div>';
    +
    +	print '</form>';
     }
     
     // End of page
    diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php
    index 58eb2178da4..3c94e775ee0 100644
    --- a/htdocs/variants/class/ProductCombination.class.php
    +++ b/htdocs/variants/class/ProductCombination.class.php
    @@ -634,7 +634,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
     		}
     
     		$db->commit();
    -		return 1;
    +		return $newproduct->id;
     	}
     
     	/**
    
    From 58be4ac7a32836d28d7a1df033ba57f02225ebda Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Thu, 11 Oct 2018 12:36:10 +0200
    Subject: [PATCH 135/433] New: works with variants: - Hide child products into
     list if PRODUIT_ATTRIBUTES_HIDECHILD is activated
    
    ---
     htdocs/product/list.php | 10 ++++++++++
     1 file changed, 10 insertions(+)
    
    diff --git a/htdocs/product/list.php b/htdocs/product/list.php
    index 28f08035198..720ef957c01 100644
    --- a/htdocs/product/list.php
    +++ b/htdocs/product/list.php
    @@ -286,6 +286,11 @@ if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_ty
     	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid";
     }
     
    +if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
    +	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid";
    +}
    +
    +
     $sql.= ' WHERE p.entity IN ('.getEntity('product').')';
     if ($sall) $sql .= natural_search(array_keys($fieldstosearchall), $sall);
     // if the type is not 1, we show all products (type = 0,2,3)
    @@ -294,6 +299,11 @@ if (dol_strlen($search_type) && $search_type != '-1')
     	if ($search_type == 1) $sql.= " AND p.fk_product_type = 1";
     	else $sql.= " AND p.fk_product_type <> 1";
     }
    +
    +if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
    +	$sql .= " AND pac.rowid IS NULL";
    +}
    +
     if ($search_ref)     $sql .= natural_search('p.ref', $search_ref);
     if ($search_label)   $sql .= natural_search('p.label', $search_label);
     if ($search_barcode) $sql .= natural_search('p.barcode', $search_barcode);
    
    From 88ff7241f5b848aac28394142b8a876e85424aef Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 11 Oct 2018 13:12:13 +0200
    Subject: [PATCH 136/433] FIX Quick hack to solve pb of bad definition of
     public holidays
    
    ---
     htdocs/core/lib/date.lib.php | 23 +++++++++++++++++++++++
     test/phpunit/DateLibTest.php | 20 ++++++++++++++++++++
     2 files changed, 43 insertions(+)
    
    diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php
    index ea1dbe237de..23f4ebd1186 100644
    --- a/htdocs/core/lib/date.lib.php
    +++ b/htdocs/core/lib/date.lib.php
    @@ -573,6 +573,8 @@ function dol_get_first_day_week($day,$month,$year,$gm=false)
      */
     function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $lastday=0)
     {
    +	global $conf;
    +
     	$nbFerie = 0;
     
     	// Check to ensure we use correct parameters
    @@ -588,6 +590,27 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     		$jour  = date("d", $timestampStart);
     		$mois  = date("m", $timestampStart);
     		$annee = date("Y", $timestampStart);
    +
    +
    +		// Check into var $conf->global->HOLIDAY_MORE_DAYS   MM-DD,YYYY-MM-DD, ...
    +		if (! empty($conf->global->HOLIDAY_MORE_PUBLIC_HOLIDAYS))
    +		{
    +			$arrayofdaystring=explode(',',$conf->global->HOLIDAY_MORE_PUBLIC_HOLIDAYS);
    +			foreach($arrayofdaystring as $daystring)
    +			{
    +				$tmp=explode('-',$daystring);
    +				var_dump($tmp);
    +				if ($tmp[2])
    +				{
    +					if ($tmp[0] == $annee && $tmp[1] == $mois && $tmp[2] == $jour) $ferie=true;
    +				}
    +				else
    +				{
    +					if ($tmp[0] == $mois && $tmp[1] == $jour) $ferie=true;
    +				}
    +			}
    +		}
    +
     		if ($countrycode == 'FR')
     		{
     			$countryfound=1;
    diff --git a/test/phpunit/DateLibTest.php b/test/phpunit/DateLibTest.php
    index 1290523abc1..e0cd1fab31b 100644
    --- a/test/phpunit/DateLibTest.php
    +++ b/test/phpunit/DateLibTest.php
    @@ -205,6 +205,26 @@ class DateLibTest extends PHPUnit_Framework_TestCase
             $result=num_public_holiday($date1,$date2,'XX',1);
             print __METHOD__." result=".$result."\n";
             $this->assertEquals(2,$result,'NumPublicHoliday for XX');   // 1 opened day, 2 closed days (even if country unknown)
    +
    +        $conf->global->HOLIDAY_MORE_PUBLIC_HOLIDAYS='12-13,2019-12-14';
    +
    +        $date1=dol_mktime(0, 0, 0, 12, 13, 2018);
    +        $date2=dol_mktime(0, 0, 0, 12, 13, 2018);
    +        $result=num_public_holiday($date1,$date2,'YY',1);
    +        print __METHOD__." result=".$result."\n";
    +        $this->assertEquals(1,$result,'NumPublicHoliday for YY the 2018-12-13');   // 0 opened day, 1 closed days (even if country unknown)
    +
    +        $date1=dol_mktime(0, 0, 0, 12, 14, 2018);
    +        $date2=dol_mktime(0, 0, 0, 12, 14, 2018);
    +        $result=num_public_holiday($date1,$date2,'YY',1);
    +        print __METHOD__." result=".$result."\n";
    +        $this->assertEquals(0,$result,'NumPublicHoliday for YY the 2018-12-14');   // 1 opened day, 0 closed days (even if country unknown)
    +
    +        $date1=dol_mktime(0, 0, 0, 12, 14, 2019);
    +        $date2=dol_mktime(0, 0, 0, 12, 14, 2019);
    +        $result=num_public_holiday($date1,$date2,'YY',1);
    +        print __METHOD__." result=".$result."\n";
    +        $this->assertEquals(1,$result,'NumPublicHoliday for YY the 2019-12-14');   // 0 opened day, 1 closed days (even if country unknown)
         }
     
         /**
    
    From e6f179b6cb348207deb9ed5c8b488224e5e575e2 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 11 Oct 2018 13:33:44 +0200
    Subject: [PATCH 137/433] Fix look
    
    ---
     htdocs/product/stock/productlot_card.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/product/stock/productlot_card.php b/htdocs/product/stock/productlot_card.php
    index 4c614155042..7c2f4f148ad 100644
    --- a/htdocs/product/stock/productlot_card.php
    +++ b/htdocs/product/stock/productlot_card.php
    @@ -390,6 +390,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     	print '<br>';
     	print '<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?search_product_ref='.urlencode($producttmp->ref).'&search_batch='.urlencode($object->batch).'">'.$langs->trans("ShowLogOfMovementIfLot").'</a><br>';
     
    +	print '<br>';
     }
     
     
    
    From 4b32c8e100c0cf2c53f72651ba2ee11a43d9e662 Mon Sep 17 00:00:00 2001
    From: atm-ph <phf@atm-consulting.fr>
    Date: Thu, 11 Oct 2018 14:24:55 +0200
    Subject: [PATCH 138/433] Fix extrafield contact typed as date isn't show in
     the list from 'contact/address' tab of company
    
    ---
     htdocs/core/tpl/extrafields_list_print_fields.tpl.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
    index e77d0ee0eaf..855794da2d6 100644
    --- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
    +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
    @@ -21,7 +21,7 @@ if (! empty($extrafieldsobjectkey))	// New method: $extrafieldsobject can be 'so
     				if ($align) print ' align="'.$align.'"';
     				print '>';
     				$tmpkey='options_'.$key;
    -				if (in_array($extrafields->attributes[$extrafieldsobjectkey]['type'][$key], array('date', 'datetime', 'timestamp')))
    +				if (in_array($extrafields->attributes[$extrafieldsobjectkey]['type'][$key], array('date', 'datetime', 'timestamp')) && !preg_match('/^[0-9]{10}$/', $obj->$tmpkey))
     				{
     					$value = $db->jdate($obj->$tmpkey);
     				}
    
    From ab55ff2e2c71218ba84ca6683e64169615620acd Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Thu, 11 Oct 2018 15:44:23 +0200
    Subject: [PATCH 139/433] New: works with variants: - Make the checkbox working
     correctly
    
    ---
     htdocs/langs/en_US/products.lang              |  1 +
     htdocs/product/class/product.class.php        |  2 +-
     htdocs/product/list.php                       | 37 ++++++++++---------
     htdocs/product/stock/product.php              |  2 +-
     .../class/ProductCombination.class.php        |  1 +
     5 files changed, 24 insertions(+), 19 deletions(-)
    
    diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
    index 0dde8ad538a..33be55ec336 100644
    --- a/htdocs/langs/en_US/products.lang
    +++ b/htdocs/langs/en_US/products.lang
    @@ -330,6 +330,7 @@ NbOfDifferentValues=No. of different values
     NbProducts=No. of products
     ParentProduct=Parent product
     HideChildProducts=Hide variant products
    +ShowChildProducts=Show variant products
     ConfirmCloneProductCombinations=Would you like to copy all the product variants to the other parent product with the given reference?
     CloneDestinationReference=Destination product reference
     ErrorCopyProductCombinations=There was an error while copying the product variants
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 3257f9bbde5..adb17e67235 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -4,7 +4,7 @@
      * Copyright (C) 2005-2015	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2006		Andre Cianfarani		<acianfa@free.fr>
      * Copyright (C) 2007-2011	Jean Heimburger			<jean@tiaris.info>
    - * Copyright (C) 2010-2013	Juanjo Menent			<jmenent@2byte.es>
    + * Copyright (C) 2010-2018	Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2012       Cedric Salvador         <csalvador@gpcsolutions.fr>
      * Copyright (C) 2013-2014	Cedric GROSS			<c.gross@kreiz-it.fr>
      * Copyright (C) 2013-2016	Marcos García			<marcosgdf@gmail.com>
    diff --git a/htdocs/product/list.php b/htdocs/product/list.php
    index 720ef957c01..9028ceb15c2 100644
    --- a/htdocs/product/list.php
    +++ b/htdocs/product/list.php
    @@ -3,7 +3,7 @@
      * Copyright (C) 2004-2018  Laurent Destailleur     <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
      * Copyright (C) 2012-2016  Marcos García           <marcosgdf@gmail.com>
    - * Copyright (C) 2013-2016	Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2013-2018	Juanjo Menent           <jmenent@2byte.es>
      * Copyright (C) 2013-2015  Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2013       Jean Heimburger         <jean@tiaris.info>
      * Copyright (C) 2013       Cédric Salvador         <csalvador@gpcsolutions.fr>
    @@ -53,7 +53,7 @@ $sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alp
     $search_ref=GETPOST("search_ref");
     $search_barcode=GETPOST("search_barcode");
     $search_label=GETPOST("search_label");
    -$search_type = GETPOST("search_type",'int');
    +$search_type = GETPOST("search_type", 'int');
     $search_sale = GETPOST("search_sale");
     $search_categ = GETPOST("search_categ",'int');
     $search_tosell = GETPOST("search_tosell", 'int');
    @@ -66,11 +66,11 @@ $search_accountancy_code_buy = GETPOST("search_accountancy_code_buy",'alpha');
     $optioncss = GETPOST('optioncss','alpha');
     $type=GETPOST("type","int");
     
    -//Show/hide child products. Hidden by default
    -if (!$_POST) {
    -	$search_hidechildproducts = 'on';
    +//Show/hide child products
    +if (!empty($conf->variants->enabled) && ! empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
    +	$show_childproducts = GETPOST('show_childproducts');
     } else {
    -	$search_hidechildproducts = GETPOST('search_hidechildproducts');
    +	$show_childproducts = '';
     }
     
     $diroutputmassaction=$conf->product->dir_output . '/temp/massgeneration/'.$user->id;
    @@ -219,6 +219,8 @@ if (empty($reshook))
     		$search_tobuy="";
     		$search_tobatch='';
     		//$search_type='';						// There is 2 types of list: a list of product and a list of services. No list with both. So when we clear search criteria, we must keep the filter on type.
    +
    +		$show_childproducts = '';
     		$search_accountancy_code_sell='';
     		$search_accountancy_code_buy='';
     		$search_array_options=array();
    @@ -265,7 +267,7 @@ $sql.= ' p.fk_product_type, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte,
     $sql.= ' p.tobatch, p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy,';
     $sql.= ' p.datec as date_creation, p.tms as date_update, p.pmp,';
     $sql.= ' MIN(pfp.unitprice) as minsellprice';
    -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) {
    +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) {
     	$sql .= ', pac.rowid prod_comb_id';
     }
     // Add fields from extrafields
    @@ -282,11 +284,8 @@ if (! empty($search_categ) || ! empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREF
     $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
     // multilang
     if (! empty($conf->global->MAIN_MULTILANGS)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang = '".$langs->getDefaultLang() ."'";
    -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) {
    -	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid";
    -}
     
    -if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
    +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) {
     	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid";
     }
     
    @@ -300,7 +299,7 @@ if (dol_strlen($search_type) && $search_type != '-1')
     	else $sql.= " AND p.fk_product_type <> 1";
     }
     
    -if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
    +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) {
     	$sql .= " AND pac.rowid IS NULL";
     }
     
    @@ -318,7 +317,7 @@ if ($fourn_id > 0)  $sql.= " AND pfp.fk_soc = ".$fourn_id;
     if ($search_tobatch != '' && $search_tobatch >= 0)   $sql.= " AND p.tobatch = ".$db->escape($search_tobatch);
     if ($search_accountancy_code_sell) $sql.= natural_search('p.accountancy_code_sell', $search_accountancy_code_sell);
     if ($search_accountancy_code_buy)  $sql.= natural_search('p.accountancy_code_buy', $search_accountancy_code_buy);
    -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) $sql .= " AND pac.rowid IS NULL";
    +
     // Add where from extra fields
     include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
     // Add where from hooks
    @@ -328,7 +327,10 @@ $sql.=$hookmanager->resPrint;
     $sql.= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.price_ttc, p.price_base_type,";
     $sql.= " p.fk_product_type, p.duration, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock,";
     $sql.= ' p.datec, p.tms, p.entity, p.tobatch, p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.pmp';
    -if (!empty($conf->variants->enabled) && $search_hidechildproducts && ($search_type === 0)) $sql .= ', pac.rowid';
    +
    +if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && ! $show_childproducts )) {
    +	$sql .= ', pac.rowid';
    +}
     // Add fields from extrafields
     if (! empty($extrafields->attributes[$object->table_element]['label'])) {
     	foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key : '');
    @@ -402,6 +404,7 @@ if ($resql)
     	if ($search_tobuy != '') $param.="&search_tobuy=".urlencode($search_tobuy);
     	if ($fourn_id > 0) $param.=($fourn_id?"&fourn_id=".$fourn_id:"");
     	if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):"");
    +	if ($show_childproducts) $param.=($show_childproducts?"&show_childproducts=".urlencode($show_childproducts):"");
     	if ($type != '') $param.='&type='.urlencode($type);
     	if ($search_type != '') $param.='&search_type='.urlencode($search_type);
     	if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss);
    @@ -477,10 +480,10 @@ if ($resql)
     	}
     
     	//Show/hide child products. Hidden by default
    -	if (!empty($conf->variants->enabled) && $search_type === 0) {
    +	if (!empty($conf->variants->enabled) && !empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD )) {
     		$moreforfilter.='<div class="divsearchfield">';
    -		$moreforfilter.= '<input type="checkbox" id="search_hidechildproducts" name="search_hidechildproducts" value="on"'.($search_hidechildproducts ? 'checked="checked"' : '').'>';
    -		$moreforfilter.= ' <label for="search_hidechildproducts">'.$langs->trans('HideChildProducts').'</label>';
    +		$moreforfilter.= '<input type="checkbox" id="show_childproducts" name="show_childproducts"'.($show_childproducts ? 'checked="checked"':'').'>';
    +		$moreforfilter.= ' <label for="show_childproducts">'.$langs->trans('ShowChildProducts').'</label>';
     		$moreforfilter.='</div>';
     	}
     
    diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
    index 51871736a3d..dc291eb0fdc 100644
    --- a/htdocs/product/stock/product.php
    +++ b/htdocs/product/stock/product.php
    @@ -5,7 +5,7 @@
      * Copyright (C) 2005      Simon TOSSER         <simon@kornog-computing.com>
      * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2013      Cédric Salvador      <csalvador.gpcsolutions.fr>
    - * Copyright (C) 2013-2015 Juanjo Menent	    <jmenent@2byte.es>
    + * Copyright (C) 2013-2018 Juanjo Menent	    <jmenent@2byte.es>
      * Copyright (C) 2014-2015 Cédric Gross         <c.gross@kreiz-it.fr>
      * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
      * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php
    index 3c94e775ee0..8908bfa4d2d 100644
    --- a/htdocs/variants/class/ProductCombination.class.php
    +++ b/htdocs/variants/class/ProductCombination.class.php
    @@ -1,6 +1,7 @@
     <?php
     
     /* Copyright (C) 2016	Marcos García	<marcosgdf@gmail.com>
    + * Copyright (C) 2018	Juanjo Menent	<jmenent@2byte.es>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    
    From 0976616401c424a0a5fb3a3faa76f37c65915d67 Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Thu, 11 Oct 2018 17:13:39 +0200
    Subject: [PATCH 140/433] Fix: Opening brace should be on a new line
    
    ---
     htdocs/product/class/product.class.php | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index adb17e67235..e8dff4c8e92 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -3498,7 +3498,8 @@ class Product extends CommonObject
     	 *
     	 * @return 	int		Number of variants
     	 */
    -	function hasVariants() {
    +	function hasVariants()
    +	{
     		$nb = 0;
     		$sql = "SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_parent = ".$this->id;
     		$sql.= " AND entity IN (".getEntity('product').")";
    
    From 79420593f44aa1e320847d9c8e8da9ef245fa05d Mon Sep 17 00:00:00 2001
    From: atm-ph <phf@atm-consulting.fr>
    Date: Thu, 11 Oct 2018 17:14:22 +0200
    Subject: [PATCH 141/433] Fix display 0 (as virtual stock) instead of empty
     string
    
    ---
     htdocs/product/reassort.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php
    index ccd01e56db7..a915594c4de 100644
    --- a/htdocs/product/reassort.php
    +++ b/htdocs/product/reassort.php
    @@ -338,7 +338,7 @@ if ($resql)
     		// Real stock
     		print '<td align="right">';
             if ($objp->seuil_stock_alerte != '' && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
    -		print $objp->stock_physique;
    +		print $objp->stock_physique|0;
     		print '</td>';
     
     		// Details per warehouse
    
    From 849a1a94000f9a959423a7f26b2d8b0bb93e5b31 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 09:26:58 +0200
    Subject: [PATCH 142/433] Standardize and update code
    
    ---
     .../template/class/myobject.class.php            |  9 +++++++++
     htdocs/product/class/product.class.php           |  3 +++
     htdocs/product/class/productbatch.class.php      | 16 ++++++++++------
     .../product/class/productcustomerprice.class.php | 10 +++++++++-
     .../class/propalmergepdfproduct.class.php        | 13 +++++++++++++
     5 files changed, 44 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php
    index b04dd735e49..19e6bcd64a4 100644
    --- a/htdocs/modulebuilder/template/class/myobject.class.php
    +++ b/htdocs/modulebuilder/template/class/myobject.class.php
    @@ -130,8 +130,17 @@ class MyObject extends CommonObject
     
     	public $date_creation;
     	public $tms;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
     	public $import_key;
     	// END MODULEBUILDER PROPERTIES
     
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 050d756ad82..3e1ceb8b2dc 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -290,6 +290,9 @@ class Product extends CommonObject
     
     	public $oldcopy;
     
    +	/**
    +     * @var int ID
    +     */
         public $fk_price_expression;
     
         /* To store supplier price found */
    diff --git a/htdocs/product/class/productbatch.class.php b/htdocs/product/class/productbatch.class.php
    index f6a7df212eb..eb4fc32baed 100644
    --- a/htdocs/product/class/productbatch.class.php
    +++ b/htdocs/product/class/productbatch.class.php
    @@ -37,13 +37,17 @@ class Productbatch extends CommonObject
     
     	private static $_table_element='product_batch';		//!< Name of table without prefix where object is stored
     
    -	var $tms='';
    -	var $fk_product_stock;
    -	var $sellby='';
    -	var $eatby='';
    -	var $batch='';
    -	var $qty;
    +	public $tms='';
    +	public $fk_product_stock;
    +	public $sellby='';
    +	public $eatby='';
    +	public $batch='';
    +	public $qty;
     	public $warehouseid;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
     
     
    diff --git a/htdocs/product/class/productcustomerprice.class.php b/htdocs/product/class/productcustomerprice.class.php
    index 5aaa2c079ea..3079fef5412 100644
    --- a/htdocs/product/class/productcustomerprice.class.php
    +++ b/htdocs/product/class/productcustomerprice.class.php
    @@ -45,6 +45,10 @@ class Productcustomerprice extends CommonObject
     
     	public $datec = '';
     	public $tms = '';
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
     
     	/**
    @@ -987,12 +991,16 @@ class PriceByCustomerLine
     
     	public $datec = '';
     	public $tms = '';
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
     
     	/**
     	 * @var int Thirdparty ID
     	 */
    -  public $fk_soc;
    +    public $fk_soc;
     
     	public $price;
     	public $price_ttc;
    diff --git a/htdocs/product/class/propalmergepdfproduct.class.php b/htdocs/product/class/propalmergepdfproduct.class.php
    index 3a7f3fb586d..f2aabb86876 100644
    --- a/htdocs/product/class/propalmergepdfproduct.class.php
    +++ b/htdocs/product/class/propalmergepdfproduct.class.php
    @@ -647,11 +647,24 @@ class PropalmergepdfproductLine
     	 */
     	public $id;
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
    +
     	public $file_name;
     	public $lang;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_mod;
    +
     	public $datec='';
     	public $tms='';
     	public $import_key;
    
    From 357173f0ef55f34e4248ef964cd92fe7a00e8116 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 09:30:53 +0200
    Subject: [PATCH 143/433] Standardize and update code
    
    ---
     .../price_global_variable_updater.class.php     |  5 +++++
     .../product/inventory/class/inventory.class.php | 17 +++++++++++++++++
     htdocs/product/stock/class/entrepot.class.php   |  4 ++++
     .../stock/class/mouvementstock.class.php        |  8 ++++++++
     htdocs/product/stock/class/productlot.class.php | 13 +++++++++++++
     .../stock/class/productstockentrepot.class.php  |  9 +++++++++
     6 files changed, 56 insertions(+)
    
    diff --git a/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php b/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php
    index b06a249ccc6..c4dda3481bb 100644
    --- a/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php
    +++ b/htdocs/product/dynamic_price/class/price_global_variable_updater.class.php
    @@ -60,7 +60,12 @@ class PriceGlobalVariableUpdater
     	public $description;
     
         public $parameters;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_variable;
    +
         public $update_interval;				//!< Interval in mins
         public $next_update;					//!< Next update timestamp
         public $last_status;
    diff --git a/htdocs/product/inventory/class/inventory.class.php b/htdocs/product/inventory/class/inventory.class.php
    index e1be589ac88..39df52a8208 100644
    --- a/htdocs/product/inventory/class/inventory.class.php
    +++ b/htdocs/product/inventory/class/inventory.class.php
    @@ -114,7 +114,11 @@ class Inventory extends CommonObject
     	 */
     	public $entity;
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_warehouse;
    +
     	public $date_inventory;
     	public $title;
     
    @@ -126,9 +130,22 @@ class Inventory extends CommonObject
     	public $date_creation;
     	public $date_validation;
     	public $tms;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_valid;
    +
     	public $import_key;
     	// END MODULEBUILDER PROPERTIES
     
    diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php
    index 575aa2a705d..b2a78a9cd3e 100644
    --- a/htdocs/product/stock/class/entrepot.class.php
    +++ b/htdocs/product/stock/class/entrepot.class.php
    @@ -78,6 +78,10 @@ class Entrepot extends CommonObject
     	//! Code Postal
     	public $zip;
     	public $town;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_parent;
     
     	// List of short language codes for status
    diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
    index 0d8338c4d9f..f5fad015636 100644
    --- a/htdocs/product/stock/class/mouvementstock.class.php
    +++ b/htdocs/product/stock/class/mouvementstock.class.php
    @@ -49,6 +49,10 @@ class MouvementStock extends CommonObject
     	public $tms = '';
     	public $datem = '';
     	public $price;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_author;
     
     	/**
    @@ -56,7 +60,11 @@ class MouvementStock extends CommonObject
          */
         public $label;
     
    +    /**
    +     * @var int ID
    +     */
     	public $fk_origin;
    +
     	public $origintype;
     	public $inventorycode;
     	public $batch;
    diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php
    index d7b77cd83ee..1530e068856 100644
    --- a/htdocs/product/stock/class/productlot.class.php
    +++ b/htdocs/product/stock/class/productlot.class.php
    @@ -63,14 +63,27 @@ class Productlot extends CommonObject
     	 */
     	public $entity;
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
    +
     	public $batch;
     	public $eatby = '';
     	public $sellby = '';
     	public $datec = '';
     	public $tms = '';
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
     	public $import_key;
     
     
    diff --git a/htdocs/product/stock/class/productstockentrepot.class.php b/htdocs/product/stock/class/productstockentrepot.class.php
    index 1ab24b553d8..6b12af88c7a 100644
    --- a/htdocs/product/stock/class/productstockentrepot.class.php
    +++ b/htdocs/product/stock/class/productstockentrepot.class.php
    @@ -51,8 +51,17 @@ class ProductStockEntrepot extends CommonObject
     	public $table_element = 'product_warehouse_properties';
     
     	public $tms = '';
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_product;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_entrepot;
    +
     	public $seuil_stock_alerte;
     	public $desiredstock;
     	public $import_key;
    
    From 7e6cdfb5ec178f7495370f3afe16be2e6b447110 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 09:34:54 +0200
    Subject: [PATCH 144/433] Standardize and update code
    
    ---
     htdocs/projet/class/task.class.php            | 17 +++++++++++++++++
     htdocs/resource/class/dolresource.class.php   |  5 +++++
     htdocs/societe/class/societe.class.php        | 13 +++++++++++++
     htdocs/societe/class/societeaccount.class.php |  9 +++++++++
     4 files changed, 44 insertions(+)
    
    diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
    index a3fd5fb1703..84829bf85cb 100644
    --- a/htdocs/projet/class/task.class.php
    +++ b/htdocs/projet/class/task.class.php
    @@ -49,6 +49,9 @@ class Task extends CommonObject
     	public $picto = 'task';
     	protected $childtables=array('projet_task_time');    // To test if we can delete object
     
    +	/**
    +     * @var int ID parent task
    +     */
         public $fk_task_parent;
     
         /**
    @@ -67,10 +70,24 @@ class Task extends CommonObject
     	public $date_start;
     	public $date_end;
     	public $progress;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_statut;
    +
     	public $priority;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_valid;
    +
     	public $rang;
     
     	public $timespent_min_date;
    diff --git a/htdocs/resource/class/dolresource.class.php b/htdocs/resource/class/dolresource.class.php
    index 1c04a5633ec..c6e25c4d837 100644
    --- a/htdocs/resource/class/dolresource.class.php
    +++ b/htdocs/resource/class/dolresource.class.php
    @@ -47,7 +47,12 @@ class Dolresource extends CommonObject
     	public $element_type;
     	public $busy;
     	public $mandatory;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_create;
    +
     	public $type_label;
     	public $tms='';
     
    diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
    index dbc51c93816..6343fcf0e91 100644
    --- a/htdocs/societe/class/societe.class.php
    +++ b/htdocs/societe/class/societe.class.php
    @@ -281,7 +281,12 @@ class Societe extends CommonObject
     	public $remise_supplier_percent;
     	public $mode_reglement_supplier_id;
     	public $cond_reglement_supplier_id;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_prospectlevel;
    +
     	public $name_bis;
     
     	//Log data
    @@ -449,12 +454,20 @@ class Societe extends CommonObject
     	public $array_options;
     
     	// Incoterms
    +	/**
    +     * @var int ID
    +     */
     	public $fk_incoterms;
    +
     	public $location_incoterms;
     	public $libelle_incoterms;  //Used into tooltip
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
     	public $fk_multicurrency;
    +
     	public $multicurrency_code;
     
     
    diff --git a/htdocs/societe/class/societeaccount.class.php b/htdocs/societe/class/societeaccount.class.php
    index bcb09675c3d..12a664f2686 100644
    --- a/htdocs/societe/class/societeaccount.class.php
    +++ b/htdocs/societe/class/societeaccount.class.php
    @@ -127,8 +127,17 @@ class SocieteAccount extends CommonObject
     	public $note_private;
     	public $date_creation;
     	public $tms;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_creat;
    +
    +	/**
    +     * @var int ID
    +     */
     	public $fk_user_modif;
    +
     	public $import_key;
     
     	/**
    
    From ded5c4c3ddb029ec73d5f0f269c3f58277ed113a Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 11:02:03 +0200
    Subject: [PATCH 145/433] Social network module
    
    ---
     htdocs/adherents/card.php                | 18 +++++-
     htdocs/contact/list.php                  | 38 +++++++++++-
     htdocs/core/actions_sendmails.inc.php    |  2 +-
     htdocs/core/class/commonobject.class.php | 17 +++++-
     htdocs/core/lib/functions.lib.php        | 67 +++++++++++----------
     htdocs/langs/en_US/admin.lang            |  6 +-
     htdocs/langs/en_US/boxes.lang            |  4 +-
     htdocs/langs/en_US/companies.lang        | 28 ++++-----
     htdocs/langs/en_US/mails.lang            |  8 +--
     htdocs/langs/en_US/main.lang             |  2 +-
     htdocs/societe/index.php                 |  2 +-
     htdocs/theme/eldy/style.css.php          |  3 +
     htdocs/theme/md/style.css.php            |  3 +
     htdocs/user/card.php                     | 74 +++++++++++++++++++++++-
     14 files changed, 204 insertions(+), 68 deletions(-)
    
    diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php
    index bc29c67c244..e9aa0f98146 100644
    --- a/htdocs/adherents/card.php
    +++ b/htdocs/adherents/card.php
    @@ -980,7 +980,7 @@ else
     		print '<tr><td>'.$langs->trans("PhoneMobile").'</td><td><input type="text" name="phone_mobile" size="20" value="'.(GETPOST('phone_mobile','alpha')?GETPOST('phone_mobile','alpha'):$object->phone_mobile).'"></td></tr>';
     
     	    // Skype
    -	    if (! empty($conf->skype->enabled))
    +	    if (! empty($conf->socialnetworks->enabled))
     	    {
     			print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="member_skype" size="40" value="'.(GETPOST('member_skype','alpha')?GETPOST('member_skype','alpha'):$object->skype).'"></td></tr>';
     	    }
    @@ -1218,12 +1218,24 @@ else
     		print '<tr><td>'.$langs->trans("PhoneMobile").'</td><td><input type="text" name="phone_mobile" size="20" value="'.(isset($_POST["phone_mobile"])?GETPOST("phone_mobile"):$object->phone_mobile).'"></td></tr>';
     
     	    // Skype
    -	    if (! empty($conf->skype->enabled))
    +	    if (! empty($conf->socialnetworks->enabled))
     	    {
     			    print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="skype" class="minwidth100" value="'.(isset($_POST["skype"])?GETPOST("skype"):$object->skype).'"></td></tr>';
     	    }
     
    -		// Birthday
    +	    // Twitter
    +	    if (! empty($conf->socialnetworks->enabled))
    +	    {
    +	    	print '<tr><td>'.$langs->trans("Twitter").'</td><td><input type="text" name="twitter" class="minwidth100" value="'.(isset($_POST["twitter"])?GETPOST("twitter"):$object->twitter).'"></td></tr>';
    +	    }
    +
    +	    // Facebook
    +	    if (! empty($conf->socialnetworks->enabled))
    +	    {
    +	    	print '<tr><td>'.$langs->trans("Facebook").'</td><td><input type="text" name="facebook" class="minwidth100" value="'.(isset($_POST["facebook"])?GETPOST("facebook"):$object->facebook).'"></td></tr>';
    +	    }
    +
    +	    // Birthday
     		print "<tr><td>".$langs->trans("Birthday")."</td><td>\n";
     		print $form->selectDate(($object->birth ? $object->birth : -1),'birth','','',1,'formsoc');
     		print "</td></tr>\n";
    diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php
    index 04132fa9b75..cd536118f8e 100644
    --- a/htdocs/contact/list.php
    +++ b/htdocs/contact/list.php
    @@ -68,6 +68,8 @@ $search_phone_mobile=GETPOST("search_phone_mobile",'alpha');
     $search_fax=GETPOST("search_fax",'alpha');
     $search_email=GETPOST("search_email",'alpha');
     $search_skype=GETPOST("search_skype",'alpha');
    +$search_twitter=GETPOST("search_twitter",'alpha');
    +$search_facebook=GETPOST("search_facebook",'alpha');
     $search_priv=GETPOST("search_priv",'alpha');
     $search_categ=GETPOST("search_categ",'int');
     $search_categ_thirdparty=GETPOST("search_categ_thirdparty",'int');
    @@ -156,7 +158,9 @@ $arrayfields=array(
     	'p.phone_mobile'=>array('label'=>"PhoneMobile", 'checked'=>1),
     	'p.fax'=>array('label'=>"Fax", 'checked'=>0),
     	'p.email'=>array('label'=>"EMail", 'checked'=>1),
    -	'p.skype'=>array('label'=>"Skype", 'checked'=>1, 'enabled'=>(! empty($conf->skype->enabled))),
    +	'p.skype'=>array('label'=>"Skype", 'checked'=>1, 'enabled'=>(! empty($conf->socialnetworks->enabled))),
    +	'p.twitter'=>array('label'=>"Twitter", 'checked'=>1, 'enabled'=>(! empty($conf->socialnetworks->enabled))),
    +	'p.facebook'=>array('label'=>"Facebook", 'checked'=>1, 'enabled'=>(! empty($conf->socialnetworks->enabled))),
     	'p.thirdparty'=>array('label'=>"ThirdParty", 'checked'=>1, 'enabled'=>empty($conf->global->SOCIETE_DISABLE_CONTACTS)),
     	'p.priv'=>array('label'=>"ContactVisibility", 'checked'=>1, 'position'=>200),
     	'p.datec'=>array('label'=>"DateCreationShort", 'checked'=>0, 'position'=>500),
    @@ -217,6 +221,8 @@ if (empty($reshook))
     		$search_fax="";
     		$search_email="";
     		$search_skype="";
    +		$search_twitter="";
    +		$search_facebook="";
     		$search_priv="";
     		$search_status=-1;
     		$search_categ='';
    @@ -311,6 +317,8 @@ if (strlen($search_phone_pro))      $sql.= natural_search('p.phone', $search_pho
     if (strlen($search_phone_mobile))   $sql.= natural_search('p.phone_mobile', $search_phone_mobile);
     if (strlen($search_fax))            $sql.= natural_search('p.fax', $search_fax);
     if (strlen($search_skype))          $sql.= natural_search('p.skype', $search_skype);
    +if (strlen($search_twitter))        $sql.= natural_search('p.twitter', $search_twitter);
    +if (strlen($search_facebook))       $sql.= natural_search('p.facebook', $search_facebook);
     if (strlen($search_email))          $sql.= natural_search('p.email', $search_email);
     if (strlen($search_zip))   			$sql.= natural_search("p.zip",$search_zip);
     if ($search_status != '' && $search_status >= 0) $sql.= " AND p.statut = ".$db->escape($search_status);
    @@ -601,6 +609,18 @@ if (! empty($arrayfields['p.skype']['checked']))
     	print '<input class="flat" type="text" name="search_skype" size="6" value="'.dol_escape_htmltag($search_skype).'">';
     	print '</td>';
     }
    +if (! empty($arrayfields['p.twitter']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat" type="text" name="search_twitter" size="6" value="'.dol_escape_htmltag($search_twitter).'">';
    +	print '</td>';
    +}
    +if (! empty($arrayfields['p.facebook']['checked']))
    +{
    +	print '<td class="liste_titre">';
    +	print '<input class="flat" type="text" name="search_facebook" size="6" value="'.dol_escape_htmltag($search_facebook).'">';
    +	print '</td>';
    +}
     if (! empty($arrayfields['p.thirdparty']['checked']))
     {
     	print '<td class="liste_titre">';
    @@ -671,6 +691,8 @@ if (! empty($arrayfields['p.phone_mobile']['checked']))        print_liste_field
     if (! empty($arrayfields['p.fax']['checked']))                 print_liste_field_titre($arrayfields['p.fax']['label'],$_SERVER["PHP_SELF"],"p.fax", $begin, $param, '', $sortfield,$sortorder);
     if (! empty($arrayfields['p.email']['checked']))               print_liste_field_titre($arrayfields['p.email']['label'],$_SERVER["PHP_SELF"],"p.email", $begin, $param, '', $sortfield,$sortorder);
     if (! empty($arrayfields['p.skype']['checked']))               print_liste_field_titre($arrayfields['p.skype']['label'],$_SERVER["PHP_SELF"],"p.skype", $begin, $param, '', $sortfield,$sortorder);
    +if (! empty($arrayfields['p.twitter']['checked']))             print_liste_field_titre($arrayfields['p.twitter']['label'],$_SERVER["PHP_SELF"],"p.twitter", $begin, $param, '', $sortfield,$sortorder);
    +if (! empty($arrayfields['p.facebook']['checked']))            print_liste_field_titre($arrayfields['p.facebook']['label'],$_SERVER["PHP_SELF"],"p.facebook", $begin, $param, '', $sortfield,$sortorder);
     if (! empty($arrayfields['p.thirdparty']['checked']))          print_liste_field_titre($arrayfields['p.thirdparty']['label'],$_SERVER["PHP_SELF"],"s.nom", $begin, $param, '', $sortfield,$sortorder);
     if (! empty($arrayfields['p.priv']['checked']))                print_liste_field_titre($arrayfields['p.priv']['label'],$_SERVER["PHP_SELF"],"p.priv", $begin, $param, 'align="center"', $sortfield,$sortorder);
     // Extra fields
    @@ -801,7 +823,19 @@ while ($i < min($num,$limit))
     	// Skype
     	if (! empty($arrayfields['p.skype']['checked']))
     	{
    -		if (! empty($conf->skype->enabled)) { print '<td>'.dol_print_skype($obj->skype,$obj->rowid,$obj->socid,'AC_SKYPE',18).'</td>'; }
    +		if (! empty($conf->socialnetworks->enabled)) { print '<td>'.dol_print_socialnetworks($obj->skype,$obj->rowid,$obj->socid,'skype').'</td>'; }
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Twitter
    +	if (! empty($arrayfields['p.twitter']['checked']))
    +	{
    +		if (! empty($conf->socialnetworks->enabled)) { print '<td>'.dol_print_socialnetworks($obj->twitter,$obj->rowid,$obj->socid,'twitter').'</td>'; }
    +		if (! $i) $totalarray['nbfield']++;
    +	}
    +	// Facebook
    +	if (! empty($arrayfields['p.facebook']['checked']))
    +	{
    +		if (! empty($conf->socialnetworks->enabled)) { print '<td>'.dol_print_socialnetworks($obj->facebook,$obj->rowid,$obj->socid,'facebook').'</td>'; }
     		if (! $i) $totalarray['nbfield']++;
     	}
     	// Company
    diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php
    index 6afd6b1e354..153c5ca9364 100644
    --- a/htdocs/core/actions_sendmails.inc.php
    +++ b/htdocs/core/actions_sendmails.inc.php
    @@ -425,7 +425,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
     					    if (empty($actiontypecode)) $actiontypecode='AC_OTH_AUTO'; // Event insert into agenda automatically
     
     						$object->socid			= $sendtosocid;	   // To link to a company
    -						$object->sendtoid		= $sendtoid;	   // To link to contacts/addresses. This is an array.
    +						$object->sendtoid		= $sendtoid;	   // To link to contact addresses. This is an array.
     						$object->actiontypecode	= $actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
     						$object->actionmsg		= $actionmsg;      // Long text
     						$object->actionmsg2		= $actionmsg2;     // Short text
    diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
    index a11cd3dd49e..76e2b1a093a 100644
    --- a/htdocs/core/class/commonobject.class.php
    +++ b/htdocs/core/class/commonobject.class.php
    @@ -609,12 +609,23 @@ abstract class CommonObject
     			$out.=dol_print_url($this->url,'_goout',0,1);
     			$outdone++;
     		}
    -		if (! empty($conf->skype->enabled))
    +		$out.='<div style="clear: both;">';
    +		if (! empty($conf->socialnetworks->enabled))
     		{
    -			$out.='<div style="clear: both;"></div>';
    -			if ($this->skype) $out.=dol_print_skype($this->skype,$this->id,$object->id,'AC_SKYPE');
    +			if ($this->skype) $out.=dol_print_socialnetworks($this->skype,$this->id,$object->id,'skype');
     			$outdone++;
     		}
    +		if (! empty($conf->socialnetworks->enabled))
    +		{
    +			if ($this->twitter) $out.=dol_print_socialnetworks($this->twitter,$this->id,$object->id,'twitter');
    +			$outdone++;
    +		}
    +		if (! empty($conf->socialnetworks->enabled))
    +		{
    +			if ($this->facebook) $out.=dol_print_socialnetworks($this->facebook,$this->id,$object->id,'facebook');
    +			$outdone++;
    +		}
    +		$out.='</div>';
     
     		$out.='<!-- END Part to show address block -->';
     
    diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
    index 4424d3fa904..8883d1ad89c 100644
    --- a/htdocs/core/lib/functions.lib.php
    +++ b/htdocs/core/lib/functions.lib.php
    @@ -2189,50 +2189,52 @@ function dol_print_email($email,$cid=0,$socid=0,$addlink=0,$max=64,$showinvalid=
     }
     
     /**
    - * Show Skype link
    + * Show social network link
      *
    - * @param	string		$skype			Skype to show (only skype, without 'Name of recipient' before)
    + * @param	string		$value			Skype to show (only skype, without 'Name of recipient' before)
      * @param	int 		$cid 			Id of contact if known
      * @param	int 		$socid 			Id of third party if known
    - * @param	int 		$addlink		0=no link to create action
    - * @param	int			$max			Max number of characters to show
    + * @param	string 		$type			'skype','facebook',...
      * @return	string						HTML Link
      */
    -function dol_print_skype($skype,$cid=0,$socid=0,$addlink=0,$max=64)
    +function dol_print_socialnetworks($value,$cid,$socid,$type)
     {
     	global $conf,$user,$langs;
     
    -	$newskype=$skype;
    +	$newskype=$value;
     
    -	if (empty($skype)) return '&nbsp;';
    +	if (empty($value)) return '&nbsp;';
     
    -	if (! empty($addlink))
    +	if (! empty($type))
     	{
    -		$newskype =img_picto($langs->trans("Skype"), 'object_skype.png');
    -		$newskype.= '&nbsp;';
    -		$newskype.=dol_trunc($skype,$max);
    -		$newskype.= '&nbsp;';
    -		$newskype.='<a href="skype:';
    -		$newskype.=dol_trunc($skype,$max);
    -		$newskype.='?call" alt="'.$langs->trans("Call").'&nbsp;'.$skype.'" title="'.$langs->trans("Call").'&nbsp;'.$skype.'">';
    -		$newskype.='<img src="'.DOL_URL_ROOT.'/theme/common/skype_callbutton.png" border="0">';
    -		$newskype.='</a>&nbsp;&nbsp;&nbsp;<a href="skype:';
    -		$newskype.=dol_trunc($skype,$max);
    -		$newskype.='?chat" alt="'.$langs->trans("Chat").'&nbsp;'.$skype.'" title="'.$langs->trans("Chat").'&nbsp;'.$skype.'">';
    -		$newskype.='<img src="'.DOL_URL_ROOT.'/theme/common/skype_chatbutton.png" border="0">';
    -		$newskype.='</a>';
    -
    -		if (($cid || $socid) && ! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create)
    +		$newskype ='<div class="divsocialnetwork inline-block valignmiddle">';
    +		$newskype.=img_picto($langs->trans(strtoupper($type)), $type.'.png', '', false, 0, 0, '', 'paddingright');
    +		$newskype.=$value;
    +		if ($type == 'skype')
     		{
    -			$type='AC_SKYPE'; $link='';
    -			if (! empty($conf->global->AGENDA_ADDACTIONFORSKYPE)) $link='<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&amp;backtopage=1&amp;actioncode='.$type.'&amp;contactid='.$cid.'&amp;socid='.$socid.'">'.img_object($langs->trans("AddAction"),"calendar").'</a>';
    -			$newskype='<div class="divskype nowrap">'.$newskype.($link?' '.$link:'').'</div>';
    +			$newskype.= '&nbsp;';
    +			$newskype.='<a href="skype:';
    +			$newskype.=$value;
    +			$newskype.='?call" alt="'.$langs->trans("Call").'&nbsp;'.$value.'" title="'.$langs->trans("Call").'&nbsp;'.$value.'">';
    +			$newskype.='<img src="'.DOL_URL_ROOT.'/theme/common/skype_callbutton.png" border="0">';
    +			$newskype.='</a><a href="skype:';
    +			$newskype.=$value;
    +			$newskype.='?chat" alt="'.$langs->trans("Chat").'&nbsp;'.$value.'" title="'.$langs->trans("Chat").'&nbsp;'.$value.'">';
    +			$newskype.='<img class="paddingleft" src="'.DOL_URL_ROOT.'/theme/common/skype_chatbutton.png" border="0">';
    +			$newskype.='</a>';
     		}
    +		if (($cid || $socid) && ! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create && $type=='skype')
    +		{
    +			$addlink='AC_SKYPE'; $link='';
    +			if (! empty($conf->global->AGENDA_ADDACTIONFORSKYPE)) $link='<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&amp;backtopage=1&amp;actioncode='.$addlink.'&amp;contactid='.$cid.'&amp;socid='.$socid.'">'.img_object($langs->trans("AddAction"),"calendar").'</a>';
    +			$newskype.=($link?' '.$link:'');
    +		}
    +		$newskype.='</div>';
     	}
     	else
     	{
     		$langs->load("errors");
    -		$newskype.=img_warning($langs->trans("ErrorBadSkype",$skype));
    +		$newskype.=img_warning($langs->trans("ErrorBadSocialNetworkValue",$value));
     	}
     	return $newskype;
     }
    @@ -3151,11 +3153,13 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
     		//if (in_array($picto, array('switch_off', 'switch_on', 'off', 'on')))
     		if (empty($srconly) && in_array($pictowithoutext, array(
     				'bank', 'close_title', 'delete', 'edit', 'ellipsis-h', 'filter', 'grip', 'grip_title', 'list', 'listlight', 'off', 'on', 'play', 'playdisabled', 'printer', 'resize',
    -				'note','switch_off', 'switch_on', 'unlink', 'uparrow', '1downarrow', '1uparrow')
    -			)) {
    +				'note','switch_off', 'switch_on', 'unlink', 'uparrow', '1downarrow', '1uparrow',
    +				'skype','twitter','facebook'
    +			)
    +		)) {
     			$fakey = $pictowithoutext;
     			$facolor = ''; $fasize = '';
    -			$marginleftonlyshort = 0;
    +			$marginleftonlyshort = 2;
     			if ($pictowithoutext == 'switch_off') {
     				$fakey = 'fa-toggle-off';
     				$facolor = '#999';
    @@ -3237,12 +3241,13 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
     			else {
     				$fakey = 'fa-'.$pictowithoutext;
     				$facolor = '#444';
    +				$marginleftonlyshort=0;
     			}
     
     			if (preg_match('/class="([^"]+)"/', $moreatt, $reg)) {
     				$morecss.= ($morecss?' ':'').$reg[1];
     			}
    -			$enabledisablehtml = '<span class="fa '.$fakey.' '.($marginleftonlyshort?'marginleftonlyshort':'marginleftonly').' valignmiddle'.($morecss?' '.$morecss:'').'" style="'.($fasize?('font-size: '.$fasize.';'):'').($facolor?(' color: '.$facolor.';'):'').'" alt="'.dol_escape_htmltag($titlealt).'"'.(($notitle || empty($title))?'':' title="'.dol_escape_htmltag($title).'"').($moreatt?' '.$moreatt:'').'>';
    +			$enabledisablehtml = '<span class="fa '.$fakey.' '.($marginleftonlyshort?($marginleftonlyshort==1?'marginleftonlyshort':'marginleftonly'):'').' valignmiddle'.($morecss?' '.$morecss:'').'" style="'.($fasize?('font-size: '.$fasize.';'):'').($facolor?(' color: '.$facolor.';'):'').'" alt="'.dol_escape_htmltag($titlealt).'"'.(($notitle || empty($title))?'':' title="'.dol_escape_htmltag($title).'"').($moreatt?' '.$moreatt:'').'>';
     			if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
     				$enabledisablehtml.= $titlealt;
     			}
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index 9d9abd92f4c..d4665bb4ccd 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -898,7 +898,7 @@ DictionaryVAT=VAT Rates or Sales Tax Rates
     DictionaryRevenueStamp=Amount of tax stamps
     DictionaryPaymentConditions=Payment terms
     DictionaryPaymentModes=Payment modes
    -DictionaryTypeContact=Contact/Address types
    +DictionaryTypeContact=Contact address types
     DictionaryTypeOfContainer=Type of website pages/containers
     DictionaryEcotaxe=Ecotax (WEEE)
     DictionaryPaperFormat=Paper formats
    @@ -1137,7 +1137,7 @@ ExtraFieldsLinesRec=Complementary attributes (templates invoices lines)
     ExtraFieldsSupplierOrdersLines=Complementary attributes (order lines)
     ExtraFieldsSupplierInvoicesLines=Complementary attributes (invoice lines)
     ExtraFieldsThirdParties=Complementary attributes (thirdparty)
    -ExtraFieldsContacts=Complementary attributes (contact/address)
    +ExtraFieldsContacts=Complementary attributes (contact address)
     ExtraFieldsMember=Complementary attributes (member)
     ExtraFieldsMemberType=Complementary attributes (member type)
     ExtraFieldsCustomerInvoices=Complementary attributes (invoices)
    @@ -1695,7 +1695,7 @@ ListOfNotificationsPerUser=List of notifications per user*
     ListOfNotificationsPerUserOrContact=List of notifications per user* or per contact**
     ListOfFixedNotifications=List of fixed notifications
     GoOntoUserCardToAddMore=Go on the tab "Notifications" of a user to add or remove notifications for users
    -GoOntoContactCardToAddMore=Go on the tab "Notifications" of a third party to add or remove notifications for contacts/addresses
    +GoOntoContactCardToAddMore=Go on the tab "Notifications" of a third party to add or remove notifications for contact addresses
     Threshold=Threshold
     BackupDumpWizard=Wizard to build database backup dump file
     SomethingMakeInstallFromWebNotPossible=Installation of external module is not possible from the web interface for the following reason:
    diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang
    index 4254c2cacaf..cc46e702a75 100644
    --- a/htdocs/langs/en_US/boxes.lang
    +++ b/htdocs/langs/en_US/boxes.lang
    @@ -15,7 +15,7 @@ BoxLastSuppliers=Latest modified suppliers
     BoxLastCustomerOrders=Latest customer orders
     BoxLastActions=Latest actions
     BoxLastContracts=Latest contracts
    -BoxLastContacts=Latest contacts/addresses
    +BoxLastContacts=Latest contact addresses
     BoxLastMembers=Latest members
     BoxFicheInter=Latest interventions
     BoxCurrentAccounts=Open accounts balance
    @@ -34,7 +34,7 @@ BoxTitleLastFicheInter=Latest %s modified interventions
     BoxTitleOldestUnpaidCustomerBills=Customer Invoices: oldest %s unpaid
     BoxTitleOldestUnpaidSupplierBills=Supplier Invoices: oldest %s unpaid
     BoxTitleCurrentAccounts=Open Accounts: balances
    -BoxTitleLastModifiedContacts=Contacts/Addresses: latest %s modified
    +BoxTitleLastModifiedContacts=Contact addresses: latest %s modified
     BoxMyLastBookmarks=Bookmarks: latest %s modified
     BoxOldestExpiredServices=Oldest active expired services
     BoxLastExpiredServices=Latest %s oldest contacts with active expired services
    diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang
    index fbdd9685975..ef0328b9349 100644
    --- a/htdocs/langs/en_US/companies.lang
    +++ b/htdocs/langs/en_US/companies.lang
    @@ -3,7 +3,7 @@ ErrorCompanyNameAlreadyExists=Company name %s already exists. Choose another one
     ErrorSetACountryFirst=Set the country first
     SelectThirdParty=Select a third party
     ConfirmDeleteCompany=Are you sure you want to delete this company and all inherited information?
    -DeleteContact=Delete a contact/address
    +DeleteContact=Delete a contact address
     ConfirmDeleteContact=Are you sure you want to delete this contact and all inherited information?
     MenuNewThirdParty=New Third Party
     MenuNewCustomer=New Customer
    @@ -19,9 +19,9 @@ ProspectionArea=Prospection area
     IdThirdParty=Id third party
     IdCompany=Company Id
     IdContact=Contact Id
    -Contacts=Contacts/Addresses
    -ThirdPartyContacts=Third party contacts
    -ThirdPartyContact=Third party contact/address
    +Contacts=Contact addresses
    +ThirdPartyContacts=Third party contact addresses
    +ThirdPartyContact=Third party contact address
     Company=Company
     CompanyName=Company name
     AliasNames=Alias name (commercial, trademark, ...)
    @@ -40,7 +40,7 @@ ThirdPartyCustomersWithIdProf12=Customers with %s or %s
     ThirdPartySuppliers=Vendors
     ThirdPartyType=Type of company
     Individual=Private individual
    -ToCreateContactWithSameName=Will create automatically a contact/address with same information as the third party under the third party. In most cases, even if your third party is a physical person, creating a third party alone is enough.
    +ToCreateContactWithSameName=Will create automatically a contact address with same information as the third party under the third party. In most cases, even if your third party is a physical person, creating a third party alone is enough.
     ParentCompany=Parent company
     Subsidiaries=Subsidiaries
     ReportByMonth=Report by month
    @@ -289,16 +289,16 @@ SupplierAbsoluteDiscountMy=Absolute vendor discounts (entered by yourself)
     DiscountNone=None
     Supplier=Vendor
     AddContact=Create contact
    -AddContactAddress=Create contact/address
    +AddContactAddress=Create contact address
     EditContact=Edit contact
    -EditContactAddress=Edit contact/address
    +EditContactAddress=Edit contact address
     Contact=Contact
     ContactId=Contact id
    -ContactsAddresses=Contacts/Addresses
    +ContactsAddresses=Contact addresses
     FromContactName=Name:
     NoContactDefinedForThirdParty=No contact defined for this third party
     NoContactDefined=No contact defined
    -DefaultContact=Default contact/address
    +DefaultContact=Default contact address
     AddThirdParty=Create third party
     DeleteACompany=Delete a company
     PersonalInformations=Personal data
    @@ -315,8 +315,8 @@ ValidityControledByModule=Validity controlled by module
     ThisIsModuleRules=This is rules for this module
     ProspectToContact=Prospect to contact
     CompanyDeleted=Company "%s" deleted from database.
    -ListOfContacts=List of contacts/addresses
    -ListOfContactsAddresses=List of contacts/addresses
    +ListOfContacts=List of contact addresses
    +ListOfContactsAddresses=List of contact addresses
     ListOfThirdParties=List of Third Parties
     ShowCompany=Show Third Party
     ShowContact=Show contact
    @@ -333,7 +333,7 @@ NoContactForAnyProposal=This contact is not a contact for any commercial proposa
     NoContactForAnyContract=This contact is not a contact for any contract
     NoContactForAnyInvoice=This contact is not a contact for any invoice
     NewContact=New contact
    -NewContactAddress=New Contact/Address
    +NewContactAddress=New Contact address
     MyContacts=My contacts
     Capital=Capital
     CapitalOf=Capital of %s
    @@ -390,7 +390,7 @@ NoDolibarrAccess=No Dolibarr access
     ExportDataset_company_1=Third Parties (companies/foundations/physical people) and their properties
     ExportDataset_company_2=Contacts and their properties
     ImportDataset_company_1=Third Parties (companies/foundations/physical people) and their properties
    -ImportDataset_company_2=Contacts/Addresses and attributes
    +ImportDataset_company_2=Contact addresses and attributes
     ImportDataset_company_3=Bank accounts of Third Parties
     ImportDataset_company_4=Third Parties - sales representatives (assign sales representatives/users to companies)
     PriceLevel=Price level
    @@ -409,7 +409,7 @@ YouMustCreateContactFirst=To be able to add email notifications, you must first
     ListSuppliersShort=List of Vendors
     ListProspectsShort=List of Prospects
     ListCustomersShort=List of Customers
    -ThirdPartiesArea=Third Parties/Contacts
    +ThirdPartiesArea=Third Parties and Contacts addresses area
     LastModifiedThirdParties=Last %s modified Third Parties
     UniqueThirdParties=Total of Third Parties
     InActivity=Open
    diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang
    index 8f9c49d8bff..6c6b31db764 100644
    --- a/htdocs/langs/en_US/mails.lang
    +++ b/htdocs/langs/en_US/mails.lang
    @@ -99,7 +99,7 @@ MailSelectedRecipients=Selected recipients
     MailingArea=EMailings area
     LastMailings=Latest %s emailings
     TargetsStatistics=Targets statistics
    -NbOfCompaniesContacts=Unique contacts/addresses
    +NbOfCompaniesContacts=Unique contact addresses
     MailNoChangePossible=Recipients for validated emailing can't be changed
     SearchAMailing=Search mailing
     SendMailing=Send emailing
    @@ -138,7 +138,7 @@ NbOfTargetedContacts=Current number of targeted contact emails
     UseFormatFileEmailToTarget=Imported file must have format <strong>email;name;firstname;other</strong>
     UseFormatInputEmailToTarget=Enter a string with format <strong>email;name;firstname;other</strong>
     MailAdvTargetRecipients=Recipients (advanced selection)
    -AdvTgtTitle=Fill input fields to preselect the third parties or contacts/addresses to target
    +AdvTgtTitle=Fill input fields to preselect the third parties or contact addresses to target
     AdvTgtSearchTextHelp=Use %% as wildcards. For example to find all item like <b>jean, joe, jim</b>, you can input <b>j%%</b>, you can also use ; as separator for value, and use ! for except this value. For example  <b>jean;joe;jim%%;!jimo;!jima%</b> will target all jean, joe, start with jim but not jimo and not everything that starts with jima
     AdvTgtSearchIntHelp=Use interval to select int or float value
     AdvTgtMinVal=Minimum value
    @@ -159,8 +159,8 @@ AdvTgtDeleteFilter=Delete filter
     AdvTgtSaveFilter=Save filter
     AdvTgtCreateFilter=Create filter
     AdvTgtOrCreateNewFilter=Name of new filter
    -NoContactWithCategoryFound=No contact/address with a category found
    -NoContactLinkedToThirdpartieWithCategoryFound=No contact/address with a category found
    +NoContactWithCategoryFound=No contact address with a category found
    +NoContactLinkedToThirdpartieWithCategoryFound=No contact address with a category found
     OutGoingEmailSetup=Outgoing email setup
     InGoingEmailSetup=Incoming email setup
     OutGoingEmailSetupForEmailing=Outgoing email setup (for mass emailing)
    diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
    index b1c51659b07..5a017330f20 100644
    --- a/htdocs/langs/en_US/main.lang
    +++ b/htdocs/langs/en_US/main.lang
    @@ -434,7 +434,7 @@ LatestLinkedEvents=Latest %s linked events
     CompanyFoundation=Company/Organization
     Accountant=Accountant
     ContactsForCompany=Contacts for this third party
    -ContactsAddressesForCompany=Contacts/addresses for this third party
    +ContactsAddressesForCompany=Contact addresses for this third party
     AddressesForCompany=Addresses for this third party
     ActionsOnCompany=Events about this third party
     ActionsOnMember=Events about this member
    diff --git a/htdocs/societe/index.php b/htdocs/societe/index.php
    index f53a9042fca..0759008c435 100644
    --- a/htdocs/societe/index.php
    +++ b/htdocs/societe/index.php
    @@ -1,6 +1,6 @@
     <?php
     /* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2015 Laurent Destailleur  <eldy@users.sourceforge.net>
    + * Copyright (C) 2004-2018 Laurent Destailleur  <eldy@users.sourceforge.net>
      * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
      * Copyright (C) 2014      Charles-Fr Benke	    <charles.fr@benke.fr>
      * Copyright (C) 2015      Jean-François Ferry	<jfefe@aternatik.fr>
    diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
    index 82f50a5771c..bb43aa0af55 100644
    --- a/htdocs/theme/eldy/style.css.php
    +++ b/htdocs/theme/eldy/style.css.php
    @@ -696,6 +696,9 @@ textarea.centpercent {
     	height: 28px;
     	vertical-align: middle;
     }
    +.divsocialnetwork:not(:first-child) {
    +    padding-left: 20px;
    +}
     div.divsearchfield {
     	float: <?php print $left; ?>;
     	margin-<?php print $right; ?>: 12px;
    diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
    index 23575680acf..b347d305dd9 100644
    --- a/htdocs/theme/md/style.css.php
    +++ b/htdocs/theme/md/style.css.php
    @@ -689,6 +689,9 @@ textarea.centpercent {
     	height: 28px;
     	vertical-align: middle;
     }
    +.divsocialnetwork:not(:first-child) {
    +    padding-left: 20px;
    +}
     div.divsearchfield {
     	float: <?php print $left; ?>;
     	margin-<?php print $right; ?>: 12px;
    diff --git a/htdocs/user/card.php b/htdocs/user/card.php
    index 888550a6408..9dee03e87c6 100644
    --- a/htdocs/user/card.php
    +++ b/htdocs/user/card.php
    @@ -1000,7 +1000,7 @@ if ($action == 'create' || $action == 'adduserldap')
     	print '</td></tr>';
     
     	// Skype
    -	if (! empty($conf->skype->enabled))
    +	if (! empty($conf->socialnetworks->enabled))
     	{
     		print '<tr><td>'.$langs->trans("Skype").'</td>';
     		print '<td>';
    @@ -1011,7 +1011,41 @@ if ($action == 'create' || $action == 'adduserldap')
     		}
     		else
     		{
    -			print '<input class="maxwidth200" type="text" name="skype" value="'.GETPOST('skype').'">';
    +			print '<input class="maxwidth200" type="text" name="skype" value="'.GETPOST('skype','alpha').'">';
    +		}
    +		print '</td></tr>';
    +	}
    +
    +	// Twitter
    +	if (! empty($conf->socialnetworks->enabled))
    +	{
    +		print '<tr><td>'.$langs->trans("Twitter").'</td>';
    +		print '<td>';
    +		if (! empty($ldap_twitter))
    +		{
    +			print '<input type="hidden" name="skype" value="'.$ldap_twitter.'">';
    +			print $ldap_twitter;
    +		}
    +		else
    +		{
    +			print '<input class="maxwidth200" type="text" name="twitter" value="'.GETPOST('twitter','alpha').'">';
    +		}
    +		print '</td></tr>';
    +	}
    +
    +	// Facebook
    +	if (! empty($conf->socialnetworks->enabled))
    +	{
    +		print '<tr><td>'.$langs->trans("Facebook").'</td>';
    +		print '<td>';
    +		if (! empty($ldap_facebook))
    +		{
    +			print '<input type="hidden" name="skype" value="'.$ldap_facebook.'">';
    +			print $ldap_facebook;
    +		}
    +		else
    +		{
    +			print '<input class="maxwidth200" type="text" name="facebook" value="'.GETPOST('facebook','alpha').'">';
     		}
     		print '</td></tr>';
     	}
    @@ -2195,7 +2229,7 @@ else
     			print '</td></tr>';
     
     			// Skype
    -			if (! empty($conf->skype->enabled))
    +			if (! empty($conf->socialnetworks->enabled))
     			{
     				print '<tr><td>'.$langs->trans("Skype").'</td>';
     				print '<td>';
    @@ -2211,6 +2245,40 @@ else
     				print '</td></tr>';
     			}
     
    +			// Twitter
    +			if (! empty($conf->socialnetworks->enabled))
    +			{
    +				print '<tr><td>'.$langs->trans("Twitter").'</td>';
    +				print '<td>';
    +				if ($caneditfield  && empty($object->ldap_sid))
    +				{
    +					print '<input size="40" type="text" name="twitter" class="flat" value="'.$object->twitter.'">';
    +				}
    +				else
    +				{
    +					print '<input type="hidden" name="twitter" value="'.$object->twitter.'">';
    +					print $object->twitter;
    +				}
    +				print '</td></tr>';
    +			}
    +
    +			// Skype
    +			if (! empty($conf->socialnetworks->enabled))
    +			{
    +				print '<tr><td>'.$langs->trans("Facebook").'</td>';
    +				print '<td>';
    +				if ($caneditfield  && empty($object->ldap_sid))
    +				{
    +					print '<input size="40" type="text" name="facebook" class="flat" value="'.$object->facebook.'">';
    +				}
    +				else
    +				{
    +					print '<input type="hidden" name="facebook" value="'.$object->facebook.'">';
    +					print $object->facebook;
    +				}
    +				print '</td></tr>';
    +			}
    +
     			// EMail
     			print "<tr>".'<td'.(! empty($conf->global->USER_MAIL_REQUIRED)?' class="fieldrequired"':'').'>'.$langs->trans("EMail").'</td>';
     			print '<td>';
    
    From cb53e18aa49db8b8b53460c80aeca3015d9596ba Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 11:12:29 +0200
    Subject: [PATCH 146/433] Social network module
    
    ---
     htdocs/adherents/card.php                 | 24 +++++++++++++++++++++--
     htdocs/adherents/class/adherent.class.php | 21 ++++++++++++++++++--
     htdocs/user/card.php                      | 10 ++++++++--
     3 files changed, 49 insertions(+), 6 deletions(-)
    
    diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php
    index e9aa0f98146..908a46c91d1 100644
    --- a/htdocs/adherents/card.php
    +++ b/htdocs/adherents/card.php
    @@ -301,6 +301,8 @@ if (empty($reshook))
     			$object->phone_mobile= trim(GETPOST("phone_mobile",'alpha'));
     			$object->email       = preg_replace('/\s+/', '', GETPOST("member_email",'alpha'));
     			$object->skype       = trim(GETPOST("skype",'alpha'));
    +			$object->twitter     = trim(GETPOST("twitter",'alpha'));
    +			$object->facebook    = trim(GETPOST("facebook",'alpha'));
     			$object->birth       = $birthdate;
     
     			$object->typeid      = GETPOST("typeid",'int');
    @@ -443,6 +445,8 @@ if (empty($reshook))
     		$phone_perso=GETPOST("phone_perso",'alpha');
     		$phone_mobile=GETPOST("phone_mobile",'alpha');
     		$skype=GETPOST("member_skype",'alpha');
    +		$twitter=GETPOST("member_twitter",'alpha');
    +		$facebook=GETPOST("member_facebook",'alpha');
     		$email=preg_replace('/\s+/', '', GETPOST("member_email",'alpha'));
     		$login=GETPOST("member_login",'alpha');
     		$pass=GETPOST("password",'alpha');
    @@ -467,7 +471,11 @@ if (empty($reshook))
     		$object->phone       = $phone;
     		$object->phone_perso = $phone_perso;
     		$object->phone_mobile= $phone_mobile;
    +
     		$object->skype       = $skype;
    +		$object->twitter     = $twitter;
    +		$object->facebook    = $facebook;
    +
     		$object->email       = $email;
     		$object->login       = $login;
     		$object->pass        = $pass;
    @@ -985,7 +993,19 @@ else
     			print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="member_skype" size="40" value="'.(GETPOST('member_skype','alpha')?GETPOST('member_skype','alpha'):$object->skype).'"></td></tr>';
     	    }
     
    -		// Birthday
    +	    // Twitter
    +	    if (! empty($conf->socialnetworks->enabled))
    +	    {
    +	    	print '<tr><td>'.$langs->trans("Twitter").'</td><td><input type="text" name="member_twitter" size="40" value="'.(GETPOST('member_twitter','alpha')?GETPOST('member_twitter','alpha'):$object->twitter).'"></td></tr>';
    +	    }
    +
    +	    // Facebook
    +	    if (! empty($conf->socialnetworks->enabled))
    +	    {
    +	    	print '<tr><td>'.$langs->trans("Facebook").'</td><td><input type="text" name="member_facebook" size="40" value="'.(GETPOST('member_facebook','alpha')?GETPOST('member_facebook','alpha'):$object->facebook).'"></td></tr>';
    +	    }
    +
    +	    // Birthday
     		print "<tr><td>".$langs->trans("Birthday")."</td><td>\n";
     		print $form->selectDate(($object->birth ? $object->birth : -1),'birth','','',1,'formsoc');
     		print "</td></tr>\n";
    @@ -1220,7 +1240,7 @@ else
     	    // Skype
     	    if (! empty($conf->socialnetworks->enabled))
     	    {
    -			    print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="skype" class="minwidth100" value="'.(isset($_POST["skype"])?GETPOST("skype"):$object->skype).'"></td></tr>';
    +			print '<tr><td>'.$langs->trans("Skype").'</td><td><input type="text" name="skype" class="minwidth100" value="'.(isset($_POST["skype"])?GETPOST("skype"):$object->skype).'"></td></tr>';
     	    }
     
     	    // Twitter
    diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php
    index 21f6c3407d9..888e3043de1 100644
    --- a/htdocs/adherents/class/adherent.class.php
    +++ b/htdocs/adherents/class/adherent.class.php
    @@ -88,7 +88,11 @@ class Adherent extends CommonObject
     	public $state;                 // Label of department
     
     	public $email;
    +
     	public $skype;
    +	public $twitter;
    +	public $facebook;
    +
     	public $phone;
     	public $phone_perso;
     	public $phone_mobile;
    @@ -468,6 +472,8 @@ class Adherent extends CommonObject
     		$sql.= ", state_id = ".($this->state_id>0?$this->db->escape($this->state_id):"null");
     		$sql.= ", email = '".$this->db->escape($this->email)."'";
     		$sql.= ", skype = '".$this->db->escape($this->skype)."'";
    +		$sql.= ", twitter = '".$this->db->escape($this->twitter)."'";
    +		$sql.= ", facebook = '".$this->db->escape($this->facebook)."'";
     		$sql.= ", phone = ".($this->phone?"'".$this->db->escape($this->phone)."'":"null");
     		$sql.= ", phone_perso = ".($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null");
     		$sql.= ", phone_mobile = ".($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null");
    @@ -574,6 +580,8 @@ class Adherent extends CommonObject
     
     						$luser->email=$this->email;
     						$luser->skype=$this->skype;
    +						$luser->twitter=$this->twitter;
    +						$luser->facebook=$this->facebook;
     						$luser->office_phone=$this->phone;
     						$luser->user_mobile=$this->phone_mobile;
     
    @@ -613,6 +621,8 @@ class Adherent extends CommonObject
     						$lthirdparty->town=$this->town;
     						$lthirdparty->email=$this->email;
     						$lthirdparty->skype=$this->skype;
    +						$lthirdparty->twitter=$this->twitter;
    +						$lthirdparty->facebook=$this->facebook;
     						$lthirdparty->phone=$this->phone;
     						$lthirdparty->state_id=$this->state_id;
     						$lthirdparty->country_id=$this->country_id;
    @@ -1100,7 +1110,7 @@ class Adherent extends CommonObject
     
     		$sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
     		$sql.= " d.note_public,";
    -		$sql.= " d.email, d.skype, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
    +		$sql.= " d.email, d.skype, d.twitter, d.facebook, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
     		$sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
     		$sql.= " d.datec as datec,";
     		$sql.= " d.tms as datem,";
    @@ -1172,7 +1182,10 @@ class Adherent extends CommonObject
     				$this->phone_perso		= $obj->phone_perso;
     				$this->phone_mobile		= $obj->phone_mobile;
     				$this->email			= $obj->email;
    +
     				$this->skype			= $obj->skype;
    +				$this->twitter			= $obj->twitter;
    +				$this->facebook			= $obj->facebook;
     
     				$this->photo			= $obj->photo;
     				$this->statut			= $obj->statut;
    @@ -2265,7 +2278,9 @@ class Adherent extends CommonObject
     		$this->country = 'France';
     		$this->morphy = 1;
     		$this->email = 'specimen@specimen.com';
    -		$this->skype = 'tom.hanson';
    +		$this->skype = 'skypepseudo';
    +		$this->twitter = 'twitterpseudo';
    +		$this->facebook = 'facebookpseudo';
     		$this->phone        = '0999999999';
     		$this->phone_perso  = '0999999998';
     		$this->phone_mobile = '0999999997';
    @@ -2372,6 +2387,8 @@ class Adherent extends CommonObject
     		if ($this->town && ! empty($conf->global->LDAP_MEMBER_FIELD_TOWN))						$info[$conf->global->LDAP_MEMBER_FIELD_TOWN] = $this->town;
     		if ($this->country_code && ! empty($conf->global->LDAP_MEMBER_FIELD_COUNTRY))			$info[$conf->global->LDAP_MEMBER_FIELD_COUNTRY] = $this->country_code;
     		if ($this->skype && ! empty($conf->global->LDAP_MEMBER_FIELD_SKYPE))					$info[$conf->global->LDAP_MEMBER_FIELD_SKYPE] = $this->skype;
    +		if ($this->twitter && ! empty($conf->global->LDAP_MEMBER_FIELD_TWITTER))				$info[$conf->global->LDAP_MEMBER_FIELD_TWITTER] = $this->twitter;
    +		if ($this->facebook && ! empty($conf->global->LDAP_MEMBER_FIELD_FACEBOOK))				$info[$conf->global->LDAP_MEMBER_FIELD_FACEBOOK] = $this->facebook;
     		if ($this->phone && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE))					$info[$conf->global->LDAP_MEMBER_FIELD_PHONE] = $this->phone;
     		if ($this->phone_perso && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO))		$info[$conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO] = $this->phone_perso;
     		if ($this->phone_mobile && ! empty($conf->global->LDAP_MEMBER_FIELD_MOBILE))			$info[$conf->global->LDAP_MEMBER_FIELD_MOBILE] = $this->phone_mobile;
    diff --git a/htdocs/user/card.php b/htdocs/user/card.php
    index 9dee03e87c6..cf733932129 100644
    --- a/htdocs/user/card.php
    +++ b/htdocs/user/card.php
    @@ -201,6 +201,8 @@ if (empty($reshook)) {
     			$object->office_fax = GETPOST("office_fax", 'alpha');
     			$object->user_mobile = GETPOST("user_mobile");
     			$object->skype = GETPOST("skype", 'alpha');
    +			$object->twitter = GETPOST("twitter", 'alpha');
    +			$object->facebook = GETPOST("facebook", 'alpha');
     			$object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha'));
     			$object->job = GETPOST("job", 'alpha');
     			$object->signature = GETPOST("signature");
    @@ -348,6 +350,8 @@ if (empty($reshook)) {
     				$object->office_fax = GETPOST("office_fax", 'alpha');
     				$object->user_mobile = GETPOST("user_mobile");
     				$object->skype = GETPOST("skype", 'alpha');
    +				$object->twitter = GETPOST("twitter", 'alpha');
    +				$object->facebook = GETPOST("facebook", 'alpha');
     				$object->email = preg_replace('/\s+/', '', GETPOST("email", 'alpha'));
     				$object->job = GETPOST("job", 'alpha');
     				$object->signature = GETPOST("signature",'none');
    @@ -588,6 +592,8 @@ if (empty($reshook)) {
     					$ldap_fax = $attribute[$conf->global->LDAP_FIELD_FAX];
     					$ldap_mobile = $attribute[$conf->global->LDAP_FIELD_MOBILE];
     					$ldap_skype = $attribute[$conf->global->LDAP_FIELD_SKYPE];
    +					$ldap_twitter = $attribute[$conf->global->LDAP_FIELD_TWITTER];
    +					$ldap_facebook = $attribute[$conf->global->LDAP_FIELD_FACEBOOK];
     					$ldap_mail = $attribute[$conf->global->LDAP_FIELD_MAIL];
     					$ldap_sid = $attribute[$conf->global->LDAP_FIELD_SID];
     				}
    @@ -1023,7 +1029,7 @@ if ($action == 'create' || $action == 'adduserldap')
     		print '<td>';
     		if (! empty($ldap_twitter))
     		{
    -			print '<input type="hidden" name="skype" value="'.$ldap_twitter.'">';
    +			print '<input type="hidden" name="twitter" value="'.$ldap_twitter.'">';
     			print $ldap_twitter;
     		}
     		else
    @@ -1040,7 +1046,7 @@ if ($action == 'create' || $action == 'adduserldap')
     		print '<td>';
     		if (! empty($ldap_facebook))
     		{
    -			print '<input type="hidden" name="skype" value="'.$ldap_facebook.'">';
    +			print '<input type="hidden" name="facebook" value="'.$ldap_facebook.'">';
     			print $ldap_facebook;
     		}
     		else
    
    From 82c89f739d3389b11b7154fc3037f0c4105d5a31 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 11:29:47 +0200
    Subject: [PATCH 147/433] social network module
    
    ---
     htdocs/user/class/user.class.php | 41 +++++++++++++++++++++++++++-----
     1 file changed, 35 insertions(+), 6 deletions(-)
    
    diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php
    index f3fa431daa0..da0e39d9ad7 100644
    --- a/htdocs/user/class/user.class.php
    +++ b/htdocs/user/class/user.class.php
    @@ -69,7 +69,11 @@ class User extends CommonObject
     	public $gender;
     	public $birth;
     	public $email;
    +
     	public $skype;
    +	public $twitter;
    +	public $facebook;
    +
     	public $job;			// job position
     	public $signature;
     
    @@ -220,7 +224,8 @@ class User extends CommonObject
     		$login=trim($login);
     
     		// Get user
    -		$sql = "SELECT u.rowid, u.lastname, u.firstname, u.employee, u.gender, u.birth, u.email, u.job, u.skype, u.signature, u.office_phone, u.office_fax, u.user_mobile,";
    +		$sql = "SELECT u.rowid, u.lastname, u.firstname, u.employee, u.gender, u.birth, u.email, u.job, u.skype, u.twitter, u.facebook,";
    +		$sql.= " u.signature, u.office_phone, u.office_fax, u.user_mobile,";
     		$sql.= " u.address, u.zip, u.town, u.fk_state as state_id, u.fk_country as country_id,";
     		$sql.= " u.admin, u.login, u.note,";
     		$sql.= " u.pass, u.pass_crypted, u.pass_temp, u.api_key,";
    @@ -325,6 +330,8 @@ class User extends CommonObject
     				$this->user_mobile  = $obj->user_mobile;
     				$this->email		= $obj->email;
     				$this->skype		= $obj->skype;
    +				$this->twitter		= $obj->twitter;
    +				$this->facebook		= $obj->facebook;
     				$this->job			= $obj->job;
     				$this->signature	= $obj->signature;
     				$this->admin		= $obj->admin;
    @@ -1220,6 +1227,8 @@ class User extends CommonObject
     		$this->gender		= $contact->gender;
     		$this->email		= $contact->email;
     		$this->skype 		= $contact->skype;
    +		$this->twitter 		= $contact->twitter;
    +		$this->facebook		= $contact->facebook;
     		$this->office_phone	= $contact->phone_pro;
     		$this->office_fax	= $contact->fax;
     		$this->user_mobile	= $contact->phone_mobile;
    @@ -1433,7 +1442,11 @@ class User extends CommonObject
     		$this->office_fax   = trim($this->office_fax);
     		$this->user_mobile  = trim($this->user_mobile);
     		$this->email        = trim($this->email);
    +
     		$this->skype        = trim($this->skype);
    +		$this->twitter      = trim($this->twitter);
    +		$this->facebook     = trim($this->facebook);
    +
     		$this->job    		= trim($this->job);
     		$this->signature    = trim($this->signature);
     		$this->note         = trim($this->note);
    @@ -1483,6 +1496,8 @@ class User extends CommonObject
     		$sql.= ", user_mobile = '".$this->db->escape($this->user_mobile)."'";
     		$sql.= ", email = '".$this->db->escape($this->email)."'";
     		$sql.= ", skype = '".$this->db->escape($this->skype)."'";
    +		$sql.= ", twitter = '".$this->db->escape($this->twitter)."'";
    +		$sql.= ", facebook = '".$this->db->escape($this->facebook)."'";
     		$sql.= ", job = '".$this->db->escape($this->job)."'";
     		$sql.= ", signature = '".$this->db->escape($this->signature)."'";
     		$sql.= ", accountancy_code = '".$this->db->escape($this->accountancy_code)."'";
    @@ -1567,7 +1582,11 @@ class User extends CommonObject
     						$adh->country_id=$this->country_id;
     
     						$adh->email=$this->email;
    +
     						$adh->skype=$this->skype;
    +						$adh->twitter=$this->twitter;
    +						$adh->facebook=$this->facebook;
    +
     						$adh->phone=$this->office_phone;
     						$adh->phone_mobile=$this->user_mobile;
     
    @@ -1615,7 +1634,11 @@ class User extends CommonObject
     						//$tmpobj->societe=(empty($tmpobj->societe) && $this->societe_id ? $this->societe_id : $tmpobj->societe);
     
     						$tmpobj->email=$this->email;
    +
     						$tmpobj->skype=$this->skype;
    +						$tmpobj->twitter=$this->twitter;
    +						$tmpobj->facebook=$this->facebook;
    +
     						$tmpobj->phone_pro=$this->office_phone;
     						$tmpobj->phone_mobile=$this->user_mobile;
     						$tmpobj->fax=$this->office_fax;
    @@ -2474,13 +2497,15 @@ class User extends CommonObject
     			'LDAP_FIELD_NAME'		=> 'lastname',
     			'LDAP_FIELD_FIRSTNAME'	=> 'firstname',
     			'LDAP_FIELD_LOGIN'		=> 'login',
    -			'LDAP_FIELD_LOGIN_SAMBA'	=> 'login',
    +			'LDAP_FIELD_LOGIN_SAMBA'=> 'login',
     			'LDAP_FIELD_PHONE'		=> 'office_phone',
     			'LDAP_FIELD_MOBILE'		=> 'user_mobile',
    -			'LDAP_FIELD_FAX'			=> 'office_fax',
    +			'LDAP_FIELD_FAX'		=> 'office_fax',
     			'LDAP_FIELD_MAIL'		=> 'email',
    -			'LDAP_FIELD_SID'			=> 'ldap_sid',
    -			'LDAP_FIELD_SKYPE'		=> 'skype'
    +			'LDAP_FIELD_SID'		=> 'ldap_sid',
    +			'LDAP_FIELD_SKYPE'		=> 'skype',
    +			'LDAP_FIELD_TWITTER'	=> 'twitter',
    +			'LDAP_FIELD_FACEBOOK'	=> 'facebook'
     		);
     
     		// Champs
    @@ -2591,7 +2616,9 @@ class User extends CommonObject
     		$this->gender='man';
     		$this->note='This is a note';
     		$this->email='email@specimen.com';
    -		$this->skype='tom.hanson';
    +		$this->skype='skypepseudo';
    +		$this->twitter='twitterpseudo';
    +		$this->facebook='facebookpseudo';
     		$this->office_phone='0999999999';
     		$this->office_fax='0999999998';
     		$this->user_mobile='0999999997';
    @@ -2745,6 +2772,8 @@ class User extends CommonObject
     		$this->office_fax=$ldapuser->{$conf->global->LDAP_FIELD_FAX};
     		$this->email=$ldapuser->{$conf->global->LDAP_FIELD_MAIL};
     		$this->skype=$ldapuser->{$conf->global->LDAP_FIELD_SKYPE};
    +		$this->twitter=$ldapuser->{$conf->global->LDAP_FIELD_TWITTER};
    +		$this->facebook=$ldapuser->{$conf->global->LDAP_FIELD_FACEBOOK};
     		$this->ldap_sid=$ldapuser->{$conf->global->LDAP_FIELD_SID};
     
     		$this->job=$ldapuser->{$conf->global->LDAP_FIELD_TITLE};
    
    From 53b099858f40ca77697125e8dc78be1e67e415fc Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 12:04:04 +0200
    Subject: [PATCH 148/433] FIX cutomer or supplier categories visible or not
     when required
    
    ---
     htdocs/societe/card.php | 161 ++++++++++++++++++++++++++--------------
     1 file changed, 105 insertions(+), 56 deletions(-)
    
    diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php
    index ee4d05231ee..1fbabc01462 100644
    --- a/htdocs/societe/card.php
    +++ b/htdocs/societe/card.php
    @@ -1063,6 +1063,39 @@ else
                             	$("#TypeName").html(document.formsoc.LastName.value);
                             	document.formsoc.private.value=1;
                             });
    +
    +						init_customer_categ();
    +			  			$("#customerprospect").change(function() {
    +								init_customer_categ();
    +						});
    +						function init_customer_categ() {
    +								console.log("is customer or prospect = "+jQuery("#customerprospect").val());
    +								if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() == 0 || '.(empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER)?'1':'0').'))
    +								{
    +									jQuery(".visibleifcustomer").hide();
    +								}
    +								else
    +								{
    +									jQuery(".visibleifcustomer").show();
    +								}
    +						}
    +
    +						init_supplier_categ();
    +			       		$("#fournisseur").change(function() {
    +							init_supplier_categ();
    +						});
    +						function init_supplier_categ() {
    +								console.log("is supplier = "+jQuery("#fournisseur").val());
    +								if (jQuery("#fournisseur").val() == 0)
    +								{
    +									jQuery(".visibleifsupplier").hide();
    +								}
    +								else
    +								{
    +									jQuery(".visibleifsupplier").show();
    +								}
    +						}
    +
                             $("#selectcountry_id").change(function() {
                             	document.formsoc.action.value="create";
                             	document.formsoc.submit();
    @@ -1421,22 +1454,20 @@ else
     			$langs->load('categories');
     
     			// Customer
    -			if ($object->prospect || $object->client || (! $object->fournisseur && ! empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) {
    -				print '<tr><td class="toptd">' . fieldLabel('CustomersCategoriesShort', 'custcats') . '</td><td colspan="3">';
    -				$cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, 'parent', null, null, 1);
    -				print $form->multiselectarray('custcats', $cate_arbo, GETPOST('custcats', 'array'), null, null, null,
    -					null, "90%");
    -				print "</td></tr>";
    -			}
    +			//if ($object->prospect || $object->client || (! $object->fournisseur && ! empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) {
    +			print '<tr class="visibleifcustomer"><td class="toptd">' . fieldLabel('CustomersCategoriesShort', 'custcats') . '</td><td colspan="3">';
    +			$cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, 'parent', null, null, 1);
    +			print $form->multiselectarray('custcats', $cate_arbo, GETPOST('custcats', 'array'), null, null, null, null, "90%");
    +			print "</td></tr>";
    +			//}
     
     			// Supplier
    -			if ($object->fournisseur) {
    -				print '<tr><td class="toptd">' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . '</td><td colspan="3">';
    -				$cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, 'parent', null, null, 1);
    -				print $form->multiselectarray('suppcats', $cate_arbo, GETPOST('suppcats', 'array'), null, null, null,
    -					null, "90%");
    -				print "</td></tr>";
    -			}
    +			//if ($object->fournisseur) {
    +			print '<tr class="visibleifsupplier"><td class="toptd">' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . '</td><td colspan="3">';
    +			$cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, 'parent', null, null, 1);
    +			print $form->multiselectarray('suppcats', $cate_arbo, GETPOST('suppcats', 'array'), null, null, null, null, "90%");
    +			print "</td></tr>";
    +			//}
     		}
     
     		// Multicurrency
    @@ -1488,11 +1519,6 @@ else
         }
         elseif ($action == 'edit')
         {
    -        /*
    -         * Edition
    -         */
    -
    -
             //print load_fiche_titre($langs->trans("EditCompany"));
     
             if ($socid)
    @@ -1612,8 +1638,10 @@ else
                 	$sub2=0;
                 }else{$sub2=1;}
     
    -            print "\n".'<script type="text/javascript">';
    -            print '$(document).ready(function () {
    +            if ($conf->use_javascript_ajax)
    +            {
    +            	print "\n".'<script type="text/javascript">';
    +            	print '$(document).ready(function () {
         			var val='.$sub.';
         			var val2='.$sub2.';
         			if("#localtax1assuj_value".value==undefined){
    @@ -1647,19 +1675,44 @@ else
         				}
         			});
     
    -               });';
    -            print '</script>'."\n";
    +				init_customer_categ();
    +	  			$("#customerprospect").change(function() {
    +					init_customer_categ();
    +				});
    +       			function init_customer_categ() {
    +					console.log("is customer or prospect = "+jQuery("#customerprospect").val());
    +					if (jQuery("#customerprospect").val() == 0 && (jQuery("#fournisseur").val() == 0 || '.(empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER)?'1':'0').'))
    +					{
    +						jQuery(".visibleifcustomer").hide();
    +					}
    +					else
    +					{
    +						jQuery(".visibleifcustomer").show();
    +					}
    +				}
     
    +				init_supplier_categ();
    +	  			$("#fournisseur").change(function() {
    +					init_supplier_categ();
    +				});
    +       			function init_supplier_categ() {
    +					console.log("is supplier = "+jQuery("#fournisseur").val());
    +					if (jQuery("#fournisseur").val() == 0)
    +					{
    +						jQuery(".visibleifsupplier").hide();
    +					}
    +					else
    +					{
    +						jQuery(".visibleifsupplier").show();
    +					}
    +				};
     
    -            if ($conf->use_javascript_ajax)
    -            {
    -                print "\n".'<script type="text/javascript" language="javascript">';
    -                print '$(document).ready(function () {
    -                			$("#selectcountry_id").change(function() {
    -                				document.formsoc.action.value="edit";
    -                				document.formsoc.submit();
    -                			});
    -                       })';
    +       			$("#selectcountry_id").change(function() {
    +       				document.formsoc.action.value="edit";
    +      				document.formsoc.submit();
    +        			});
    +
    +                })';
                     print '</script>'."\n";
                 }
     
    @@ -2022,34 +2075,30 @@ else
     			if (! empty($conf->categorie->enabled)  && ! empty($user->rights->categorie->lire))
     			{
     				// Customer
    -				if ($object->prospect || $object->client || (! $object->fournisseur && ! empty($conf->global->THIRDPARTY_CAN_HAVE_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT_SUPPLIER))) {
    -					print '<tr><td>' . fieldLabel('CustomersCategoriesShort', 'custcats') . '</td>';
    -					print '<td colspan="3">';
    -					$cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, null, null, null, 1);
    -					$c = new Categorie($db);
    -					$cats = $c->containing($object->id, Categorie::TYPE_CUSTOMER);
    -					$arrayselected=array();
    -					foreach ($cats as $cat) {
    -						$arrayselected[] = $cat->id;
    -					}
    -					print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
    -					print "</td></tr>";
    +				print '<tr class="visibleifcustomer"><td>' . fieldLabel('CustomersCategoriesShort', 'custcats') . '</td>';
    +				print '<td colspan="3">';
    +				$cate_arbo = $form->select_all_categories(Categorie::TYPE_CUSTOMER, null, null, null, null, 1);
    +				$c = new Categorie($db);
    +				$cats = $c->containing($object->id, Categorie::TYPE_CUSTOMER);
    +				$arrayselected=array();
    +				foreach ($cats as $cat) {
    +					$arrayselected[] = $cat->id;
     				}
    +				print $form->multiselectarray('custcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
    +				print "</td></tr>";
     
     				// Supplier
    -				if ($object->fournisseur) {
    -					print '<tr><td>' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . '</td>';
    -					print '<td colspan="3">';
    -					$cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, null, null, null, 1);
    -					$c = new Categorie($db);
    -					$cats = $c->containing($object->id, Categorie::TYPE_SUPPLIER);
    -					$arrayselected=array();
    -					foreach ($cats as $cat) {
    -						$arrayselected[] = $cat->id;
    -					}
    -					print $form->multiselectarray('suppcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
    -					print "</td></tr>";
    +				print '<tr class="visibleifsupplier"><td>' . fieldLabel('SuppliersCategoriesShort', 'suppcats') . '</td>';
    +				print '<td colspan="3">';
    +				$cate_arbo = $form->select_all_categories(Categorie::TYPE_SUPPLIER, null, null, null, null, 1);
    +				$c = new Categorie($db);
    +				$cats = $c->containing($object->id, Categorie::TYPE_SUPPLIER);
    +				$arrayselected=array();
    +				foreach ($cats as $cat) {
    +					$arrayselected[] = $cat->id;
     				}
    +				print $form->multiselectarray('suppcats', $cate_arbo, $arrayselected, '', 0, '', 0, '90%');
    +				print "</td></tr>";
     			}
     
     			// Multicurrency
    
    From b4e254247267bdc1d5c65454c2e3894d02d33ef1 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 12:20:05 +0200
    Subject: [PATCH 149/433] Standardize and update code
    
    ---
     htdocs/stripe/class/stripe.class.php          |  3 ++
     .../class/supplier_proposal.class.php         | 28 +++++++++++++++++++
     2 files changed, 31 insertions(+)
    
    diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php
    index 3c07c9ae5f6..e66fc769a09 100644
    --- a/htdocs/stripe/class/stripe.class.php
    +++ b/htdocs/stripe/class/stripe.class.php
    @@ -38,6 +38,9 @@ class Stripe extends CommonObject
     	 */
         public $fk_soc;
     
    +    /**
    +     * @var int ID
    +     */
     	public $fk_key;
     
     	/**
    diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php
    index 688f6aa1276..adc2c8643ac 100644
    --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php
    +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php
    @@ -166,7 +166,11 @@ class SupplierProposal extends CommonObject
         public $specimen;
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
     	public $fk_multicurrency;
    +
     	public $multicurrency_code;
     	public $multicurrency_tx;
     	public $multicurrency_total_ht;
    @@ -2712,9 +2716,21 @@ class SupplierProposalLine extends CommonObjectLine
     	 */
     	public $id;
     
    +	/**
    +     * @var int ID
    +     */
         public $fk_supplier_proposal;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_parent_line;
    +
         public $desc;          	// Description ligne
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_product;		// Id produit predefini
     
     	/**
    @@ -2733,11 +2749,19 @@ class SupplierProposalLine extends CommonObjectLine
         public $tva_tx;
         public $subprice;
         public $remise_percent;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_remise_except;
     
         public $rang = 0;
     
    +    /**
    +     * @var int ID
    +     */
     	public $fk_fournprice;
    +
     	public $pa_ht;
     	public $marge_tx;
     	public $marque_tx;
    @@ -2811,7 +2835,11 @@ class SupplierProposalLine extends CommonObjectLine
         public $ref_supplier;
     
     	// Multicurrency
    +	/**
    +     * @var int ID
    +     */
     	public $fk_multicurrency;
    +
     	public $multicurrency_code;
     	public $multicurrency_subprice;
     	public $multicurrency_total_ht;
    
    From ba40ad4aabf1d7779a61e8cc604f150f3a0e328c Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 12:23:45 +0200
    Subject: [PATCH 150/433] Standardize and update code
    
    ---
     htdocs/ticket/class/actions_ticket.class.php | 3 +++
     htdocs/ticket/class/ticketlogs.class.php     | 8 ++++++++
     htdocs/user/class/user.class.php             | 3 +++
     htdocs/website/class/websitepage.class.php   | 4 ++++
     4 files changed, 18 insertions(+)
    
    diff --git a/htdocs/ticket/class/actions_ticket.class.php b/htdocs/ticket/class/actions_ticket.class.php
    index 2fd26b5797b..7e8ae39564a 100644
    --- a/htdocs/ticket/class/actions_ticket.class.php
    +++ b/htdocs/ticket/class/actions_ticket.class.php
    @@ -70,6 +70,9 @@ class ActionsTicket
     	 */
     	public $description;
     
    +	/**
    +     * @var int ID
    +     */
         public $fk_statut;
     
         /**
    diff --git a/htdocs/ticket/class/ticketlogs.class.php b/htdocs/ticket/class/ticketlogs.class.php
    index 01ba7972ced..79a4c95efed 100644
    --- a/htdocs/ticket/class/ticketlogs.class.php
    +++ b/htdocs/ticket/class/ticketlogs.class.php
    @@ -62,8 +62,16 @@ class Ticketlogs// extends CommonObject
     	 */
     	public $id;
     
    +	/**
    +     * @var int ID
    +     */
         public $fk_track_id;
    +
    +    /**
    +     * @var int ID
    +     */
         public $fk_user_create;
    +
         public $datec = '';
         public $message;
     
    diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php
    index da0e39d9ad7..d2afacce54a 100644
    --- a/htdocs/user/class/user.class.php
    +++ b/htdocs/user/class/user.class.php
    @@ -123,6 +123,9 @@ class User extends CommonObject
     	public $socid;
     	public $contactid;
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_member;
     
     	/**
    diff --git a/htdocs/website/class/websitepage.class.php b/htdocs/website/class/websitepage.class.php
    index 4277a03167d..b6ef620b7d2 100644
    --- a/htdocs/website/class/websitepage.class.php
    +++ b/htdocs/website/class/websitepage.class.php
    @@ -49,7 +49,11 @@ class WebsitePage extends CommonObject
     	 */
     	public $picto = 'label';
     
    +	/**
    +     * @var int ID
    +     */
     	public $fk_website;
    +
     	public $pageurl;
     	public $aliasalt;
     	public $type_container;
    
    From 9d4f6dc44465b6ed0368dee271be2c97222affce Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 15:55:36 +0200
    Subject: [PATCH 151/433] Standardize and update code
    
    ---
     htdocs/accountancy/admin/account.php | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php
    index 087f9957f16..c9b72d9cc4c 100644
    --- a/htdocs/accountancy/admin/account.php
    +++ b/htdocs/accountancy/admin/account.php
    @@ -38,11 +38,11 @@ $id = GETPOST('id', 'int');
     $rowid = GETPOST('rowid', 'int');
     $contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'accountingaccountlist';   // To manage different context of search
     
    -$search_account = GETPOST("search_account");
    -$search_label = GETPOST("search_label");
    -$search_accountparent = GETPOST("search_accountparent");
    -$search_pcgtype = GETPOST("search_pcgtype");
    -$search_pcgsubtype = GETPOST("search_pcgsubtype");
    +$search_account = GETPOST('search_account','alpha');
    +$search_label = GETPOST('search_label','alpha');
    +$search_accountparent = GETPOST('search_accountparent','alpha');
    +$search_pcgtype = GETPOST('search_pcgtype','alpha');
    +$search_pcgsubtype = GETPOST('search_pcgsubtype','alpha');
     
     // Security check
     if ($user->societe_id > 0) accessforbidden();
    
    From 4000845970445be656ca2c6df51469c4f6909b86 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 15:57:38 +0200
    Subject: [PATCH 152/433] Update screenshot
    
    ---
     .../dolibarr_screenshot5_1920x1080_b.jpg      | Bin 126498 -> 274292 bytes
     1 file changed, 0 insertions(+), 0 deletions(-)
    
    diff --git a/doc/images/dolibarr_screenshot5_1920x1080_b.jpg b/doc/images/dolibarr_screenshot5_1920x1080_b.jpg
    index 5f7d8a5b573d9e7b3e055a62890cb02fa37e1ae0..0b5c749cb5c70905cd0c946c31b53e9ac62c5476 100644
    GIT binary patch
    literal 274292
    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
    
    literal 126498
    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
    
    
    From 181c1e0b77b606fbfc172e4e7e17854937214edd Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 16:01:27 +0200
    Subject: [PATCH 153/433] Standardize and update code
    
    ---
     htdocs/accountancy/admin/accountmodel.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php
    index e3ed164d60b..c50bb495c09 100644
    --- a/htdocs/accountancy/admin/accountmodel.php
    +++ b/htdocs/accountancy/admin/accountmodel.php
    @@ -55,8 +55,8 @@ $acts[1] = "disable";
     $actl[0] = img_picto($langs->trans("Disabled"),'switch_off');
     $actl[1] = img_picto($langs->trans("Activated"),'switch_on');
     
    -$listoffset=GETPOST('listoffset');
    -$listlimit=GETPOST('listlimit')>0?GETPOST('listlimit'):1000;
    +$listoffset=GETPOST('listoffset','alpha');
    +$listlimit=GETPOST('listlimit','int')>0?GETPOST('listlimit','int'):1000;
     $active = 1;
     
     $sortfield = GETPOST("sortfield",'aZ09comma');
    
    From c5edb3289b9d048074e8dacb486dee27494ef121 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 16:09:05 +0200
    Subject: [PATCH 154/433] Standardize and update code
    
    ---
     htdocs/accountancy/admin/accountmodel.php | 12 ++++++------
     1 file changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php
    index c50bb495c09..efa23a6a586 100644
    --- a/htdocs/accountancy/admin/accountmodel.php
    +++ b/htdocs/accountancy/admin/accountmodel.php
    @@ -139,13 +139,13 @@ $sourceList=array();
      * Actions
      */
     
    -if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x'))
    +if (GETPOST('button_removefilter','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter_x','alpha'))
     {
     	$search_country_id = '';
     }
     
     // Actions add or modify an entry into a dictionary
    -if (GETPOST('actionadd') || GETPOST('actionmodify'))
    +if (GETPOST('actionadd','alpha') || GETPOST('actionmodify','alpha'))
     {
     	$listfield=explode(',', str_replace(' ', '',$tabfield[$id]));
     	$listfieldinsert=explode(',',$tabfieldinsert[$id]);
    @@ -235,7 +235,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	if ($_POST["accountancy_code_buy"] <= 0) $_POST["accountancy_code_buy"]='';	// If empty, we force to null
     
     	// Si verif ok et action add, on ajoute la ligne
    -	if ($ok && GETPOST('actionadd'))
    +	if ($ok && GETPOST('actionadd','alpha'))
     	{
     		if ($tabrowid[$id])
     		{
    @@ -300,7 +300,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	}
     
     	// Si verif ok et action modify, on modifie la ligne
    -	if ($ok && GETPOST('actionmodify'))
    +	if ($ok && GETPOST('actionmodify','alpha'))
     	{
     		if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; }
     		else { $rowidcol="rowid"; }
    @@ -341,7 +341,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	//$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
     
    -if (GETPOST('actioncancel'))
    +if (GETPOST('actioncancel','alpha'))
     {
     	//$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
    @@ -560,7 +560,7 @@ if ($id)
     
     		$obj = new stdClass();
     		// If data was already input, we define them in obj to populate input fields.
    -		if (GETPOST('actionadd'))
    +		if (GETPOST('actionadd','alpha'))
     		{
     			foreach ($fieldlist as $key=>$val)
     			{
    
    From 4df574d58ed36ffbcbf0e1843b8b8e122985f796 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 16:23:27 +0200
    Subject: [PATCH 155/433] Standardize and update code
    
    ---
     htdocs/accountancy/admin/card.php            | 34 ++++++++++++--------
     htdocs/accountancy/admin/categories_list.php | 14 ++++----
     2 files changed, 27 insertions(+), 21 deletions(-)
    
    diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php
    index 6a92a3f6080..b64bf291955 100644
    --- a/htdocs/accountancy/admin/card.php
    +++ b/htdocs/accountancy/admin/card.php
    @@ -73,25 +73,28 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount)
     		// To manage zero or not at the end of the accounting account
     		if($conf->global->ACCOUNTING_MANAGE_ZERO == 1)
     		{
    -			$account_number = GETPOST('account_number');
    +			$account_number = GETPOST('account_number','int');
     		}
     		else
     		{
    -			$account_number = clean_account(GETPOST('account_number'));
    +			$account_number = clean_account(GETPOST('account_number','int'));
     		}
     
    -		if (GETPOST('account_parent') <= 0) {
    +		if (GETPOST('account_parent','int') <= 0)
    +		{
     			$account_parent = 0;
    -		} else {
    +		}
    +		else
    +		{
     			$account_parent = GETPOST('account_parent','int');
     		}
     
     		$object->fk_pcg_version = $obj->pcg_version;
    -		$object->pcg_type = GETPOST('pcg_type');
    -		$object->pcg_subtype = GETPOST('pcg_subtype');
    +		$object->pcg_type = GETPOST('pcg_type','alpha');
    +		$object->pcg_subtype = GETPOST('pcg_subtype','alpha');
     		$object->account_number = $account_number;
     		$object->account_parent = $account_parent;
    -		$object->account_category = GETPOST('account_category');
    +		$object->account_category = GETPOST('account_category','alpha');
     		$object->label = GETPOST('label', 'alpha');
     		$object->active = 1;
     
    @@ -135,25 +138,28 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount)
     		// To manage zero or not at the end of the accounting account
     		if($conf->global->ACCOUNTING_MANAGE_ZERO == 1)
     		{
    -			$account_number = GETPOST('account_number');
    +			$account_number = GETPOST('account_number','int');
     		}
     		else
     		{
    -			$account_number = clean_account(GETPOST('account_number'));
    +			$account_number = clean_account(GETPOST('account_number','int'));
     		}
     
    -		if (GETPOST('account_parent') <= 0) {
    +		if (GETPOST('account_parent','int') <= 0)
    +		{
     			$account_parent = 0;
    -		} else {
    +		}
    +		else
    +		{
     			$account_parent = GETPOST('account_parent','int');
     		}
     
     		$object->fk_pcg_version = $obj->pcg_version;
    -		$object->pcg_type = GETPOST('pcg_type');
    -		$object->pcg_subtype = GETPOST('pcg_subtype');
    +		$object->pcg_type = GETPOST('pcg_type','alpha');
    +		$object->pcg_subtype = GETPOST('pcg_subtype','alpha');
     		$object->account_number = $account_number;
     		$object->account_parent = $account_parent;
    -		$object->account_category = GETPOST('account_category');
    +		$object->account_category = GETPOST('account_category','alpha');
     		$object->label = GETPOST('label', 'alpha');
     
     		$result = $object->update($user);
    diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php
    index 900205b7588..14a6b56512d 100644
    --- a/htdocs/accountancy/admin/categories_list.php
    +++ b/htdocs/accountancy/admin/categories_list.php
    @@ -51,8 +51,8 @@ $acts[1] = "disable";
     $actl[0] = img_picto($langs->trans("Disabled"),'switch_off');
     $actl[1] = img_picto($langs->trans("Activated"),'switch_on');
     
    -$listoffset=GETPOST('listoffset');
    -$listlimit=GETPOST('listlimit')>0?GETPOST('listlimit'):1000;
    +$listoffset=GETPOST('listoffset','alpha');
    +$listlimit=GETPOST('listlimit','int')>0?GETPOST('listlimit','int'):1000;
     $active = 1;
     
     $sortfield = GETPOST("sortfield",'aZ09comma');
    @@ -134,13 +134,13 @@ $sourceList=array();
      * Actions
      */
     
    -if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x'))
    +if (GETPOST('button_removefilter','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter_x','alpha'))
     {
         $search_country_id = '';
     }
     
     // Actions add or modify an entry into a dictionary
    -if (GETPOST('actionadd') || GETPOST('actionmodify'))
    +if (GETPOST('actionadd','alpha') || GETPOST('actionmodify','alpha'))
     {
         $listfield=explode(',', str_replace(' ', '',$tabfield[$id]));
         $listfieldinsert=explode(',',$tabfieldinsert[$id]);
    @@ -250,7 +250,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
         }
     
         // Si verif ok et action modify, on modifie la ligne
    -    if ($ok && GETPOST('actionmodify'))
    +    if ($ok && GETPOST('actionmodify','alpha'))
         {
             if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; }
             else { $rowidcol="rowid"; }
    @@ -291,7 +291,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
         //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
     
    -if (GETPOST('actioncancel'))
    +if (GETPOST('actioncancel','alpha'))
     {
         //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
    @@ -513,7 +513,7 @@ if ($id)
     
             $obj = new stdClass();
             // If data was already input, we define them in obj to populate input fields.
    -        if (GETPOST('actionadd'))
    +        if (GETPOST('actionadd','alpha'))
             {
                 foreach ($fieldlist as $key=>$val)
                 {
    
    From bd426d105235080055e852aaa5c39bc39f581414 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 16:44:25 +0200
    Subject: [PATCH 156/433] Standardize and update code
    
    ---
     htdocs/accountancy/admin/categories.php      | 4 ++--
     htdocs/accountancy/admin/defaultaccounts.php | 2 +-
     htdocs/accountancy/admin/fiscalyear_card.php | 4 ++--
     3 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/accountancy/admin/categories.php b/htdocs/accountancy/admin/categories.php
    index 735c5595ddc..6e003738173 100644
    --- a/htdocs/accountancy/admin/categories.php
    +++ b/htdocs/accountancy/admin/categories.php
    @@ -37,9 +37,9 @@ $id = GETPOST('id', 'int');
     $rowid = GETPOST('rowid', 'int');
     $cancel = GETPOST('cancel','alpha');
     $action = GETPOST('action','aZ09');
    -$cat_id = GETPOST('account_category');
    +$cat_id = GETPOST('account_category','int');
     $selectcpt = GETPOST('cpt_bk', 'array');
    -$cpt_id = GETPOST('cptid');
    +$cpt_id = GETPOST('cptid','int');
     
     if ($cat_id == 0) {
     	$cat_id = null;
    diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php
    index 8cd45c1cfda..31fc04fa745 100644
    --- a/htdocs/accountancy/admin/defaultaccounts.php
    +++ b/htdocs/accountancy/admin/defaultaccounts.php
    @@ -76,7 +76,7 @@ $list_account = array (
     $accounting_mode = empty($conf->global->ACCOUNTING_MODE) ? 'RECETTES-DEPENSES' : $conf->global->ACCOUNTING_MODE;
     
     
    -if (GETPOST('change_chart'))
    +if (GETPOST('change_chart', 'alpha'))
     {
         $chartofaccounts = GETPOST('chartofaccounts', 'int');
     
    diff --git a/htdocs/accountancy/admin/fiscalyear_card.php b/htdocs/accountancy/admin/fiscalyear_card.php
    index cc4dd9dbb7f..05c7a3fd174 100644
    --- a/htdocs/accountancy/admin/fiscalyear_card.php
    +++ b/htdocs/accountancy/admin/fiscalyear_card.php
    @@ -166,7 +166,7 @@ if ($action == 'create')
     	print '<table class="border" width="100%">';
     
     	// Label
    -	print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans("Label") . '</td><td><input name="label" size="32" value="' . GETPOST("label") . '"></td></tr>';
    +	print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans("Label") . '</td><td><input name="label" size="32" value="' . GETPOST('label', 'alpha') . '"></td></tr>';
     
     	// Date start
     	print '<tr><td class="fieldrequired">' . $langs->trans("DateStart") . '</td><td>';
    @@ -183,7 +183,7 @@ if ($action == 'create')
     	print '<tr>';
     	print '<td class="fieldrequired">' . $langs->trans("Status") . '</td>';
     	print '<td class="valeur">';
    -	print $form->selectarray('statut', $statut2label, GETPOST('statut'));
    +	print $form->selectarray('statut', $statut2label, GETPOST('statut', 'int'));
     	print '</td></tr>';
     	*/
     
    
    From 1cfb06934c867c208361a6f1ae859830c32a8094 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 16:49:53 +0200
    Subject: [PATCH 157/433] Standardize and update code
    
    ---
     htdocs/accountancy/admin/journals_list.php  | 18 +++++++++---------
     htdocs/accountancy/admin/productaccount.php |  4 ++--
     2 files changed, 11 insertions(+), 11 deletions(-)
    
    diff --git a/htdocs/accountancy/admin/journals_list.php b/htdocs/accountancy/admin/journals_list.php
    index 20d0a5200a5..ae254788b08 100644
    --- a/htdocs/accountancy/admin/journals_list.php
    +++ b/htdocs/accountancy/admin/journals_list.php
    @@ -51,8 +51,8 @@ $acts[1] = "disable";
     $actl[0] = img_picto($langs->trans("Disabled"),'switch_off');
     $actl[1] = img_picto($langs->trans("Activated"),'switch_on');
     
    -$listoffset=GETPOST('listoffset');
    -$listlimit=GETPOST('listlimit')>0?GETPOST('listlimit'):1000;
    +$listoffset=GETPOST('listoffset', 'alpha');
    +$listlimit=GETPOST('listlimit', 'int')>0?GETPOST('listlimit', 'int'):1000;
     $active = 1;
     
     $sortfield = GETPOST("sortfield",'alpha');
    @@ -143,13 +143,13 @@ $sourceList = array(
      * Actions
      */
     
    -if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x'))
    +if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha'))
     {
     	$search_country_id = '';
     }
     
     // Actions add or modify an entry into a dictionary
    -if (GETPOST('actionadd') || GETPOST('actionmodify'))
    +if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha'))
     {
     	$listfield=explode(',', str_replace(' ', '',$tabfield[$id]));
     	$listfieldinsert=explode(',',$tabfieldinsert[$id]);
    @@ -190,7 +190,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	if ($_POST["accountancy_code_buy"] <= 0) $_POST["accountancy_code_buy"]='';	// If empty, we force to null
     
     	// Si verif ok et action add, on ajoute la ligne
    -	if ($ok && GETPOST('actionadd'))
    +	if ($ok && GETPOST('actionadd', 'alpha'))
     	{
     		if ($tabrowid[$id])
     		{
    @@ -252,7 +252,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	}
     
     	// Si verif ok et action modify, on modifie la ligne
    -	if ($ok && GETPOST('actionmodify'))
    +	if ($ok && GETPOST('actionmodify', 'alpha'))
     	{
     		if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; }
     		else { $rowidcol="rowid"; }
    @@ -294,7 +294,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify'))
     	//$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     }
     
    -//if (GETPOST('actioncancel'))
    +//if (GETPOST('actioncancel', 'alpha'))
     //{
     //	$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
     //}
    @@ -462,7 +462,7 @@ if ($id)
     
     		$obj = new stdClass();
     		// If data was already input, we define them in obj to populate input fields.
    -		if (GETPOST('actionadd'))
    +		if (GETPOST('actionadd', 'alpha'))
     		{
     			foreach ($fieldlist as $key=>$val)
     			{
    @@ -504,7 +504,7 @@ if ($id)
     		$paramwithsearch = $param;
     		if ($sortorder) $paramwithsearch.= '&sortorder='.$sortorder;
     		if ($sortfield) $paramwithsearch.= '&sortfield='.$sortfield;
    -		if (GETPOST('from')) $paramwithsearch.= '&from='.GETPOST('from','alpha');
    +		if (GETPOST('from', 'alpha')) $paramwithsearch.= '&from='.GETPOST('from','alpha');
     
     		// There is several pages
     		if ($num > $listlimit)
    diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php
    index 2467b89b108..0babd9aab5f 100644
    --- a/htdocs/accountancy/admin/productaccount.php
    +++ b/htdocs/accountancy/admin/productaccount.php
    @@ -62,8 +62,8 @@ $search_current_account_valid = GETPOST('search_current_account_valid', 'alpha')
     if ($search_current_account_valid == '') $search_current_account_valid='withoutvalidaccount';
     
     $accounting_product_mode = GETPOST('accounting_product_mode', 'alpha');
    -$btn_changeaccount = GETPOST('changeaccount');
    -$btn_changetype = GETPOST('changetype');
    +$btn_changeaccount = GETPOST('changeaccount', 'alpha');
    +$btn_changetype = GETPOST('changetype', 'alpha');
     
     $limit = GETPOST('limit','int')?GETPOST('limit','int'):(empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION)?$conf->liste_limit:$conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
     $sortfield = GETPOST("sortfield",'alpha');
    
    From 18b3238bad56baeb277853af1741b07ca5d7a8d2 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 16:56:01 +0200
    Subject: [PATCH 158/433] Standardize and update code
    
    ---
     htdocs/accountancy/bookkeeping/card.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php
    index 5add04d7361..a8ff1e13338 100644
    --- a/htdocs/accountancy/bookkeeping/card.php
    +++ b/htdocs/accountancy/bookkeeping/card.php
    @@ -217,7 +217,7 @@ else if ($action == "confirm_create") {
     		$action='create';
     		$error++;
     	}
    -	if (! GETPOST('next_num_mvt'))
    +	if (! GETPOST('next_num_mvt', 'alpha'))
     	{
     		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NumPiece")), null, 'errors');
     		$error++;
    @@ -253,7 +253,7 @@ else if ($action == "confirm_create") {
     }
     
     if ($action == 'setdate') {
    -	$datedoc = dol_mktime(0, 0, 0, GETPOST('doc_datemonth'), GETPOST('doc_dateday'), GETPOST('doc_dateyear'));
    +	$datedoc = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int'));
     	$result = $object->updateByMvt($piece_num,'doc_date',$db->idate($datedoc),$mode);
     	if ($result < 0) {
     		setEventMessages($object->error, $object->errors, 'errors');
    @@ -357,7 +357,7 @@ if ($action == 'create')
     
     	print '<tr>';
     	print '<td class="fieldrequired">' . $langs->trans("Codejournal") . '</td>';
    -	print '<td>' . $formaccounting->select_journal(GETPOST('code_journal'),'code_journal',0,1,array(),1,1) . '</td>';
    +	print '<td>' . $formaccounting->select_journal(GETPOST('code_journal', 'alpha'),'code_journal',0,1,array(),1,1) . '</td>';
     	print '</tr>';
     
     	print '<tr>';
    
    From 817920f282c517ad39cbf4d0d17392c56dde16ef Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 17:36:49 +0200
    Subject: [PATCH 159/433] Prepare 6.0.8
    
    ---
     ChangeLog | 31 +++++++++++++++++++++++++++++++
     1 file changed, 31 insertions(+)
    
    diff --git a/ChangeLog b/ChangeLog
    index 405aaa9ed9d..1bffab94cda 100644
    --- a/ChangeLog
    +++ b/ChangeLog
    @@ -2,6 +2,37 @@
     English Dolibarr ChangeLog
     --------------------------------------------------------------
     
    +***** ChangeLog for 6.0.8 compared to 6.0.7 *****
    +FIX: #8762
    +FIX: #9032
    +FIX: case when we valid form with keyboard
    +FIX: clause must not be there
    +FIX: dol_delete_file must work in a context without db handler loaded
    +FIX: entity test must be on product_fourn_price table and not product table
    +FIX: Fetch shipping will now fetch project id
    +FIX: $fk_account is always empty, must be $soc->fk_account
    +FIX: getEntity project and not projet
    +FIX: If we enable 3 steps for supplier order approbation, we must no…
    +FIX: If we enable 3 steps for supplier order approbation, we must not delete all fourn rights def.
    +FIX: Keep supplier proposal price for supplier order
    +FIX: langs fr
    +FIX: missing filters during ordering
    +FIX: missing filters during reordering
    +FIX: need to filter on aa.entity for same accounting accounts available in several entities
    +FIX: page must always be 0 when we search
    +FIX: page must always be 0 when we search (to avoid case : when we're on page 3 and we're looking for a precise thirdparty, we stay on page 3 and nothing's displaied)
    +FIX: PDF address: handle when contact thirdparty different from document thirdparty
    +FIX: propal: correctly preset project when creating with origin/originid
    +FIX: pu_ht_devise was not converted to numeric so decimals were lost
    +FIX: pu_ht_devise was not converted to numeric so decimals were lost when calculating total_ht_devise
    +FIX: remain to pay for credit note was wrong on invoice list
    +FIX: shipment: fk_proje(c)t not handled in fetch() and update() methods
    +FIX: showOptionals: column mismatches
    +FIX: sometimes amounts are identical but php find them different.
    +FIX: test is_erasable() must be done before call function delete()
    +FIX: test is_erasable() must be done before call function delete() too to avoid delete invoice with &action=delete in url
    +FIX: we must see number of all shared projects
    +FIX: wrong var name
     
     ***** ChangeLog for 6.0.7 compared to 6.0.6 *****
     FIX: #8023
    
    From 1ab6cd4b59b542422131cc2e52ab7d5572d5c858 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 17:51:32 +0200
    Subject: [PATCH 160/433] Update card.php
    
    ---
     htdocs/compta/facture/card.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
    index aeb145a7ea2..6f24d1f86fb 100644
    --- a/htdocs/compta/facture/card.php
    +++ b/htdocs/compta/facture/card.php
    @@ -3250,7 +3250,7 @@ if ($action == 'create')
     		print '<tr><td>' . $langs->trans($newclassname) . '</td><td colspan="2">' . $objectsrc->getNomUrl(1);
     		// We check if Origin document (id and type is known) has already at least one invoice attached to it
     		$objectsrc->fetchObjectLinked($originid,$origin,'','facture');
    -		if(!empty($objectsrc->linkedObjects['facture']) && is_array($objectsrc->linkedObjects['facture']))
    +		if (is_array($objectsrc->linkedObjects['facture']) && count($objectsrc->linkedObjects['facture']) >= 1)
     		{
     			setEventMessages('WarningBillExist', null, 'warnings');
     			echo ' ('.$langs->trans('LatestRelatedBill').end($objectsrc->linkedObjects['facture'])->getNomUrl(1).')';
    
    From afd9b4ea1a793ffcee8de396e24dc9a21a71ef4d Mon Sep 17 00:00:00 2001
    From: Marc de Lima Lucio <marc.delimalucio@atm-consulting.fr>
    Date: Fri, 12 Oct 2018 18:19:17 +0200
    Subject: [PATCH 161/433] FIX: propal pdf: missing parenthesis for customs code
    
    ---
     htdocs/comm/propal/card.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php
    index 2fdaadd1d59..c21e6ebec10 100644
    --- a/htdocs/comm/propal/card.php
    +++ b/htdocs/comm/propal/card.php
    @@ -868,6 +868,7 @@ if (empty($reshook))
     				// Add custom code and origin country into description
     				if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code)))
     				{
    +					$tmptxt = '(';
     					// Define output language
     					if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
     						$outputlangs = $langs;
    
    From 60a5444c1408cbcd3c9f56e4d2b83349f0f63377 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 18:50:33 +0200
    Subject: [PATCH 162/433] Fix app name to match Stripe advice
    
    ---
     htdocs/stripe/config.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php
    index defbc620cc8..d25176c21b4 100644
    --- a/htdocs/stripe/config.php
    +++ b/htdocs/stripe/config.php
    @@ -54,5 +54,5 @@ else
     }
     
     \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
    -\Stripe\Stripe::setAppInfo("Stripe", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version
    +\Stripe\Stripe::setAppInfo("Dolibarr StripeModule", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version
     \Stripe\Stripe::setApiVersion("2018-07-27"); // force version API
    
    From 2d2b9a030cc8b3f8c477c012aa62616509813268 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 19:01:01 +0200
    Subject: [PATCH 163/433] Fix app name to match Stripe advice
    
    ---
     htdocs/stripe/config.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/stripe/config.php b/htdocs/stripe/config.php
    index d25176c21b4..7aa22678d7a 100644
    --- a/htdocs/stripe/config.php
    +++ b/htdocs/stripe/config.php
    @@ -54,5 +54,5 @@ else
     }
     
     \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']);
    -\Stripe\Stripe::setAppInfo("Dolibarr StripeModule", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version
    +\Stripe\Stripe::setAppInfo("Dolibarr Stripe", DOL_VERSION, "https://www.dolibarr.org"); // add dolibarr version
     \Stripe\Stripe::setApiVersion("2018-07-27"); // force version API
    
    From d4b02c05524b89ecfb70c78b45be3e293fb484ff Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 19:03:03 +0200
    Subject: [PATCH 164/433] Release 6.0.8
    
    ---
     htdocs/filefunc.inc.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php
    index 9ab5de809b9..41fcff97fd8 100644
    --- a/htdocs/filefunc.inc.php
    +++ b/htdocs/filefunc.inc.php
    @@ -31,7 +31,7 @@
      */
     
     if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr');
    -if (! defined('DOL_VERSION')) define('DOL_VERSION','6.0.8');		// a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
    +if (! defined('DOL_VERSION')) define('DOL_VERSION','6.0.9');		// a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
     
     if (! defined('EURO')) define('EURO',chr(128));
     
    
    From bb606df5e064351715196bd7b1528e3629c53e10 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 19:12:20 +0200
    Subject: [PATCH 165/433] Prepare 7.0.4
    
    ---
     ChangeLog | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
     1 file changed, 57 insertions(+)
    
    diff --git a/ChangeLog b/ChangeLog
    index bdbb165903d..0a74e1b6f8e 100644
    --- a/ChangeLog
    +++ b/ChangeLog
    @@ -2,6 +2,63 @@
     English Dolibarr ChangeLog
     --------------------------------------------------------------
     
    +
    +***** ChangeLog for 7.0.4 compared to 7.0.3 *****
    +FIX: #8984 button create expense report
    +FIX: #9032
    +FIX: #9161
    +FIX: #9328
    +FIX: According to french law, if seller is in France and buyer isn't in UE and isn't a company, TVA used = TVA product
    +FIX: Add calls to fetchComments function
    +FIX: better compatibility with multicompany
    +FIX: case when we valid form with keyboard
    +FIX: character making error on bill list
    +FIX: check !empty exclude select element
    +FIX: combo into popup become crazy with IE10
    +FIX: combo of stock in popup are crazy in IE
    +FIX: Deletion of files in migration
    +FIX: exclude element of the select
    +FIX: extrafieldkey
    +FIX: Fetch function will fetch comments
    +FIX: Fetch task will now fetch comments
    +FIX: filter supplier invoice list by societe name.
    +FIX: $fk_account is always empty, must be $soc->fk_account
    +FIX: Force stripe api version to avoid trouble if we update stripe api
    +FIX: getEntity project and not projet
    +FIX: Get templates in a forced language
    +FIX: global $mysoc missing (to avoid php notice on lines 279, 280 & 281)
    +FIX: Injection
    +FIX: invoice stats: situation invoices were not counted
    +FIX: keep context filter on contact list on change column displayed
    +FIX: Keep same project when creating shipping from order
    +FIX: langs fr
    +FIX: Lose filter on payment type or category after a sort on invoice list
    +FIX: Missing behavior
    +FIX: missing hook to edit sql
    +FIX: multicompany compatibility !
    +FIX: need to filter on current entity on replenish
    +FIX: Option MAIN_DISABLE_NOTES_TAB #9611
    +FIX: page must always be 0 when we search (to avoid case : when we're on page 3 and we're looking for a precise thirdparty, we stay on page 3 and nothing's displaied)
    +FIX: Pagination on related item pages
    +FIX: Pagination on withdraw request list
    +FIX: PDF address: handle when contact thirdparty different from document thirdparty
    +FIX: PHP warning, undefined index notnull
    +FIX: Product marge tabs on product card
    +FIX: Product margin tab and credit note
    +FIX: propal: correctly preset project when creating with origin/originid
    +FIX: remain to pay for credit note was wrong on invoice list
    +FIX: remove debug
    +FIX: Remove fetchComments from project and task fetch function
    +FIX: remove rowid for multicompany compatibility
    +FIX: Search on Ref project on order list
    +FIX: search on ref project on propal list
    +FIX: showOptionals: column mismatches
    +FIX: SQL Injections reported by mu shcor (ADLab of Venustech)
    +FIX: stock replenish with multientity
    +FIX: table llx_chargessociales doesn't exists
    +FIX: we must see number of all shared projects
    +FIX: when stock is empty for current entity but > 0 in other entity, until this commit product wasn't displaied on replenishment, it must depends on multientity stock sharing
    +
     ***** ChangeLog for 7.0.3 compared to 7.0.2 *****
     FIX: 7.0 task contact card without withproject parameters
     FIX: #8722
    
    From 7e82e3d44c4927b65bc0c907ad904e30c0a0089a Mon Sep 17 00:00:00 2001
    From: Philippe Grand <philippe.grand@atoo-net.com>
    Date: Fri, 12 Oct 2018 19:13:07 +0200
    Subject: [PATCH 166/433] Update card.php
    
    ---
     htdocs/accountancy/admin/card.php | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php
    index b64bf291955..74958d606ec 100644
    --- a/htdocs/accountancy/admin/card.php
    +++ b/htdocs/accountancy/admin/card.php
    @@ -73,11 +73,11 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount)
     		// To manage zero or not at the end of the accounting account
     		if($conf->global->ACCOUNTING_MANAGE_ZERO == 1)
     		{
    -			$account_number = GETPOST('account_number','int');
    +			$account_number = GETPOST('account_number','string');
     		}
     		else
     		{
    -			$account_number = clean_account(GETPOST('account_number','int'));
    +			$account_number = clean_account(GETPOST('account_number','string'));
     		}
     
     		if (GETPOST('account_parent','int') <= 0)
    @@ -138,11 +138,11 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount)
     		// To manage zero or not at the end of the accounting account
     		if($conf->global->ACCOUNTING_MANAGE_ZERO == 1)
     		{
    -			$account_number = GETPOST('account_number','int');
    +			$account_number = GETPOST('account_number','string');
     		}
     		else
     		{
    -			$account_number = clean_account(GETPOST('account_number','int'));
    +			$account_number = clean_account(GETPOST('account_number','string'));
     		}
     
     		if (GETPOST('account_parent','int') <= 0)
    
    From bd60fe6ffda132beacb69bfd492c04f4212f9a61 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 19:13:11 +0200
    Subject: [PATCH 167/433] Prepare 7.0.4
    
    ---
     ChangeLog | 5 +++++
     1 file changed, 5 insertions(+)
    
    diff --git a/ChangeLog b/ChangeLog
    index 0a74e1b6f8e..61b3f85edb3 100644
    --- a/ChangeLog
    +++ b/ChangeLog
    @@ -58,6 +58,11 @@ FIX: stock replenish with multientity
     FIX: table llx_chargessociales doesn't exists
     FIX: we must see number of all shared projects
     FIX: when stock is empty for current entity but > 0 in other entity, until this commit product wasn't displaied on replenishment, it must depends on multientity stock sharing
    +FIX: when we're just admin and not super admin, if we create new user with transverse mode, we don't see it then we can't add him in usergroup
    +FIX: wrong function name
    +FIX: Wrong position of firstname lastname
    +FIX: wrong value for module part and return access denied
    +FIX: Wrong variable and trigger name
     
     ***** ChangeLog for 7.0.3 compared to 7.0.2 *****
     FIX: 7.0 task contact card without withproject parameters
    
    From 6a363fd1ab2d17d96d8e2b008dcdcf26d05b5015 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 19:26:00 +0200
    Subject: [PATCH 168/433] API Stripe 2018-09-24
    
    ---
     .../core/triggers/interface_80_modStripe_Stripe.class.php | 8 ++++----
     htdocs/public/payment/newpayment.php                      | 7 ++++++-
     2 files changed, 10 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
    index 43dc796bd5f..04326e7a3fe 100644
    --- a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
    +++ b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
    @@ -17,7 +17,7 @@
      */
     
     /**
    - *  \file       htdocs/core/triggers/interface_50_modStripe_Stripe.class.php
    + *  \file       htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
      *  \ingroup    core
      *  \brief      Fichier
      *  \remarks    Son propre fichier d'actions peut etre cree par recopie de celui-ci:
    @@ -148,9 +148,9 @@ class InterfaceStripe
     				{
     					$namecleaned = $object->name ? $object->name : null;
     					$vatcleaned = array(
    -          "tax_id" => $object->tva_intra ? $object->tva_intra : null,	// We force data to "null" if empty as expected by Stripe
    -          "type" => 'vat',
    -          );
    +						"tax_id" => $object->tva_intra ? $object->tva_intra : null,	// We force data to "null" if empty as expected by Stripe
    +						"type" => 'vat',
    +					);
     
     					// Detect if we change a Stripe info (email, description, vat id)
     					$changerequested = 0;
    diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php
    index a03c0a719c6..08e50e58be7 100644
    --- a/htdocs/public/payment/newpayment.php
    +++ b/htdocs/public/payment/newpayment.php
    @@ -495,12 +495,17 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     		}
     		else
     		{
    +			$vatcleaned = array(
    +				"tax_id" => $vatnumber ? $vatnumber : null,	// We force data to "null" if empty as expected by Stripe
    +				"type" => 'vat',
    +			);
    +
     			dol_syslog("Create anonymous customer card profile", LOG_DEBUG, 0, '_stripe');
     			$customer = \Stripe\Customer::create(array(
     				'email' => $email,
     				'description' => ($email?'Anonymous customer for '.$email:'Anonymous customer'),
     				'metadata' => $metadata,
    -				'business_vat_id' => ($vatnumber?$vatnumber:null),
    +				'tax_info' => $vatcleaned,
     				'source'  => $stripeToken           // source can be a token OR array('object'=>'card', 'exp_month'=>xx, 'exp_year'=>xxxx, 'number'=>xxxxxxx, 'cvc'=>xxx, 'name'=>'Cardholder's full name', zip ?)
     			));
     			// Return $customer = array('id'=>'cus_XXXX', ...)
    
    From d8edb1f6b864639c2ecbb40f7de104358010097a Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 20:28:26 +0200
    Subject: [PATCH 169/433] Fix regression in online payment
    
    ---
     htdocs/public/payment/newpayment.php | 16 +++++++++-------
     1 file changed, 9 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php
    index cedca6cae73..3afd590da53 100644
    --- a/htdocs/public/payment/newpayment.php
    +++ b/htdocs/public/payment/newpayment.php
    @@ -413,7 +413,7 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     	$dol_type=(GETPOST('s', 'alpha') ? GETPOST('s', 'alpha') : GETPOST('source', 'alpha'));
       	$dol_id=GETPOST('dol_id', 'int');
       	$vatnumber = GETPOST('vatnumber','alpha');
    -	$savesource=GETPOST('savesource', 'int');
    +	$savesource=GETPOSTISSET('savesource')?GETPOST('savesource', 'int'):1;
     
     	dol_syslog("stripeToken = ".$stripeToken, LOG_DEBUG, 0, '_stripe');
     	dol_syslog("email = ".$email, LOG_DEBUG, 0, '_stripe');
    @@ -454,9 +454,11 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     			$customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 1);
     
     			// Create Stripe card from Token
    -			if (! empty($savesource)) {
    -			$card = $customer->sources->create(array("source" => $stripeToken, "metadata" => $metadata));
    -			} else { $card = $stripeToken; }
    +			if ($savesource) {
    +				$card = $customer->sources->create(array("source" => $stripeToken, "metadata" => $metadata));
    +			} else {
    +				$card = $stripeToken;
    +			}
     
     			if (empty($card))
     			{
    @@ -467,9 +469,9 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     			}
     			else
     			{
    -        if (! empty($FULLTAG))       $metadata["FULLTAG"] = $FULLTAG;
    -        if (! empty($dol_id))        $metadata["dol_id"] = $dol_id;
    -        if (! empty($dol_type))      $metadata["dol_type"] = $dol_type;
    +				if (! empty($FULLTAG))       $metadata["FULLTAG"] = $FULLTAG;
    +				if (! empty($dol_id))        $metadata["dol_id"] = $dol_id;
    +				if (! empty($dol_type))      $metadata["dol_type"] = $dol_type;
     
     				dol_syslog("Create charge on card ".$card->id, LOG_DEBUG, 0, '_stripe');
     				$charge = \Stripe\Charge::create(array(
    
    From 2bbf9a3429b9d46b37ef61250c35bb83d4bae226 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 20:37:59 +0200
    Subject: [PATCH 170/433] Hide feature that need re-engeneering
    
    ---
     .../class/actions_datapolicies.class.php      | 77 ++++++++++---------
     htdocs/datapolicies/lib/datapolicies.lib.php  | 11 ++-
     2 files changed, 47 insertions(+), 41 deletions(-)
    
    diff --git a/htdocs/datapolicies/class/actions_datapolicies.class.php b/htdocs/datapolicies/class/actions_datapolicies.class.php
    index d65de390b8c..45e443cb274 100644
    --- a/htdocs/datapolicies/class/actions_datapolicies.class.php
    +++ b/htdocs/datapolicies/class/actions_datapolicies.class.php
    @@ -363,45 +363,48 @@ class ActionsDatapolicies
             global $conf, $user, $langs;
             $langs->load('datapolicies@datapolicies');
     
    -        $dialog = '<div id="dialogdatapolicies" style="display:none;" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">';
    -        $dialog .= '<div class="confirmmessage">' . img_help('', '') . ' ' . $langs->trans('DATAPOLICIES_PORTABILITE_CONFIRMATION') . '</div>';
    -        $dialog .= "</div>";
    -        $dialog .= '<script>
    -                  $( function() {
    -                    $("#rpgpdbtn").on("click", function(){
    -                        var href = $(this).attr("href");
    -                        $( "#dialogdatapolicies" ).dialog({
    -                          modal: true,
    -                          buttons: {
    -                            "OK": function() {
    -                              window.open(href);
    -                              $( this ).dialog( "close" );
    -                            },
    -                            "' . $langs->trans('Cancel') . '": function() {
    -                              $( this ).dialog( "close" );
    -                            }
    -                          }
    -                        });
    +        if (! empty($conf->global->DATAPOLICIES_ENABLE_EMAILS))
    +        {
    +	        $dialog = '<div id="dialogdatapolicies" style="display:none;" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">';
    +	        $dialog .= '<div class="confirmmessage">' . img_help('', '') . ' ' . $langs->trans('DATAPOLICIES_PORTABILITE_CONFIRMATION') . '</div>';
    +	        $dialog .= "</div>";
    +	        $dialog .= '<script>
    +	                  $( function() {
    +	                    $("#rpgpdbtn").on("click", function(){
    +	                        var href = $(this).attr("href");
    +	                        $( "#dialogdatapolicies" ).dialog({
    +	                          modal: true,
    +	                          buttons: {
    +	                            "OK": function() {
    +	                              window.open(href);
    +	                              $( this ).dialog( "close" );
    +	                            },
    +	                            "' . $langs->trans('Cancel') . '": function() {
    +	                              $( this ).dialog( "close" );
    +	                            }
    +	                          }
    +	                        });
     
     
    -                    return false;
    -                    });
    -                  } );
    -                  </script>';
    -        echo $dialog;
    -        if ($parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
    -            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=datapolicies_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    -        } elseif ($parameters['currentcontext'] == 'membercard') {
    -            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=datapolicies_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    -        } elseif ($parameters['currentcontext'] == 'contactcard') {
    -            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=datapolicies_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    -        }
    -        if (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
    -            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=send_datapolicies" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    -        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'membercard') {
    -            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=send_datapolicies" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    -        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'contactcard') {
    -            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=send_datapolicies" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	                    return false;
    +	                    });
    +	                  } );
    +	                  </script>';
    +	        echo $dialog;
    +	        if ($parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
    +	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=datapolicies_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    +	        } elseif ($parameters['currentcontext'] == 'membercard') {
    +	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=datapolicies_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    +	        } elseif ($parameters['currentcontext'] == 'contactcard') {
    +	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=datapolicies_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    +	        }
    +	        if (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
    +	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=send_datapolicies" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'membercard') {
    +	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=send_datapolicies" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'contactcard') {
    +	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=send_datapolicies" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	        }
             }
         }
     
    diff --git a/htdocs/datapolicies/lib/datapolicies.lib.php b/htdocs/datapolicies/lib/datapolicies.lib.php
    index 59366d1f93d..cca255801a8 100644
    --- a/htdocs/datapolicies/lib/datapolicies.lib.php
    +++ b/htdocs/datapolicies/lib/datapolicies.lib.php
    @@ -40,10 +40,13 @@ function datapoliciesAdminPrepareHead()
     	$head[$h][2] = 'settings';
     	$h++;
     
    -	$head[$h][0] = dol_buildpath("/datapolicies/admin/setupmail.php", 1);
    -	$head[$h][1] = $langs->trans("DATAPOLICIESMail");
    -	$head[$h][2] = 'settings';
    -	$h++;
    +	if (! empty($conf->global->DATAPOLICIES_ENABLE_EMAILS))
    +	{
    +		$head[$h][0] = dol_buildpath("/datapolicies/admin/setupmail.php", 1);
    +		$head[$h][1] = $langs->trans("DATAPOLICIESMail");
    +		$head[$h][2] = 'settings';
    +		$h++;
    +	}
     
     	complete_head_from_modules($conf, $langs, $object, $head, $h, 'datapolicies');
     
    
    From 1e635cff1b3bf7d21cb78f2ed1c7669d23dafe43 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 21:00:33 +0200
    Subject: [PATCH 171/433] Fix new stripe API
    
    ---
     .../interface_80_modStripe_Stripe.class.php   | 23 +++++++---
     htdocs/public/payment/newpayment.php          | 46 +++++++++++--------
     htdocs/stripe/class/stripe.class.php          | 19 +++++---
     3 files changed, 55 insertions(+), 33 deletions(-)
    
    diff --git a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
    index 04326e7a3fe..cb03315496a 100644
    --- a/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
    +++ b/htdocs/core/triggers/interface_80_modStripe_Stripe.class.php
    @@ -147,22 +147,33 @@ class InterfaceStripe
     				if ($customer)
     				{
     					$namecleaned = $object->name ? $object->name : null;
    -					$vatcleaned = array(
    -						"tax_id" => $object->tva_intra ? $object->tva_intra : null,	// We force data to "null" if empty as expected by Stripe
    -						"type" => 'vat',
    -					);
    +					$vatcleaned = $object->tva_intra ? $object->tva_intra : null;
    +
    +					$taxinfo = array('type'=>'vat');
    +					if ($vatcleaned)
    +					{
    +						$taxinfo["tax_id"] = $vatcleaned;
    +					}
    +					// We force data to "null" if not defined as expected by Stripe
    +					if (empty($vatcleaned)) $taxinfo=null;
     
     					// Detect if we change a Stripe info (email, description, vat id)
     					$changerequested = 0;
     					if (! empty($object->email) && $object->email != $customer->email) $changerequested++;
     					if ($namecleaned != $customer->description) $changerequested++;
    -					if ($vatcleaned != $customer->tax_info) $changerequested++;
    +					if (! isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned)) $changerequested++;
    +					elseif (isset($customer->tax_info['tax_id']) && is_null($vatcleaned)) $changerequested++;
    +					elseif (isset($customer->tax_info['tax_id']) && ! is_null($vatcleaned))
    +					{
    +						if ($vatcleaned != $customer->tax_info['tax_id']) $changerequested++;
    +					}
     
     					if ($changerequested)
     					{
     						if (! empty($object->email)) $customer->email = $object->email;
     						$customer->description = $namecleaned;
    -						$customer->tax_info = $vatcleaned;
    +						if (empty($taxinfo)) $customer->tax_info = array('type'=>'vat', 'tax_id'=>null);
    +						else $customer->tax_info = $taxinfo;
     
     						$customer->save();
     					}
    diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php
    index 08e50e58be7..e0234fcd1f9 100644
    --- a/htdocs/public/payment/newpayment.php
    +++ b/htdocs/public/payment/newpayment.php
    @@ -413,12 +413,12 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     	$dol_type=(GETPOST('s', 'alpha') ? GETPOST('s', 'alpha') : GETPOST('source', 'alpha'));
       	$dol_id=GETPOST('dol_id', 'int');
       	$vatnumber = GETPOST('vatnumber','alpha');
    -	$savesource=GETPOST('savesource', 'int');
    +  	$savesource=GETPOSTISSET('savesource')?GETPOST('savesource', 'int'):1;
     
    -	dol_syslog("stripeToken = ".$stripeToken, LOG_DEBUG, 0, '_stripe');
    -	dol_syslog("email = ".$email, LOG_DEBUG, 0, '_stripe');
    -	dol_syslog("thirdparty_id = ".$thirdparty_id, LOG_DEBUG, 0, '_stripe');
    -	dol_syslog("vatnumber = ".$vatnumber, LOG_DEBUG, 0, '_stripe');
    +	dol_syslog("POST stripeToken = ".$stripeToken, LOG_DEBUG, 0, '_stripe');
    +	dol_syslog("POST email = ".$email, LOG_DEBUG, 0, '_stripe');
    +	dol_syslog("POST thirdparty_id = ".$thirdparty_id, LOG_DEBUG, 0, '_stripe');
    +	dol_syslog("POST vatnumber = ".$vatnumber, LOG_DEBUG, 0, '_stripe');
     
     	$error = 0;
     
    @@ -444,7 +444,6 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     				$servicestatus = 1;
     			}
     
    -
     			$thirdparty = new Societe($db);
     			$thirdparty->fetch($thirdparty_id);
     
    @@ -455,9 +454,11 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     			$customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 1);
     
     			// Create Stripe card from Token
    -			if (! empty($savesource)) {
    -			$card = $customer->sources->create(array("source" => $stripeToken, "metadata" => $metadata));
    -			} else { $card = $stripeToken; }
    +			if ($savesource) {
    +				$card = $customer->sources->create(array("source" => $stripeToken, "metadata" => $metadata));
    +			} else {
    +				$card = $stripeToken;
    +			}
     
     			if (empty($card))
     			{
    @@ -468,9 +469,9 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     			}
     			else
     			{
    -        if (! empty($FULLTAG))       $metadata["FULLTAG"] = $FULLTAG;
    -        if (! empty($dol_id))        $metadata["dol_id"] = $dol_id;
    -        if (! empty($dol_type))      $metadata["dol_type"] = $dol_type;
    +				if (! empty($FULLTAG))       $metadata["FULLTAG"] = $FULLTAG;
    +				if (! empty($dol_id))        $metadata["dol_id"] = $dol_id;
    +				if (! empty($dol_type))      $metadata["dol_type"] = $dol_type;
     
     				dol_syslog("Create charge on card ".$card->id, LOG_DEBUG, 0, '_stripe');
     				$charge = \Stripe\Charge::create(array(
    @@ -495,24 +496,29 @@ if ($action == 'charge' && ! empty($conf->stripe->enabled))
     		}
     		else
     		{
    -			$vatcleaned = array(
    -				"tax_id" => $vatnumber ? $vatnumber : null,	// We force data to "null" if empty as expected by Stripe
    -				"type" => 'vat',
    -			);
    +			$vatcleaned = $vatnumber ? $vatnumber : null;
    +
    +			$taxinfo = array('type'=>'vat');
    +			if ($vatcleaned)
    +			{
    +				$taxinfo["tax_id"] = $vatcleaned;
    +			}
    +			// We force data to "null" if not defined as expected by Stripe
    +			if (empty($vatcleaned)) $taxinfo=null;
     
     			dol_syslog("Create anonymous customer card profile", LOG_DEBUG, 0, '_stripe');
     			$customer = \Stripe\Customer::create(array(
     				'email' => $email,
     				'description' => ($email?'Anonymous customer for '.$email:'Anonymous customer'),
     				'metadata' => $metadata,
    -				'tax_info' => $vatcleaned,
    +				'tax_info' => $taxinfo,
     				'source'  => $stripeToken           // source can be a token OR array('object'=>'card', 'exp_month'=>xx, 'exp_year'=>xxxx, 'number'=>xxxxxxx, 'cvc'=>xxx, 'name'=>'Cardholder's full name', zip ?)
     			));
     			// Return $customer = array('id'=>'cus_XXXX', ...)
     
    -        if (! empty($FULLTAG))       $metadata["FULLTAG"] = $FULLTAG;
    -        if (! empty($dol_id))        $metadata["dol_id"] = $dol_id;
    -        if (! empty($dol_type))      $metadata["dol_type"] = $dol_type;
    +			if (! empty($FULLTAG))       $metadata["FULLTAG"] = $FULLTAG;
    +			if (! empty($dol_id))        $metadata["dol_id"] = $dol_id;
    +			if (! empty($dol_type))      $metadata["dol_type"] = $dol_type;
     
     			// The customer was just created with a source, so we can make a charge
     			// with no card defined, the source just used for customer creation will be used.
    diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php
    index 5aabb60f07c..db2553ee167 100644
    --- a/htdocs/stripe/class/stripe.class.php
    +++ b/htdocs/stripe/class/stripe.class.php
    @@ -189,13 +189,18 @@ class Stripe extends CommonObject
     					"description" => $object->name,
     					"metadata" => array('dol_id'=>$object->id, 'dol_version'=>DOL_VERSION, 'dol_entity'=>$conf->entity, 'ipaddress'=>(empty($_SERVER['REMOTE_ADDR'])?'':$_SERVER['REMOTE_ADDR']))
     				);
    -        
    -                        if ($object->tva_intra!=null)
    -	                {
    -				$dataforcustomer["tax_info"] = array(
    -                                        "tax_id" => $object->tva_intra,
    -                                        "type" => 'vat');
    -			}
    +
    +				$vatcleaned = $object->tva_intra ? $object->tva_intra : null;
    +
    +				$taxinfo = array('type'=>'vat');
    +				if ($vatcleaned)
    +				{
    +					$taxinfo["tax_id"] = $vatcleaned;
    +				}
    +				// We force data to "null" if not defined as expected by Stripe
    +				if (empty($vatcleaned)) $taxinfo=null;
    +
    +				$dataforcustomer["tax_info"] = $taxinfo;
     
     				//$a = \Stripe\Stripe::getApiKey();
     				//var_dump($a);var_dump($key);exit;
    
    From b78932b9f7679cec79d97cf6b0046c6bdec3bde4 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 12 Oct 2018 21:11:40 +0200
    Subject: [PATCH 172/433] Prepare 7.0.5
    
    ---
     htdocs/filefunc.inc.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php
    index adfe8cea7e9..dbc0e4bda8c 100644
    --- a/htdocs/filefunc.inc.php
    +++ b/htdocs/filefunc.inc.php
    @@ -31,7 +31,7 @@
      */
     
     if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr');
    -if (! defined('DOL_VERSION')) define('DOL_VERSION','7.0.4');		// a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
    +if (! defined('DOL_VERSION')) define('DOL_VERSION','7.0.5');		// a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
     
     if (! defined('EURO')) define('EURO',chr(128));
     
    
    From e2748953c3a7e8b0de07f504124bcc183ec90efb Mon Sep 17 00:00:00 2001
    From: atm-ph <phf@atm-consulting.fr>
    Date: Fri, 12 Oct 2018 22:31:47 +0200
    Subject: [PATCH 173/433] Fix print extrafield date in list
    
    ---
     htdocs/core/tpl/extrafields_list_print_fields.tpl.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
    index 855794da2d6..6d72c63ab41 100644
    --- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
    +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php
    @@ -21,7 +21,7 @@ if (! empty($extrafieldsobjectkey))	// New method: $extrafieldsobject can be 'so
     				if ($align) print ' align="'.$align.'"';
     				print '>';
     				$tmpkey='options_'.$key;
    -				if (in_array($extrafields->attributes[$extrafieldsobjectkey]['type'][$key], array('date', 'datetime', 'timestamp')) && !preg_match('/^[0-9]{10}$/', $obj->$tmpkey))
    +				if (in_array($extrafields->attributes[$extrafieldsobjectkey]['type'][$key], array('date', 'datetime', 'timestamp')) && !is_numeric($obj->$tmpkey))
     				{
     					$value = $db->jdate($obj->$tmpkey);
     				}
    
    From 0f8ac57c854c292e0349a9c247d87513d7180893 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Fri, 12 Oct 2018 22:34:23 +0200
    Subject: [PATCH 174/433] remove var_dump
    
    ---
     htdocs/core/lib/date.lib.php | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php
    index 23f4ebd1186..8985a4e7621 100644
    --- a/htdocs/core/lib/date.lib.php
    +++ b/htdocs/core/lib/date.lib.php
    @@ -599,7 +599,6 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     			foreach($arrayofdaystring as $daystring)
     			{
     				$tmp=explode('-',$daystring);
    -				var_dump($tmp);
     				if ($tmp[2])
     				{
     					if ($tmp[0] == $annee && $tmp[1] == $mois && $tmp[2] == $jour) $ferie=true;
    
    From 23e4cd57f33f8575f2a52912569063e091ae9c7e Mon Sep 17 00:00:00 2001
    From: atm-ph <phf@atm-consulting.fr>
    Date: Fri, 12 Oct 2018 23:27:38 +0200
    Subject: [PATCH 175/433] Fix warnings PHP7
    
    ---
     htdocs/product/reassort.php              | 1 +
     htdocs/product/reassortlot.php           | 1 +
     htdocs/product/stock/productlot_list.php | 3 ++-
     3 files changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php
    index 70dce7470cd..b1b612d1a39 100644
    --- a/htdocs/product/reassort.php
    +++ b/htdocs/product/reassort.php
    @@ -54,6 +54,7 @@ $fourn_id = GETPOST("fourn_id",'int');
     $sortfield = GETPOST("sortfield",'alpha');
     $sortorder = GETPOST("sortorder",'alpha');
     $page = GETPOST("page",'int');
    +if (empty($page) || $page < 0) $page = 0;
     if (! $sortfield) $sortfield="p.ref";
     if (! $sortorder) $sortorder="ASC";
     $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
    diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php
    index 490986b155e..e1b6c82c8f3 100644
    --- a/htdocs/product/reassortlot.php
    +++ b/htdocs/product/reassortlot.php
    @@ -58,6 +58,7 @@ $fourn_id = GETPOST("fourn_id",'int');
     $sortfield = GETPOST("sortfield",'alpha');
     $sortorder = GETPOST("sortorder",'alpha');
     $page = GETPOST("page",'int');
    +if (empty($page) || $page < 0) $page = 0;
     if (! $sortfield) $sortfield="p.ref";
     if (! $sortorder) $sortorder="ASC";
     $limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
    diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php
    index 325ddd5f796..8e5e5d925e9 100644
    --- a/htdocs/product/stock/productlot_list.php
    +++ b/htdocs/product/stock/productlot_list.php
    @@ -47,6 +47,7 @@ $id			= GETPOST('id','int');
     $action		= GETPOST('action','alpha');
     $backtopage = GETPOST('backtopage');
     $myparam	= GETPOST('myparam','alpha');
    +$toselect = GETPOST('toselect', 'array');
     
     
     $search_entity=GETPOST('search_entity','int');
    @@ -152,7 +153,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
         $search_import_key='';
     	$search_date_creation='';
     	$search_date_update='';
    -	$toselect='';
    +	$toselect=array();
     	$search_array_options=array();
     }
     
    
    From 7b17b453bf38b0864cb7772effd1e1f25ef9026b Mon Sep 17 00:00:00 2001
    From: atm-ph <phf@atm-consulting.fr>
    Date: Fri, 12 Oct 2018 23:29:35 +0200
    Subject: [PATCH 176/433] Fix sort and switch page
    
    ---
     htdocs/product/reassort.php    | 35 ++++++++++++++-------------
     htdocs/product/reassortlot.php | 43 +++++++++++++++++++---------------
     2 files changed, 43 insertions(+), 35 deletions(-)
    
    diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php
    index b1b612d1a39..fe087fd16a3 100644
    --- a/htdocs/product/reassort.php
    +++ b/htdocs/product/reassort.php
    @@ -92,11 +92,15 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
         $sref="";
         $snom="";
         $sall="";
    +	$tosell="";
    +	$tobuy="";
         $search_sale="";
         $search_categ="";
         $type="";
         $catid='';
         $toolowstock='';
    +	$fourn_id='';
    +	$sbarcode='';
     }
     
     
    @@ -183,6 +187,20 @@ if ($resql)
     	}
     	$texte.=' ('.$langs->trans("Stocks").')';
     
    +	$param='';
    +	if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
    +	if ($sall)	$param.="&sall=".$sall;
    +	if ($tosell)	$param.="&tosell=".$tosell;
    +	if ($tobuy)		$param.="&tobuy=".$tobuy;
    +	if ($type)		$param.="&type=".$type;
    +	if ($fourn_id)	$param.="&fourn_id=".$fourn_id;
    +	if ($snom)		$param.="&snom=".$snom;
    +	if ($sref)		$param.="&sref=".$sref;
    +	if ($search_sale) $param.="&search_sale=".$search_sale;
    +	if ($search_categ) $param.="&search_categ=".$search_categ;
    +	if ($toolowstock) $param.="&toolowstock=".$toolowstock;
    +	if ($sbarcode) $param.="&sbarcode=".$sbarcode;
    +	if ($catid) $param.="&catid=".$catid;
     
     	llxHeader("", $texte, $helpurl);
     
    @@ -193,14 +211,7 @@ if ($resql)
         print '<input type="hidden" name="page" value="'.$page.'">';
     	print '<input type="hidden" name="type" value="'.$type.'">';
     
    -	if ($sref || $snom || $sall || GETPOST('search'))
    -	{
    -	    print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&amp;sall=".$sall."&amp;tosell=".$tosell."&amp;tobuy=".$tobuy.(!empty($search_categ) ? '&amp;search_categ='.$search_categ : '').(!empty($toolowstock) ? '&amp;toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit);
    -	}
    -	else
    -	{
    -	    print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&amp;type=$type":"").(!empty($search_categ) ? '&amp;search_categ='.$search_categ : '').(!empty($toolowstock) ? '&amp;toolowstock='.$toolowstock : ''), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit);
    -	}
    +	print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit);
     
     	if (! empty($catid))
     	{
    @@ -236,14 +247,6 @@ if ($resql)
             print '</div>';
         }
     
    -	$param='';
    -	if ($tosell)	$param.="&tosell=".$tosell;
    -	if ($tobuy)		$param.="&tobuy=".$tobuy;
    -	if ($type)		$param.="&type=".$type;
    -	if ($fourn_id)	$param.="&fourn_id=".$fourn_id;
    -	if ($snom)		$param.="&snom=".$snom;
    -	if ($sref)		$param.="&sref=".$sref;
    -
     	$formProduct = new FormProduct($db);
     	$formProduct->loadWarehouses();
     	$warehouses_list = $formProduct->cache_warehouses;
    diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php
    index e1b6c82c8f3..7cedbcd3981 100644
    --- a/htdocs/product/reassortlot.php
    +++ b/htdocs/product/reassortlot.php
    @@ -89,6 +89,8 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
         $sref="";
         $snom="";
         $sall="";
    +	$tosell="";
    +	$tobuy="";
         $search_sale="";
         $search_categ="";
         $type="";
    @@ -96,6 +98,8 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
         $toolowstock='';
         $search_batch='';
         $search_warehouse='';
    +	$fourn_id='';
    +	$sbarcode='';
     }
     
     
    @@ -194,6 +198,24 @@ if ($resql)
     	}
     	$texte.=' ('.$langs->trans("StocksByLotSerial").')';
     
    +	$param='';
    +	if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
    +	if ($sall)		$param.="&sall=".$sall;
    +	if ($tosell)		$param.="&tosell=".$tosell;
    +	if ($tobuy)			$param.="&tobuy=".$tobuy;
    +	if ($type)			$param.="&type=".$type;
    +	if ($fourn_id)		$param.="&fourn_id=".$fourn_id;
    +	if ($snom)			$param.="&snom=".$snom;
    +	if ($sref)			$param.="&sref=".$sref;
    +	if ($search_batch)	$param.="&search_batch=".$search_batch;
    +	if ($sbarcode)		$param.="&sbarcode=".$sbarcode;
    +	if ($search_warehouse)	$param.="&search_warehouse=".$search_warehouse;
    +	if ($catid)			$param.="&catid=".$catid;
    +	if ($toolowstock)	$param.="&toolowstock=".$toolowstock;
    +	if ($search_sale)	$param.="&search_sale=".$search_sale;
    +	if ($search_categ)	$param.="&search_categ=".$search_categ;
    +	/*if ($eatby)		$param.="&eatby=".$eatby;
    +	if ($sellby)	$param.="&sellby=".$sellby;*/
     
     	llxHeader("",$title,$helpurl,$texte);
     
    @@ -204,14 +226,8 @@ if ($resql)
         print '<input type="hidden" name="page" value="'.$page.'">';
     	print '<input type="hidden" name="type" value="'.$type.'">';
     
    -	if ($sref || $snom || $sall || GETPOST('search'))
    -	{
    -		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=".$sref."&snom=".$snom."&amp;sall=".$sall."&amp;tosell=".$tosell."&amp;tobuy=".$tobuy, $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit);
    -	}
    -	else
    -	{
    -		print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], "&sref=$sref&snom=$snom&fourn_id=$fourn_id".(isset($type)?"&amp;type=$type":""), $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit);
    -	}
    +	print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder,'',$num, $nbtotalofrecords, 'title_products', 0, '', '', $limit);
    +
     
     	if (! empty($catid))
     	{
    @@ -245,17 +261,6 @@ if ($resql)
         }
     
     
    -	$param='';
    -	if ($tosell)		$param.="&tosell=".$tosell;
    -	if ($tobuy)			$param.="&tobuy=".$tobuy;
    -	if ($type)			$param.="&type=".$type;
    -	if ($fourn_id)		$param.="&fourn_id=".$fourn_id;
    -	if ($snom)			$param.="&snom=".$snom;
    -	if ($sref)			$param.="&sref=".$sref;
    -	if ($search_batch)	$param.="&search_batch=".$search_batch;
    -	/*if ($eatby)		$param.="&eatby=".$eatby;
    -	if ($sellby)	$param.="&sellby=".$sellby;*/
    -
         print '<div class="div-table-responsive">';
     	print '<table class="tagtable liste'.($moreforfilter?" listwithfilterbefore":"").'">';
     
    
    From 9551cb12f5eabbdc23c11304f928d0191661f62d Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 09:59:33 +0200
    Subject: [PATCH 177/433] Standardize and update code
    
    ---
     htdocs/admin/dict.php   | 2 +-
     htdocs/contact/list.php | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php
    index aaa4fb03706..0b5b63d35d6 100644
    --- a/htdocs/admin/dict.php
    +++ b/htdocs/admin/dict.php
    @@ -592,7 +592,7 @@ if ($id == 10)
      * Actions
      */
     
    -if (GETPOST('button_removefilter') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter_x'))
    +if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha'))
     {
         $search_country_id = '';
         $search_code = '';
    diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php
    index cd536118f8e..52a2c4bbe7f 100644
    --- a/htdocs/contact/list.php
    +++ b/htdocs/contact/list.php
    @@ -202,7 +202,7 @@ if (empty($reshook))
     	include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
     
     	// Did we click on purge search criteria ?
    -	if (GETPOST('button_removefilter_x') || GETPOST('button_removefilter.x') || GETPOST('button_removefilter'))	// All tests are required to be compatible with all browsers
    +	if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha'))	// All tests are required to be compatible with all browsers
     	{
     		$sall="";
     		$search_id='';
    
    From d98ebbd9ee2dec094491d52c7555df1acb862f84 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 10:39:27 +0200
    Subject: [PATCH 178/433] Standardize and update code
    
    ---
     htdocs/compta/prelevement/create.php | 2 +-
     htdocs/fichinter/card-rec.php        | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php
    index 0d07c341458..3dccc0ff912 100644
    --- a/htdocs/compta/prelevement/create.php
    +++ b/htdocs/compta/prelevement/create.php
    @@ -46,7 +46,7 @@ $result = restrictedArea($user, 'prelevement', '', '', 'bons');
     $action = GETPOST('action','alpha');
     $mode = GETPOST('mode','alpha')?GETPOST('mode','alpha'):'real';
     $format = GETPOST('format','aZ09');
    -$limit = GETPOST('limit')?GETPOST('limit','int'):$conf->liste_limit;
    +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
     $page = GETPOST("page",'int');
     if (empty($page) || $page == -1) { $page = 0; }     // If $page is not defined, or '' or -1
     $offset = $limit * $page;
    diff --git a/htdocs/fichinter/card-rec.php b/htdocs/fichinter/card-rec.php
    index 8ef79639e05..66f693858c9 100644
    --- a/htdocs/fichinter/card-rec.php
    +++ b/htdocs/fichinter/card-rec.php
    @@ -60,7 +60,7 @@ $result = restrictedArea($user, 'ficheinter', $id, $objecttype);
     if ($page == -1)
     	$page = 0 ;
     
    -$limit = GETPOST('limit')?GETPOST('limit', 'int'):$conf->liste_limit;
    +$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit;
     $offset = $limit * $page ;
     
     if ($sortorder == "")
    
    From ec12a0d456485b992475b5accf76954efbabbbf3 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 11:03:05 +0200
    Subject: [PATCH 179/433] update resources url
    
    ---
     doc/index.html | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/doc/index.html b/doc/index.html
    index b888b13d9a6..5c655136e3e 100644
    --- a/doc/index.html
    +++ b/doc/index.html
    @@ -11,15 +11,15 @@ informations on Dolibarr.<br>
     But if you are looking for other resources (downloads, documentation, addons, ...), you can find this
     on Internet on web following sites:<br>
     <br>
    -* <a href="http://wiki.dolibarr.org">Dolibarr wiki (documentation)</a><br>
    +* <a href="https://wiki.dolibarr.org">Dolibarr wiki (documentation)</a><br>
     <br>
    -* <a href="http://www.dolibarr.org">Dolibarr portal (official website)</a><br>
    +* <a href="https://www.dolibarr.org">Dolibarr portal (official website)</a><br>
     <br>
    -* <a href="http://demo.dolibarr.org">Dolibarr demo (online)</a><br>
    +* <a href="https://demo.dolibarr.org">Dolibarr demo (online)</a><br>
     <br>
    -* <a href="http://www.nltechno.com/pages/dolibarrwinbin.php">DoliWamp, the Dolibarr for Windows</a><br>
    +* <a href="https://www.nltechno.com/pages/dolibarrwinbin.php">DoliWamp, the Dolibarr for Windows</a><br>
     <br>
    -* <a href="http://www.dolistore.com">DoliStore (official addons/plugins market place)</a><br>
    +* <a href="https://www.dolistore.com">DoliStore (official addons/plugins market place)</a><br>
     
     </body>
     </html>
    \ No newline at end of file
    
    From f8fbb976f662f8f9d1b692ee945ca8838b7657ba Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 11:06:13 +0200
    Subject: [PATCH 180/433] fix typo and update resource url
    
    ---
     doc/user/README-FR | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/doc/user/README-FR b/doc/user/README-FR
    index f3a839de008..fbf67fd89bc 100644
    --- a/doc/user/README-FR
    +++ b/doc/user/README-FR
    @@ -3,9 +3,9 @@ README (french)
     Documentation utilisateur
     --------------------------------
     
    -* Pour une prise en main et installation rapide, consulter le fichier
    +* Pour une prise en main et installation rapide, consultez le fichier
     README-FR à la racine.
     
    -* Une documentation utilisateur francophone plus consistente est disponible en
    +* Une documentation utilisateur francophone plus consistante est disponible en
     ligne sur le site Web de Dolibarr à l'adresse:
    -http://www.dolibarr.fr
    +https://www.dolibarr.fr
    
    From 653589cc6786fcc380e99be805cf7056981d1f21 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 11:07:04 +0200
    Subject: [PATCH 181/433] update resource url
    
    ---
     doc/user/README | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/doc/user/README b/doc/user/README
    index 19507dba0e4..129dff11058 100644
    --- a/doc/user/README
    +++ b/doc/user/README
    @@ -4,4 +4,4 @@ User guide
     --------------------------------
     
     * All Dolibarr guides are available, on line, on the Dolibarr Web site:
    -http://www.dolibarr.org
    +https://www.dolibarr.org
    
    From e71a738209fa0b10aae23dd6724840ec3d4dbd57 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 11:08:58 +0200
    Subject: [PATCH 182/433] fix typo and update resource url
    
    ---
     doc/install/README-FR | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/doc/install/README-FR b/doc/install/README-FR
    index f954601ae0d..2cee29cf2df 100644
    --- a/doc/install/README-FR
    +++ b/doc/install/README-FR
    @@ -9,19 +9,19 @@ Téléchargement
     * Dolibarr ERP/CRM can be downloaded at sourceforge:
     http://sourceforge.net/projects/dolibarr/files
     or from Dolibarr official web site:
    -http://www.dolibarr.org
    +https://www.dolibarr.org
     
     * Most external modules are only available on DoliStore:
    -http://www.dolistore.org
    +https://www.dolistore.org
     
     
     --------------------------------
     Documentation utilisateur
     --------------------------------
     
    -* Pour une prise en main et installation rapide, consulter le fichier
    +* Pour une prise en main et installation rapide, consultez le fichier
     README-FR à la racine.
     
    -* Une documentation utilisateur francophone plus consistente est disponible en
    +* Une documentation utilisateur francophone plus consistante est disponible en
     ligne sur le wiki de Dolibarr à l'adresse:
    -http://wiki.dolibarr.org
    +https://wiki.dolibarr.org
    
    From a48554e8757659f20a69e6e7d66f0ef87622fd80 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 11:19:41 +0200
    Subject: [PATCH 183/433] fix typo
    
    ---
     dev/dolibarr_changes.txt | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt
    index 6303eaafaae..24832103c6c 100644
    --- a/dev/dolibarr_changes.txt
    +++ b/dev/dolibarr_changes.txt
    @@ -1,5 +1,5 @@
     
    -This file describe changes made on external library after beeing included
    +This file describes changes made on external libraries after being included
     in Dolibarr root.
     
     
    
    From 1e0cf8dc8a785cec1377d88c017cc495f7ac7085 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 11:42:29 +0200
    Subject: [PATCH 184/433] fix typo
    
    ---
     README-FR.md | 34 +++++++++++++++++-----------------
     1 file changed, 17 insertions(+), 17 deletions(-)
    
    diff --git a/README-FR.md b/README-FR.md
    index 4435d47d30e..19d4ae25df9 100644
    --- a/README-FR.md
    +++ b/README-FR.md
    @@ -16,8 +16,8 @@ Dolibarr est distribué sous les termes de la licence GNU General Public License
     ## INSTALLER DOLIBARR
     
     Si vous n'avez pas de connaissances techniques, et que vous recherchez
    -un programme d'installation qui install Dolibarr ERP/CRM en quelques clics,
    -vous devez vous réorienter vers DoliWamp (la version tout-en-un
    +un programme d'installation qui installe Dolibarr ERP/CRM en quelques clics,
    +vous devez vous ré-orienter vers DoliWamp (la version tout-en-un
     de Dolibarr pour Windows), DoliDeb (la version tout-en-un pour Debian ou
     Ubuntu) ou DoliRpm (la version tout-en-un de Dolibarr pour Fedora, Redhat,
     OpenSuse, Mandriva ou Mageia).
    @@ -25,39 +25,39 @@ OpenSuse, Mandriva ou Mageia).
     Vous pouvez les télécharger depuis la rubrique *download* du portail officiel: 
     https://www.dolibarr.org/
     
    -Si vous avez déjà installé un serveur Web avec PHP et une base de donnée (MariaDb/MySql/PostgreSql),
    +Si vous avez déjà installé un serveur Web avec PHP et une base de données (MariaDb/MySql/PostgreSql),
     vous pouvez installer Dolibarr avec cette version de la manière suivante:
     
    -- Copier le répertoire "dolibarr" et son contenu dans la racine de votre serveur
    -  web, ou bien copier le répertoire sur le serveur et configurer ce serveur pour
    +- Copiez le répertoire "dolibarr" et son contenu dans la racine de votre serveur
    +  web, ou bien copiez le répertoire sur le serveur et configurez ce serveur pour
       utiliser "dolibarr/htdocs" comme racine d'un nouveau virtual host (ce second 
       choix requiert des compétences et habilitations en administration du serveur
       web).
       
    -- Créer un fichier vide "htdocs/conf/conf.php" et attribuer les permissions
    +- Créez un fichier vide "htdocs/conf/conf.php" et attribuez les permissions
       en lecture et écriture pour le user du serveur web (les permissions en 
       écriture seront supprimées une fois l'installation terminée).
     
    -- Depuis votre navigateur, appeler la page "install/" de dolibarr. L'url dépend 
    -  du choix fait à la première etape:
    +- Depuis votre navigateur, appelez la page "install/" de dolibarr. L'url dépend 
    +  du choix fait à la première étape:
        http://localhost/dolibarr/htdocs/install/
       ou
        http://yourdolibarrvirtualhost/install/
        
    -- Suivez les instructions fournies par l'installeur...
    +- Suivez les instructions fournies par l'installateur...
     
     
     
     ## METTRE A JOUR DOLIBARR
     
    -Pour mettre a jour Dolibarr depuis une vieille version vers celle ci:
    -- Ecraser les vieux fichiers dans le vieux repertoire 'dolibarr' par les fichiers
    +Pour mettre à jour Dolibarr depuis une vieille version vers celle ci:
    +- Ecrasez les vieux fichiers dans le vieux répertoire 'dolibarr' par les fichiers
       fournis dans ce nouveau package.
       
    -- Au prochain accès, Dolibarr proposera la page de "mise a jour" des données (si necessaire).
    -  Si un fichier install.lock existe pour vérouiller le processus de mise à jour, il sera demandé de le supprimer manuellement (vous devriez trouver le fichier install.lock dans le répertoire utilisé pour stocker les documents générés ou transféré sur le serveur. Dans la plupart des cas, c'est le répertoire appelé "documents") 
    -
    -*Note: Le processus de migration peut etre lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/*
    +- Au prochain accès, Dolibarr proposera la page de "mise à jour" des données (si nécessaire).
    +  Si un fichier install.lock existe pour verrouiller le processus de mise à jour, il sera demandé de le supprimer manuellement (vous devriez trouver le fichier install.lock dans le répertoire utilisé pour stocker les documents générés ou transférés sur le serveur. Dans la plupart des cas, c'est le répertoire appelé "documents") 
    +  
    +*Note: Le processus de migration peut être lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/*
       
     
     ## CE QUI EST NOUVEAU
    @@ -136,7 +136,7 @@ Dolibarr peut aussi être étendu à volonté avec l'ajout de module/application
     
     ## CE QUE DOLIBARR NE PEUT PAS (ENCORE) FAIRE
     
    -Voici un liste de fonctionnalites pas encore gérées par Dolibarr:
    +Voici un liste de fonctionnalités pas encore gérées par Dolibarr:
     - Dolibarr ne contient pas de module de Gestion de la paie.
     - Les tâches du module de gestion de projets n'ont pas de dépendances entre elle.
     - Dolibarr n'embarque pas de Webmail intégré nativement.
    @@ -145,7 +145,7 @@ Voici un liste de fonctionnalites pas encore gérées par Dolibarr:
     
     ## DOCUMENTATION
     
    -Les documentations utilisateur, développeur et traducteur sont disponible sous forme de ressources de la communautés via la site [Wiki](https://wiki.dolibarr.org).
    +La documentation utilisateur, développeur et traducteur est disponible sous forme de ressources de la communauté via le site [Wiki](https://wiki.dolibarr.org).
     
     
     ## CONTRIBUER
    
    From 30630ff3686a9fdafca8f785ccf367ebe3a5e549 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 11:58:19 +0200
    Subject: [PATCH 185/433] fix typo
    
    ---
     .../modules/commande/doc/pdf_einstein.modules.php  | 14 +++++++-------
     1 file changed, 7 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    index d3b5d12d620..37d2742c1b1 100644
    --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    @@ -149,13 +149,13 @@ class pdf_einstein extends ModelePDFCommandes
     		$this->marge_haute =isset($conf->global->MAIN_PDF_MARGIN_TOP)?$conf->global->MAIN_PDF_MARGIN_TOP:10;
     		$this->marge_basse =isset($conf->global->MAIN_PDF_MARGIN_BOTTOM)?$conf->global->MAIN_PDF_MARGIN_BOTTOM:10;
     
    -		$this->option_logo = 1;                    // Affiche logo
    -		$this->option_tva = 1;                     // Gere option tva FACTURE_TVAOPTION
    -		$this->option_modereg = 1;                 // Affiche mode reglement
    -		$this->option_condreg = 1;                 // Affiche conditions reglement
    -		$this->option_codeproduitservice = 1;      // Affiche code produit-service
    -		$this->option_multilang = 1;               // Dispo en plusieurs langues
    -		$this->option_escompte = 0;                // Affiche si il y a eu escompte
    +		$this->option_logo = 1;                    // Display logo
    +		$this->option_tva = 1;                     // Manage the vat option FACTURE_TVAOPTION
    +		$this->option_modereg = 1;                 // Display payment mode
    +		$this->option_condreg = 1;                 // Display payment terms
    +		$this->option_codeproduitservice = 1;      // Display product-service code
    +		$this->option_multilang = 1;               // Available in several languages
    +		$this->option_escompte = 0;                // Displays if there has been a discount
     		$this->option_credit_note = 0;             // Support credit notes
     		$this->option_freetext = 1;				   // Support add of a personalised text
     		$this->option_draft_watermark = 1;		   // Support add of a watermark on drafts
    
    From e5cc4ae61b21bb34ca58297ea2fb25598a8a3f38 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sat, 13 Oct 2018 12:00:59 +0200
    Subject: [PATCH 186/433] Code comment
    
    ---
     htdocs/core/modules/import/import_csv.modules.php  | 8 +++++---
     htdocs/core/modules/import/import_xlsx.modules.php | 7 +++++--
     2 files changed, 10 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php
    index 60dc9bf6c15..34bff81e55c 100644
    --- a/htdocs/core/modules/import/import_csv.modules.php
    +++ b/htdocs/core/modules/import/import_csv.modules.php
    @@ -633,6 +633,7 @@ class ImportCsv extends ModeleImports
     				//print 'listfields='.$listfields.'<br>listvalues='.$listvalues.'<br>';
     
     				// If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined
    +				// so we can try to make the insert or update now.
     				if (! $errorforthistable)
     				{
     					//print "$alias/$tablename/$listfields/$listvalues<br>";
    @@ -644,7 +645,7 @@ class ImportCsv extends ModeleImports
     						if (!empty($updatekeys)) {
     							// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
     
    -							if (empty($lastinsertid)) {
    +							if (empty($lastinsertid)) {	// No insert done yet for a parent table
     								$sqlSelect = 'SELECT rowid FROM '.$tablename;
     
     								$data = array_combine($listfields, $listvalues);
    @@ -680,10 +681,11 @@ class ImportCsv extends ModeleImports
     									$error++;
     								}
     							} else {
    -								// We have a last INSERT ID. Check if we have a row referencing this foreign key.
    +								// We have a last INSERT ID (got by previous pass), so we check if we have a row referencing this foreign key.
     								// This is required when updating table with some extrafields. When inserting a record in parent table, we can make
     								// a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record
    -								// may already exists. So we rescan the extrafield table to be know if record exists or not for the rowid.
    +								// may already exists. So we rescan the extrafield table to know if record exists or not for the rowid.
    +								// Note: For extrafield tablename, we have in importfieldshidden_array an enty 'extra.fk_object'=>'lastrowid-tableparent' so $keyfield is 'fk_object'
     								$sqlSelect = 'SELECT rowid FROM '.$tablename;
     
     								if(empty($keyfield)) $keyfield = 'rowid';
    diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php
    index 36b57e2d69a..2c37caa5d40 100644
    --- a/htdocs/core/modules/import/import_xlsx.modules.php
    +++ b/htdocs/core/modules/import/import_xlsx.modules.php
    @@ -656,6 +656,7 @@ class ImportXlsx extends ModeleImports
     				//print 'listfields='.$listfields.'<br>listvalues='.$listvalues.'<br>';
     
     				// If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined
    +				// so we can try to make the insert or update now.
     				if (! $errorforthistable)
     				{
     					//print "$alias/$tablename/$listfields/$listvalues<br>";
    @@ -665,7 +666,8 @@ class ImportXlsx extends ModeleImports
     						$insertdone = false;
     						if (!empty($updatekeys)) {
     							// We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
    -							if (empty($lastinsertid)) {
    +
    +							if (empty($lastinsertid)) {	// No insert done yet for a parent table
     								$sqlSelect = 'SELECT rowid FROM '.$tablename;
     
     								$data = array_combine($listfields, $listvalues);
    @@ -704,7 +706,8 @@ class ImportXlsx extends ModeleImports
     								// We have a last INSERT ID. Check if we have a row referencing this foreign key.
     								// This is required when updating table with some extrafields. When inserting a record in parent table, we can make
     								// a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record
    -								// may already exists. So we rescan the extrafield table to be know if record exists or not for the rowid.
    +								// may already exists. So we rescan the extrafield table to know if record exists or not for the rowid.
    +								// Note: For extrafield tablename, we have in importfieldshidden_array an enty 'extra.fk_object'=>'lastrowid-tableparent' so $keyfield is 'fk_object'
     								$sqlSelect = 'SELECT rowid FROM '.$tablename;
     
     								if(empty($keyfield)) $keyfield = 'rowid';
    
    From effd11e1f9bf9a4e875e4db68c6e55a47cda90da Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 12:42:01 +0200
    Subject: [PATCH 187/433] translation
    
    ---
     htdocs/core/modules/commande/doc/pdf_einstein.modules.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    index 37d2742c1b1..273027f3b99 100644
    --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    @@ -27,7 +27,7 @@
     /**
      *	\file       htdocs/core/modules/commande/doc/pdf_einstein.modules.php
      *	\ingroup    commande
    - *	\brief      Fichier de la classe permettant de generer les commandes au modele Einstein
    + *	\brief      File of Class to generate PDF orders with template Einstein
      */
     
     require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
    @@ -38,7 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
     
     
     /**
    - *	Classe to generate PDF orders with template Einstein
    + *	Class to generate PDF orders with template Einstein
      */
     class pdf_einstein extends ModelePDFCommandes
     {
    
    From 31152e10f6915f318ea7735db4eb8d52ba8ca2d5 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sat, 13 Oct 2018 13:27:59 +0200
    Subject: [PATCH 188/433] Trans
    
    ---
     htdocs/langs/fr_FR/users.lang | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/langs/fr_FR/users.lang b/htdocs/langs/fr_FR/users.lang
    index e0f461cd196..fa5e772fe7e 100644
    --- a/htdocs/langs/fr_FR/users.lang
    +++ b/htdocs/langs/fr_FR/users.lang
    @@ -6,7 +6,7 @@ Permission=Droit
     Permissions=Droits
     EditPassword=Modifier mot de passe
     SendNewPassword=Régénérer et envoyer mot de passe
    -SendNewPasswordLink=Envoyer le lien pour réinitialiser le mot de passe
    +SendNewPasswordLink=Réinitialiser le mot de passe
     ReinitPassword=Régénérer mot de passe
     PasswordChangedTo=Mot de passe modifié en: %s
     SubjectNewPassword=Votre mot de passe pour %s
    
    From 56f5aaf1ad147d0d85c4cc9cadab75cd3d56ccb2 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sat, 13 Oct 2018 13:56:23 +0200
    Subject: [PATCH 189/433] html5
    
    ---
     dev/examples/mail/dolibarr_mail_simpleHTML.txt | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/dev/examples/mail/dolibarr_mail_simpleHTML.txt b/dev/examples/mail/dolibarr_mail_simpleHTML.txt
    index 5c552221ca6..391800f5095 100644
    --- a/dev/examples/mail/dolibarr_mail_simpleHTML.txt
    +++ b/dev/examples/mail/dolibarr_mail_simpleHTML.txt
    @@ -4,4 +4,4 @@ X-Mailer: Dolibarr version 2.7.0-beta (using php mail)
     MIME-Version: 1.0
     Content-Type: text/html; charset=UTF-8
     Content-Transfer-Encoding: 8bit
    -<html><head><title></title></head><body>Test&eacute;<br />fdsfsdf<br />fsdf<strong>sfd</strong>s<br />fssdfsd<br /></body></html>
    +<html><head><title></title></head><body>Test&eacute;<br>fdsfsdf<br>fsdf<strong>sfd</strong>s<br>fssdfsd<br></body></html>
    
    From 8a928a72faeb7b99d09e7b8a439c5539f501d44c Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sat, 13 Oct 2018 14:03:32 +0200
    Subject: [PATCH 190/433] Sync transifex
    
    ---
     htdocs/langs/en_US/accountancy.lang   |  12 +-
     htdocs/langs/en_US/admin.lang         | 212 +++++++++++++-------------
     htdocs/langs/en_US/agenda.lang        |  12 +-
     htdocs/langs/en_US/banks.lang         |  10 +-
     htdocs/langs/en_US/bills.lang         |  66 ++++----
     htdocs/langs/en_US/blockedlog.lang    |   6 +-
     htdocs/langs/en_US/boxes.lang         |   6 +-
     htdocs/langs/en_US/commercial.lang    |   2 +-
     htdocs/langs/en_US/companies.lang     |  38 ++---
     htdocs/langs/en_US/compta.lang        |  14 +-
     htdocs/langs/en_US/cron.lang          |   4 +-
     htdocs/langs/en_US/deliveries.lang    |   6 +-
     htdocs/langs/en_US/dict.lang          |   2 +-
     htdocs/langs/en_US/donations.lang     |   2 +-
     htdocs/langs/en_US/errors.lang        |  16 +-
     htdocs/langs/en_US/exports.lang       |   6 +-
     htdocs/langs/en_US/externalsite.lang  |   2 +-
     htdocs/langs/en_US/ftp.lang           |   2 +-
     htdocs/langs/en_US/holiday.lang       |  20 +--
     htdocs/langs/en_US/install.lang       |   8 +-
     htdocs/langs/en_US/ldap.lang          |   2 +-
     htdocs/langs/en_US/link.lang          |   2 +-
     htdocs/langs/en_US/mails.lang         |  18 +--
     htdocs/langs/en_US/main.lang          |  48 +++---
     htdocs/langs/en_US/members.lang       |   8 +-
     htdocs/langs/en_US/modulebuilder.lang |   8 +-
     htdocs/langs/en_US/multicurrency.lang |   2 +-
     htdocs/langs/en_US/opensurvey.lang    |   4 +-
     htdocs/langs/en_US/orders.lang        |   8 +-
     htdocs/langs/en_US/other.lang         |  24 +--
     htdocs/langs/en_US/paybox.lang        |   2 +-
     htdocs/langs/en_US/paypal.lang        |   4 +-
     htdocs/langs/en_US/productbatch.lang  |   2 +-
     htdocs/langs/en_US/products.lang      |   6 +-
     htdocs/langs/en_US/projects.lang      |   4 +-
     htdocs/langs/en_US/propal.lang        |   2 +-
     htdocs/langs/en_US/salaries.lang      |   2 +-
     htdocs/langs/en_US/sendings.lang      |   2 +-
     htdocs/langs/en_US/sms.lang           |   2 +-
     htdocs/langs/en_US/stocks.lang        |   9 +-
     htdocs/langs/en_US/trips.lang         |   4 +-
     htdocs/langs/en_US/users.lang         |   4 +-
     htdocs/langs/en_US/website.lang       |  10 +-
     htdocs/langs/en_US/withdrawals.lang   |   6 +-
     htdocs/langs/en_US/workflow.lang      |   4 +-
     45 files changed, 316 insertions(+), 317 deletions(-)
    
    diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang
    index 7475c1640e6..0e59bf9a5a3 100644
    --- a/htdocs/langs/en_US/accountancy.lang
    +++ b/htdocs/langs/en_US/accountancy.lang
    @@ -58,19 +58,19 @@ AccountancyAreaDescJournalSetup=STEP %s: Create or check content of your journal
     AccountancyAreaDescChartModel=STEP %s: Create a model of chart of account from menu %s
     AccountancyAreaDescChart=STEP %s: Create or check content of your chart of account from menu %s
     
    -AccountancyAreaDescVat=STEP %s: Define accounting accounts for each VAT Rates. For this, use the menu entry %s.    
    +AccountancyAreaDescVat=STEP %s: Define accounting accounts for each VAT Rates. For this, use the menu entry %s.
     AccountancyAreaDescDefault=STEP %s: Define default accounting accounts. For this, use the menu entry %s.
     AccountancyAreaDescExpenseReport=STEP %s: Define default accounting accounts for each type of expense report. For this, use the menu entry %s.
    -AccountancyAreaDescSal=STEP %s: Define default accounting accounts for payment of salaries. For this, use the menu entry %s.    
    +AccountancyAreaDescSal=STEP %s: Define default accounting accounts for payment of salaries. For this, use the menu entry %s.
     AccountancyAreaDescContrib=STEP %s: Define default accounting accounts for special expenses (miscellaneous taxes). For this, use the menu entry %s.
     AccountancyAreaDescDonation=STEP %s: Define default accounting accounts for donation. For this, use the menu entry %s.
     AccountancyAreaDescMisc=STEP %s: Define mandatory default account and default accounting accounts for miscellaneous transactions. For this, use the menu entry %s.
    -AccountancyAreaDescLoan=STEP %s: Define default accounting accounts for loans. For this, use the menu entry %s. 
    +AccountancyAreaDescLoan=STEP %s: Define default accounting accounts for loans. For this, use the menu entry %s.
     AccountancyAreaDescBank=STEP %s: Define accounting accounts and journal code for each bank and financial accounts. For this, use the menu entry %s.
     AccountancyAreaDescProd=STEP %s: Define accounting accounts on your products/services. For this, use the menu entry %s.
     
     AccountancyAreaDescBind=STEP %s: Check the binding between existing %s lines and accounting account is done, so application will be able to journalize transactions in Ledger in one click. Complete missing bindings. For this, use the menu entry %s.
    -AccountancyAreaDescWriteRecords=STEP %s: Write transactions into the Ledger. For this, go into menu <strong>%s</strong>, and click into button <strong>%s</strong>. 
    +AccountancyAreaDescWriteRecords=STEP %s: Write transactions into the Ledger. For this, go into menu <strong>%s</strong>, and click into button <strong>%s</strong>.
     AccountancyAreaDescAnalyze=STEP %s: Add or edit existing transactions and generate reports and exports.
     
     AccountancyAreaDescClosePeriod=STEP %s: Close period so we can't make modification in a future.
    @@ -165,7 +165,7 @@ NumPiece=Piece number
     TransactionNumShort=Num. transaction
     AccountingCategory=Personalized groups
     GroupByAccountAccounting=Group by accounting account
    -AccountingAccountGroupsDesc=You can define here some groups of accounting account. They will be used for personalized accounting reports.  
    +AccountingAccountGroupsDesc=You can define here some groups of accounting account. They will be used for personalized accounting reports.
     ByAccounts=By accounts
     ByPredefinedAccountGroups=By predefined groups
     ByPersonalizedAccountGroups=By personalized groups
    @@ -191,7 +191,7 @@ NewAccountingMvt=New transaction
     NumMvts=Numero of transaction
     ListeMvts=List of movements
     ErrorDebitCredit=Debit and Credit cannot have a value at the same time
    -AddCompteFromBK=Add accounting accounts to the group 
    +AddCompteFromBK=Add accounting accounts to the group
     ReportThirdParty=List third party account
     DescThirdPartyReport=Consult here the list of the third party customers and vendors and their accounting accounts
     ListAccounts=List of the accounting accounts
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index d4665bb4ccd..93a48d763cd 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -23,7 +23,7 @@ FilesUpdated=Updated Files
     FilesModified=Modified Files
     FilesAdded=Added Files
     FileCheckDolibarr=Check integrity of application files
    -AvailableOnlyOnPackagedVersions=The local file for integrity checking is only available when application is installed from an official package 
    +AvailableOnlyOnPackagedVersions=The local file for integrity checking is only available when application is installed from an official package
     XmlNotFound=Xml Integrity File of application not found
     SessionId=Session ID
     SessionSaveHandler=Handler to save sessions
    @@ -96,9 +96,9 @@ NoMaxSizeByPHPLimit=Note: No limit is set in your PHP configuration
     MaxSizeForUploadedFiles=Maximum size for uploaded files (0 to disallow any upload)
     UseCaptchaCode=Use graphical code (CAPTCHA) on login page
     AntiVirusCommand= Full path to antivirus command
    -AntiVirusCommandExample= Example for ClamWin: c:\Progra~1\ClamWin\bin\clamscan.exe<br>Example for ClamAv: /usr/bin/clamscan
    +AntiVirusCommandExample= Example for ClamWin: c:\\Progra~1\\ClamWin\\bin\\clamscan.exe<br>Example for ClamAv: /usr/bin/clamscan
     AntiVirusParam= More parameters on command line
    -AntiVirusParamExample= Example for ClamWin: --database="C:\Program Files (x86)\ClamWin\lib"
    +AntiVirusParamExample= Example for ClamWin: --database="C:\\Program Files (x86)\\ClamWin\\lib"
     ComptaSetup=Accounting module setup
     UserSetup=User management setup
     MultiCurrencySetup=Multi-currency setup
    @@ -184,7 +184,7 @@ AddDropTable=Add DROP TABLE command
     ExportStructure=Structure
     NameColumn=Name columns
     ExtendedInsert=Extended INSERT
    -NoLockBeforeInsert=No lock commands around INSERT 
    +NoLockBeforeInsert=No lock commands around INSERT
     DelayedInsert=Delayed insert
     EncodeBinariesInHexa=Encode binary data in hexadecimal
     IgnoreDuplicateRecords=Ignore errors of duplicate record (INSERT IGNORE)
    @@ -199,7 +199,7 @@ ModulesDeployDesc=If permissions on your file system allow it, you can use this
     ModulesMarketPlaces=Find external app/modules
     ModulesDevelopYourModule=Develop your own app/modules
     ModulesDevelopDesc=You may also develop your own module or find a partner to develop one for you.
    -DOLISTOREdescriptionLong=Instead of switching on <a href="https://www.dolistore.com">www.dolistore.com</a> web site to find an external module, you can use this embedded tool that will make the seach on the external market place for you (may be slow, need an internet access)...
    +DOLISTOREdescriptionLong=Instead of switching on <a href="https://www.dolistore.com">www.dolistore.com</a> web site to find an external module, you can use this embedded tool that will perform the search on the external market place for you (may be slow, need an internet access)...
     NewModule=New
     FreeModule=Free
     CompatibleUpTo=Compatible with version %s
    @@ -208,7 +208,7 @@ CompatibleAfterUpdate=This module requires an update to your Dolibarr %s (Min %s
     SeeInMarkerPlace=See in Market place
     Updated=Updated
     Nouveauté=Novelty
    -AchatTelechargement=Buy / Download 
    +AchatTelechargement=Buy / Download
     GoModuleSetupArea=To deploy/install a new module, go onto the Module setup area at <a href="%s">%s</a>.
     DoliStoreDesc=DoliStore, the official market place for Dolibarr ERP/CRM external modules
     DoliPartnersDesc=List of companies providing custom-developed modules or features.<br>Note: since Dolibarr is an open source application, <i>anyone</i> experienced in PHP programming may develop a module.
    @@ -286,7 +286,7 @@ MAIN_MAIL_DEFAULT_FROMTYPE=Default sender email for manual sending (User email o
     UserEmail=User email
     CompanyEmail=Company email
     FeatureNotAvailableOnLinux=Feature not available on Unix like systems. Test your sendmail program locally.
    -SubmitTranslation=If translation for this language is not complete or you find errors, you can correct this by editing files into directory <b>langs/%s</b> and submit your change to www.transifex.com/dolibarr-association/dolibarr/
    +SubmitTranslation=If translation for this language is not complete or you find errors, you can correct this by editing files in directory <b>langs/%s</b> and submit your change to www.transifex.com/dolibarr-association/dolibarr/
     SubmitTranslationENUS=If translation for this language is not complete or you find errors, you can correct this by editing files into directory <b>langs/%s</b> and submit modified files on dolibarr.org/forum or for developers on github.com/Dolibarr/dolibarr.
     ModuleSetup=Module setup
     ModulesSetup=Modules/Application setup
    @@ -309,11 +309,11 @@ DoNotUseInProduction=Do not use in production
     ThisIsProcessToFollow=This is steps to process:
     ThisIsAlternativeProcessToFollow=This is an alternative setup to process manually:
     StepNb=Step %s
    -FindPackageFromWebSite=Find a package that provides feature you want (for example on official web site %s).
    +FindPackageFromWebSite=Find a package that provides features you want (for example on official web site %s).
     DownloadPackageFromWebSite=Download package (for example from official web site %s).
     UnpackPackageInDolibarrRoot=Unpack/unzip the packaged files into the server directory dedicated to Dolibarr: <b>%s</b>
     UnpackPackageInModulesRoot=To deploy/install an external module, unpack/unzip the packaged files into the server directory dedicated to external modules:<br><b>%s</b>
    -SetupIsReadyForUse=Module deployment is finished. You must however enable and setup the module in your application by going on the page to setup modules: <a href="%s">%s</a>.
    +SetupIsReadyForUse=Module deployment is finished. You must however enable and setup the module in your application by going to the page setup modules: <a href="%s">%s</a>.
     NotExistsDirect=The alternative root directory is not defined to an existing directory.<br>
     InfDirAlt=Since version 3, it is possible to define an alternative root directory. This allows you to store, into a dedicated directory, plug-ins and custom templates.<br>Just create a directory at the root of Dolibarr (eg: custom).<br>
     InfDirExample=<br>Then declare it in the file <strong>conf.php</strong><br> $dolibarr_main_url_root_alt='/custom'<br>$dolibarr_main_document_root_alt='/path/of/dolibarr/htdocs/custom'<br>If these lines are commented with "#", to enable them, just uncomment by removing the "#" character.
    @@ -333,7 +333,7 @@ GenericMaskCodes4a=<u>Example on the 99th %s of the third party TheCompany, with
     GenericMaskCodes4b=<u>Example on third party created on 2007-03-01:</u><br>
     GenericMaskCodes4c=<u>Example on product created on 2007-03-01:</u><br>
     GenericMaskCodes5=<b>ABC{yy}{mm}-{000000}</b> will give <b>ABC0701-000099</b><br><b>{0000+100@1}-ZZZ/{dd}/XXX</b> will give <b>0199-ZZZ/31/XXX</b><br><b>IN{yy}{mm}-{0000}-{t}</b> will give <b>IN0701-0099-A</b> if the type of company is 'Responsable Inscripto' with code for type that is 'A_RI'
    -GenericNumRefModelDesc=Returns a customizable number according to a defined mask. 
    +GenericNumRefModelDesc=Returns a customizable number according to a defined mask.
     ServerAvailableOnIPOrPort=Server is available at address <b>%s</b> on port <b>%s</b>
     ServerNotAvailableOnIPOrPort=Server is not available at address <b>%s</b> on port <b>%s</b>
     DoTestServerAvailability=Test server connectivity
    @@ -347,25 +347,25 @@ SeeWikiForAllTeam=Take a look at the wiki page for full list of all actors and t
     UseACacheDelay= Delay for caching export response in seconds (0 or empty for no cache)
     DisableLinkToHelpCenter=Hide link "<b>Need help or support</b>" on login page
     DisableLinkToHelp=Hide link to online help "<b>%s</b>"
    -AddCRIfTooLong=There is no automatic wrapping, so if line is out of page on documents because too long, you must add yourself carriage returns in the textarea.
    -ConfirmPurge=Are you sure you want to execute this purge?<br>This will delete definitely all your data files with no way to restore them (ECM files, attached files...). 
    +AddCRIfTooLong=There is no automatic text wrapping, text that is too long will not display on documents. Please add carriage returns in the text area if needed.
    +ConfirmPurge=Are you sure you want to execute this purge?<br>This will permanently delete all your data files with no way to restore them (ECM files, attached files...).
     MinLength=Minimum length
     LanguageFilesCachedIntoShmopSharedMemory=Files .lang loaded in shared memory
     LanguageFile=Language file
     ExamplesWithCurrentSetup=Examples with current configuration
     ListOfDirectories=List of OpenDocument templates directories
    -ListOfDirectoriesForModelGenODT=List of directories containing templates files with OpenDocument format.<br><br>Put here full path of directories.<br>Add a carriage return between eah directory.<br>To add a directory of the GED module, add here <b>DOL_DATA_ROOT/ecm/yourdirectoryname</b>.<br><br>Files in those directories must end with <b>.odt</b> or <b>.ods</b>. 
    +ListOfDirectoriesForModelGenODT=List of directories containing templates files with OpenDocument format.<br><br>Put here full path of directories.<br>Add a carriage return between eah directory.<br>To add a directory of the GED module, add here <b>DOL_DATA_ROOT/ecm/yourdirectoryname</b>.<br><br>Files in those directories must end with <b>.odt</b> or <b>.ods</b>.
     NumberOfModelFilesFound=Number of ODT/ODS template files found in these directories
    -ExampleOfDirectoriesForModelGen=Examples of syntax:<br>c:\mydir<br>/home/mydir<br>DOL_DATA_ROOT/ecm/ecmdir
    -FollowingSubstitutionKeysCanBeUsed=<br>To know how to create your odt document templates, before storing them in those directories, read wiki documentation: 
    +ExampleOfDirectoriesForModelGen=Examples of syntax:<br>c:\\mydir<br>/home/mydir<br>DOL_DATA_ROOT/ecm/ecmdir
    +FollowingSubstitutionKeysCanBeUsed=<br>To know how to create your odt document templates, before storing them in those directories, read wiki documentation:
     FullListOnOnlineDocumentation=http://wiki.dolibarr.org/index.php/Create_an_ODT_document_template
     FirstnameNamePosition=Position of Name/Lastname
     DescWeather=The following pictures will be shown on dashboard when number of late actions reach the following values:
     KeyForWebServicesAccess=Key to use Web Services (parameter "dolibarrkey" in webservices)
     TestSubmitForm=Input test form
    -ThisForceAlsoTheme=Using this menu manager will also use its own theme whatever is user choice. Also this menu manager specialized for smartphones does not works on all smartphone. Use another menu manager if you experience problems on yours. 
    +ThisForceAlsoTheme=Using this menu manager will also use its own theme whatever is user choice. Also this menu manager specialized for smartphones does not works on all smartphone. Use another menu manager if you experience problems on yours.
     ThemeDir=Skins directory
    -ConnectionTimeout=Connexion timeout
    +ConnectionTimeout=Connection timeout
     ResponseTimeout=Response timeout
     SmsTestMessage=Test message from __PHONEFROM__ to __PHONETO__
     ModuleMustBeEnabledFirst=Module <b>%s</b> must be enabled first if you need this feature.
    @@ -377,7 +377,7 @@ PDFAddressForging=Rules to forge address boxes
     HideAnyVATInformationOnPDF=Hide all information related to Sales tax / VAT on generated PDF
     PDFRulesForSalesTax=Rules for Sales Tax / VAT
     PDFLocaltax=Rules for %s
    -HideLocalTaxOnPDF=Hide %s rate into pdf column tax sale
    +HideLocalTaxOnPDF=Hide %s rate in pdf column tax sale
     HideDescOnPDF=Hide products description on generated PDF
     HideRefOnPDF=Hide products ref. on generated PDF
     HideDetailsOnPDF=Hide product lines details on generated PDF
    @@ -387,7 +387,7 @@ UrlGenerationParameters=Parameters to secure URLs
     SecurityTokenIsUnique=Use a unique securekey parameter for each URL
     EnterRefToBuildUrl=Enter reference for object %s
     GetSecuredUrl=Get calculated URL
    -ButtonHideUnauthorized=Hide buttons to non-admin users for unauthorized actions instead of showing greyed disabled buttons
    +ButtonHideUnauthorized=Hide buttons for non-admin users for unauthorized actions instead of showing greyed disabled buttons
     OldVATRates=Old VAT rate
     NewVATRates=New VAT rate
     PriceBaseTypeToChange=Modify on prices with base reference value defined on
    @@ -408,13 +408,13 @@ ExtrafieldSelect = Select list
     ExtrafieldSelectList = Select from table
     ExtrafieldSeparator=Separator (not a field)
     ExtrafieldPassword=Password
    -ExtrafieldRadio=Radio buttons (on choice only)
    +ExtrafieldRadio=Radio buttons (one choice only)
     ExtrafieldCheckBox=Checkboxes
     ExtrafieldCheckBoxFromList=Checkboxes from table
     ExtrafieldLink=Link to an object
     ComputedFormula=Computed field
     ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: <strong>$db, $conf, $langs, $mysoc, $user, $object</strong>.<br><strong>WARNING</strong>: Only some properties of $object may be available. If you need a properties not loaded, just fetch yourself the object into your formula like in the second example.<br>Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.<br><br>Example of formula:<br>$object->id < 10 ? round($object->id / 2, 2) : ($object->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)<br><br>Example to reload object<br>(($reloadedobj = new Societe($db)) && ($reloadedobj->fetch($obj->id ? $obj->id : ($obj->rowid ? $obj->rowid : $object->id)) > 0)) ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5 : '-1'<br><br>Other example of formula to force load of object and its parent object:<br>(($reloadedobj = new Task($db)) && ($reloadedobj->fetch($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetch($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : 'Parent project not found'
    -ExtrafieldParamHelpPassword=Keep this field empty means value will be stored without encryption (field must be only hidden with star on screen).<br>Set here value 'auto' to use the default encryption rule to save password into database (then value read will be the hash only, no way to retreive original value)
    +ExtrafieldParamHelpPassword=Leaving this field blank means this value will be stored without encryption (field must be only hidden with star on screen).<br>Set  'auto' to use the default encryption rule to save password into database (then value read will be the hash only, no way to retrieve original value)
     ExtrafieldParamHelpselect=List of values must be lines with format key,value (where key can't be '0')<br><br> for example : <br>1,value1<br>2,value2<br>code3,value3<br>...<br><br>In order to have the list depending on another complementary attribute list :<br>1,value1|options_<i>parent_list_code</i>:parent_key<br>2,value2|options_<i>parent_list_code</i>:parent_key <br><br>In order to have the list depending on another list :<br>1,value1|<i>parent_list_code</i>:parent_key<br>2,value2|<i>parent_list_code</i>:parent_key
     ExtrafieldParamHelpcheckbox=List of values must be lines with format key,value (where key can't be '0')<br><br> for example : <br>1,value1<br>2,value2<br>3,value3<br>...
     ExtrafieldParamHelpradio=List of values must be lines with format key,value (where key can't be '0')<br><br> for example : <br>1,value1<br>2,value2<br>3,value3<br>...
    @@ -439,7 +439,7 @@ InitEmptyBarCode=Init value for next %s empty records
     EraseAllCurrentBarCode=Erase all current barcode values
     ConfirmEraseAllCurrentBarCode=Are you sure you want to erase all current barcode values?
     AllBarcodeReset=All barcode values have been removed
    -NoBarcodeNumberingTemplateDefined=No numbering barcode template enabled into barcode module setup.
    +NoBarcodeNumberingTemplateDefined=No numbering barcode template enabled in the barcode module setup.
     EnableFileCache=Enable file cache
     ShowDetailsInPDFPageFoot=Add more details into footer of PDF files, like your company address, or manager names (to complete professional ids, company capital and VAT number).
     NoDetails=No more details in footer
    @@ -450,22 +450,22 @@ EnableAndSetupModuleCron=If you want to have this recurring invoice generated au
     ModuleCompanyCodeCustomerAquarium=%s followed by customer code for a customer accounting code
     ModuleCompanyCodeSupplierAquarium=%s followed by supplier code for a supplier accounting code
     ModuleCompanyCodePanicum=Return an empty accounting code.
    -ModuleCompanyCodeDigitaria=Accounting code depends on third party code. The code is composed of the character "C" in the first position followed by the first 5 characters of the third party code.  
    -Use3StepsApproval=By default, Purchase Orders need to be created and approved by 2 different users (one step/user to create and one step/user to approve. Note that if user has both permission to create and approve, one step/user will be enough). You can ask with this option to introduce a third step/user approval, if amount is higher than a dedicated value (so 3 steps will be necessary: 1=validation, 2=first approval and 3=second approval if amount is enough).<br>Set this to empty if one approval (2 steps) is enough, set it to a very low value (0.1) if a second approval (3 steps) is always required.  
    +ModuleCompanyCodeDigitaria=Accounting code depends on third party code. The code is composed of the character "C" in the first position followed by the first 5 characters of the third party code.
    +Use3StepsApproval=By default, Purchase Orders need to be created and approved by 2 different users (one step/user to create and one step/user to approve. Note that if user has both permission to create and approve, one step/user will be enough). You can ask with this option to introduce a third step/user approval, if amount is higher than a dedicated value (so 3 steps will be necessary: 1=validation, 2=first approval and 3=second approval if amount is enough).<br>Set this to empty if one approval (2 steps) is enough, set it to a very low value (0.1) if a second approval (3 steps) is always required.
     UseDoubleApproval=Use a 3 steps approval when amount (without tax) is higher than...
    -WarningPHPMail=WARNING: It is often better to setup outgoing emails to use the email server of your provider instead of the default setup. Some email providers (like Yahoo) do not allow you to send an email from another server than their own server. Your current setup uses the server of the application to send email and not the server of your email provider, so some recipients (the one compatible with the restrictive DMARC protocol), will ask your email provider if they can accept your email and some email providers (like Yahoo) may respond "no" because the server is not a server of them, so few of your sent Emails may not be accepted (be careful also to your email provider sending quota).<br>If your Email provider (like Yahoo) has this restriction, you must change Email setup to choose the other method "SMTP server" and enter the SMTP server and credentials provided by your Email provider (ask your EMail provider to get SMTP credentials for your account).
    +WarningPHPMail=WARNING: It is often better to setup outgoing emails to use the email server of your provider instead of the default setup. Some email providers (like Yahoo) do not allow you to send an email from another server than their own server. Your current setup uses the server of the application to send email and not the server of your email provider, so some recipients (the one compatible with the restrictive DMARC protocol), will ask your email provider if they can accept your email and some email providers (like Yahoo) may respond "no" because the server is not their, so few of your sent Emails may not be accepted (be careful also of your email provider's sending quota).<br>If your Email provider (like Yahoo) has this restriction, you must change Email setup to choose the other method "SMTP server" and enter the SMTP server and credentials provided by your Email provider (ask your Email provider to get SMTP credentials for your account).
     WarningPHPMail2=If your email SMTP provider need to restrict email client to some IP addresses (very rare), this is the IP address of the mail user agent (MUA) for your ERP CRM application: <strong>%s</strong>.
     ClickToShowDescription=Click to show description
    -DependsOn=This module need the module(s)
    +DependsOn=This module needs the module(s)
     RequiredBy=This module is required by module(s)
    -TheKeyIsTheNameOfHtmlField=This is the name of the HTML field. This need to have technical knowledges to read the content of the HTML page to get the key name of a field.
    -PageUrlForDefaultValues=You must enter here the relative url of the page. If you include parameters in URL, the default values will be effective if all parameters are set to same value. Examples:
    +TheKeyIsTheNameOfHtmlField=This is the name of the HTML field. Technical knowledge is required to read the content of the HTML page to get the key name of a field.
    +PageUrlForDefaultValues=You must enter the relative url of the page. If you include parameters in URL, the default values will be effective if all parameters are set to same value. Examples:
     PageUrlForDefaultValuesCreate=<br>For form to create a new thirdparty, it is <strong>%s</strong>,<br>If you want default value only if url has some parameter, you can use <strong>%s</strong>
     PageUrlForDefaultValuesList=<br>For page that list third-parties, it is <strong>%s</strong>,<br>If you want default value only if url has some parameter, you can use <strong>%s</strong>
     EnableDefaultValues=Enable usage of personalized default values
    -EnableOverwriteTranslation=Enable usage of overwrote translation
    +EnableOverwriteTranslation=Enable usage of overwritten translation
     GoIntoTranslationMenuToChangeThis=A translation has been found for the key with this code. To change this value, you must edit it from Home-Setup-translation.
    -WarningSettingSortOrder=Warning, setting a default sort order may result in a technical error when going on the list page if field is an unknown field. If you experience such an error, come back to this page to remove the default sort order and restore default behavior. 
    +WarningSettingSortOrder=Warning, setting a default sort order may result in a technical error when going on the list page if field is an unknown field. If you experience such an error, come back to this page to remove the default sort order and restore default behavior.
     Field=Field
     ProductDocumentTemplates=Document templates to generate product document
     FreeLegalTextOnExpenseReports=Free legal text on expense reports
    @@ -476,7 +476,7 @@ SendEmailsReminders=Send agenda reminders by emails
     davDescription=Add a component to be a DAV server
     DAVSetup=Setup of module DAV
     DAV_ALLOW_PUBLIC_DIR=Enable the public directory (WebDav directory with no login required)
    -DAV_ALLOW_PUBLIC_DIRTooltip=The WebDav public directory is a WebDAV directory everybody can access to (in read and write mode), with no need to have/use an existing login/password account.
    +DAV_ALLOW_PUBLIC_DIRTooltip=The WebDav public directory is a WebDAV directory everybody can access  (in read and write mode), with no need to have/use an existing login/password account.
     DAV_ALLOW_ECM_DIR=Enable the root directy of DMS/ECM module (login required)
     DAV_ALLOW_ECM_DIRTooltip=The root directory where all files are manually uploaded when using the DMS/ECM module. Like for the feature from the web interface, you will need a valid login/password with granted permissions to access it.
     # Modules
    @@ -487,7 +487,7 @@ Module1Desc=Companies and contact management (customers, prospects...)
     Module2Name=Commercial
     Module2Desc=Commercial management
     Module10Name=Accounting
    -Module10Desc=Simple accounting reports (journals, turnover) based onto database content. Does not use any ledger table.
    +Module10Desc=Simple accounting reports (journals, turnover) based on database content. Does not use any ledger table.
     Module20Name=Proposals
     Module20Desc=Commercial proposal management
     Module22Name=Mass E-mailings
    @@ -541,9 +541,9 @@ Module200Desc=LDAP directory synchronization
     Module210Name=PostNuke
     Module210Desc=PostNuke integration
     Module240Name=Data exports
    -Module240Desc=Tool to export Dolibarr data (with assistants)
    +Module240Desc=Tool to export Dolibarr data (with assistance)
     Module250Name=Data imports
    -Module250Desc=Tool to import data into Dolibarr (with assistants)
    +Module250Desc=Tool to import data into Dolibarr (with assistance)
     Module310Name=Members
     Module310Desc=Foundation members management
     Module320Name=RSS Feed
    @@ -584,7 +584,7 @@ Module2200Desc=Enable the usage of math expressions for prices
     Module2300Name=Scheduled jobs
     Module2300Desc=Scheduled jobs management (alias cron or chrono table)
     Module2400Name=Events/Agenda
    -Module2400Desc=Track events. Let Dolibarr log automatic events for tracking purposes or record manual events or meetings. This is the main important module for a good Customer or Supplier Relationship Management.
    +Module2400Desc=Track events. Let Dolibarr log automatic events for tracking purposes or record manual events or meetings. This is the main module for good Customer or Supplier Relationship Management.
     Module2500Name=DMS / ECM
     Module2500Desc=Document Management System / Electronic Content Management. Automatic organization of your generated or stored documents. Share them when you need.
     Module2600Name=API/Web services (SOAP server)
    @@ -592,9 +592,9 @@ Module2600Desc=Enable the Dolibarr SOAP server providing API services
     Module2610Name=API/Web services (REST server)
     Module2610Desc=Enable the Dolibarr REST server providing API services
     Module2660Name=Call WebServices (SOAP client)
    -Module2660Desc=Enable the Dolibarr web services client (Can be used to push data/requests to external servers. Supplier orders supported only for the moment)
    +Module2660Desc=Enable the Dolibarr web services client (Can be used to push data/requests to external servers. Only Supplier orders currently supported.)
     Module2700Name=Gravatar
    -Module2700Desc=Use online Gravatar service (www.gravatar.com) to show photo of users/members (found with their emails). Need an internet access
    +Module2700Desc=Use online Gravatar service (www.gravatar.com) to show photo of users/members (found with their emails). Needs Internet access
     Module2800Desc=FTP Client
     Module2900Name=GeoIPMaxmind
     Module2900Desc=GeoIP Maxmind conversions capabilities
    @@ -625,7 +625,7 @@ Module50150Desc=Point of sales module (Touch screen POS).
     Module50200Name=Paypal
     Module50200Desc=Offer customers a PayPal online payment page (PayPal account or credit/debit cards). This can be used to allow your customers to make free payments or for a payment on a particular Dolibarr object (invoice, order, ...)
     Module50400Name=Accounting (advanced)
    -Module50400Desc=Accounting management (double entries, support general and auxiliary ledgers). Export the ledger in several other accounting software format.
    +Module50400Desc=Accounting management (double entries, support general and auxiliary ledgers). Export the ledger in several other accounting software formats.
     Module54000Name=PrintIPP
     Module54000Desc=Direct print (without opening the documents) using Cups IPP interface (Printer must be visible from server, and CUPS must be installed on server).
     Module55000Name=Poll, Survey or Vote
    @@ -692,7 +692,7 @@ Permission109=Delete sendings
     Permission111=Read financial accounts
     Permission112=Create/modify/delete and compare transactions
     Permission113=Setup financial accounts (create, manage categories)
    -Permission114=Reconciliate transactions
    +Permission114=Reconcile transactions
     Permission115=Export transactions and account statements
     Permission116=Transfers between accounts
     Permission117=Manage cheques dispatching
    @@ -700,25 +700,25 @@ Permission121=Read third parties linked to user
     Permission122=Create/modify third parties linked to user
     Permission125=Delete third parties linked to user
     Permission126=Export third parties
    -Permission141=Read all projects and tasks (also private projects i am not contact for)
    -Permission142=Create/modify all projects and tasks (also private projects i am not contact for)
    +Permission141=Read all projects and tasks (also private projects I am not a contact for)
    +Permission142=Create/modify all projects and tasks (also private projects I am not a contact for)
     Permission144=Delete all projects and tasks (also private projects i am not contact for)
     Permission146=Read providers
     Permission147=Read stats
     Permission151=Read direct debit payment orders
     Permission152=Create/modify a direct debit payment orders
     Permission153=Send/Transmit direct debit payment orders
    -Permission154=Record Credits/Rejects of direct debit payment orders
    +Permission154=Record Credits/Rejections of direct debit payment orders
     Permission161=Read contracts/subscriptions
     Permission162=Create/modify contracts/subscriptions
     Permission163=Activate a service/subscription of a contract
     Permission164=Disable a service/subscription of a contract
     Permission165=Delete contracts/subscriptions
     Permission167=Export contracts
    -Permission171=Read trips and expenses (yours and your subordinates) 
    +Permission171=Read trips and expenses (yours and your subordinates)
     Permission172=Create/modify trips and expenses
     Permission173=Delete trips and expenses
    -Permission174=Read all trips and expenses 
    +Permission174=Read all trips and expenses
     Permission178=Export trips and expenses
     Permission180=Read suppliers
     Permission181=Read supplier orders
    @@ -761,7 +761,7 @@ PermissionAdvanced253=Create/modify internal/external users and permissions
     Permission254=Create/modify external users only
     Permission255=Modify other users password
     Permission256=Delete or disable other users
    -Permission262=Extend access to all third parties (not only third parties that user is a sale representative).<br>Not effective for external users (always limited to themselves for proposals, orders, invoices, contracts, etc.).<br>Not effective for projects (only rules on project permissions, visibility and assignment matters).
    +Permission262=Extend access to all third parties (not only third parties that user is a sale representative for).<br>Not effective for external users (always limited to themselves for proposals, orders, invoices, contracts, etc.).<br>Not effective for projects (only rules on project permissions, visibility and assignment matters).
     Permission271=Read CA
     Permission272=Read invoices
     Permission273=Issue invoices
    @@ -771,7 +771,7 @@ Permission283=Delete contacts
     Permission286=Export contacts
     Permission291=Read tariffs
     Permission292=Set permissions on the tariffs
    -Permission293=Modify costumers tariffs
    +Permission293=Modify customers tariffs
     Permission300=Read bar codes
     Permission301=Create/modify bar codes
     Permission302=Delete bar codes
    @@ -810,7 +810,7 @@ Permission538=Export services
     Permission701=Read donations
     Permission702=Create/modify donations
     Permission703=Delete donations
    -Permission771=Read expense reports (yours and your subordinates) 
    +Permission771=Read expense reports (yours and your subordinates)
     Permission772=Create/modify expense reports
     Permission773=Delete expense reports
     Permission774=Read all expense reports (even for user not subordinates)
    @@ -848,8 +848,8 @@ Permission1251=Run mass imports of external data into database (data load)
     Permission1321=Export customer invoices, attributes and payments
     Permission1322=Reopen a paid bill
     Permission1421=Export customer orders and attributes
    -Permission20001=Read leave requests (your leaves and the one of your subordinates)
    -Permission20002=Create/modify your leave requests (yours leaves and the one of your subordinates)
    +Permission20001=Read leave requests (your leave and that of your subordinates)
    +Permission20002=Create/modify your leave requests (your leave and that of your subordinates)
     Permission20003=Delete leave requests
     Permission20004=Read all leave requests (even of user not subordinates)
     Permission20005=Create/modify leave requests for everybody (even of user not subordinates)
    @@ -915,7 +915,7 @@ DictionaryAccountancyJournal=Accounting journals
     DictionaryEMailTemplates=Email Templates
     DictionaryUnits=Units
     DictionaryProspectStatus=Prospection status
    -DictionaryHolidayTypes=Types of leaves
    +DictionaryHolidayTypes=Types of leave
     DictionaryOpportunityStatus=Lead status for project/lead
     DictionaryExpenseTaxCat=Expense report - Transportation categories
     DictionaryExpenseTaxRange=Expense report - Range by transportation category
    @@ -962,7 +962,7 @@ CalcLocaltax3=Sales
     CalcLocaltax3Desc=Local Taxes reports are the total of localtaxes sales
     LabelUsedByDefault=Label used by default if no translation can be found for code
     LabelOnDocuments=Label on documents
    -LabelOrTranslationKey=Label or translation key 
    +LabelOrTranslationKey=Label or translation key
     NbOfDays=No. of days
     AtEndOfMonth=At end of month
     CurrentNext=Current/Next
    @@ -1072,7 +1072,7 @@ DisplayDesc=You can choose each parameter related to the Dolibarr look and feel
     AvailableModules=Available app/modules
     ToActivateModule=To activate modules, go on setup Area (Home->Setup->Modules).
     SessionTimeOut=Time out for session
    -SessionExplanation=This number guarantee that session will never expire before this delay, if the session cleaner is done by Internal PHP session cleaner (and nothing else). Internal PHP session cleaner does not guaranty that session will expire just after this delay. It will expire, after this delay, and when the session cleaner is ran, so every <b>%s/%s</b> access, but only during access made by other sessions.<br>Note: on some servers with an external session cleaning mechanism (cron under debian, ubuntu ...), the sessions can be destroyed after a period defined by the default <strong>session.gc_maxlifetime</strong>, no matter what the value entered here. 
    +SessionExplanation=This number guarantees that the session will never expire before this delay, if the session cleaner is done by Internal PHP session cleaner (and nothing else). Internal PHP session cleaner does not guarantee that the session will expire after this delay. It will expire, after this delay, and when the session cleaner is run, so every <b>%s/%s</b> access, but only during access made by other sessions.<br>Note: on some servers with an external session cleaning mechanism (cron under debian, ubuntu ...), the sessions can be destroyed after a period defined by the default <strong>session.gc_maxlifetime</strong>, no matter what the value entered here is.
     TriggersAvailable=Available triggers
     TriggersDesc=Triggers are files that will modify the behavior of Dolibarr workflow once copied into the directory <b>htdocs/core/triggers</b>. They realize new actions, activated on Dolibarr events (new company creation, invoice validation, ...).
     TriggerDisabledByName=Triggers in this file are disabled by the <b>-NORUN</b> suffix in their name.
    @@ -1097,17 +1097,17 @@ NoEventFoundWithCriteria=No security event has been found for this search criter
     SeeLocalSendMailSetup=See your local sendmail setup
     BackupDesc=To make a complete backup of Dolibarr, you must:
     BackupDesc2=Save content of documents directory (<b>%s</b>) that contains all uploaded and generated files (So it includes all dump files generated at step 1).
    -BackupDesc3=Save content of your database (<b>%s</b>) into a dump file. For this, you can use following assistant.
    +BackupDesc3=Save content of your database (<b>%s</b>) into a dump file. For this, you can use the following assistant.
     BackupDescX=Archived directory should be stored in a secure place.
     BackupDescY=The generated dump file should be stored in a secure place.
    -BackupPHPWarning=Backup cannot be guaranteed with this method. Prefer previous one
    +BackupPHPWarning=Backup cannot be guaranteed with this method. Previous one recommended.
     RestoreDesc=To restore a Dolibarr backup, you must:
     RestoreDesc2=Restore archive file (zip file for example) of documents directory to extract tree of files in documents directory of a new Dolibarr installation or into this current documents directory (<b>%s</b>).
     RestoreDesc3=Restore the data, from a backup dump file, into the database of the new Dolibarr installation or into the database of this current installation (<b>%s</b>). Warning, once restore is finished, you must use a login/password, that existed when backup was made, to connect again. To restore a backup database into this current installation, you can follow this assistant.
     RestoreMySQL=MySQL import
     ForcedToByAModule= This rule is forced to <b>%s</b> by an activated module
     PreviousDumpFiles=Generated database backup files
    -WeekStartOnDay=First day of week 
    +WeekStartOnDay=First day of week
     RunningUpdateProcessMayBeRequired=Running the upgrade process seems to be required (Programs version %s differs from database version %s)
     YouMustRunCommandFromCommandLineAfterLoginToUser=You must run this command from command line after login to a shell with user <b>%s</b> or you must add -W option at end of command line to provide <b>%s</b> password.
     YourPHPDoesNotHaveSSLSupport=SSL functions not available in your PHP
    @@ -1130,7 +1130,7 @@ MAIN_PROXY_HOST=Name/Address of proxy server
     MAIN_PROXY_PORT=Port of proxy server
     MAIN_PROXY_USER=Login to use the proxy server
     MAIN_PROXY_PASS=Password to use the proxy server
    -DefineHereComplementaryAttributes=Define here any attributes not already available by default, that you want to be supported for %s.
    +DefineHereComplementaryAttributes=Define any attributes not already available by default, that you want to be supported for %s here.
     ExtraFields=Complementary attributes
     ExtraFieldsLines=Complementary attributes (lines)
     ExtraFieldsLinesRec=Complementary attributes (templates invoices lines)
    @@ -1151,13 +1151,13 @@ AlphaNumOnlyLowerCharsAndNoSpace=only alphanumericals and lower case characters
     SendmailOptionNotComplete=Warning, on some Linux systems, to send email from your email, sendmail execution setup must contains option -ba (parameter mail.force_extra_parameters into your php.ini file). If some recipients never receive emails, try to edit this PHP parameter with mail.force_extra_parameters = -ba).
     PathToDocuments=Path to documents
     PathDirectory=Directory
    -SendmailOptionMayHurtBuggedMTA=Feature to send mails using method "PHP mail direct" will generate a mail message that might be not correctly parsed by some receiving mail servers. Result is that some mails can't be read by people hosted by those bugged platforms. It's case for some Internet providers (Ex: Orange in France). This is not a problem into Dolibarr nor into PHP but onto receiving mail server. You can however add option MAIN_FIX_FOR_BUGGED_MTA to 1 into setup - other to modify Dolibarr to avoid this. However, you may experience problem with other servers that respect strictly the SMTP standard. The other solution (recommended) is to use the method "SMTP socket library" that has no disadvantages.
    +SendmailOptionMayHurtBuggedMTA=Feature to send mails using method "PHP mail direct" will generate a mail message that might not be parsed correctly by some receiving mail servers. The result is that some mails can't be read by people hosted by those bugged platforms. This is the case for some Internet providers (Ex: Orange in France). This is not a problem with Dolibarr or PHP but with the receiving mail server. You can however add an option MAIN_FIX_FOR_BUGGED_MTA to 1 in Setup - Other to modify Dolibarr to avoid this. However, you may experience problems with other servers that strictly use the SMTP standard. The other solution (recommended) is to use the method "SMTP socket library" which has no disadvantages.
     TranslationSetup=Setup of translation
     TranslationKeySearch=Search a translation key or string
     TranslationOverwriteKey=Overwrite a translation string
     TranslationDesc=How to set displayed application language :<br>* Systemwide: menu <strong>Home - Setup - Display</strong><br>* Per user: Use the <strong>User display setup</strong> tab on user card (click on username at the top of the screen).
     TranslationOverwriteDesc=You can also override strings filling the following table. Choose your language from "%s" dropdown, insert the translation key string into "%s" and your new translation into "%s"
    -TranslationOverwriteDesc2=You can use the other tab to help you know translation key to use
    +TranslationOverwriteDesc2=You can use the other tab to help you know which translation key to use
     TranslationString=Translation string
     CurrentTranslationString=Current translation string
     WarningAtLeastKeyOrTranslationRequired=A search criteria is required at least for key or translation string
    @@ -1166,16 +1166,16 @@ OriginalValueWas=The original translation is overwritten. Original value was:<br
     TransKeyWithoutOriginalValue=You forced a new translation for the translation key '<strong>%s</strong>' that does not exist in any language files
     TotalNumberOfActivatedModules=Activated application/modules: <b>%s</b> / <b>%s</b>
     YouMustEnableOneModule=You must at least enable 1 module
    -ClassNotFoundIntoPathWarning=Class %s not found into PHP path
    +ClassNotFoundIntoPathWarning=Class %s not found in PHP path
     YesInSummer=Yes in summer
     OnlyFollowingModulesAreOpenedToExternalUsers=Note, only the following modules are opened to external users (whatever the permissions of such users) and only if permissions are granted:
     SuhosinSessionEncrypt=Session storage encrypted by Suhosin
     ConditionIsCurrently=Condition is currently %s
    -YouUseBestDriver=You use driver %s that is best driver available currently.
    +YouUseBestDriver=You use driver %s which is the best driver available currently.
     YouDoNotUseBestDriver=You use driver %s but driver %s is recommended.
     NbOfProductIsLowerThanNoPb=You have only %s products/services in the database. This does not require any particular optimization.
     SearchOptim=Search optimization
    -YouHaveXProductUseSearchOptim=You have %s product into database. You should add the constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 into Home-Setup-Other, you limit the search to the beginning of strings making possible for database to use index and you should get an immediate response.
    +YouHaveXProductUseSearchOptim=You have %s products in the database. You should add the constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 in Home-Setup-Other. Limit the search to the beginning of strings which makes it possible for the database to use indexes and you should get an immediate response.
     BrowserIsOK=You are using the %s web browser. This browser is ok for security and performance.
     BrowserIsKO=You are using the %s web browser. This browser is known to be a bad choice for security, performance and reliability. We recommend using Firefox, Chrome, Opera or Safari.
     XDebugInstalled=XDebug is loaded.
    @@ -1188,7 +1188,7 @@ FillThisOnlyIfRequired=Example: +2 (fill only if timezone offset problems are ex
     GetBarCode=Get barcode
     ##### Module password generation
     PasswordGenerationStandard=Return a password generated according to internal Dolibarr algorithm: 8 characters containing shared numbers and characters in lowercase.
    -PasswordGenerationNone=Do not suggest any generated password. Password must be typed in manually.
    +PasswordGenerationNone=Do not suggest a generated password. Password must be typed in manually.
     PasswordGenerationPerso=Return a password according to your personally defined configuration.
     SetupPerso=According to your configuration
     PasswordPatternDesc=Password pattern description
    @@ -1217,7 +1217,7 @@ MustBeMandatory=Mandatory to create third parties (if vat number or type of comp
     MustBeInvoiceMandatory=Mandatory to validate invoices?
     TechnicalServicesProvided=Technical services provided
     #####DAV #####
    -WebDAVSetupDesc=This is the links to access the WebDAV directory. It contains a "public" dir open to any user knowing the URL (if public directory access allowed) and a "private" directory that need an existing login account/password to access to.
    +WebDAVSetupDesc=This is the links to access the WebDAV directory. It contains a "public" dir open to any user knowing the URL (if public directory access allowed) and a "private" directory that need an existing login account/password to access.
     WebDavServer=Root URL of %s server : %s
     ##### Webcal setup #####
     WebCalUrlForVCalExport=An export link to <b>%s</b> format is available at following link: %s
    @@ -1366,8 +1366,8 @@ LDAPFieldLoginSamba=Login (samba, activedirectory)
     LDAPFieldLoginSambaExample=Example : samaccountname
     LDAPFieldFullname=Full name
     LDAPFieldFullnameExample=Example : cn
    -LDAPFieldPasswordNotCrypted=Password not crypted
    -LDAPFieldPasswordCrypted=Password crypted
    +LDAPFieldPasswordNotCrypted=Password not encrypted
    +LDAPFieldPasswordCrypted=Password encrypted
     LDAPFieldPasswordExample=Example : userPassword
     LDAPFieldCommonNameExample=Example : cn
     LDAPFieldName=Name
    @@ -1415,10 +1415,10 @@ LDAPDescMembersTypes=This page allows you to define LDAP attributes name in LDAP
     LDAPDescValues=Example values are designed for <b>OpenLDAP</b> with following loaded schemas: <b>core.schema, cosine.schema, inetorgperson.schema</b>). If you use thoose values and OpenLDAP, modify your LDAP config file <b>slapd.conf</b> to have all thoose schemas loaded.
     ForANonAnonymousAccess=For an authenticated access (for a write access for example)
     PerfDolibarr=Performance setup/optimizing report
    -YouMayFindPerfAdviceHere=You will find on this page some checks or advice related to performance.
    -NotInstalled=Not installed, so your server is not slow down by this.
    +YouMayFindPerfAdviceHere=This page provides some checks or advice related to performance.
    +NotInstalled=Not installed, so your server is not slowed down by this.
     ApplicativeCache=Applicative cache
    -MemcachedNotAvailable=No applicative cache found. You can enhance performance by installing a cache server Memcached and a module able to use this cache server.<br>More information here <a href="http://wiki.dolibarr.org/index.php/Module_MemCached_EN">http://wiki.dolibarr.org/index.php/Module_MemCached_EN</a>.<br>Note that a lot of web hosting provider does not provide such cache server. 
    +MemcachedNotAvailable=No applicative cache found. You can enhance performance by installing a cache server Memcached and a module able to use this cache server.<br>More information here <a href="http://wiki.dolibarr.org/index.php/Module_MemCached_EN">http://wiki.dolibarr.org/index.php/Module_MemCached_EN</a>.<br>Note that a lot of web hosting provider does not provide such cache server.
     MemcachedModuleAvailableButNotSetup=Module memcached for applicative cache found but setup of module is not complete.
     MemcachedAvailableAndSetup=Module memcached dedicated to use memcached server is enabled.
     OPCodeCache=OPCode cache
    @@ -1433,9 +1433,9 @@ CacheByServerDesc=For example using the Apache directive "ExpiresByType image/gi
     CacheByClient=Cache by browser
     CompressionOfResources=Compression of HTTP responses
     CompressionOfResourcesDesc=For example using the Apache directive "AddOutputFilterByType DEFLATE"
    -TestNotPossibleWithCurrentBrowsers=Such an automatic detection is not possible with current browsers 
    -DefaultValuesDesc=You can define/force here the default value you want to get when you create a new record, and/or default filters or sort order when your list record.
    -DefaultCreateForm=Default values (on forms to create)
    +TestNotPossibleWithCurrentBrowsers=Such an automatic detection is not possible with current browsers
    +DefaultValuesDesc=Here you can define/force the default value you want to have when you create a new record, and/or default filters or sort order when your list records.
    +DefaultCreateForm=Default values (to create on forms)
     DefaultSearchFilters=Default search filters
     DefaultSortOrder=Default sort orders
     DefaultFocus=Default focus fields
    @@ -1445,11 +1445,11 @@ ProductSetup=Products module setup
     ServiceSetup=Services module setup
     ProductServiceSetup=Products and Services modules setup
     NumberOfProductShowInSelect=Max number of products in combos select lists (0=no limit)
    -ViewProductDescInFormAbility=Visualization of product descriptions in the forms (otherwise as popup tooltip)
    +ViewProductDescInFormAbility=Display product descriptions in forms (otherwise as popup tooltip)
     MergePropalProductCard=Activate in product/service Attached Files tab an option to merge product PDF document to proposal PDF azur if product/service is in the proposal
    -ViewProductDescInThirdpartyLanguageAbility=Visualization of products descriptions in the language of the third party
    +ViewProductDescInThirdpartyLanguageAbility=Display products descriptions in the language of the third party
     UseSearchToSelectProductTooltip=Also if you have a large number of products (> 100 000), you can increase speed by setting constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string.
    -UseSearchToSelectProduct=Wait you press a key before loading content of product combo list (This may increase performance if you have a large number of products, but it is less convenient)
    +UseSearchToSelectProduct=Wait until you press a key before loading content of product combo list (This may increase performance if you have a large number of products, but it is less convenient)
     SetDefaultBarcodeTypeProducts=Default barcode type to use for products
     SetDefaultBarcodeTypeThirdParties=Default barcode type to use for third parties
     UseUnits=Define a unit of measure for Quantity during order, proposal or invoice lines edition
    @@ -1465,7 +1465,7 @@ SyslogFilename=File name and path
     YouCanUseDOL_DATA_ROOT=You can use DOL_DATA_ROOT/dolibarr.log for a log file in Dolibarr "documents" directory. You can set a different path to store this file.
     ErrorUnknownSyslogConstant=Constant %s is not a known Syslog constant
     OnlyWindowsLOG_USER=Windows only supports LOG_USER
    -CompressSyslogs=Compression and backup of debug log files (generated by module Log for debug) 
    +CompressSyslogs=Compression and backup of debug log files (generated by module Log for debug)
     SyslogFileNumberOfSaves=Log backups
     ConfigureCleaningCronjobToSetFrequencyOfSaves=Configure cleaning scheduled job to set log backup frequency
     ##### Donations #####
    @@ -1486,7 +1486,7 @@ BarcodeDescC39=Barcode of type C39
     BarcodeDescC128=Barcode of type C128
     BarcodeDescDATAMATRIX=Barcode of type Datamatrix
     BarcodeDescQRCODE=Barcode of type QR code
    -GenbarcodeLocation=Bar code generation command line tool (used by internal engine for some bar code types). Must be compatible with "genbarcode".<br>For example: /usr/local/bin/genbarcode 
    +GenbarcodeLocation=Bar code generation command line tool (used by internal engine for some bar code types). Must be compatible with "genbarcode".<br>For example: /usr/local/bin/genbarcode
     BarcodeInternalEngine=Internal engine
     BarCodeNumberManager=Manager to auto define barcode numbers
     ##### Prelevements #####
    @@ -1529,7 +1529,7 @@ FCKeditorForMail=WYSIWIG creation/edition for all mail (except Tools->eMailing)
     ##### OSCommerce 1 #####
     OSCommerceErrorConnectOkButWrongDatabase=Connection succeeded but database does not appear to be an OSCommerce database (Key %s not found in table %s).
     OSCommerceTestOk=Connection to server '%s' on database '%s' with user '%s' successful.
    -OSCommerceTestKo1=Connection to server '%s' succeed but database '%s' could not be reached.
    +OSCommerceTestKo1=Connection to server '%s' succeeded but database '%s' could not be reached.
     OSCommerceTestKo2=Connection to server '%s' with user '%s' failed.
     ##### Stock #####
     StockSetup=Stock module setup
    @@ -1563,7 +1563,7 @@ ConfirmDeleteMenu=Are you sure you want to delete menu entry <b>%s</b>?
     FailedToInitializeMenu=Failed to initialize menu
     ##### Tax #####
     TaxSetup=Taxes, social or fiscal taxes and dividends module setup
    -OptionVatMode=VAT due 
    +OptionVatMode=VAT due
     OptionVATDefault=Standard basis
     OptionVATDebitOption=Accrual basis
     OptionVatDefaultDesc=VAT is due:<br>- on delivery for goods (we use invoice date)<br>- on payments for services
    @@ -1582,15 +1582,15 @@ InvoiceDateUsed=Invoice date used
     YourCompanyDoesNotUseVAT=Your company has been defined to not use VAT (Home - Setup - Company/Organization), so there is no VAT options to setup.
     AccountancyCode=Accounting Code
     AccountancyCodeSell=Sale account. code
    -AccountancyCodeBuy=Purchase account. code 
    +AccountancyCodeBuy=Purchase account. code
     ##### Agenda #####
     AgendaSetup=Events and agenda module setup
     PasswordTogetVCalExport=Key to authorize export link
     PastDelayVCalExport=Do not export event older than
    -AGENDA_USE_EVENT_TYPE=Use events types (managed into menu Setup -> Dictionaries -> Type of agenda events)
    -AGENDA_USE_EVENT_TYPE_DEFAULT=Set automatically this default value for type of event into event create form
    -AGENDA_DEFAULT_FILTER_TYPE=Set automatically this type of event into search filter of agenda view
    -AGENDA_DEFAULT_FILTER_STATUS=Set automatically this status for events into search filter of agenda view
    +AGENDA_USE_EVENT_TYPE=Use events types (managed in menu Setup -> Dictionaries -> Type of agenda events)
    +AGENDA_USE_EVENT_TYPE_DEFAULT=Automatically set this default value for type of event in event create form
    +AGENDA_DEFAULT_FILTER_TYPE=Automatically set this type of event in search filter of agenda view
    +AGENDA_DEFAULT_FILTER_STATUS=Automatically set this status for events in search filter of agenda view
     AGENDA_DEFAULT_VIEW=Which tab do you want to open by default when selecting menu Agenda
     AGENDA_REMINDER_EMAIL=Enable event reminder <b>by emails</b> (remind option/delay can be defined on each event). Note: Module <strong>%s</strong> must be enabled and correctly setup to have reminder sent at the correct frequency.
     AGENDA_REMINDER_BROWSER=Enable event reminder <b>on user's browser</b> (when event date is reached, each user is able to refuse this from the browser confirmation question)
    @@ -1599,17 +1599,17 @@ AGENDA_SHOW_LINKED_OBJECT=Show linked object into agenda view
     ##### Clicktodial #####
     ClickToDialSetup=Click To Dial module setup
     ClickToDialUrlDesc=Url called when a click on phone picto is done.  In URL, you can use tags<br><b>__PHONETO__</b> that will be replaced with the phone number of person to call<br><b>__PHONEFROM__</b> that will be replaced with phone number of calling person (yours)<br><b>__LOGIN__</b> that will be replaced with clicktodial login (defined on user card)<br><b>__PASS__</b> that will be replaced with clicktodial password (defined on user card).
    -ClickToDialDesc=This module allows to make phone numbers clickable. A click on this icon will call make your phone to call the phone number. This can be used to call a call center system from Dolibarr that can call the phone number on a SIP system for example.
    +ClickToDialDesc=This module allows to make phone numbers clickable. A click on this icon will call make your phone call the phone number. This can be used to call a call center system from Dolibarr that can call the phone number on a SIP system for example.
     ClickToDialUseTelLink=Use just a link "tel:" on phone numbers
    -ClickToDialUseTelLinkDesc=Use this method if your users have a softphone or a software interface installed on the same computer as the browser, and called when you click on a link in your browser that start with "tel:". If you need a full server solution (no need of local software installation), you must set this to "No" and fill next field.
    +ClickToDialUseTelLinkDesc=Use this method if your users have a softphone or a software interface installed on the same computer as the browser, and called when you click on a link in your browser that starts with "tel:". If you need a full server solution (no need of local software installation), you must set this to "No" and fill next field.
     ##### Point Of Sales (CashDesk) #####
     CashDesk=Point of sales
     CashDeskSetup=Point of sales module setup
    -CashDeskThirdPartyForSell=Default generic third party to use for sells
    +CashDeskThirdPartyForSell=Default generic third party to use for sales
     CashDeskBankAccountForSell=Default account to use to receive cash payments
     CashDeskBankAccountForCheque= Default account to use to receive payments by cheque
     CashDeskBankAccountForCB= Default account to use to receive payments by credit cards
    -CashDeskDoNotDecreaseStock=Disable stock decrease when a sell is done from Point of Sale (if "no", stock decrease is done for each sell done from POS, whatever is option set into module Stock).
    +CashDeskDoNotDecreaseStock=Disable stock decrease when a sale is done from Point of Sale (if "no", stock decrease is done for each sale done from POS, irrespective of the option set in module Stock).
     CashDeskIdWareHouse=Force and restrict warehouse to use for stock decrease
     StockDecreaseForPointOfSaleDisabled=Stock decrease from Point of Sale disabled
     StockDecreaseForPointOfSaleDisabledbyBatch=Stock decrease in POS is not compatible with lot management
    @@ -1630,7 +1630,7 @@ ApiProductionMode=Enable production mode (this will activate use of a cache for
     ApiExporerIs=You can explore and test the APIs at URL
     OnlyActiveElementsAreExposed=Only elements from enabled modules are exposed
     ApiKey=Key for API
    -WarningAPIExplorerDisabled=The API explorer has been disabled. API explorer is not required to provide API services. It is a tool for developer to find/test REST APIs. If you need this tool, go into setup of module API REST to activate it. 
    +WarningAPIExplorerDisabled=The API explorer has been disabled. API explorer is not required to provide API services. It is a tool for developer to find/test REST APIs. If you need this tool, go into setup of module API REST to activate it.
     ##### Bank #####
     BankSetupModule=Bank module setup
     FreeLegalTextOnChequeReceipts=Free text on cheque receipts
    @@ -1682,7 +1682,7 @@ NoAmbiCaracAutoGeneration=Do not use ambiguous characters ("1","l","i","|","0","
     SalariesSetup=Setup of module salaries
     SortOrder=Sort order
     Format=Format
    -TypePaymentDesc=0:Customer payment type, 1:Vendor payment type, 2:Both customers and vendors payment type 
    +TypePaymentDesc=0:Customer payment type, 1:Vendor payment type, 2:Both customers and vendors payment type
     IncludePath=Include path (defined into variable %s)
     ExpenseReportsSetup=Setup of module Expense Reports
     TemplatePDFExpenseReports=Document templates to generate expense report document
    @@ -1694,14 +1694,14 @@ YouMayFindNotificationsFeaturesIntoModuleNotification=You may find options for E
     ListOfNotificationsPerUser=List of notifications per user*
     ListOfNotificationsPerUserOrContact=List of notifications per user* or per contact**
     ListOfFixedNotifications=List of fixed notifications
    -GoOntoUserCardToAddMore=Go on the tab "Notifications" of a user to add or remove notifications for users
    +GoOntoUserCardToAddMore=Go to the tab "Notifications" of a user to add or remove notifications for users
     GoOntoContactCardToAddMore=Go on the tab "Notifications" of a third party to add or remove notifications for contact addresses
     Threshold=Threshold
     BackupDumpWizard=Wizard to build database backup dump file
     SomethingMakeInstallFromWebNotPossible=Installation of external module is not possible from the web interface for the following reason:
    -SomethingMakeInstallFromWebNotPossible2=For this reason, process to upgrade described here is only manual steps a privileged user can do. 
    +SomethingMakeInstallFromWebNotPossible2=For this reason, process to upgrade described here is only manual steps a privileged user can do.
     InstallModuleFromWebHasBeenDisabledByFile=Install of external module from application has been disabled by your administrator. You must ask him to remove the file <strong>%s</strong> to allow this feature.
    -ConfFileMustContainCustom=Installing or building an external module from application need to save the module files into directory <strong>%s</strong>. To have this directory processed by Dolibarr, you must setup your <strong>conf/conf.php</strong> to add the 2 directive lines:<br><strong>$dolibarr_main_url_root_alt='/custom';</strong><br><strong>$dolibarr_main_document_root_alt='%s/custom';</strong> 
    +ConfFileMustContainCustom=Installing or building an external module from application need to save the module files into directory <strong>%s</strong>. To have this directory processed by Dolibarr, you must setup your <strong>conf/conf.php</strong> to add the 2 directive lines:<br><strong>$dolibarr_main_url_root_alt='/custom';</strong><br><strong>$dolibarr_main_document_root_alt='%s/custom';</strong>
     HighlightLinesOnMouseHover=Highlight table lines when mouse move passes over
     HighlightLinesColor=Highlight color of the line when the mouse passes over (keep empty for no highlight)
     HighlightLinesChecked=Highlight color of the line when it is checked (keep empty for no highlight)
    @@ -1729,7 +1729,7 @@ UrlTrackingDesc=If the provider or transport service offer a page or web site to
     OpportunityPercent=When you create a lead, you will define an estimated amount of project/lead. According to status of lead, this amount may be multiplied by this rate to evaluate global amount all your opportunities may generate. Value is percent (between 0 and 100).
     TemplateForElement=This template record is dedicated to which element
     TypeOfTemplate=Type of template
    -TemplateIsVisibleByOwnerOnly=Template is visible by owner only
    +TemplateIsVisibleByOwnerOnly=Template is visible to owner only
     VisibleEverywhere=Visible everywhere
     VisibleNowhere=Visible nowhere
     FixTZ=TimeZone fix
    @@ -1755,10 +1755,10 @@ YouUseLastStableVersion=You use the latest stable version
     TitleExampleForMajorRelease=Example of message you can use to announce this major release (feel free to use it on your web sites)
     TitleExampleForMaintenanceRelease=Example of message you can use to announce this maintenance release (feel free to use it on your web sites)
     ExampleOfNewsMessageForMajorRelease=Dolibarr ERP & CRM %s is available. Version %s is a major release with a lot of new features for both users and developers. You can download it from the download area of https://www.dolibarr.org portal (subdirectory Stable versions). You can read <a href="https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog">ChangeLog</a> for complete list of changes.
    -ExampleOfNewsMessageForMaintenanceRelease=Dolibarr ERP & CRM %s is available. Version %s is a maintenance version, so it contains only fixes of bugs. We recommend everybody using an older version to upgrade to this one. As any maintenance release, no new features, nor data structure change is present into this version. You can download it from the download area of https://www.dolibarr.org portal (subdirectory Stable versions). You can read <a href="https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog">ChangeLog</a> for complete list of changes.
    -MultiPriceRuleDesc=When option "Several level of prices per product/service" is on, you can define different prices (one per price level) for each product. To save you time, you can enter here rule to have price for each level autocalculated according to price of first level, so you will have to enter only price for first level on each product. This page is here to save you time and can be useful only if your prices for each level are relative to first level. You can ignore this page in most cases.
    +ExampleOfNewsMessageForMaintenanceRelease=Dolibarr ERP & CRM %s is available. Version %s is a maintenance version, so it contains only fixes of bugs. We recommend everybody using an older version to upgrade to this one. As any maintenance release, no new features or data structure change is present in this version. You can download it from the download area of https://www.dolibarr.org portal (subdirectory Stable versions). You can read <a href="https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog">ChangeLog</a> for complete list of changes.
    +MultiPriceRuleDesc=When option "Several level of prices per product/service" is on, you can define different prices (one per price level) for each product. To save you time, here you can enter a rule to have a price for each level autocalculated according to the price of first level, so you will have to only enter a price for the first level on each product. This page is here to save you time and can be useful only if your prices for each level are relative to first level. You can ignore this page in most cases.
     ModelModulesProduct=Templates for product documents
    -ToGenerateCodeDefineAutomaticRuleFirst=To be able to generate automatically codes, you must first define a manager to auto define barcode number.
    +ToGenerateCodeDefineAutomaticRuleFirst=To be able to generate codes automatically, you must first define a manager to auto define barcode number.
     SeeSubstitutionVars=See * note for list of possible substitution variables
     SeeChangeLog=See ChangeLog file (english only)
     AllPublishers=All publishers
    @@ -1779,19 +1779,19 @@ AddOtherPagesOrServices=Add other pages or services
     AddModels=Add document or numbering templates
     AddSubstitutions=Add keys substitutions
     DetectionNotPossible=Detection not possible
    -UrlToGetKeyToUseAPIs=Url to get token to use API (once token has been received it is saved on database user table and must be provided on each API call) 
    +UrlToGetKeyToUseAPIs=Url to get token to use API (once token has been received it is saved in database user table and must be provided on each API call)
     ListOfAvailableAPIs=List of available APIs
     activateModuleDependNotSatisfied=Module "%s" depends on module "%s", that is missing, so module "%1$s" may not work correctly. Please install module "%2$s" or disable module "%1$s" if you want to be safe from any surprise
    -CommandIsNotInsideAllowedCommands=The command you try to run is not in the list of allowed commands defined into parameter <strong>$dolibarr_main_restrict_os_commands</strong> in the <strong>conf.php</strong> file.
    +CommandIsNotInsideAllowedCommands=The command you are trying to run is not in the list of allowed commands defined in parameter <strong>$dolibarr_main_restrict_os_commands</strong> in the <strong>conf.php</strong> file.
     LandingPage=Landing page
    -SamePriceAlsoForSharedCompanies=If you use a multicompany module, with the choice "Single price", price will be also the same for all companies if products are shared between environments
    +SamePriceAlsoForSharedCompanies=If you use a multicompany module, with the choice "Single price", the price will also be the same for all companies if products are shared between environments
     ModuleEnabledAdminMustCheckRights=Module has been activated. Permissions for activated module(s) were given to admin users only. You may need to grant permissions to other users or groups manually if necessary.
    -UserHasNoPermissions=This user has no permission defined
    +UserHasNoPermissions=This user has no permissions defined
     TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "%s")<br>Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "%s" in days)<br>Use "Current/Next" to have payment term date being the first Nth of the month after delta (delta is field "%s", N is stored into field "%s")
     BaseCurrency=Reference currency of the company (go into setup of company to change this)
    -WarningNoteModuleInvoiceForFrenchLaw=This module %s is compliant with french laws (Loi Finance 2016). 
    -WarningNoteModulePOSForFrenchLaw=This module %s is compliant with french laws (Loi Finance 2016) because module Non Reversible Logs is automatically activated. 
    -WarningInstallationMayBecomeNotCompliantWithLaw=You are trying to install module %s that is an external module. Activating an external module means you trust the publisher of that module and that you are sure that this module does not impact adversely the behavior of your application, and is compliant with laws of your country (%s). If the module introduces an illegal feature, you become responsible for the use of a illegal software.
    +WarningNoteModuleInvoiceForFrenchLaw=This module %s is compliant with French laws (Loi Finance 2016).
    +WarningNoteModulePOSForFrenchLaw=This module %s is compliant with French laws (Loi Finance 2016) because module Non Reversible Logs is automatically activated.
    +WarningInstallationMayBecomeNotCompliantWithLaw=You are trying to install module %s that is an external module. Activating an external module means you trust the publisher of that module and that you are sure that this module does not adversely impact the behavior of your application, and is compliant with laws of your country (%s). If the module introduces an illegal feature, you become responsible for the use of illegal software.
     MAIN_PDF_MARGIN_LEFT=Left margin on PDF
     MAIN_PDF_MARGIN_RIGHT=Right margin on PDF
     MAIN_PDF_MARGIN_TOP=Top margin on PDF
    @@ -1803,9 +1803,9 @@ SeveralLangugeVariatFound=Several language variants found
     COMPANY_AQUARIUM_REMOVE_SPECIAL=Remove special characters
     COMPANY_AQUARIUM_CLEAN_REGEX=Regex filter to clean value (COMPANY_AQUARIUM_CLEAN_REGEX)
     GDPRContact=Privacy Policies or GDPR contact
    -GDPRContactDesc=If you store data about European companies/citizen, you can store here the contact who is responsible for the General Data Protection Regulation
    +GDPRContactDesc=If you store data about European companies/citizen, you can store the contact who is responsible for the General Data Protection Regulation here
     HelpOnTooltip=Help text to show on tooltip
    -HelpOnTooltipDesc=Put here a text or a translation key for a text to show on a tooltip when this field appears into a form
    +HelpOnTooltipDesc=Put text or a translation key here for the text to show on a tooltip when this field appears in a form
     YouCanDeleteFileOnServerWith=You can delete this file on server with Command Line:<br>%s
     ChartLoaded=Chart of account loaded
     SocialNetworkSetup=Setup of module Social Networks
    @@ -1814,7 +1814,7 @@ VATIsUsedIsOff=Note: The option to use sales Tax or VAT has been set to <strong>
     SwapSenderAndRecipientOnPDF=Swap sender and recipient address on PDF
     FeatureSupportedOnTextFieldsOnly=Warning, feature supported on text fields only
     ##### Resource ####
    -ResourceSetup=Configuration du module Resource 
    +ResourceSetup=Configuration du module Resource
     UseSearchToSelectResource=Use a search form to choose a resource (rather than a drop-down list).
     DisabledResourceLinkUser=Disable feature to link a resource to users
     DisabledResourceLinkContact=Disable feature to link a resource to contacts
    diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang
    index a68bac6d961..cd39a43abe8 100644
    --- a/htdocs/langs/en_US/agenda.lang
    +++ b/htdocs/langs/en_US/agenda.lang
    @@ -1,12 +1,12 @@
    -# Dolibarr language file - Source file is en_US - agenda 
    +# Dolibarr language file - Source file is en_US - agenda
     IdAgenda=ID event
     Actions=Events
     Agenda=Agenda
     TMenuAgenda=Agenda
     Agendas=Agendas
     LocalAgenda=Internal calendar
    -ActionsOwnedBy=Event owned by 
    -ActionsOwnedByShort=Owner 
    +ActionsOwnedBy=Event owned by
    +ActionsOwnedByShort=Owner
     AffectedTo=Assigned to
     Event=Event
     Events=Events
    @@ -31,8 +31,8 @@ ViewWeek=Week view
     ViewPerUser=Per user view
     ViewPerType=Per type view
     AutoActions= Automatic filling
    -AgendaAutoActionDesc= Define here events for which you want Dolibarr to create automatically an event in agenda. If nothing is checked, only manual actions will be included in logged and visible into agenda. Automatic tracking of business actions done on objects (validation, status change) will not be saved. 
    -AgendaSetupOtherDesc= This page provides options to allow export of your Dolibarr events into an external calendar (thunderbird, google calendar, ...)
    +AgendaAutoActionDesc= Here you can define events which you want Dolibarr to create automatically  in Agenda. If nothing is checked, only manual actions will be included in logs and displayed in Agenda. Automatic tracking of business actions done on objects (validation, status change) will not be saved.
    +AgendaSetupOtherDesc= This page provides options to allow exports of your Dolibarr events into an external calendar (thunderbird, google calendar, ...)
     AgendaExtSitesDesc=This page allows to declare external sources of calendars to see their events into Dolibarr agenda.
     ActionsEvents=Events for which Dolibarr will create an action in agenda automatically
     EventRemindersByEmailNotEnabled=Event reminders by email was not enabled into %s module setup.
    @@ -111,7 +111,7 @@ DefaultWorkingHours=Default working hours in day (Example: 9-18)
     # External Sites ical
     ExportCal=Export calendar
     ExtSites=Import external calendars
    -ExtSitesEnableThisTool=Show external calendars (defined into global setup) into agenda. Does not affect external calendars defined by users.
    +ExtSitesEnableThisTool=Show external calendars (defined in global setup) in Agenda. Does not affect external calendars defined by users.
     ExtSitesNbOfAgenda=Number of calendars
     AgendaExtNb=Calendar no. %s
     ExtSiteUrlAgenda=URL to access .ical file
    diff --git a/htdocs/langs/en_US/banks.lang b/htdocs/langs/en_US/banks.lang
    index a83b3cd755b..7650613341e 100644
    --- a/htdocs/langs/en_US/banks.lang
    +++ b/htdocs/langs/en_US/banks.lang
    @@ -46,7 +46,7 @@ BankAccountDomiciliation=Account address
     BankAccountCountry=Account country
     BankAccountOwner=Account owner name
     BankAccountOwnerAddress=Account owner address
    -RIBControlError=Integrity check of values fails. This means information for this account number are not complete or wrong (check country, numbers and IBAN).
    +RIBControlError=Integrity check of values fails. This means the information for this account number is incomplete or incorrect (check country, numbers and IBAN).
     CreateAccount=Create account
     NewBankAccount=New account
     NewFinancialAccount=New financial account
    @@ -105,7 +105,7 @@ SocialContributionPayment=Social/fiscal tax payment
     BankTransfer=Bank transfer
     BankTransfers=Bank transfers
     MenuBankInternalTransfer=Internal transfer
    -TransferDesc=Transfer from one account to another one, Dolibarr will write two record (a debit in source account and a credit in target account. The same amount (except sign), label and date will be used for this transaction)
    +TransferDesc=Transfer from one account to another one, Dolibarr will write two records (a debit in source account and a credit in target account). The same amount (except sign), label and date will be used for this transaction)
     TransferFrom=From
     TransferTo=To
     TransferFromToDone=A transfer from <b>%s</b> to <b>%s</b> of <b>%s</b> %s has been recorded.
    @@ -136,8 +136,8 @@ BankTransactionLine=Bank entry
     AllAccounts=All bank and cash accounts
     BackToAccount=Back to account
     ShowAllAccounts=Show for all accounts
    -FutureTransaction=Transaction in futur. No way to conciliate.
    -SelectChequeTransactionAndGenerate=Select/filter checks to include into the check deposit receipt and click on "Create".
    +FutureTransaction=Transaction in future. No way to reconcile.
    +SelectChequeTransactionAndGenerate=Select/filter checks to include in the check deposit receipt and click on "Create".
     InputReceiptNumber=Choose the bank statement related with the conciliation. Use a sortable numeric value: YYYYMM or YYYYMMDD
     EventualyAddCategory=Eventually, specify a category in which to classify the records
     ToConciliate=To reconcile?
    @@ -163,4 +163,4 @@ ShowVariousPayment=Show miscellaneous payments
     AddVariousPayment=Add miscellaneous payments
     SEPAMandate=SEPA mandate
     YourSEPAMandate=Your SEPA mandate
    -FindYourSEPAMandate=This is your SEPA mandate to authorize our company to make direct debit order to your bank. Thanks to return it signed (scan of the signed document) or sent it by mail to 
    +FindYourSEPAMandate=This is your SEPA mandate to authorize our company to make direct debit order to your bank. Return it signed (scan of the signed document) or send it by mail to
    diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang
    index 0eb53d1af98..f2a46bd3077 100644
    --- a/htdocs/langs/en_US/bills.lang
    +++ b/htdocs/langs/en_US/bills.lang
    @@ -25,12 +25,12 @@ InvoiceProFormaAsk=Proforma invoice
     InvoiceProFormaDesc=<b>Proforma invoice</b> is an image of a true invoice but has no accountancy value.
     InvoiceReplacement=Replacement invoice
     InvoiceReplacementAsk=Replacement invoice for invoice
    -InvoiceReplacementDesc=<b>Replacement invoice</b> is used to cancel and replace completely an invoice with no payment already received.<br><br>Note: Only invoices with no payment on it can be replaced. If the invoice you replace is not yet closed, it will be automatically closed to 'abandoned'.
    +InvoiceReplacementDesc=<b>Replacement invoice</b> is used to cancel and completely replace an invoice with no payment already received.<br><br>Note: Only invoices with no payment on it can be replaced. If the invoice you replace is not yet closed, it will be automatically closed to 'abandoned'.
     InvoiceAvoir=Credit note
     InvoiceAvoirAsk=Credit note to correct invoice
    -InvoiceAvoirDesc=The <b>credit note</b> is a negative invoice used to solve fact that an invoice has an amount that differs than amount really paid (because customer paid too much by error, or will not paid completely since he returned some products for example).
    +InvoiceAvoirDesc=The <b>credit note</b> is a negative invoice used to correct the fact that an invoice has an amount that differs from the amount really paid (eg customer paid too much by mistake, or will not pay completely since he returned some products).
     invoiceAvoirWithLines=Create Credit Note with lines from the origin invoice
    -invoiceAvoirWithPaymentRestAmount=Create Credit Note with remaining unpaid of origin invoice 
    +invoiceAvoirWithPaymentRestAmount=Create Credit Note with remaining unpaid of origin invoice
     invoiceAvoirLineWithPaymentRestAmount=Credit Note for remaining unpaid amount
     ReplaceInvoice=Replace invoice %s
     ReplacementInvoice=Replacement invoice
    @@ -66,12 +66,12 @@ paymentInInvoiceCurrency=in invoices currency
     PaidBack=Paid back
     DeletePayment=Delete payment
     ConfirmDeletePayment=Are you sure you want to delete this payment?
    -ConfirmConvertToReduc=Do you want to convert this %s into an absolute discount ?<br>The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this customer.
    -ConfirmConvertToReducSupplier=Do you want to convert this %s into an absolute discount ?<br>The amount will so be saved among all discounts and could be used as a discount for a current or a future invoice for this supplier.
    +ConfirmConvertToReduc=Do you want to convert this %s into an absolute discount?<br>The amount will be saved among all discounts and could be used as a discount for a current or a future invoice for this customer.
    +ConfirmConvertToReducSupplier=Do you want to convert this %s into an absolute discount?<br>The amount will be saved among all discounts and could be used as a discount for a current or a future invoice for this supplier.
     SupplierPayments=Suppliers payments
     ReceivedPayments=Received payments
     ReceivedCustomersPayments=Payments received from customers
    -PayedSuppliersPayments=Payments payed to suppliers
    +PayedSuppliersPayments=Payments paid to suppliers
     ReceivedCustomersPaymentsToValid=Received customers payments to validate
     PaymentsReportsForYear=Payments reports for %s
     PaymentsReports=Payments reports
    @@ -91,8 +91,8 @@ PaymentConditionsShort=Payment terms
     PaymentAmount=Payment amount
     ValidatePayment=Validate payment
     PaymentHigherThanReminderToPay=Payment higher than reminder to pay
    -HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the rest to pay. <br> Edit your entry, otherwise confirm and think about creating a credit note of the excess received for each overpaid invoice.
    -HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the rest to pay. <br> Edit your entry, otherwise confirm and think about creating a credit note of the excess paid for each overpaid invoice.
    +HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider creating a credit note for the excess received for each overpaid invoice.
    +HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider creating a credit note for the excess paid for each overpaid invoice.
     ClassifyPaid=Classify 'Paid'
     ClassifyPaidPartially=Classify 'Paid partially'
     ClassifyCanceled=Classify 'Abandoned'
    @@ -146,7 +146,7 @@ ErrorVATIntraNotConfigured=Intra-Community VAT number not yet defined
     ErrorNoPaiementModeConfigured=No default payment mode defined. Go to Invoice module setup to fix this.
     ErrorCreateBankAccount=Create a bank account, then go to Setup panel of Invoice module to define payment modes
     ErrorBillNotFound=Invoice %s does not exist
    -ErrorInvoiceAlreadyReplaced=Error, you try to validate an invoice to replace invoice %s. But this one has already been replaced by invoice %s.
    +ErrorInvoiceAlreadyReplaced=Error, you tried to validate an invoice to replace invoice %s. But this one has already been replaced by invoice %s.
     ErrorDiscountAlreadyUsed=Error, discount already used
     ErrorInvoiceAvoirMustBeNegative=Error, correct invoice must have a negative amount
     ErrorInvoiceOfThisTypeMustBePositive=Error, this type of invoice must have a positive amount
    @@ -180,20 +180,20 @@ ConfirmClassifyPaidBill=Are you sure you want to change invoice <b>%s</b> to sta
     ConfirmCancelBill=Are you sure you want to cancel invoice <b>%s</b>?
     ConfirmCancelBillQuestion=Why do you want to classify this invoice 'abandoned'?
     ConfirmClassifyPaidPartially=Are you sure you want to change invoice <b>%s</b> to status paid?
    -ConfirmClassifyPaidPartiallyQuestion=This invoice has not been paid completely. What are reasons for you to close this invoice?
    +ConfirmClassifyPaidPartiallyQuestion=This invoice has not been paid completely. What is the reason/s for you closing this invoice?
     ConfirmClassifyPaidPartiallyReasonAvoir=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I regularize the VAT with a credit note.
     ConfirmClassifyPaidPartiallyReasonDiscount=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term.
     ConfirmClassifyPaidPartiallyReasonDiscountNoVat=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I accept to lose the VAT on this discount.
    -ConfirmClassifyPaidPartiallyReasonDiscountVat=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I recover the VAT on this discount without a credit note. 
    +ConfirmClassifyPaidPartiallyReasonDiscountVat=Remaining unpaid <b>(%s %s)</b> is a discount granted because payment was made before term. I recover the VAT on this discount without a credit note.
     ConfirmClassifyPaidPartiallyReasonBadCustomer=Bad customer
     ConfirmClassifyPaidPartiallyReasonProductReturned=Products partially returned
     ConfirmClassifyPaidPartiallyReasonOther=Amount abandoned for other reason
    -ConfirmClassifyPaidPartiallyReasonDiscountNoVatDesc=This choice is possible if your invoice has been provided with suitable comment. (Example «Only the tax corresponding to the price that has been actually paid gives rights to deduction»)
    -ConfirmClassifyPaidPartiallyReasonDiscountVatDesc=In some countries, this choice might be possible only if your invoice contains correct note.
    +ConfirmClassifyPaidPartiallyReasonDiscountNoVatDesc=This choice is possible if your invoice has been provided with suitable comments. (Example «Only the tax corresponding to the price that has been actually paid gives rights to deduction»)
    +ConfirmClassifyPaidPartiallyReasonDiscountVatDesc=In some countries, this choice might be possible only if your invoice contains correct notes.
     ConfirmClassifyPaidPartiallyReasonAvoirDesc=Use this choice if all other does not suit
    -ConfirmClassifyPaidPartiallyReasonBadCustomerDesc=A <b>bad customer</b> is a customer that refuse to pay his debt.
    +ConfirmClassifyPaidPartiallyReasonBadCustomerDesc=A <b>bad customer</b> is a customer that refuses to pay his debt.
     ConfirmClassifyPaidPartiallyReasonProductReturnedDesc=This choice is used when payment is not complete because some of products were returned
    -ConfirmClassifyPaidPartiallyReasonOtherDesc=Use this choice if all other does not suit, for example in following situation:<br>- payment not complete because some products were shipped back<br>- amount claimed too important because a discount was forgotten<br>In all cases, amount over-claimed must be corrected in accountancy system by creating a credit note.
    +ConfirmClassifyPaidPartiallyReasonOtherDesc=Use this choice if all others are not suitable, for example in following situation:<br>- payment not complete because some products were shipped back<br>- amount claimed too important because a discount was forgotten<br>In all cases, amount over-claimed must be corrected in accountancy system by creating a credit note.
     ConfirmClassifyAbandonReasonOther=Other
     ConfirmClassifyAbandonReasonOtherDesc=This choice will be used in all other cases. For example because you plan to create a replacing invoice.
     ConfirmCustomerPayment=Do you confirm this payment input for <b>%s</b> %s?
    @@ -304,8 +304,8 @@ DiscountAlreadyCounted=Discounts or credits already consumed
     CustomerDiscounts=Customer discounts
     SupplierDiscounts=Vendors discounts
     BillAddress=Bill address
    -HelpEscompte=This discount is a discount granted to customer because its payment was made before term.
    -HelpAbandonBadCustomer=This amount has been abandoned (customer said to be a bad customer) and is considered as an exceptional loose.
    +HelpEscompte=This discount is a discount granted to customer because payment was made before term.
    +HelpAbandonBadCustomer=This amount has been abandoned (customer said to be a bad customer) and is considered as an exceptional loss.
     HelpAbandonOther=This amount has been abandoned since it was an error (wrong customer or invoice replaced by another for example)
     IdSocialContribution=Social/fiscal tax payment id
     PaymentId=Payment id
    @@ -323,19 +323,19 @@ InvoiceNotChecked=No invoice selected
     CloneInvoice=Clone invoice
     ConfirmCloneInvoice=Are you sure you want to clone this invoice <b>%s</b>?
     DisabledBecauseReplacedInvoice=Action disabled because invoice has been replaced
    -DescTaxAndDividendsArea=This area presents a summary of all payments made for special expenses. Only record with payment during the fixed year are included here.
    +DescTaxAndDividendsArea=This area presents a summary of all payments made for special expenses. Only records with payment during the fixed year are included here.
     NbOfPayments=No. of payments
     SplitDiscount=Split discount in two
    -ConfirmSplitDiscount=Are you sure you want to split this discount of <b>%s</b> %s into 2 lower discounts?
    +ConfirmSplitDiscount=Are you sure you want to split this discount of <b>%s</b> %s into 2 smaller discounts?
     TypeAmountOfEachNewDiscount=Input amount for each of two parts:
    -TotalOfTwoDiscountMustEqualsOriginal=Total of two new discount must be equal to original discount amount. 
    +TotalOfTwoDiscountMustEqualsOriginal=Total of two new discounts must be equal to original discount amount.
     ConfirmRemoveDiscount=Are you sure you want to remove this discount?
     RelatedBill=Related invoice
     RelatedBills=Related invoices
     RelatedCustomerInvoices=Related customer invoices
     RelatedSupplierInvoices=Related supplier invoices
     LatestRelatedBill=Latest related invoice
    -WarningBillExist=Warning, one or more invoice already exist
    +WarningBillExist=Warning, one or more invoices already exist
     MergingPDFTool=Merging PDF tool
     AmountPaymentDistributedOnInvoice=Payment amount distributed on invoice
     PaymentOnDifferentThirdBills=Allow payments on different third parties bills but same parent company
    @@ -346,7 +346,7 @@ 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 ? 
    +ConfirmRemoveSituationFromCycle=Remove this invoice %s from cycle ?
     ConfirmOuting=Confirm outing
     FrequencyPer_d=Every %s days
     FrequencyPer_m=Every %s months
    @@ -410,8 +410,8 @@ PaymentTypeCHQ=Check
     PaymentTypeShortCHQ=Check
     PaymentTypeTIP=TIP (Documents against Payment)
     PaymentTypeShortTIP=TIP Payment
    -PaymentTypeVAD=On line payment
    -PaymentTypeShortVAD=On line payment
    +PaymentTypeVAD=Online payment
    +PaymentTypeShortVAD=Online payment
     PaymentTypeTRA=Bank draft
     PaymentTypeShortTRA=Draft
     PaymentTypeFAC=Factor
    @@ -438,7 +438,7 @@ NetToBePaid=Net to be paid
     PhoneNumber=Tel
     FullPhoneNumber=Telephone
     TeleFax=Fax
    -PrettyLittleSentence=Accept the amount of payments due by checks issued in my name as a Member of an accounting association approved by the Fiscal Administration.  
    +PrettyLittleSentence=Accept the amount of payments due by checks issued in my name as a Member of an accounting association approved by the Fiscal Administration.
     IntracommunityVATNumber=Intracommunity number of VAT
     PaymentByChequeOrderedTo=Check payment (including tax) are payable to %s send to
     PaymentByChequeOrderedToShort=Check payment (including tax) are payable to
    @@ -447,7 +447,7 @@ PaymentByTransferOnThisBankAccount=Payment by transfer on the following bank acc
     VATIsNotUsedForInvoice=* Non applicable VAT art-293B of CGI
     LawApplicationPart1=By application of the law 80.335 of 12/05/80
     LawApplicationPart2=the goods remain the property of
    -LawApplicationPart3=the seller until the complete cashing of
    +LawApplicationPart3=the seller until full payment of
     LawApplicationPart4=their price.
     LimitedLiabilityCompanyCapital=SARL with Capital of
     UseLine=Apply
    @@ -476,19 +476,19 @@ Reported=Delayed
     DisabledBecausePayments=Not possible since there are some payments
     CantRemovePaymentWithOneInvoicePaid=Can't remove payment since there is at least one invoice classified paid
     ExpectedToPay=Expected payment
    -CantRemoveConciliatedPayment=Can't remove conciliated payment
    +CantRemoveConciliatedPayment=Can't remove reconciled payment
     PayedByThisPayment=Paid by this payment
    -ClosePaidInvoicesAutomatically=Classify "Paid" all standard, down payment or replacement invoices entirely paid.
    +ClosePaidInvoicesAutomatically=Classify "Paid" all standard, down payment or replacement invoices paid entirely.
     ClosePaidCreditNotesAutomatically=Classify "Paid" all credit notes entirely paid back.
    -ClosePaidContributionsAutomatically=Classify "Paid" all social or fiscal contributions entirely paid.
    -AllCompletelyPayedInvoiceWillBeClosed=All invoice with no remain to pay will be automatically closed to status "Paid".
    +ClosePaidContributionsAutomatically=Classify "Paid" all social or fiscal contributions paid entirely.
    +AllCompletelyPayedInvoiceWillBeClosed=All invoice with no remainder to pay will be automatically closed with status "Paid".
     ToMakePayment=Pay
     ToMakePaymentBack=Pay back
     ListOfYourUnpaidInvoices=List of unpaid invoices
     NoteListOfYourUnpaidInvoices=Note: This list contains only invoices for third parties you are linked to as a sale representative.
     RevenueStamp=Revenue stamp
    -YouMustCreateInvoiceFromThird=This option is only available when creating invoice from tab "customer" of third party
    -YouMustCreateInvoiceFromSupplierThird=This option is only available when creating invoice from tab "supplier" of third party
    +YouMustCreateInvoiceFromThird=This option is only available when creating invoices from tab "customer" of third party
    +YouMustCreateInvoiceFromSupplierThird=This option is only available when creating invoices from tab "supplier" of third party
     YouMustCreateStandardInvoiceFirstDesc=You have to create a standard invoice first and convert it to "template" to create a new template invoice
     PDFCrabeDescription=Invoice PDF template Crabe. A complete invoice template (recommended Template)
     PDFCrevetteDescription=Invoice PDF template Crevette. A complete invoice template for situation invoices
    @@ -535,7 +535,7 @@ invoiceLineProgressError=Invoice line progress can't be greater than or equal to
     updatePriceNextInvoiceErrorUpdateline=Error : update price on invoice line : %s
     ToCreateARecurringInvoice=To create a recurring invoice for this contract, first create this draft invoice, then convert it into an invoice template and define the frequency for generation of future invoices.
     ToCreateARecurringInvoiceGene=To generate future invoices regularly and manually, just go on menu <strong>%s - %s - %s</strong>.
    -ToCreateARecurringInvoiceGeneAuto=If you need to have such invoices generated automatically, ask you administrator to enable and setup module <strong>%s</strong>. Note that both method (manual and automatic) can be used together with no risk of duplication.
    +ToCreateARecurringInvoiceGeneAuto=If you need to have such invoices generated automatically, ask your administrator to enable and setup module <strong>%s</strong>. Note that both method (manual and automatic) can be used together with no risk of duplication.
     DeleteRepeatableInvoice=Delete template invoice
     ConfirmDeleteRepeatableInvoice=Are your sure you want to delete the template invoice?
     CreateOneBillByThird=Create one invoice per third party (otherwise, one invoice per order)
    diff --git a/htdocs/langs/en_US/blockedlog.lang b/htdocs/langs/en_US/blockedlog.lang
    index fb52e8476ee..88d3662be9c 100644
    --- a/htdocs/langs/en_US/blockedlog.lang
    +++ b/htdocs/langs/en_US/blockedlog.lang
    @@ -8,7 +8,7 @@ BrowseBlockedLog=Unalterable logs
     ShowAllFingerPrintsMightBeTooLong=Show all archived logs (might be long)
     ShowAllFingerPrintsErrorsMightBeTooLong=Show all non-valid archive logs (might be long)
     DownloadBlockChain=Download fingerprints
    -KoCheckFingerprintValidity=Archived log is not valid. It means someone (a hacker?) has modified some datas of this archived log after it was recorded, or has erased the previous archived record (check that line with previous # exists).
    +KoCheckFingerprintValidity=Archived log is not valid. It means someone (a hacker?) has modified some data of this archived log after it was recorded, or has erased the previous archived record (check that line with previous # exists).
     OkCheckFingerprintValidity=Archived log is valid. It means all data on this line were not modified and record follow the previous one.
     OkCheckFingerprintValidityButChainIsKo=Archived log seems valid compared to previous one but the chain was corrupted previously.
     AddedByAuthority=Stored into remote authority
    @@ -22,7 +22,7 @@ logPAYMENT_CUSTOMER_CREATE=Customer payment created
     logPAYMENT_CUSTOMER_DELETE=Customer payment logical deletion
     logDONATION_PAYMENT_CREATE=Donation payment created
     logDONATION_PAYMENT_DELETE=Donation payment logical deletion
    -logBILL_PAYED=Customer invoice payed
    +logBILL_PAYED=Customer invoice paid
     logBILL_UNPAYED=Customer invoice set unpaid
     logBILL_VALIDATE=Customer invoice validated
     logBILL_SENTBYMAIL=Customer invoice send by mail
    @@ -49,5 +49,5 @@ BlockedLogAreRequiredByYourCountryLegislation=Unalterable Logs module may be req
     BlockedLogActivatedBecauseRequiredByYourCountryLegislation=Unalterable Logs module was activated because of the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they cannot be validated by a tax audit.
     BlockedLogDisableNotAllowedForCountry=List of countries where usage of this module is mandatory (just to prevent to disable the module by error, if your country is in this list, disable of module is not possible without editing this list first. Note also that enabling/disabling this module will keep a track into the unalterable log).
     OnlyNonValid=Non-valid
    -TooManyRecordToScanRestrictFilters=Too many record to scan/analyze. Please restrict list with more restrictive filters.
    +TooManyRecordToScanRestrictFilters=Too many records to scan/analyze. Please restrict list with more restrictive filters.
     RestrictYearToExport=Restrict month / year to export
    diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang
    index cc46e702a75..8a519879ac3 100644
    --- a/htdocs/langs/en_US/boxes.lang
    +++ b/htdocs/langs/en_US/boxes.lang
    @@ -15,7 +15,7 @@ BoxLastSuppliers=Latest modified suppliers
     BoxLastCustomerOrders=Latest customer orders
     BoxLastActions=Latest actions
     BoxLastContracts=Latest contracts
    -BoxLastContacts=Latest contact addresses
    +BoxLastContacts=Latest contacts/addresses
     BoxLastMembers=Latest members
     BoxFicheInter=Latest interventions
     BoxCurrentAccounts=Open accounts balance
    @@ -34,7 +34,7 @@ BoxTitleLastFicheInter=Latest %s modified interventions
     BoxTitleOldestUnpaidCustomerBills=Customer Invoices: oldest %s unpaid
     BoxTitleOldestUnpaidSupplierBills=Supplier Invoices: oldest %s unpaid
     BoxTitleCurrentAccounts=Open Accounts: balances
    -BoxTitleLastModifiedContacts=Contact addresses: latest %s modified
    +BoxTitleLastModifiedContacts=Contacts/Addresses: latest %s modified
     BoxMyLastBookmarks=Bookmarks: latest %s modified
     BoxOldestExpiredServices=Oldest active expired services
     BoxLastExpiredServices=Latest %s oldest contacts with active expired services
    @@ -83,4 +83,4 @@ ForCustomersOrders=Customers orders
     ForProposals=Proposals
     LastXMonthRolling=The latest %s month rolling
     ChooseBoxToAdd=Add widget to your dashboard
    -BoxAdded=Widget was added in your dashboard
    \ No newline at end of file
    +BoxAdded=Widget was added in your dashboard
    diff --git a/htdocs/langs/en_US/commercial.lang b/htdocs/langs/en_US/commercial.lang
    index a130ce82f79..0a0deb99a1f 100644
    --- a/htdocs/langs/en_US/commercial.lang
    +++ b/htdocs/langs/en_US/commercial.lang
    @@ -76,4 +76,4 @@ WelcomeOnOnlineSignaturePage=Welcome to the page to accept commercial proposals
     ThisScreenAllowsYouToSignDocFrom=This screen allow you to accept and sign, or refuse, a quote/commercial proposal
     ThisIsInformationOnDocumentToSign=This is information on document to accept or refuse
     SignatureProposalRef=Signature of quote/commercial proposal %s
    -FeatureOnlineSignDisabled=Feature for online signing disabled or document generated before the feature was enabled  
    \ No newline at end of file
    +FeatureOnlineSignDisabled=Feature for online signing disabled or document generated before the feature was enabled
    diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang
    index ef0328b9349..e026ac5673d 100644
    --- a/htdocs/langs/en_US/companies.lang
    +++ b/htdocs/langs/en_US/companies.lang
    @@ -3,7 +3,7 @@ ErrorCompanyNameAlreadyExists=Company name %s already exists. Choose another one
     ErrorSetACountryFirst=Set the country first
     SelectThirdParty=Select a third party
     ConfirmDeleteCompany=Are you sure you want to delete this company and all inherited information?
    -DeleteContact=Delete a contact address
    +DeleteContact=Delete a contact/address
     ConfirmDeleteContact=Are you sure you want to delete this contact and all inherited information?
     MenuNewThirdParty=New Third Party
     MenuNewCustomer=New Customer
    @@ -19,9 +19,9 @@ ProspectionArea=Prospection area
     IdThirdParty=Id third party
     IdCompany=Company Id
     IdContact=Contact Id
    -Contacts=Contact addresses
    -ThirdPartyContacts=Third party contact addresses
    -ThirdPartyContact=Third party contact address
    +Contacts=Contacts/Addresses
    +ThirdPartyContacts=Third party contacts
    +ThirdPartyContact=Third party contact/address
     Company=Company
     CompanyName=Company name
     AliasNames=Alias name (commercial, trademark, ...)
    @@ -40,7 +40,7 @@ ThirdPartyCustomersWithIdProf12=Customers with %s or %s
     ThirdPartySuppliers=Vendors
     ThirdPartyType=Type of company
     Individual=Private individual
    -ToCreateContactWithSameName=Will create automatically a contact address with same information as the third party under the third party. In most cases, even if your third party is a physical person, creating a third party alone is enough.
    +ToCreateContactWithSameName=Will create a Third Party and a linked Contact/Address with same information as the Third Party. In most cases, even if your Third Party is a physical person, creating a Third Party alone is enough.
     ParentCompany=Parent company
     Subsidiaries=Subsidiaries
     ReportByMonth=Report by month
    @@ -274,8 +274,8 @@ CompanyHasRelativeDiscount=This customer has a default discount of <b>%s%%</b>
     CompanyHasNoRelativeDiscount=This customer has no relative discount by default
     HasRelativeDiscountFromSupplier=You have a default discount of <b>%s%%</b> from this supplier
     HasNoRelativeDiscountFromSupplier=You have no default relative discount from this supplier
    -CompanyHasAbsoluteDiscount=This customer has discount available (credits notes or down payments) for <b>%s</b> %s
    -CompanyHasDownPaymentOrCommercialDiscount=This customer has discount available (commercial, down payments) for <b>%s</b> %s
    +CompanyHasAbsoluteDiscount=This customer has discounts available (credits notes or down payments) for <b>%s</b> %s
    +CompanyHasDownPaymentOrCommercialDiscount=This customer has discounts available (commercial, down payments) for <b>%s</b> %s
     CompanyHasCreditNote=This customer still has credit notes for <b>%s</b> %s
     HasNoAbsoluteDiscountFromSupplier=You have no discount credit available from this supplier
     HasAbsoluteDiscountFromSupplier=You have discounts available (credits notes or down payments) for <b>%s</b> %s from this supplier
    @@ -289,16 +289,16 @@ SupplierAbsoluteDiscountMy=Absolute vendor discounts (entered by yourself)
     DiscountNone=None
     Supplier=Vendor
     AddContact=Create contact
    -AddContactAddress=Create contact address
    +AddContactAddress=Create contact/address
     EditContact=Edit contact
    -EditContactAddress=Edit contact address
    +EditContactAddress=Edit contact/address
     Contact=Contact
     ContactId=Contact id
    -ContactsAddresses=Contact addresses
    +ContactsAddresses=Contacts/Addresses
     FromContactName=Name:
     NoContactDefinedForThirdParty=No contact defined for this third party
     NoContactDefined=No contact defined
    -DefaultContact=Default contact address
    +DefaultContact=Default contact/address
     AddThirdParty=Create third party
     DeleteACompany=Delete a company
     PersonalInformations=Personal data
    @@ -312,11 +312,11 @@ SupplierCodeDesc=Vendor Code, unique for all vendors
     RequiredIfCustomer=Required if third party is a customer or prospect
     RequiredIfSupplier=Required if third party is a vendor
     ValidityControledByModule=Validity controlled by module
    -ThisIsModuleRules=This is rules for this module
    +ThisIsModuleRules=Rules for this module
     ProspectToContact=Prospect to contact
     CompanyDeleted=Company "%s" deleted from database.
    -ListOfContacts=List of contact addresses
    -ListOfContactsAddresses=List of contact addresses
    +ListOfContacts=List of contacts/addresses
    +ListOfContactsAddresses=List of contacts/addresses
     ListOfThirdParties=List of Third Parties
     ShowCompany=Show Third Party
     ShowContact=Show contact
    @@ -333,19 +333,19 @@ NoContactForAnyProposal=This contact is not a contact for any commercial proposa
     NoContactForAnyContract=This contact is not a contact for any contract
     NoContactForAnyInvoice=This contact is not a contact for any invoice
     NewContact=New contact
    -NewContactAddress=New Contact address
    +NewContactAddress=New Contact/Address
     MyContacts=My contacts
     Capital=Capital
     CapitalOf=Capital of %s
     EditCompany=Edit company
    -ThisUserIsNot=This user is not a prospect, customer nor vendor
    +ThisUserIsNot=This user is not a prospect, customer or vendor
     VATIntraCheck=Check
     VATIntraCheckDesc=The link <b>%s</b> uses the European VAT checker service (VIES). An external internet access from server is required for this service to work.
     VATIntraCheckURL=http://ec.europa.eu/taxation_customs/vies/vieshome.do
     VATIntraCheckableOnEUSite=Check intra-Community VAT on the European Commission website
     VATIntraManualCheck=You can also check manually on the European Commission website <a href="%s" target="_blank">%s</a>
     ErrorVATCheckMS_UNAVAILABLE=Check not possible. Check service is not provided by the member state (%s).
    -NorProspectNorCustomer=Nor prospect, nor customer
    +NorProspectNorCustomer=Not prospect, or customer
     JuridicalStatus=Legal Entity Type
     Staff=Staff
     ProspectLevelShort=Potential
    @@ -390,7 +390,7 @@ NoDolibarrAccess=No Dolibarr access
     ExportDataset_company_1=Third Parties (companies/foundations/physical people) and their properties
     ExportDataset_company_2=Contacts and their properties
     ImportDataset_company_1=Third Parties (companies/foundations/physical people) and their properties
    -ImportDataset_company_2=Contact addresses and attributes
    +ImportDataset_company_2=Contacts/Addresses and attributes
     ImportDataset_company_3=Bank accounts of Third Parties
     ImportDataset_company_4=Third Parties - sales representatives (assign sales representatives/users to companies)
     PriceLevel=Price level
    @@ -409,7 +409,7 @@ YouMustCreateContactFirst=To be able to add email notifications, you must first
     ListSuppliersShort=List of Vendors
     ListProspectsShort=List of Prospects
     ListCustomersShort=List of Customers
    -ThirdPartiesArea=Third Parties and Contacts addresses area
    +ThirdPartiesArea=Third Parties/Contacts
     LastModifiedThirdParties=Last %s modified Third Parties
     UniqueThirdParties=Total of Third Parties
     InActivity=Open
    diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang
    index 3a18ae3e376..6ad5e357b35 100644
    --- a/htdocs/langs/en_US/compta.lang
    +++ b/htdocs/langs/en_US/compta.lang
    @@ -6,7 +6,7 @@ OptionMode=Option for accountancy
     OptionModeTrue=Option Incomes-Expenses
     OptionModeVirtual=Option Claims-Debts
     OptionModeTrueDesc=In this context, the turnover is calculated over payments (date of payments). The validity of the figures is assured only if the book-keeping is scrutinized through the input/output on the accounts via invoices.
    -OptionModeVirtualDesc=In this context, the turnover is calculated over invoices (date of validation). When these invoices are due, whether they have been paid or not, they are listed in the turnover output. 
    +OptionModeVirtualDesc=In this context, the turnover is calculated over invoices (date of validation). When these invoices are due, whether they have been paid or not, they are listed in the turnover output.
     FeatureIsSupportedInInOutModeOnly=Feature only available in CREDITS-DEBTS accountancy mode (See Accountancy module configuration)
     VATReportBuildWithOptionDefinedInModule=Amounts shown here are calculated using rules defined by Tax module setup.
     LTReportBuildWithOptionDefinedInModule=Amounts shown here are calculated using rules defined by Company setup.
    @@ -29,7 +29,7 @@ BalanceBefore=Balance (before)
     Balance=Balance
     Debit=Debit
     Credit=Credit
    -Piece=Accounting Doc. 
    +Piece=Accounting Doc.
     AmountHTVATRealReceived=Net collected
     AmountHTVATRealPaid=Net paid
     VATToPay=Tax sales
    @@ -111,7 +111,7 @@ Refund=Refund
     SocialContributionsPayments=Social/fiscal taxes payments
     ShowVatPayment=Show VAT payment
     TotalToPay=Total to pay
    -BalanceVisibilityDependsOnSortAndFilters=Balance is visible in this list only if table is sorted on %s and filtered for 1 bank account
    +BalanceVisibilityDependsOnSortAndFilters=Balance is visible in this list only if table is sorted ascending on %s and filtered for 1 bank account
     CustomerAccountancyCode=Customer accounting code
     SupplierAccountancyCode=Vendor accounting code
     CustomerAccountancyCodeShort=Cust. account. code
    @@ -167,7 +167,7 @@ RulesAmountOnInOutBookkeepingRecord=It includes record in your Ledger with accou
     RulesResultBookkeepingPredefined=It includes record in your Ledger with accounting accounts that has the group "EXPENSE" or "INCOME"
     RulesResultBookkeepingPersonalized=It show record in your Ledger with accounting accounts <b>grouped by personalized groups</b>
     SeePageForSetup=See menu <a href="%s">%s</a> for setup
    -DepositsAreNotIncluded=- Down payment invoices are nor included
    +DepositsAreNotIncluded=- Down payment invoices are not included
     DepositsAreIncluded=- Down payment invoices are included
     LT1ReportByCustomers=Report tax 2 by third party
     LT2ReportByCustomers=Report tax 3 by third party
    @@ -191,7 +191,7 @@ RulesVATInProducts=- For material assets, the report includes the VAT received o
     RulesVATDueServices=- For services, the report includes VAT invoices due, paid or not, based on the invoice date.
     RulesVATDueProducts=- For material assets, the report includes the VAT invoices, based on the invoice date.
     OptionVatInfoModuleComptabilite=Note: For material assets, it should use the date of delivery to be more fair.
    -ThisIsAnEstimatedValue=This is a preview, based on business events and not from the final ledger table, so final results may differ from this preview values 
    +ThisIsAnEstimatedValue=This is a preview, based on business events and not from the final ledger table, so final results may differ from this preview values
     PercentOfInvoice=%%/invoice
     NotUsedForGoods=Not used on goods
     ProposalStats=Statistics on proposals
    @@ -203,7 +203,7 @@ ToDispatch=To dispatch
     ThirdPartyMustBeEditAsCustomer=Third party must be defined as a customer
     SellsJournal=Sales Journal
     PurchasesJournal=Purchases Journal
    -DescSellsJournal=Sales Journal 
    +DescSellsJournal=Sales Journal
     DescPurchasesJournal=Purchases Journal
     InvoiceRef=Invoice ref.
     CodeNotDef=Not defined
    @@ -256,4 +256,4 @@ PaidDuringThisPeriod=Paid during this period
     ByVatRate=By sale tax rate
     TurnoverbyVatrate=Turnover invoiced by sale tax rate
     TurnoverCollectedbyVatrate=Turnover collected by sale tax rate
    -PurchasebyVatrate=Purchase by sale tax rate
    \ No newline at end of file
    +PurchasebyVatrate=Purchase by sale tax rate
    diff --git a/htdocs/langs/en_US/cron.lang b/htdocs/langs/en_US/cron.lang
    index f968d2ac1fb..63d56feca61 100644
    --- a/htdocs/langs/en_US/cron.lang
    +++ b/htdocs/langs/en_US/cron.lang
    @@ -11,11 +11,11 @@ URLToLaunchCronJobs=URL to check and launch qualified cron jobs
     OrToLaunchASpecificJob=Or to check and launch a specific job
     KeyForCronAccess=Security key for URL to launch cron jobs
     FileToLaunchCronJobs=Command line to check and launch qualified cron jobs
    -CronExplainHowToRunUnix=On Unix environment you should use the following crontab entry to run the command line each 5 minutes 
    +CronExplainHowToRunUnix=On Unix environment you should use the following crontab entry to run the command line each 5 minutes
     CronExplainHowToRunWin=On Microsoft(tm) Windows environment you can use Scheduled Task tools to run the command line each 5 minutes
     CronMethodDoesNotExists=Class %s does not contains any method %s
     CronJobDefDesc=Cron job profiles are defined into the module descriptor file. When module is activated, they are loaded and available so you can administer the jobs from the admin tools menu %s.
    -CronJobProfiles=List of predefined cron job profiles 
    +CronJobProfiles=List of predefined cron job profiles
     # Menu
     EnabledAndDisabled=Enabled and disabled
     # Page list
    diff --git a/htdocs/langs/en_US/deliveries.lang b/htdocs/langs/en_US/deliveries.lang
    index 1c9cb791900..0d432c3f426 100644
    --- a/htdocs/langs/en_US/deliveries.lang
    +++ b/htdocs/langs/en_US/deliveries.lang
    @@ -17,11 +17,11 @@ DeliveryNotValidated=Delivery not validated
     StatusDeliveryCanceled=Canceled
     StatusDeliveryDraft=Draft
     StatusDeliveryValidated=Received
    -# merou PDF model						   
    -NameAndSignature=Name and Signature : 
    +# merou PDF model
    +NameAndSignature=Name and Signature :
     ToAndDate=To___________________________________ on ____/_____/__________
     GoodStatusDeclaration=Have received the goods above in good condition,
    -Deliverer=Deliverer : 
    +Deliverer=Deliverer :
     Sender=Sender
     Recipient=Recipient
     ErrorStockIsNotEnough=There's not enough stock
    diff --git a/htdocs/langs/en_US/dict.lang b/htdocs/langs/en_US/dict.lang
    index 0993d8bfb9a..59e7cc058f4 100644
    --- a/htdocs/langs/en_US/dict.lang
    +++ b/htdocs/langs/en_US/dict.lang
    @@ -354,4 +354,4 @@ ExpAuto13PCV=13 CV and more
     ExpCyclo=Capacity lower to 50cm3
     ExpMoto12CV=Motorbike 1 or 2 CV
     ExpMoto345CV=Motorbike 3, 4 or 5 CV
    -ExpMoto5PCV=Motorbike 5 CV and more
    \ No newline at end of file
    +ExpMoto5PCV=Motorbike 5 CV and more
    diff --git a/htdocs/langs/en_US/donations.lang b/htdocs/langs/en_US/donations.lang
    index 748057cc9cc..5edc8d62033 100644
    --- a/htdocs/langs/en_US/donations.lang
    +++ b/htdocs/langs/en_US/donations.lang
    @@ -27,7 +27,7 @@ IConfirmDonationReception=The recipient declare reception, as a donation, of the
     MinimumAmount=Minimum amount is  %s
     FreeTextOnDonations=Free text to show in footer
     FrenchOptions=Options for France
    -DONATION_ART200=Show article 200 from CGI if you are concerned 
    +DONATION_ART200=Show article 200 from CGI if you are concerned
     DONATION_ART238=Show article 238 from CGI if you are concerned
     DONATION_ART885=Show article 885 from CGI if you are concerned
     DonationPayment=Donation payment
    diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang
    index 9e179519739..29dbf4b4287 100644
    --- a/htdocs/langs/en_US/errors.lang
    +++ b/htdocs/langs/en_US/errors.lang
    @@ -74,7 +74,7 @@ ErrorLDAPSetupNotComplete=Dolibarr-LDAP matching is not complete.
     ErrorLDAPMakeManualTest=A .ldif file has been generated in directory %s. Try to load it manually from command line to have more information on errors.
     ErrorCantSaveADoneUserWithZeroPercentage=Can't save an action with "status not started" if field "done by" is also filled.
     ErrorRefAlreadyExists=Ref used for creation already exists.
    -ErrorPleaseTypeBankTransactionReportName=Please enter the bank statement name where the entry has to be reported (Format YYYYMM or YYYYMMDD) 
    +ErrorPleaseTypeBankTransactionReportName=Please enter the bank statement name where the entry has to be reported (Format YYYYMM or YYYYMMDD)
     ErrorRecordHasChildren=Failed to delete record since it has some child records.
     ErrorRecordHasAtLeastOneChildOfType=Object has at least one child of type %s
     ErrorRecordIsUsedCantDelete=Can't delete record. It is already used or included into another object.
    @@ -116,7 +116,7 @@ ErrorLoginDoesNotExists=User with login <b>%s</b> could not be found.
     ErrorLoginHasNoEmail=This user has no email address. Process aborted.
     ErrorBadValueForCode=Bad value for security code. Try again with new value...
     ErrorBothFieldCantBeNegative=Fields %s and %s can't be both negative
    -ErrorFieldCantBeNegativeOnInvoice=Field <strong>%s</strong> can't be negative on such type of invoice. If you want to add a discount line, just create the discount first with link %s on screen and apply it to invoice. You can also ask your admin to set option FACTURE_ENABLE_NEGATIVE_LINES to 1 to restore old behaviour. 
    +ErrorFieldCantBeNegativeOnInvoice=Field <strong>%s</strong> can't be negative on such type of invoice. If you want to add a discount line, just create the discount first with link %s on screen and apply it to invoice. You can also ask your admin to set option FACTURE_ENABLE_NEGATIVE_LINES to 1 to restore old behaviour.
     ErrorQtyForCustomerInvoiceCantBeNegative=Quantity for line into customer invoices can't be negative
     ErrorWebServerUserHasNotPermission=User account <b>%s</b> used to execute web server has no permission for that
     ErrorNoActivatedBarcode=No barcode type activated
    @@ -140,7 +140,7 @@ ErrorBadFormat=Bad format!
     ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst=Error, this member is not yet linked to any third party. Link member to an existing third party or create a new third party before creating subscription with invoice.
     ErrorThereIsSomeDeliveries=Error, there is some deliveries linked to this shipment. Deletion refused.
     ErrorCantDeletePaymentReconciliated=Can't delete a payment that had generated a bank entry that was reconciled
    -ErrorCantDeletePaymentSharedWithPayedInvoice=Can't delete a payment shared by at least one invoice with status Payed
    +ErrorCantDeletePaymentSharedWithPayedInvoice=Can't delete a payment shared by at least one invoice with status Paid
     ErrorPriceExpression1=Cannot assign to constant '%s'
     ErrorPriceExpression2=Cannot redefine built-in function '%s'
     ErrorPriceExpression3=Undefined variable '%s' in function definition
    @@ -198,7 +198,7 @@ ErrorModuleFileSeemsToHaveAWrongFormat=The module package seems to have a wrong
     ErrorFilenameDosNotMatchDolibarrPackageRules=The name of the module package (<strong>%s</strong>) does not match expected name syntax: <strong>%s</strong>
     ErrorDuplicateTrigger=Error, duplicate trigger name %s. Already loaded from %s.
     ErrorNoWarehouseDefined=Error, no warehouses defined.
    -ErrorBadLinkSourceSetButBadValueForRef=The link you use is not valid. A 'source' for payment is defined, but value for 'ref' is not valid. 
    +ErrorBadLinkSourceSetButBadValueForRef=The link you use is not valid. A 'source' for payment is defined, but value for 'ref' is not valid.
     ErrorTooManyErrorsProcessStopped=Too many errors. Process was stopped.
     ErrorMassValidationNotAllowedWhenStockIncreaseOnAction=Mass validation is not possible when option to increase/decrease stock is set on this action (you must validate one by one so you can define the warehouse to increase/decrease)
     ErrorObjectMustHaveStatusDraftToBeValidated=Object %s must have status 'Draft' to be validated.
    @@ -213,7 +213,7 @@ ErrorDescRequiredForFreeProductLines=Description is mandatory for lines with fre
     ErrorAPageWithThisNameOrAliasAlreadyExists=The page/container <strong>%s</strong> has the same name or alternative alias that the one your try to use
     
     # Warnings
    -WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user.  
    +WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user.
     WarningMandatorySetupNotComplete=Mandatory setup parameters are not yet defined
     WarningSafeModeOnCheckExecDir=Warning, PHP option <b>safe_mode</b> is on so command must be stored inside a directory declared by php parameter <b>safe_mode_exec_dir</b>.
     WarningBookmarkAlreadyExists=A bookmark with this title or this target (URL) already exists.
    @@ -221,14 +221,14 @@ WarningPassIsEmpty=Warning, database password is empty. This is a security hole.
     WarningConfFileMustBeReadOnly=Warning, your config file (<b>htdocs/conf/conf.php</b>) can be overwritten by the web server. This is a serious security hole. Modify permissions on file to be in read only mode for operating system user used by Web server. If you use Windows and FAT format for your disk, you must know that this file system does not allow to add permissions on file, so can't be completely safe.
     WarningsOnXLines=Warnings on <b>%s</b> source record(s)
     WarningNoDocumentModelActivated=No model, for document generation, has been activated. A model will be chosen by default until you check your module setup.
    -WarningLockFileDoesNotExists=Warning, once setup is finished, you must disable install/migrate tools by adding a file <b>install.lock</b> into directory <b>%s</b>. Missing this file is a security hole. 
    +WarningLockFileDoesNotExists=Warning, once setup is finished, you must disable install/migrate tools by adding a file <b>install.lock</b> into directory <b>%s</b>. Missing this file is a security hole.
     WarningUntilDirRemoved=All security warnings (visible by admin users only) will remain active as long as the vulnerability is present (or that constant MAIN_REMOVE_INSTALL_WARNING is added in Setup->Other Setup).
     WarningCloseAlways=Warning, closing is done even if amount differs between source and target elements. Enable this feature with caution.
     WarningUsingThisBoxSlowDown=Warning, using this box slow down seriously all pages showing the box.
     WarningClickToDialUserSetupNotComplete=Setup of ClickToDial information for your user are not complete (see tab ClickToDial onto your user card).
     WarningFeatureDisabledWithDisplayOptimizedForBlindNoJs=Feature disabled when display setup is optimized for blind person or text browsers.
    -WarningPaymentDateLowerThanInvoiceDate=Payment date (%s) is earlier than invoice date (%s) for invoice %s. 
    -WarningTooManyDataPleaseUseMoreFilters=Too many data (more than %s lines). Please use more filters or set the constant %s to a higher limit. 
    +WarningPaymentDateLowerThanInvoiceDate=Payment date (%s) is earlier than invoice date (%s) for invoice %s.
    +WarningTooManyDataPleaseUseMoreFilters=Too many data (more than %s lines). Please use more filters or set the constant %s to a higher limit.
     WarningSomeLinesWithNullHourlyRate=Some times were recorded by some users while their hourly rate was not defined. A value of 0 %s per hour was used but this may result in wrong valuation of time spent.
     WarningYourLoginWasModifiedPleaseLogin=Your login was modified. For security purpose you will have to login with your new login before next action.
     WarningAnEntryAlreadyExistForTransKey=An entry already exists for the translation key for this language
    diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang
    index fa34b7f49ae..179556ddb19 100644
    --- a/htdocs/langs/en_US/exports.lang
    +++ b/htdocs/langs/en_US/exports.lang
    @@ -84,7 +84,7 @@ TooMuchErrors=There are still <b>%s</b> other source lines with errors but outpu
     TooMuchWarnings=There are still <b>%s</b> other source lines with warnings but output has been limited.
     EmptyLine=Empty line (will be discarded)
     CorrectErrorBeforeRunningImport=You <b>must</b> correct all errors <b>before</b> running the definitive import.
    -FileWasImported=File was imported with number <b>%s</b>. 
    +FileWasImported=File was imported with number <b>%s</b>.
     YouCanUseImportIdToFindRecord=You can find all the imported records in your database by filtering on field <b>import_key='%s'</b>.
     NbOfLinesOK=Number of lines with no errors and no warnings: <b>%s</b>.
     NbOfLinesImported=Number of lines successfully imported: <b>%s</b>.
    @@ -118,7 +118,7 @@ SetThisValueTo2ToExcludeFirstLine=For example, set this value to 3 to exclude th
     KeepEmptyToGoToEndOfFile=Keep this field empty to go up to the end of file
     SelectPrimaryColumnsForUpdateAttempt=Select column(s) to use as primary key for update attempt
     UpdateNotYetSupportedForThisImport=Update is not supported for this type of import (only insert)
    -NoUpdateAttempt=No update attempt was performed, only insert 
    +NoUpdateAttempt=No update attempt was performed, only insert
     ImportDataset_user_1=Users (employees or not) and properties
     ComputedField=Computed field
     ## filters
    @@ -130,4 +130,4 @@ FormatControlRule=Format control rule
     KeysToUseForUpdates=Key (column) to use for <b>updating</b> existing data
     NbInsert=Number of inserted lines: %s
     NbUpdate=Number of updated lines: %s
    -MultipleRecordFoundWithTheseFilters=Multiple records have been found with these filters: %s
    \ No newline at end of file
    +MultipleRecordFoundWithTheseFilters=Multiple records have been found with these filters: %s
    diff --git a/htdocs/langs/en_US/externalsite.lang b/htdocs/langs/en_US/externalsite.lang
    index afec761f5fe..da4853df0df 100644
    --- a/htdocs/langs/en_US/externalsite.lang
    +++ b/htdocs/langs/en_US/externalsite.lang
    @@ -2,4 +2,4 @@
     ExternalSiteSetup=Setup link to external website
     ExternalSiteURL=External Site URL
     ExternalSiteModuleNotComplete=Module ExternalSite was not configured properly.
    -ExampleMyMenuEntry=My menu entry
    \ No newline at end of file
    +ExampleMyMenuEntry=My menu entry
    diff --git a/htdocs/langs/en_US/ftp.lang b/htdocs/langs/en_US/ftp.lang
    index d6b9d2ca070..8ecb0c55cad 100644
    --- a/htdocs/langs/en_US/ftp.lang
    +++ b/htdocs/langs/en_US/ftp.lang
    @@ -11,4 +11,4 @@ FTPFailedToRemoveFile=Failed to remove file <b>%s</b>.
     FTPFailedToRemoveDir=Failed to remove directory <b>%s</b> (Check permissions and that directory is empty).
     FTPPassiveMode=Passive mode
     ChooseAFTPEntryIntoMenu=Choose a FTP entry into menu...
    -FailedToGetFile=Failed to get files %s
    \ No newline at end of file
    +FailedToGetFile=Failed to get files %s
    diff --git a/htdocs/langs/en_US/holiday.lang b/htdocs/langs/en_US/holiday.lang
    index 5c9c9e04200..1411ae3ad56 100644
    --- a/htdocs/langs/en_US/holiday.lang
    +++ b/htdocs/langs/en_US/holiday.lang
    @@ -1,10 +1,10 @@
     # Dolibarr language file - Source file is en_US - holiday
     HRM=HRM
    -Holidays=Leaves
    -CPTitreMenu=Leaves
    +Holidays=Leave
    +CPTitreMenu=Leave
     MenuReportMonth=Monthly statement
     MenuAddCP=New leave request
    -NotActiveModCP=You must enable the module Leaves to view this page.
    +NotActiveModCP=You must enable the module Leave to view this page.
     AddCP=Make a leave request
     DateDebCP=Start date
     DateFinCP=End date
    @@ -15,7 +15,7 @@ ApprovedCP=Approved
     CancelCP=Canceled
     RefuseCP=Refused
     ValidatorCP=Approbator
    -ListeCP=List of leaves
    +ListeCP=List of leave
     LeaveId=Leave ID
     ReviewedByCP=Will be approved by
     UserForApprovalID=User for approval ID
    @@ -25,8 +25,8 @@ UserForApprovalLogin=Login of approval user
     DescCP=Description
     SendRequestCP=Create leave request
     DelayToRequestCP=Leave requests must be made at least <b>%s day(s)</b> before them.
    -MenuConfCP=Balance of leaves
    -SoldeCPUser=Leaves balance is <b>%s</b> days.
    +MenuConfCP=Balance of leave
    +SoldeCPUser=Leave balance is <b>%s</b> days.
     ErrorEndDateCP=You must select an end date greater than the start date.
     ErrorSQLCreateCP=An SQL error occurred during the creation:
     ErrorIDFicheCP=An error has occurred, the leave request does not exist.
    @@ -85,7 +85,7 @@ NewSoldeCP=New Balance
     alreadyCPexist=A leave request has already been done on this period.
     FirstDayOfHoliday=First day of vacation
     LastDayOfHoliday=Last day of vacation
    -BoxTitleLastLeaveRequests=Latest %s modified leave requests 
    +BoxTitleLastLeaveRequests=Latest %s modified leave requests
     HolidaysMonthlyUpdate=Monthly update
     ManualUpdate=Manual update
     HolidaysCancelation=Leave request cancelation
    @@ -101,8 +101,8 @@ LEAVE_SICK=Sick leave
     LEAVE_OTHER=Other leave
     LEAVE_PAID_FR=Paid vacation
     ## Configuration du Module ##
    -LastUpdateCP=Latest automatic update of leaves allocation
    -MonthOfLastMonthlyUpdate=Month of latest automatic update of leaves allocation
    +LastUpdateCP=Latest automatic update of leave allocation
    +MonthOfLastMonthlyUpdate=Month of latest automatic update of leave allocation
     UpdateConfCPOK=Updated successfully.
     Module27130Name= Management of leave requests
     Module27130Desc= Management of leave requests
    @@ -121,4 +121,4 @@ HolidaysCanceled=Canceled leaved request
     HolidaysCanceledBody=Your leave request for %s to %s has been canceled.
     FollowedByACounter=1: This type of leave need to be followed by a counter. Counter is incremented manually or automatically and when a leave request is validated, counter is decremented.<br>0: Not followed by a counter.
     NoLeaveWithCounterDefined=There is no leave types defined that need to be followed by a counter
    -GoIntoDictionaryHolidayTypes=Go into <strong>Home - Setup - Dictionaries - Type of leaves</strong> to setup the different types of leaves.
    +GoIntoDictionaryHolidayTypes=Go into <strong>Home - Setup - Dictionaries - Type of leave</strong> to setup the different types of leaves.
    diff --git a/htdocs/langs/en_US/install.lang b/htdocs/langs/en_US/install.lang
    index e8a89657b6a..bcca348c861 100644
    --- a/htdocs/langs/en_US/install.lang
    +++ b/htdocs/langs/en_US/install.lang
    @@ -127,9 +127,9 @@ OpenBaseDir=PHP openbasedir parameter
     YouAskToCreateDatabaseSoRootRequired=You checked the box "Create database". For this, you need to provide the login/password of superuser (bottom of form).
     YouAskToCreateDatabaseUserSoRootRequired=You checked the box "Create database owner". For this, you need to provide the login/password of superuser (bottom of form).
     NextStepMightLastALongTime=The current step may take several minutes. Please wait until the next screen is shown completely before continuing.
    -MigrationCustomerOrderShipping=Migrate shipping for customer orders storage 
    -MigrationShippingDelivery=Upgrade storage of shipping 
    -MigrationShippingDelivery2=Upgrade storage of shipping 2 
    +MigrationCustomerOrderShipping=Migrate shipping for customer orders storage
    +MigrationShippingDelivery=Upgrade storage of shipping
    +MigrationShippingDelivery2=Upgrade storage of shipping 2
     MigrationFinished=Migration finished
     LastStepDesc=<strong>Last step</strong>: Define here the login and password you wish to use to connect to Dolibarr. <b>Do not lose this as it is the master account to administer all other/additional user accounts.</b>
     ActivateModule=Activate module %s
    @@ -208,4 +208,4 @@ ErrorFoundDuringMigration=Error(s) were reported during the migration process so
     YouTryInstallDisabledByDirLock=The application tried to self-upgrade, but the install/upgrade pages have been disabled for security (directory renamed with .lock suffix).<br>
     YouTryInstallDisabledByFileLock=The application tried to self-upgrade, but the install/upgrade pages have been disabled for security (by the existence of a lock file <strong>install.lock</strong> in the dolibarr documents directory).<br>
     ClickHereToGoToApp=Click here to go to your application
    -ClickOnLinkOrRemoveManualy=Click on the following link. If you always see this same page, you must remove/rename the file install.lock in the documents directory.
    \ No newline at end of file
    +ClickOnLinkOrRemoveManualy=Click on the following link. If you always see this same page, you must remove/rename the file install.lock in the documents directory.
    diff --git a/htdocs/langs/en_US/ldap.lang b/htdocs/langs/en_US/ldap.lang
    index 67824ccd237..abe11602147 100644
    --- a/htdocs/langs/en_US/ldap.lang
    +++ b/htdocs/langs/en_US/ldap.lang
    @@ -24,4 +24,4 @@ MemberTypeSynchronized=Member type synchronized
     ContactSynchronized=Contact synchronized
     ForceSynchronize=Force synchronizing Dolibarr -> LDAP
     ErrorFailedToReadLDAP=Failed to read LDAP database. Check LDAP module setup and database accessibility.
    -PasswordOfUserInLDAP=Password of user in LDAP
    \ No newline at end of file
    +PasswordOfUserInLDAP=Password of user in LDAP
    diff --git a/htdocs/langs/en_US/link.lang b/htdocs/langs/en_US/link.lang
    index 77a1814f1ca..fdcf07aeff4 100644
    --- a/htdocs/langs/en_US/link.lang
    +++ b/htdocs/langs/en_US/link.lang
    @@ -7,4 +7,4 @@ ErrorFileNotLinked=The file could not be linked
     LinkRemoved=The link %s has been removed
     ErrorFailedToDeleteLink= Failed to remove link '<b>%s</b>'
     ErrorFailedToUpdateLink= Failed to update link '<b>%s</b>'
    -URLToLink=URL to link
    \ No newline at end of file
    +URLToLink=URL to link
    diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang
    index 6c6b31db764..d4f835874e7 100644
    --- a/htdocs/langs/en_US/mails.lang
    +++ b/htdocs/langs/en_US/mails.lang
    @@ -45,7 +45,7 @@ MailingStatusReadAndUnsubscribe=Read and unsubscribe
     ErrorMailRecipientIsEmpty=Email recipient is empty
     WarningNoEMailsAdded=No new Email to add to recipient's list.
     ConfirmValidMailing=Are you sure you want to validate this emailing?
    -ConfirmResetMailing=Warning, by reinitializing emailing <b>%s</b>, you will allow resending this email in a mass mailing. Are you sure you this is what you want to do?
    +ConfirmResetMailing=Warning, by re-initializing emailing <b>%s</b> , you will allow resending this email in a mass mailing. Are you sure you want to do this?
     ConfirmDeleteMailing=Are you sure you want to delete this emailing?
     NbOfUniqueEMails=No. of unique emails
     NbOfEMails=No. of EMails
    @@ -75,7 +75,7 @@ OnlyPDFattachmentSupported=If the PDF documents were already generated for the o
     AllRecipientSelected=The recipients of the %s record selected (if their email is known).
     GroupEmails=Group emails
     OneEmailPerRecipient=One email per recipient (by default, one email per record selected)
    -WarningIfYouCheckOneRecipientPerEmail=Warning, if you check this box, it means only one email will be sent for several different record selected, so, if your message contains substitution variables that refers to data of a record, it becomes not possible to replace them. 
    +WarningIfYouCheckOneRecipientPerEmail=Warning, if you check this box, it means only one email will be sent for several different record selected, so, if your message contains substitution variables that refers to data of a record, it becomes not possible to replace them.
     ResultOfMailSending=Result of mass EMail sending
     NbSelected=No. selected
     NbIgnored=No. ignored
    @@ -99,13 +99,13 @@ MailSelectedRecipients=Selected recipients
     MailingArea=EMailings area
     LastMailings=Latest %s emailings
     TargetsStatistics=Targets statistics
    -NbOfCompaniesContacts=Unique contact addresses
    +NbOfCompaniesContacts=Unique contacts/addresses
     MailNoChangePossible=Recipients for validated emailing can't be changed
     SearchAMailing=Search mailing
     SendMailing=Send emailing
     SentBy=Sent by
     MailingNeedCommand=Sending an emailing can be performed from command line. Ask your server administrator to launch the following command to send the emailing to all recipients:
    -MailingNeedCommand2=You can however send them online by adding parameter MAILING_LIMIT_SENDBYWEB with value of max number of emails you want to send by session. For this, go on Home - Setup - Other. 
    +MailingNeedCommand2=You can however send them online by adding parameter MAILING_LIMIT_SENDBYWEB with value of max number of emails you want to send by session. For this, go on Home - Setup - Other.
     ConfirmSendingEmailing=If you want to send emailing directly from this screen, please confirm you are sure you want to send emailing now from your browser ?
     LimitSendingEmailing=Note: Sending of emailings from web interface is done in several times for security and timeout reasons, <b>%s</b> recipients at a time for each sending session.
     TargetsReset=Clear list
    @@ -121,7 +121,7 @@ TagUnsubscribe=Unsubscribe link
     TagSignature=Signature of sending user
     EMailRecipient=Recipient EMail
     TagMailtoEmail=Recipient EMail (including html "mailto:" link)
    -NoEmailSentBadSenderOrRecipientEmail=No email sent. Bad sender or recipient email. Verify user profile. 
    +NoEmailSentBadSenderOrRecipientEmail=No email sent. Bad sender or recipient email. Verify user profile.
     # Module Notifications
     Notifications=Notifications
     NoNotificationsWillBeSent=No email notifications are planned for this event and company
    @@ -133,12 +133,12 @@ ListOfNotificationsDone=List all email notifications sent
     MailSendSetupIs=Configuration of email sending has been setup to '%s'. This mode can't be used to send mass emailing.
     MailSendSetupIs2=You must first go, with an admin account, into menu %sHome - Setup - EMails%s to change parameter <strong>'%s'</strong> to use mode '%s'. With this mode, you can enter setup of the SMTP server provided by your Internet Service Provider and use Mass emailing feature.
     MailSendSetupIs3=If you have any questions on how to setup your SMTP server, you can ask to %s.
    -YouCanAlsoUseSupervisorKeyword=You can also add the keyword <strong>__SUPERVISOREMAIL__</strong> to have email being sent to the supervisor of user (works only if an email is defined for this supervisor) 
    +YouCanAlsoUseSupervisorKeyword=You can also add the keyword <strong>__SUPERVISOREMAIL__</strong> to have email being sent to the supervisor of user (works only if an email is defined for this supervisor)
     NbOfTargetedContacts=Current number of targeted contact emails
     UseFormatFileEmailToTarget=Imported file must have format <strong>email;name;firstname;other</strong>
     UseFormatInputEmailToTarget=Enter a string with format <strong>email;name;firstname;other</strong>
     MailAdvTargetRecipients=Recipients (advanced selection)
    -AdvTgtTitle=Fill input fields to preselect the third parties or contact addresses to target
    +AdvTgtTitle=Fill input fields to preselect the third parties or contacts/addresses to target
     AdvTgtSearchTextHelp=Use %% as wildcards. For example to find all item like <b>jean, joe, jim</b>, you can input <b>j%%</b>, you can also use ; as separator for value, and use ! for except this value. For example  <b>jean;joe;jim%%;!jimo;!jima%</b> will target all jean, joe, start with jim but not jimo and not everything that starts with jima
     AdvTgtSearchIntHelp=Use interval to select int or float value
     AdvTgtMinVal=Minimum value
    @@ -159,8 +159,8 @@ AdvTgtDeleteFilter=Delete filter
     AdvTgtSaveFilter=Save filter
     AdvTgtCreateFilter=Create filter
     AdvTgtOrCreateNewFilter=Name of new filter
    -NoContactWithCategoryFound=No contact address with a category found
    -NoContactLinkedToThirdpartieWithCategoryFound=No contact address with a category found
    +NoContactWithCategoryFound=No contact/address with a category found
    +NoContactLinkedToThirdpartieWithCategoryFound=No contact/address with a category found
     OutGoingEmailSetup=Outgoing email setup
     InGoingEmailSetup=Incoming email setup
     OutGoingEmailSetupForEmailing=Outgoing email setup (for mass emailing)
    diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
    index 5a017330f20..fb2f2a8e9fb 100644
    --- a/htdocs/langs/en_US/main.lang
    +++ b/htdocs/langs/en_US/main.lang
    @@ -50,21 +50,21 @@ ErrorFailedToSendMail=Failed to send mail (sender=%s, receiver=%s)
     ErrorFileNotUploaded=File was not uploaded. Check that size does not exceed maximum allowed, that free space is available on disk and that there is not already a file with same name in this directory.
     ErrorInternalErrorDetected=Error detected
     ErrorWrongHostParameter=Wrong host parameter
    -ErrorYourCountryIsNotDefined=Your country is not defined. Go to Home-Setup-Edit and post again the form.
    -ErrorRecordIsUsedByChild=Failed to delete this record. This record is used by at least one child records.
    +ErrorYourCountryIsNotDefined=Your country is not defined. Go to Home-Setup-Edit and post the form again.
    +ErrorRecordIsUsedByChild=Failed to delete this record. This record is used by at least one child record.
     ErrorWrongValue=Wrong value
     ErrorWrongValueForParameterX=Wrong value for parameter %s
     ErrorNoRequestInError=No request in error
    -ErrorServiceUnavailableTryLater=Service not available for the moment. Try again later.
    +ErrorServiceUnavailableTryLater=Service not available at the moment. Try again later.
     ErrorDuplicateField=Duplicate value in a unique field
    -ErrorSomeErrorWereFoundRollbackIsDone=Some errors were found. We rollback changes.
    -ErrorConfigParameterNotDefined=Parameter <b>%s</b> is not defined inside Dolibarr config file <b>conf.php</b>.
    +ErrorSomeErrorWereFoundRollbackIsDone=Some errors were found. Changes have been rolled back.
    +ErrorConfigParameterNotDefined=Parameter <b>%s</b> is not defined in Dolibarr config file <b>conf.php</b>.
     ErrorCantLoadUserFromDolibarrDatabase=Failed to find user <b>%s</b> in Dolibarr database.
     ErrorNoVATRateDefinedForSellerCountry=Error, no vat rates defined for country '%s'.
     ErrorNoSocialContributionForSellerCountry=Error, no social/fiscal taxes type defined for country '%s'.
     ErrorFailedToSaveFile=Error, failed to save file.
    -ErrorCannotAddThisParentWarehouse=You are trying to add a parent warehouse which is already a child of current one
    -MaxNbOfRecordPerPage=Max number of record per page
    +ErrorCannotAddThisParentWarehouse=You are trying to add a parent warehouse which is already a child of a current one
    +MaxNbOfRecordPerPage=Max number of records per page
     NotAuthorized=You are not authorized to do that.
     SetDate=Set date
     SelectDate=Select a date
    @@ -78,7 +78,7 @@ FileRenamed=The file was successfully renamed
     FileGenerated=The file was successfully generated
     FileSaved=The file was successfully saved
     FileUploaded=The file was successfully uploaded
    -FileTransferComplete=File(s) was uploaded successfully
    +FileTransferComplete=File(s) uploaded successfully
     FilesDeleted=File(s) successfully deleted
     FileWasNotUploaded=A file is selected for attachment but was not yet uploaded. Click on "Attach file" for this.
     NbOfEntries=No. of entries
    @@ -154,7 +154,7 @@ Update=Update
     Close=Close
     CloseBox=Remove widget from your dashboard
     Confirm=Confirm
    -ConfirmSendCardByMail=Do you really want to send content of this card by mail to <b>%s</b>?
    +ConfirmSendCardByMail=Do you really want to send the content of this card by mail to <b>%s</b>?
     Delete=Delete
     Remove=Remove
     Resiliate=Terminate
    @@ -232,7 +232,7 @@ Numero=Number
     Limit=Limit
     Limits=Limits
     Logout=Logout
    -NoLogoutProcessWithAuthMode=No applicative disconnect feature with authentication mode <b>%s</b> 
    +NoLogoutProcessWithAuthMode=No applicative disconnect feature with authentication mode <b>%s</b>
     Connection=Login
     Setup=Setup
     Alert=Alert
    @@ -348,7 +348,7 @@ AmountTTCShort=Amount (inc. tax)
     AmountHT=Amount (net of tax)
     AmountTTC=Amount (inc. tax)
     AmountVAT=Amount tax
    -MulticurrencyAlreadyPaid=Already payed, original currency
    +MulticurrencyAlreadyPaid=Already paid, original currency
     MulticurrencyRemainderToPay=Remain to pay, original currency
     MulticurrencyPaymentAmount=Payment amount, original currency
     MulticurrencyAmountHT=Amount (net of tax), original currency
    @@ -429,12 +429,12 @@ ActionNotApplicable=Not applicable
     ActionRunningNotStarted=To start
     ActionRunningShort=In progress
     ActionDoneShort=Finished
    -ActionUncomplete=Uncomplete
    +ActionUncomplete=Incomplete
     LatestLinkedEvents=Latest %s linked events
     CompanyFoundation=Company/Organization
     Accountant=Accountant
     ContactsForCompany=Contacts for this third party
    -ContactsAddressesForCompany=Contact addresses for this third party
    +ContactsAddressesForCompany=Contacts/addresses for this third party
     AddressesForCompany=Addresses for this third party
     ActionsOnCompany=Events about this third party
     ActionsOnMember=Events about this member
    @@ -445,7 +445,7 @@ Completed=Completed
     Running=In progress
     RequestAlreadyDone=Request already recorded
     Filter=Filter
    -FilterOnInto=Search criteria '<strong>%s</strong>' into fields %s 
    +FilterOnInto=Search criteria '<strong>%s</strong>' into fields %s
     RemoveFilter=Remove filter
     ChartGenerated=Chart generated
     ChartNotGenerated=Chart not generated
    @@ -507,7 +507,7 @@ None=None
     NoneF=None
     NoneOrSeveral=None or several
     Late=Late
    -LateDesc=Delay to define if a record is late or not depends on your setup. Ask your admin to change delay from menu Home - Setup - Alerts.
    +LateDesc=The delay to define if a record is late or not depends on your setup. Ask your admin to change the delay from menu Home - Setup - Alerts.
     NoItemLate=No late item
     Photo=Picture
     Photos=Pictures
    @@ -659,14 +659,14 @@ Method=Method
     Receive=Receive
     CompleteOrNoMoreReceptionExpected=Complete or nothing more expected
     ExpectedValue=Expected Value
    -CurrentValue=Current Value
    +CurrentValue=Current value
     PartialWoman=Partial
     TotalWoman=Total
     NeverReceived=Never received
     Canceled=Canceled
     YouCanChangeValuesForThisListFromDictionarySetup=You can change values for this list from menu Setup - Dictionaries
     YouCanChangeValuesForThisListFrom=You can change values for this list from menu %s
    -YouCanSetDefaultValueInModuleSetup=You can set the default value used when creating a new record into module setup
    +YouCanSetDefaultValueInModuleSetup=You can set the default value used when creating a new record in module setup
     Color=Color
     Documents=Linked files
     Documents2=Documents
    @@ -692,7 +692,7 @@ DateOfSignature=Date of signature
     HidePassword=Show command with password hidden
     UnHidePassword=Show real command with clear password
     Root=Root
    -Informations=Informations
    +Informations=Information
     Page=Page
     Notes=Notes
     AddNewLine=Add new line
    @@ -705,14 +705,14 @@ Merge=Merge
     DocumentModelStandardPDF=Standard PDF template
     PrintContentArea=Show page to print main content area
     MenuManager=Menu manager
    -WarningYouAreInMaintenanceMode=Warning, you are in a maintenance mode, so only login <b>%s</b> is allowed to use the application at the moment.
    +WarningYouAreInMaintenanceMode=Warning, you are in maintenance mode, so only login <b>%s</b> is allowed to use the application at this time.
     CoreErrorTitle=System error
     CoreErrorMessage=Sorry, an error occurred. Contact your system administrator to check the logs or disable $dolibarr_main_prod=1 to get more information.
     CreditCard=Credit card
     ValidatePayment=Validate payment
     CreditOrDebitCard=Credit or debit card
     FieldsWithAreMandatory=Fields with <b>%s</b> are mandatory
    -FieldsWithIsForPublic=Fields with <b>%s</b> are shown on public list of members. If you don't want this, check off the "public" box.
    +FieldsWithIsForPublic=Fields with <b>%s</b> are shown in public list of members. If you don't want this, uncheck the "public" box.
     AccordingToGeoIPDatabase=(according to GeoIP conversion)
     Line=Line
     NotSupported=Not supported
    @@ -794,7 +794,7 @@ PrintFile=Print File %s
     ShowTransaction=Show entry on bank account
     ShowIntervention=Show intervention
     ShowContract=Show contract
    -GoIntoSetupToChangeLogo=Go into Home - Setup - Company to change logo or go into Home - Setup - Display to hide.
    +GoIntoSetupToChangeLogo=Go to Home - Setup - Company to change logo or go to Home - Setup - Display to hide.
     Deny=Deny
     Denied=Denied
     ListOf=List of %s
    @@ -926,15 +926,15 @@ SearchIntoInterventions=Interventions
     SearchIntoContracts=Contracts
     SearchIntoCustomerShipments=Customer shipments
     SearchIntoExpenseReports=Expense reports
    -SearchIntoLeaves=Leaves
    +SearchIntoLeaves=Leave
     CommentLink=Comments
     NbComments=Number of comments
     CommentPage=Comments space
     CommentAdded=Comment added
     CommentDeleted=Comment deleted
     Everybody=Everybody
    -PayedBy=Payed by
    -PayedTo=Payed to
    +PayedBy=Paid by
    +PayedTo=Paid to
     Monthly=Monthly
     Quarterly=Quarterly
     Annual=Annual
    diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang
    index e5975516e4f..e28f242d964 100644
    --- a/htdocs/langs/en_US/members.lang
    +++ b/htdocs/langs/en_US/members.lang
    @@ -33,7 +33,7 @@ DateSubscription=Subscription date
     DateEndSubscription=Subscription end date
     EndSubscription=End subscription
     SubscriptionId=Subscription id
    -MemberId=Member id 
    +MemberId=Member id
     NewMember=New member
     MemberType=Member type
     MemberTypeId=Member type id
    @@ -61,7 +61,7 @@ ConfirmDeleteMemberType=Are you sure you want to delete this member type?
     MemberTypeDeleted=Member type deleted
     MemberTypeCanNotBeDeleted=Member type can not be deleted
     NewSubscription=New subscription
    -NewSubscriptionDesc=This form allows you to record your subscription as a new member of the foundation. If you want to renew your subscription (if already a member), please contact foundation board instead by email %s. 
    +NewSubscriptionDesc=This form allows you to record your subscription as a new member of the foundation. If you want to renew your subscription (if already a member), please contact foundation board instead by email %s.
     Subscription=Subscription
     Subscriptions=Subscriptions
     SubscriptionLate=Late
    @@ -115,7 +115,7 @@ SendingReminderForExpiredSubscription=Sending reminder for expired subscriptions
     SendingEmailOnCancelation=Sending email on cancelation
     # Topic of email templates
     YourMembershipRequestWasReceived=Your membership was received.
    -YourMembershipWasValidated=Your membership was validated 
    +YourMembershipWasValidated=Your membership was validated
     YourSubscriptionWasRecorded=Your new subscription was recorded
     SubscriptionReminderEmail=Subscription reminder
     YourMembershipWasCanceled=Your membership was canceled
    @@ -125,7 +125,7 @@ ThisIsContentOfYourMembershipRequestWasReceived=We want to let you know that you
     ThisIsContentOfYourMembershipWasValidated=We want to let you know that your membership was validated with the following information:<br><br>
     ThisIsContentOfYourSubscriptionWasRecorded=We want to let you know that your new subscription was recorded.<br><br>
     ThisIsContentOfSubscriptionReminderEmail=We want to let you know that your subscription is about to expire or is already expired (__MEMBER_LAST_SUBSCRIPTION_DATE_END__). We hope you can make a renewal of it.<br><br>
    -ThisIsContentOfYourCard=This is a remind of the information we get about you. Feel free to contact us if something looks wrong.<br><br> 
    +ThisIsContentOfYourCard=This is a remind of the information we get about you. Feel free to contact us if something looks wrong.<br><br>
     DescADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT=Subject of the e-mail received in case of auto-inscription of a guest
     DescADHERENT_AUTOREGISTER_NOTIF_MAIL=E-mail received in case of auto-inscription of a guest
     DescADHERENT_EMAIL_TEMPLATE_AUTOREGISTER=Template Email to use to send email to a member on member autosubscription
    diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang
    index ffbb345fb1c..940088368d5 100644
    --- a/htdocs/langs/en_US/modulebuilder.lang
    +++ b/htdocs/langs/en_US/modulebuilder.lang
    @@ -4,7 +4,7 @@ EnterNameOfModuleDesc=Enter name of the module/application to create with no spa
     EnterNameOfObjectDesc=Enter name of the object to create with no spaces. Use uppercase to separate words (For example: MyObject, Student, Teacher...). The CRUD class file, but also API file, pages to list/add/edit/delete object and SQL files will be generated.
     ModuleBuilderDesc2=Path where modules are generated/edited (first alternative directory defined into %s): <strong>%s</strong>
     ModuleBuilderDesc3=Generated/editable modules found: <strong>%s</strong>
    -ModuleBuilderDesc4=A module is detected as 'editable' when the file <strong>%s</strong> exists in root of module directory 
    +ModuleBuilderDesc4=A module is detected as 'editable' when the file <strong>%s</strong> exists in root of module directory
     NewModule=New module
     NewObject=New object
     ModuleKey=Module key
    @@ -49,7 +49,7 @@ SpecificationFile=File with business rules
     LanguageFile=File for language
     ConfirmDeleteProperty=Are you sure you want to delete the property <strong>%s</strong>? This will change code in PHP class but also remove column from table definition of object.
     NotNull=Not NULL
    -NotNullDesc=1=Set database to NOT NULL. -1=Allow null values and force value to NULL if empty ('' or 0). 
    +NotNullDesc=1=Set database to NOT NULL. -1=Allow null values and force value to NULL if empty ('' or 0).
     SearchAll=Used for 'search all'
     DatabaseIndex=Database index
     FileAlreadyExists=File %s already exists
    @@ -95,7 +95,7 @@ YouCanUseTranslationKey=You can use here a key that is the translation key found
     DropTableIfEmpty=(Delete table if empty)
     TableDoesNotExists=The table %s does not exists
     TableDropped=Table %s deleted
    -InitStructureFromExistingTable=Build the structure array string of an existing table 
    +InitStructureFromExistingTable=Build the structure array string of an existing table
     UseAboutPage=Disable the about page
     UseDocFolder=Disable the documentation folder
    -UseSpecificReadme=Use a specific ReadMe
    \ No newline at end of file
    +UseSpecificReadme=Use a specific ReadMe
    diff --git a/htdocs/langs/en_US/multicurrency.lang b/htdocs/langs/en_US/multicurrency.lang
    index 048e6721310..47c5590b862 100644
    --- a/htdocs/langs/en_US/multicurrency.lang
    +++ b/htdocs/langs/en_US/multicurrency.lang
    @@ -17,4 +17,4 @@ rate=rate
     MulticurrencyReceived=Received, original currency
     MulticurrencyRemainderToTake=Remaining amount, original currency
     MulticurrencyPaymentAmount=Payment amount, original currency
    -AmountToOthercurrency=Amount To (in currency of receiving account)
    \ No newline at end of file
    +AmountToOthercurrency=Amount To (in currency of receiving account)
    diff --git a/htdocs/langs/en_US/opensurvey.lang b/htdocs/langs/en_US/opensurvey.lang
    index 356f1ff6efe..906de8c2f37 100644
    --- a/htdocs/langs/en_US/opensurvey.lang
    +++ b/htdocs/langs/en_US/opensurvey.lang
    @@ -19,7 +19,7 @@ SelectedDays=Selected days
     TheBestChoice=The best choice currently is
     TheBestChoices=The best choices currently are
     with=with
    -OpenSurveyHowTo=If you agree to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line. 
    +OpenSurveyHowTo=If you agree to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.
     CommentsOfVoters=Comments of voters
     ConfirmRemovalOfPoll=Are you sure you want to remove this poll (and all votes)
     RemovePoll=Remove poll
    @@ -58,4 +58,4 @@ MoreChoices=Enter more choices for the voters
     SurveyExpiredInfo=The poll has been closed or voting delay has expired.
     EmailSomeoneVoted=%s has filled a line.\nYou can find your poll at the link: \n%s
     ShowSurvey=Show survey
    -UserMustBeSameThanUserUsedToVote=You must have voted and use the same user name that the one used to vote, to post a comment
    \ No newline at end of file
    +UserMustBeSameThanUserUsedToVote=You must have voted and use the same user name that the one used to vote, to post a comment
    diff --git a/htdocs/langs/en_US/orders.lang b/htdocs/langs/en_US/orders.lang
    index e5518951222..4cd600bdc8b 100644
    --- a/htdocs/langs/en_US/orders.lang
    +++ b/htdocs/langs/en_US/orders.lang
    @@ -56,7 +56,7 @@ StatusOrderReceivedAll=All products received
     ShippingExist=A shipment exists
     QtyOrdered=Qty ordered
     ProductQtyInDraft=Product quantity into draft orders
    -ProductQtyInDraftOrWaitingApproved=Product quantity into draft or approved orders, not yet ordered 
    +ProductQtyInDraftOrWaitingApproved=Product quantity into draft or approved orders, not yet ordered
     MenuOrdersToBill=Orders delivered
     MenuOrdersToBill2=Billable orders
     ShipProduct=Ship product
    @@ -145,14 +145,14 @@ PDFEdisonDescription=A simple order model
     PDFProformaDescription=A complete proforma invoice (logo…)
     CreateInvoiceForThisCustomer=Bill orders
     NoOrdersToInvoice=No orders billable
    -CloseProcessedOrdersAutomatically=Classify "Processed" all selected orders. 
    +CloseProcessedOrdersAutomatically=Classify "Processed" all selected orders.
     OrderCreation=Order creation
     Ordered=Ordered
     OrderCreated=Your orders have been created
     OrderFail=An error happened during your orders creation
     CreateOrders=Create orders
     ToBillSeveralOrderSelectCustomer=To create an invoice for several orders, click first onto customer, then choose "%s".
    -OptionToSetOrderBilledNotEnabled=Option (from module Workflow) to set order to 'Billed' automatically when invoice is validated is off, so you will have to set status of order to 'Billed' manually.  
    +OptionToSetOrderBilledNotEnabled=Option (from module Workflow) to set order to 'Billed' automatically when invoice is validated is off, so you will have to set status of order to 'Billed' manually.
     IfValidateInvoiceIsNoOrderStayUnbilled=If invoice validation is 'No', the order will remain to status 'Unbilled' until the invoice is validated.
     CloseReceivedSupplierOrdersAutomatically=Close order to "%s" automatically if all products are received.
    -SetShippingMode=Set shipping mode
    \ No newline at end of file
    +SetShippingMode=Set shipping mode
    diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang
    index d9197b04383..67b9681fa3b 100644
    --- a/htdocs/langs/en_US/other.lang
    +++ b/htdocs/langs/en_US/other.lang
    @@ -51,11 +51,11 @@ Notify_COMPANY_CREATE=Third party created
     Notify_COMPANY_SENTBYMAIL=Mails sent from third party card
     Notify_BILL_VALIDATE=Customer invoice validated
     Notify_BILL_UNVALIDATE=Customer invoice unvalidated
    -Notify_BILL_PAYED=Customer invoice payed
    +Notify_BILL_PAYED=Customer invoice paid
     Notify_BILL_CANCEL=Customer invoice canceled
     Notify_BILL_SENTBYMAIL=Customer invoice sent by mail
     Notify_BILL_SUPPLIER_VALIDATE=Supplier invoice validated
    -Notify_BILL_SUPPLIER_PAYED=Supplier invoice payed
    +Notify_BILL_SUPPLIER_PAYED=Supplier invoice paid
     Notify_BILL_SUPPLIER_SENTBYMAIL=Supplier invoice sent by mail
     Notify_BILL_SUPPLIER_CANCELED=Supplier invoice cancelled
     Notify_CONTRACT_VALIDATE=Contract validated
    @@ -80,15 +80,15 @@ LinkedObject=Linked object
     NbOfActiveNotifications=Number of notifications (no. of recipient emails)
     PredefinedMailTest=__(Hello)__\nThis is a test mail sent to __EMAIL__.\nThe two lines are separated by a carriage return.\n\n__USER_SIGNATURE__
     PredefinedMailTestHtml=__(Hello)__\nThis is a <b>test</b> mail (the word test must be in bold).<br>The two lines are separated by a carriage return.<br><br>__USER_SIGNATURE__
    -PredefinedMailContentSendInvoice=__(Hello)__\n\nYou will find here the invoice __REF__\n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendInvoiceReminder=__(Hello)__\n\nWe would like to warn you that the invoice  __REF__ seems to not be payed. So this is the invoice in attachment again, as a reminder.\n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendProposal=__(Hello)__\n\nYou will find here the commercial proposal __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendSupplierProposal=__(Hello)__\n\nYou will find here the price request __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendOrder=__(Hello)__\n\nYou will find here the order __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendSupplierOrder=__(Hello)__\n\nYou will find here our order __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendSupplierInvoice=__(Hello)__\n\nYou will find here the invoice __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendShipping=__(Hello)__\n\nYou will find here the shipping __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    -PredefinedMailContentSendFichInter=__(Hello)__\n\nYou will find here the intervention __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendInvoice=__(Hello)__\n\nPlease find attached invoice __REF__\n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendInvoiceReminder=__(Hello)__\n\nWe would like to warn you that the invoice  __REF__ seems to have not been paid. The invoice is attached, as a reminder.\n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendProposal=__(Hello)__\n\nPlease find attached commercial proposal __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendSupplierProposal=__(Hello)__\n\nPlease find attached price request __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendOrder=__(Hello)__\n\nPlease find attached order __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendSupplierOrder=__(Hello)__\n\nPlease find attached our order __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendSupplierInvoice=__(Hello)__\n\nPlease find attached invoice __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendShipping=__(Hello)__\n\nPlease find attached shipping __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
    +PredefinedMailContentSendFichInter=__(Hello)__\n\nPlease find attached intervention __REF__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
     PredefinedMailContentThirdparty=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
     PredefinedMailContentUser=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__
     PredefinedMailContentLink=You can click on the link below to make your payment if it is not already done.\n\n%s\n\n
    @@ -188,7 +188,7 @@ NumberOfUnitsSupplierInvoices=Number of units on supplier invoices
     EMailTextInterventionAddedContact=A new intervention %s has been assigned to you.
     EMailTextInterventionValidated=The intervention %s has been validated.
     EMailTextInvoiceValidated=The invoice %s has been validated.
    -EMailTextInvoicePayed=The invoice %s has been payed.
    +EMailTextInvoicePayed=The invoice %s has been paid.
     EMailTextProposalValidated=The proposal %s has been validated.
     EMailTextProposalClosedSigned=The proposal %s has been closed signed.
     EMailTextOrderValidated=The order %s has been validated.
    diff --git a/htdocs/langs/en_US/paybox.lang b/htdocs/langs/en_US/paybox.lang
    index 89e7ff48b79..cf0bd40b716 100644
    --- a/htdocs/langs/en_US/paybox.lang
    +++ b/htdocs/langs/en_US/paybox.lang
    @@ -35,4 +35,4 @@ NewPayboxPaymentFailed=New Paybox payment tried but failed
     PAYBOX_PAYONLINE_SENDEMAIL=EMail to warn after a payment (success or failed)
     PAYBOX_PBX_SITE=Value for PBX SITE
     PAYBOX_PBX_RANG=Value for PBX Rang
    -PAYBOX_PBX_IDENTIFIANT=Value for PBX ID
    \ No newline at end of file
    +PAYBOX_PBX_IDENTIFIANT=Value for PBX ID
    diff --git a/htdocs/langs/en_US/paypal.lang b/htdocs/langs/en_US/paypal.lang
    index c088debc518..d34bb4baf18 100644
    --- a/htdocs/langs/en_US/paypal.lang
    +++ b/htdocs/langs/en_US/paypal.lang
    @@ -18,7 +18,7 @@ NewOnlinePaymentReceived=New online payment received
     NewOnlinePaymentFailed=New online payment tried but failed
     ONLINE_PAYMENT_SENDEMAIL=EMail to warn after a payment (success or not)
     ReturnURLAfterPayment=Return URL after payment
    -ValidationOfOnlinePaymentFailed=Validation of online payment failed 
    +ValidationOfOnlinePaymentFailed=Validation of online payment failed
     PaymentSystemConfirmPaymentPageWasCalledButFailed=Payment confirmation page was called by payment system returned an error
     SetExpressCheckoutAPICallFailed=SetExpressCheckout API call failed.
     DoExpressCheckoutPaymentAPICallFailed=DoExpressCheckoutPayment API call failed.
    @@ -31,4 +31,4 @@ PaypalLiveEnabled=PayPal live enabled (otherwise test/sandbox mode)
     PaypalImportPayment=Import PayPal payments
     PostActionAfterPayment=Post actions after payments
     ARollbackWasPerformedOnPostActions=A rollback was performed on all Post actions. You must complete post actions manually if they are necessary.
    -ValidationOfPaymentFailed=Validation of payment has failed
    \ No newline at end of file
    +ValidationOfPaymentFailed=Validation of payment has failed
    diff --git a/htdocs/langs/en_US/productbatch.lang b/htdocs/langs/en_US/productbatch.lang
    index f0eafc807cf..54270c4a23b 100644
    --- a/htdocs/langs/en_US/productbatch.lang
    +++ b/htdocs/langs/en_US/productbatch.lang
    @@ -21,4 +21,4 @@ ProductDoesNotUseBatchSerial=This product does not use lot/serial number
     ProductLotSetup=Setup of module lot/serial
     ShowCurrentStockOfLot=Show current stock for couple product/lot
     ShowLogOfMovementIfLot=Show log of movements for couple product/lot
    -StockDetailPerBatch=Stock detail per lot
    \ No newline at end of file
    +StockDetailPerBatch=Stock detail per lot
    diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
    index 0dde8ad538a..90436801571 100644
    --- a/htdocs/langs/en_US/products.lang
    +++ b/htdocs/langs/en_US/products.lang
    @@ -130,7 +130,7 @@ DiscountQtyMin=Default discount for qty
     NoPriceDefinedForThisSupplier=No price/qty defined for this supplier/product
     NoSupplierPriceDefinedForThisProduct=No supplier price/qty defined for this product
     PredefinedProductsToSell=Predefined products to sell
    -PredefinedServicesToSell=Predefined services to sell 
    +PredefinedServicesToSell=Predefined services to sell
     PredefinedProductsAndServicesToSell=Predefined products/services to sell
     PredefinedProductsToPurchase=Predefined product to purchase
     PredefinedServicesToPurchase=Predefined services to purchase
    @@ -269,7 +269,7 @@ GlobalVariableUpdaterHelpFormat1=Format for request is {"URL": "http://example.c
     UpdateInterval=Update interval (minutes)
     LastUpdated=Latest update
     CorrectlyUpdated=Correctly updated
    -PropalMergePdfProductActualFile=Files use to add into PDF Azur are/is 
    +PropalMergePdfProductActualFile=Files use to add into PDF Azur are/is
     PropalMergePdfProductChooseFile=Select PDF files
     IncludingProductWithTag=Including product/service with tag
     DefaultPriceRealPriceMayDependOnCustomer=Default price, real price may depend on customer
    @@ -292,7 +292,7 @@ SubProduct=Sub product
     ProductSheet=Product sheet
     ServiceSheet=Service sheet
     PossibleValues=Possible values
    -GoOnMenuToCreateVairants=Go on menu %s - %s to prepare attribute variants (like colors, size, ...) 
    +GoOnMenuToCreateVairants=Go on menu %s - %s to prepare attribute variants (like colors, size, ...)
     UseProductFournDesc=Use supplier descriptions of products in supplier documents
     ProductSupplierDescription=Supplier description for the product
     #Attributes
    diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang
    index 29216b7d8b3..ce94a6dcc46 100644
    --- a/htdocs/langs/en_US/projects.lang
    +++ b/htdocs/langs/en_US/projects.lang
    @@ -7,7 +7,7 @@ ProjectsArea=Projects Area
     ProjectStatus=Project status
     SharedProject=Everybody
     PrivateProject=Project contacts
    -ProjectsImContactFor=Projects I'm explicitely a contact of 
    +ProjectsImContactFor=Projects I'm explicitely a contact of
     AllAllowedProjects=All project I can read (mine + public)
     AllProjects=All projects
     MyProjectsDesc=This view is limited to projects you are a contact for
    @@ -126,7 +126,7 @@ TaskRessourceLinks=Contacts task
     ProjectsDedicatedToThisThirdParty=Projects dedicated to this third party
     NoTasks=No tasks for this project
     LinkedToAnotherCompany=Linked to other third party
    -TaskIsNotAssignedToUser=Task not assigned to user. Use button '<strong>%s</strong>' to assign task now. 
    +TaskIsNotAssignedToUser=Task not assigned to user. Use button '<strong>%s</strong>' to assign task now.
     ErrorTimeSpentIsEmpty=Time spent is empty
     ThisWillAlsoRemoveTasks=This action will also delete all tasks of project (<b>%s</b> tasks at the moment) and all inputs of time spent.
     IfNeedToUseOhterObjectKeepEmpty=If some objects (invoice, order, ...), belonging to another third party, must be linked to the project to create, keep this empty to have the project being multi third parties.
    diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang
    index 21ac0a0d503..0a036a588ea 100644
    --- a/htdocs/langs/en_US/propal.lang
    +++ b/htdocs/langs/en_US/propal.lang
    @@ -82,4 +82,4 @@ DefaultModelPropalCreate=Default model creation
     DefaultModelPropalToBill=Default template when closing a business proposal (to be invoiced)
     DefaultModelPropalClosed=Default template when closing a business proposal (unbilled)
     ProposalCustomerSignature=Written acceptance, company stamp, date and signature
    -ProposalsStatisticsSuppliers=Supplier proposals statistics 
    +ProposalsStatisticsSuppliers=Supplier proposals statistics
    diff --git a/htdocs/langs/en_US/salaries.lang b/htdocs/langs/en_US/salaries.lang
    index 2ba84f19514..620517b5324 100644
    --- a/htdocs/langs/en_US/salaries.lang
    +++ b/htdocs/langs/en_US/salaries.lang
    @@ -16,4 +16,4 @@ THMDescription=This value may be used to calculate cost of time consumed on a pr
     TJMDescription=This value is currently as information only and is not used for any calculation
     LastSalaries=Latest %s salary payments
     AllSalaries=All salary payments
    -SalariesStatistics=Salary statistics
    \ No newline at end of file
    +SalariesStatistics=Salary statistics
    diff --git a/htdocs/langs/en_US/sendings.lang b/htdocs/langs/en_US/sendings.lang
    index b8474775e75..2b46ada5ee9 100644
    --- a/htdocs/langs/en_US/sendings.lang
    +++ b/htdocs/langs/en_US/sendings.lang
    @@ -56,7 +56,7 @@ ProductQtyInCustomersOrdersRunning=Product quantity into open customer orders
     ProductQtyInSuppliersOrdersRunning=Product quantity into open purchase orders
     ProductQtyInShipmentAlreadySent=Product quantity from open customer order already sent
     ProductQtyInSuppliersShipmentAlreadyRecevied=Product quantity from open supplier order already received
    -NoProductToShipFoundIntoStock=No product to ship found into warehouse <b>%s</b>. Correct stock or go back to choose another warehouse. 
    +NoProductToShipFoundIntoStock=No product to ship found in warehouse <b>%s</b>. Correct stock or go back to choose another warehouse.
     WeightVolShort=Weight/Vol.
     ValidateOrderFirstBeforeShipment=You must first validate the order before being able to make shipments.
     
    diff --git a/htdocs/langs/en_US/sms.lang b/htdocs/langs/en_US/sms.lang
    index bf92a7b63cf..79bd8827198 100644
    --- a/htdocs/langs/en_US/sms.lang
    +++ b/htdocs/langs/en_US/sms.lang
    @@ -48,4 +48,4 @@ SmsInfoNumero= (international format ie : +33899701761)
     DelayBeforeSending=Delay before sending (minutes)
     SmsNoPossibleSenderFound=No sender available. Check setup of your SMS provider.
     SmsNoPossibleRecipientFound=No target available. Check setup of your SMS provider.
    -DisableStopIfSupported=Disable STOP message (if supported) 
    +DisableStopIfSupported=Disable STOP message (if supported)
    diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
    index 410ee2e887d..b3313f5ff73 100644
    --- a/htdocs/langs/en_US/stocks.lang
    +++ b/htdocs/langs/en_US/stocks.lang
    @@ -45,7 +45,6 @@ MassStockTransferShort=Mass stock transfer
     StockMovement=Stock movement
     StockMovements=Stock movements
     LabelMovement=Movement label
    -TypeMovement=Movement type
     NumberOfUnit=Number of units
     UnitPurchaseValue=Unit purchase price
     StockTooLow=Stock too low
    @@ -79,7 +78,7 @@ StockLimit=Stock limit for alert
     StockLimitDesc=(empty) means no warning.<br>0 can be used for a warning as soon as stock is empty.
     PhysicalStock=Physical stock
     RealStock=Real Stock
    -RealStockDesc=Physical or real stock is the stock you currently have into your internal warehouses/emplacements. 
    +RealStockDesc=Physical or real stock is the stock you currently have into your internal warehouses/emplacements.
     RealStockWillAutomaticallyWhen=The real stock will automatically change according to this rules (see stock module setup to change this):
     VirtualStock=Virtual stock
     VirtualStockDesc=Virtual stock is the stock you will get once all open pending actions that affect stocks will be closed (supplier order received, customer order shipped, ...)
    @@ -138,7 +137,7 @@ MovementLabel=Label of movement
     DateMovement=Date of movement
     InventoryCode=Movement or inventory code
     IsInPackage=Contained into package
    -WarehouseAllowNegativeTransfer=Stock can be negative 
    +WarehouseAllowNegativeTransfer=Stock can be negative
     qtyToTranferIsNotEnough=You don't have enough stock from your source warehouse and your setup does not allow negative stocks.
     ShowWarehouse=Show warehouse
     MovementCorrectStock=Stock correction for product %s
    @@ -178,7 +177,7 @@ inventoryMvtStock=By inventory
     inventoryWarningProductAlreadyExists=This product is already into list
     SelectCategory=Category filter
     SelectFournisseur=Supplier filter
    -inventoryOnDate=Inventory 
    +inventoryOnDate=Inventory
     INVENTORY_DISABLE_VIRTUAL=Allow to not destock child product from a kit on inventory
     INVENTORY_USE_MIN_PA_IF_NO_LAST_PA=Use the buy price if no last buy price can be found
     INVENTORY_USE_INVENTORY_DATE_FROM_DATEMVT=Stock movement have date of inventory
    @@ -204,4 +203,4 @@ RegulateStock=Regulate Stock
     ListInventory=List
     StockSupportServices=Stock management supports Services
     StockSupportServicesDesc=By default, you can stock only product with type "product". If on, and if module service is on, you can also stock a product with type "service"
    -ReceiveProducts=Receive items
    \ No newline at end of file
    +ReceiveProducts=Receive items
    diff --git a/htdocs/langs/en_US/trips.lang b/htdocs/langs/en_US/trips.lang
    index 0f9fcac1d02..2ede3bc474e 100644
    --- a/htdocs/langs/en_US/trips.lang
    +++ b/htdocs/langs/en_US/trips.lang
    @@ -33,7 +33,7 @@ ExpenseReportCanceledMessage=The expense report %s was canceled.<br> - User: %s<
     ExpenseReportPaid=An expense report was paid
     ExpenseReportPaidMessage=The expense report %s was paid.<br> - User: %s<br> - Paid by: %s<br>Click here to show the expense report: %s
     TripId=Id expense report
    -AnyOtherInThisListCanValidate=Person to inform for validation. 
    +AnyOtherInThisListCanValidate=Person to inform for validation.
     TripSociete=Information company
     TripNDF=Informations expense report
     PDFStandardExpenseReports=Standard template to generate a PDF document for expense report
    @@ -154,4 +154,4 @@ nolimitbyEX_EXP=by line (no limitation)
     
     CarCategory=Category of car
     ExpenseRangeOffset=Offset amount: %s
    -RangeIk=Mileage range
    \ No newline at end of file
    +RangeIk=Mileage range
    diff --git a/htdocs/langs/en_US/users.lang b/htdocs/langs/en_US/users.lang
    index 20c3e90ae41..68fffde3bb0 100644
    --- a/htdocs/langs/en_US/users.lang
    +++ b/htdocs/langs/en_US/users.lang
    @@ -35,7 +35,7 @@ SuperAdministrator=Super Administrator
     SuperAdministratorDesc=Global administrator
     AdministratorDesc=Administrator
     DefaultRights=Default permissions
    -DefaultRightsDesc=Define here <u>default</u> permissions that are automatically granted to a <u>new created</u> user (Go on user card to change permission of an existing user).
    +DefaultRightsDesc=Define here <u>default</u> permissions that are automatically granted to a <u>new created</u> user (Go to user card to change permission of an existing user).
     DolibarrUsers=Dolibarr users
     LastName=Last name
     FirstName=First name
    @@ -108,4 +108,4 @@ UserAccountancyCode=User accounting code
     UserLogoff=User logout
     UserLogged=User logged
     DateEmployment=Date of Employment
    -DateEmploymentEnd=End date of Employment
    \ No newline at end of file
    +DateEmploymentEnd=End date of Employment
    diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang
    index 9ed064b5d1e..55db08c3785 100644
    --- a/htdocs/langs/en_US/website.lang
    +++ b/htdocs/langs/en_US/website.lang
    @@ -1,4 +1,4 @@
    -# Dolibarr language file - Source file is en_US - website 
    +# Dolibarr language file - Source file is en_US - website
     Shortname=Code
     WebsiteSetupDesc=Create here the websites you wish to use. Then go into menu Websites to edit them.
     DeleteWebsite=Delete website
    @@ -16,7 +16,7 @@ WEBSITE_ROBOT=Robot file (robots.txt)
     WEBSITE_HTACCESS=Web site .htaccess file
     HtmlHeaderPage=HTML header (specific to this page only)
     PageNameAliasHelp=Name or alias of the page.<br>This alias is also used to forge a SEO URL when website is ran from a Virtual host of a Web server (like Apacke, Nginx, ...). Use the button "<strong>%s</strong>" to edit this alias.
    -EditTheWebSiteForACommonHeader=Note: If you want to define a personalized header for all pages, edit the header on the site level instead of on the page/container.   
    +EditTheWebSiteForACommonHeader=Note: If you want to define a personalized header for all pages, edit the header on the site level instead of on the page/container.
     MediaFiles=Media library
     EditCss=Edit website properties
     EditMenu=Edit menu
    @@ -45,12 +45,12 @@ CheckVirtualHostPerms=Check also that virtual host has permission <strong>%s</st
     ReadPerm=Read
     WritePerm=Write
     PreviewSiteServedByWebServer=<u>Preview %s in a new tab.</u><br><br>The %s will be served by an external web server (like Apache, Nginx, IIS). You must install and setup this server before to point to directory:<br><strong>%s</strong><br>URL served by external server:<br><strong>%s</strong>
    -PreviewSiteServedByDolibarr=<u>Preview %s in a new tab.</u><br><br>The %s will be served by Dolibarr server so it does not need any extra web server (like Apache, Nginx, IIS) to be installed.<br>The inconvenient is that URL of pages are not user friendly and start with path of your Dolibarr.<br>URL served by Dolibarr:<br><strong>%s</strong><br><br>To use your own external web server to serve this web site, create a virtual host on your web server that point on directory<br><strong>%s</strong><br>then enter the name of this virtual server and click on the other preview button.  
    +PreviewSiteServedByDolibarr=<u>Preview %s in a new tab.</u><br><br>The %s will be served by Dolibarr server so it does not need any extra web server (like Apache, Nginx, IIS) to be installed.<br>The inconvenient is that URL of pages are not user friendly and start with path of your Dolibarr.<br>URL served by Dolibarr:<br><strong>%s</strong><br><br>To use your own external web server to serve this web site, create a virtual host on your web server that point on directory<br><strong>%s</strong><br>then enter the name of this virtual server and click on the other preview button.
     VirtualHostUrlNotDefined=URL of the virtual host served by external web server not defined
     NoPageYet=No pages yet
     YouCanCreatePageOrImportTemplate=You can create a new page or import a full website template
     SyntaxHelp=Help on specific syntax tips
    -YouCanEditHtmlSourceckeditor=You can edit HTML source code using the "Source" button in editor. 
    +YouCanEditHtmlSourceckeditor=You can edit HTML source code using the "Source" button in editor.
     YouCanEditHtmlSource=<br><span class="fa fa-bug"></span> You can include PHP code into this source using tags <strong>&lt;?php ?&gt;</strong>. The following global variables are available: $conf, $db, $mysoc, $user, $website, $weblangs.<br><br><span class="fa fa-bug"></span> You can also include content of another Page/Container with the following syntax:<br><strong>&lt;?php includeContainer('alias_of_container_to_include'); ?&gt;</strong><br><br><span class="fa fa-bug"></span> You can make a redirect to another Page/Container with the following syntax (Note: do not output any content before a redirect):<br><strong>&lt;?php redirectToContainer('alias_of_container_to_redirect_to'); ?&gt;</strong><br><br><span class="fa fa-link"></span> To add a link to another page, use the syntax:<br><strong>&lt;a href="alias_of_page_to_link_to.php"&gt;mylink&lt;a&gt;</strong><br><br><span class="fa fa-download"></span> To include a <strong>link to download</strong> a file stored into the <strong>documents</strong> directory, use the <strong>document.php</strong> wrapper:<br>Example, for a file into documents/ecm (need to be logged), syntax is:<br><strong>&lt;a href="/document.php?modulepart=ecm&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file into documents/medias (open directory for public access), syntax is:<br><strong>&lt;a href="/document.php?modulepart=medias&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file shared with a share link (open access using the sharing hash key of file), syntax is:<br><strong>&lt;a href="/document.php?hashp=publicsharekeyoffile"&gt;</strong><br><br><span class="fa fa-picture-o"></span> To include an <strong>image</strong> stored into the <strong>documents</strong> directory, use the <strong>viewimage.php</strong> wrapper:<br>Example, for an image into documents/medias (open directory for public access), syntax is:<br><strong>&lt;img src="/viewimage.php?modulepart=medias&amp;file=[relative_dir/]filename.ext"&gt;</strong><br>
     ClonePage=Clone page/container
     CloneSite=Clone site
    @@ -90,4 +90,4 @@ EmptyPage=Empty page
     ExternalURLMustStartWithHttp=External URL must start with http:// or https://
     ZipOfWebsitePackageToImport=Zip file of website package
     ShowSubcontainers=Show included containers
    -InternalURLOfPage=Internal URL of page
    \ No newline at end of file
    +InternalURLOfPage=Internal URL of page
    diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang
    index 6162bfe6aa1..c2c384793c4 100644
    --- a/htdocs/langs/en_US/withdrawals.lang
    +++ b/htdocs/langs/en_US/withdrawals.lang
    @@ -61,7 +61,7 @@ CreateAll=Create direct debit file (all)
     CreateGuichet=Only office
     CreateBanque=Only bank
     OrderWaiting=Waiting for treatment
    -NotifyTransmision=Withdrawal Transmission 
    +NotifyTransmision=Withdrawal Transmission
     NotifyCredit=Withdrawal Credit
     NumeroNationalEmetter=National Transmitter Number
     WithBankUsingRIB=For bank accounts using RIB
    @@ -80,7 +80,7 @@ RUM=UMR
     RUMLong=Unique Mandate Reference
     RUMWillBeGenerated=If empty, UMR number will be generated once bank account information are saved
     WithdrawMode=Direct debit mode (FRST or RECUR)
    -WithdrawRequestAmount=Amount of Direct debit request: 
    +WithdrawRequestAmount=Amount of Direct debit request:
     WithdrawRequestErrorNilAmount=Unable to create direct debit request for empty amount.
     SepaMandate=SEPA Direct Debit Mandate
     SepaMandateShort=SEPA Mandate
    @@ -103,7 +103,7 @@ SEPAFRST=SEPA FRST
     ExecutionDate=Execution date
     CreateForSepa=Create direct debit file
     
    -### Notifications 
    +### Notifications
     InfoCreditSubject=Payment of direct debit payment order %s by the bank
     InfoCreditMessage=The direct debit payment order %s has been paid by the bank<br>Data of payment: %s
     InfoTransSubject=Transmission of direct debit payment order %s to bank
    diff --git a/htdocs/langs/en_US/workflow.lang b/htdocs/langs/en_US/workflow.lang
    index 3dab69667c4..c16caf44765 100644
    --- a/htdocs/langs/en_US/workflow.lang
    +++ b/htdocs/langs/en_US/workflow.lang
    @@ -1,4 +1,4 @@
    -# Dolibarr language file - Source file is en_US - workflow 
    +# Dolibarr language file - Source file is en_US - workflow
     WorkflowSetup=Workflow module setup
     WorkflowDesc=This module provides some automatic actions. By default, the workflow is open (you can do things in the order you want) but here you can activate some automatic actions.
     ThereIsNoWorkflowToModify=There is no workflow modifications available with the activated modules.
    @@ -17,4 +17,4 @@ descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source customer ord
     descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source vendor proposal as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked proposal)
     descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classify linked source purchase order as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order)
     AutomaticCreation=Automatic creation
    -AutomaticClassification=Automatic classification
    \ No newline at end of file
    +AutomaticClassification=Automatic classification
    
    From 1e58b837f070ea3e12e5e86105968a7afc159a43 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sat, 13 Oct 2018 14:11:44 +0200
    Subject: [PATCH 191/433] css
    
    ---
     htdocs/core/tpl/passwordforgotten.tpl.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/tpl/passwordforgotten.tpl.php b/htdocs/core/tpl/passwordforgotten.tpl.php
    index 0e1942c1c64..101c9ec7e67 100644
    --- a/htdocs/core/tpl/passwordforgotten.tpl.php
    +++ b/htdocs/core/tpl/passwordforgotten.tpl.php
    @@ -184,7 +184,7 @@ if (! empty($morelogincontent)) {
     </form>
     
     
    -<div class="center login_main_home paddingtopbottom<?php echo empty($conf->global->MAIN_LOGIN_BACKGROUND)?'':' backgroundsemitransparent'; ?>" style="max-width: 70%">
    +<div class="center login_main_home divpasswordmessagedesc paddingtopbottom<?php echo empty($conf->global->MAIN_LOGIN_BACKGROUND)?'':' backgroundsemitransparent'; ?>" style="max-width: 70%">
     <?php if ($mode == 'dolibarr' || ! $disabled) { ?>
     	<span class="passwordmessagedesc">
     	<?php echo $langs->trans('SendNewPasswordDesc'); ?>
    
    From 1ca3a41f4f80de3e33f545b197342a6c6710249a Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sat, 13 Oct 2018 14:16:42 +0200
    Subject: [PATCH 192/433] Fix login
    
    ---
     htdocs/theme/eldy/style.css.php | 3 +++
     htdocs/theme/md/style.css.php   | 8 ++++++++
     2 files changed, 11 insertions(+)
    
    diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
    index bb43aa0af55..0f9a6f5f7b4 100644
    --- a/htdocs/theme/eldy/style.css.php
    +++ b/htdocs/theme/eldy/style.css.php
    @@ -2038,6 +2038,9 @@ div.login_block_other { padding-top: 3px; text-align: right; }
     .alogin:hover, .atoplogin:hover {
     	text-decoration:underline !important;
     }
    +.divpasswordmessagedesc {
    +	text-align: justify;
    +}
     span.fa.atoplogin, span.fa.atoplogin:hover {
         font-size: 16px;
         text-decoration: none !important;
    diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
    index b347d305dd9..beae8039618 100644
    --- a/htdocs/theme/md/style.css.php
    +++ b/htdocs/theme/md/style.css.php
    @@ -1236,6 +1236,8 @@ div.backgroundsemitransparent {
     	padding-left: 10px;
     	padding-right: 10px;
     }
    +
    +
     div.login_block {
     	/* position: initial !important;*/
     	display: none;
    @@ -1250,6 +1252,12 @@ div.login_block {
     	color: #333 !important;
     	font-weight: normal !important;
     }
    +.divpasswordmessagedesc {
    +	text-align: justify;
    +}
    +
    +
    +
     #id-right {
     	padding-left: 0 ! important;
     }
    
    From 8779d3043f34ed8e8253f64dbdfb06fb33b22330 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sat, 13 Oct 2018 14:22:26 +0200
    Subject: [PATCH 193/433] css
    
    ---
     htdocs/theme/eldy/style.css.php | 3 ---
     htdocs/theme/md/style.css.php   | 7 ++++---
     2 files changed, 4 insertions(+), 6 deletions(-)
    
    diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
    index 0f9a6f5f7b4..bb43aa0af55 100644
    --- a/htdocs/theme/eldy/style.css.php
    +++ b/htdocs/theme/eldy/style.css.php
    @@ -2038,9 +2038,6 @@ div.login_block_other { padding-top: 3px; text-align: right; }
     .alogin:hover, .atoplogin:hover {
     	text-decoration:underline !important;
     }
    -.divpasswordmessagedesc {
    -	text-align: justify;
    -}
     span.fa.atoplogin, span.fa.atoplogin:hover {
         font-size: 16px;
         text-decoration: none !important;
    diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
    index beae8039618..3b67c895e0d 100644
    --- a/htdocs/theme/md/style.css.php
    +++ b/htdocs/theme/md/style.css.php
    @@ -1238,6 +1238,9 @@ div.backgroundsemitransparent {
     }
     
     
    +
    +/* Login */
    +
     div.login_block {
     	/* position: initial !important;*/
     	display: none;
    @@ -1252,9 +1255,7 @@ div.login_block {
     	color: #333 !important;
     	font-weight: normal !important;
     }
    -.divpasswordmessagedesc {
    -	text-align: justify;
    -}
    +
     
     
     
    
    From e19453450dcb24a55b9e5a65aea01dd8d0133e29 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sat, 13 Oct 2018 19:57:34 +0200
    Subject: [PATCH 194/433] Fix closing tag
    
    ---
     htdocs/modulebuilder/index.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
    index d406f6918a0..f6646813843 100644
    --- a/htdocs/modulebuilder/index.php
    +++ b/htdocs/modulebuilder/index.php
    @@ -1564,7 +1564,7 @@ elseif (! empty($module))
     
     						print '<br>';
     
    -						print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForLib").' : <strong>'.($realpathtolib?'':'<strike>').$pathtolib.($realpathtodocument?'':'</strike>').'</strong>';
    +						print '<span class="fa fa-file-o"></span> '.$langs->trans("PageForLib").' : <strong>'.($realpathtolib?'':'<strike>').$pathtolib.($realpathtolib?'':'</strike>').'</strong>';
     						print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtolib).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
     						print '<br>';
     						print '<span class="fa fa-file-image-o"></span> '.$langs->trans("Image").' : <strong>'.($realpathtopicto?'':'<strike>').$pathtopicto.($realpathtopicto?'':'</strike>').'</strong>';
    
    From d9e13129240303fec9572816454a899c3361bb5c Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Sun, 14 Oct 2018 06:16:14 +0200
    Subject: [PATCH 195/433] Debug FEC model export
    
    ---
     .../class/accountancyexport.class.php         | 30 +++++++++++++++----
     htdocs/accountancy/tpl/export_journal.tpl.php | 16 ++++++++--
     2 files changed, 38 insertions(+), 8 deletions(-)
    
    diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php
    index 060efab591c..13fec3cf388 100644
    --- a/htdocs/accountancy/class/accountancyexport.class.php
    +++ b/htdocs/accountancy/class/accountancyexport.class.php
    @@ -651,19 +651,39 @@ class AccountancyExport
     	 */
     	public function exportFEC($objectLines)
     	{
    -		$separator = ';';
    +		$separator = "\t";
     		$end_line = "\n";
     
    +		print "JournalCode" . $separator;
    +		print "JournalLib" . $separator;
    +		print "EcritureNum" . $separator;
    +		print "EcritureDate" . $separator;
    +		print "CompteNum" . $separator;
    +		print "CompteLib" . $separator;
    +		print "CompAuxNum" . $separator;
    +		print "CompAuxLib" . $separator;
    +		print "PieceRef" . $separator;
    +		print "PieceDate" . $separator;
    +		print "EcritureLib" . $separator;
    +		print "Debit" . $separator;
    +		print "Credit" . $separator;
    +		print "EcritureLet" . $separator;
    +		print "DateLet" . $separator;
    +		print "ValidDate" . $separator;
    +		print "Montantdevise" . $separator;
    +		print "Idevise";
    +		print $end_line;
    +
     		foreach ( $objectLines as $line ) {
     			$date_creation = dol_print_date($line->date_creation, '%d%m%Y');
     			$date_doc = dol_print_date($line->doc_date, '%d%m%Y');
     			$date_valid = dol_print_date($line->date_validated, '%d%m%Y');
     
     			// FEC:JournalCode
    -			print $line->code_journal;
    +			print $line->code_journal . $separator;
     
     			// FEC:JournalLib
    -			print $line->journal_label;
    +			print $line->journal_label . $separator;
     
     			// FEC:EcritureNum
     			print $line->piece_num . $separator;
    @@ -693,10 +713,10 @@ class AccountancyExport
     			print $line->label_operation . $separator;
     
     			// FEC:Debit
    -			print price($line->debit) . $separator;
    +			print price2num($line->debit) . $separator;
     
     			// FEC:Credit
    -			print price($line->credit) . $separator;
    +			print price2num($line->credit) . $separator;
     
     			// FEC:EcritureLet
     			print $line->lettering_code . $separator;
    diff --git a/htdocs/accountancy/tpl/export_journal.tpl.php b/htdocs/accountancy/tpl/export_journal.tpl.php
    index 773f7a7ff68..1d7e7fd6f54 100644
    --- a/htdocs/accountancy/tpl/export_journal.tpl.php
    +++ b/htdocs/accountancy/tpl/export_journal.tpl.php
    @@ -1,6 +1,6 @@
     <?php
    -/* Copyright (C) 2015  Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2016  Charlie Benke		<charlie@patas-monkey.com>
    +/* Copyright (C) 2015-2018  Alexandre Spangaro	<aspangaro@zendsi.com>
    + * Copyright (C) 2016       Charlie Benke		<charlie@patas-monkey.com>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -27,11 +27,21 @@ $code = $conf->global->MAIN_INFO_ACCOUNTANT_CODE;
     $prefix = $conf->global->ACCOUNTING_EXPORT_PREFIX_SPEC;
     $format = $conf->global->ACCOUNTING_EXPORT_FORMAT;
     $nodateexport = $conf->global->ACCOUNTING_EXPORT_NO_DATE_IN_FILENAME;
    +$siren = $conf->global->MAIN_INFO_SIREN;
     
     $date_export = "_" . dol_print_date(dol_now(), '%Y%m%d%H%M%S');
    +$endaccountingperiod = dol_print_date(dol_now(), '%Y%m%d');
     
     header('Content-Type: text/csv');
     
    -$completefilename = ($code?$code . "_":"") . ($prefix?$prefix . "_":"") . $filename . ($nodateexport?"":$date_export) . "." . $format;
    +
    +if ($conf->global->ACCOUNTING_EXPORT_MODELCSV == "11") // Specific filename for FEC model export
    +{
    +	$completefilename = $siren . "FEC" . $search_date_end . $endaccountingperiod . "." . $format;
    +}
    +else
    +{
    +	$completefilename = ($code?$code . "_":"") . ($prefix?$prefix . "_":"") . $filename . ($nodateexport?"":$date_export) . "." . $format;
    +}
     
     header('Content-Disposition: attachment;filename=' . $completefilename);
    
    From 65e6b49abb30c14ceb868249fe9dde0443b52e54 Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Sun, 14 Oct 2018 08:08:55 +0200
    Subject: [PATCH 196/433] Remove MAIN_FEATURES_LEVEL > 1 on fiscal year access
    
    ---
     htdocs/core/menus/standard/eldy.lib.php | 5 +----
     1 file changed, 1 insertion(+), 4 deletions(-)
    
    diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php
    index 51a9907a16e..303e2813245 100644
    --- a/htdocs/core/menus/standard/eldy.lib.php
    +++ b/htdocs/core/menus/standard/eldy.lib.php
    @@ -1019,10 +1019,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/export.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("ExportOptions"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_export', 60);
     
     				// Fiscal year
    -				if ($conf->global->MAIN_FEATURES_LEVEL > 1)     // Not yet used. In a future will lock some periods.
    -				{
    -					if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("FiscalPeriod"), 2, $user->rights->accounting->fiscalyear, '', $mainmenu, 'fiscalyear');
    -				}
    +				if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("FiscalPeriod"), 2, $user->rights->accounting->fiscalyear, '', $mainmenu, 'fiscalyear');
     
     				// Binding
     				if (! empty($conf->facture->enabled))
    
    From 5dd447445a7ff8cd8c341a9e00cb505a1686e1fe Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sun, 14 Oct 2018 09:43:33 +0200
    Subject: [PATCH 197/433] html5
    
    ---
     htdocs/accountancy/bookkeeping/balancebymonth.php | 14 +++++++-------
     1 file changed, 7 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/balancebymonth.php b/htdocs/accountancy/bookkeeping/balancebymonth.php
    index 3a0a1f73308..a01c42b285a 100644
    --- a/htdocs/accountancy/bookkeeping/balancebymonth.php
    +++ b/htdocs/accountancy/bookkeeping/balancebymonth.php
    @@ -64,7 +64,7 @@ $result = $db->query($sql);
     if ($result) {
     	$row = $db->fetch_row($result);
     	$nbfac = $row[0];
    -	
    +
     	$db->free($result);
     }
     
    @@ -85,7 +85,7 @@ print '<td align="center">' . $langs->trans("SeptemberMin") . '</td>';
     print '<td align="center">' . $langs->trans("OctoberMin") . '</td>';
     print '<td align="center">' . $langs->trans("NovemberMin") . '</td>';
     print '<td align="center">' . $langs->trans("DecemberMin") . '</td>';
    -print '<td align="center"><b>Total</b></td>';
    +print '<td align="center"><strong>Total</strong></td>';
     print '</tr>';
     
     $sql = "SELECT bk.numero_compte AS 'compte',";
    @@ -111,11 +111,11 @@ $resql = $db->query($sql);
     if ($resql) {
     	$i = 0;
     	$num = $db->num_rows($resql);
    -	
    +
     	while ( $i < $num ) {
    -		
    +
     		$row = $db->fetch_row($resql);
    -		
    +
     		print '<tr class="oddeven"><td width="14%">' . length_accountg($row[0]) . '</td>';
     		print '<td align="right" width="6.5%">' . price($row[1]) . '</td>';
     		print '<td align="right" width="6.5%">' . price($row[2]) . '</td>';
    @@ -129,9 +129,9 @@ if ($resql) {
     		print '<td align="right" width="6.5%">' . price($row[10]) . '</td>';
     		print '<td align="right" width="6.5%">' . price($row[11]) . '</td>';
     		print '<td align="right" width="6.5%">' . price($row[12]) . '</td>';
    -		print '<td align="right" width="8%"><b>' . price($row[13]) . '</b></td>';
    +		print '<td align="right" width="8%"><strong>' . price($row[13]) . '</strong></td>';
     		print '</tr>';
    -		
    +
     		$i ++;
     	}
     	$db->free($resql);
    
    From 1f1a614b47d7a0e8a37f496920a2f15f2ab8a189 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sun, 14 Oct 2018 10:21:06 +0200
    Subject: [PATCH 198/433] Update import.lib.php
    
    ---
     htdocs/core/lib/import.lib.php | 16 ++++++++--------
     1 file changed, 8 insertions(+), 8 deletions(-)
    
    diff --git a/htdocs/core/lib/import.lib.php b/htdocs/core/lib/import.lib.php
    index 89847d69c11..ea700c38845 100644
    --- a/htdocs/core/lib/import.lib.php
    +++ b/htdocs/core/lib/import.lib.php
    @@ -1,8 +1,9 @@
     <?php
    -/* Copyright (C) 2006-2009 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2007      Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2010      Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2010      Juanjo Menent        <jmenent@2byte.es>
    +/* Copyright (C) 2006-2009  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007       Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2010       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2010       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -20,10 +21,9 @@
      */
     
     /**
    - *  \file       htdocs/core/lib/order.lib.php
    - *  \brief      Ensemble de fonctions de base pour le module commande
    - *  \ingroup    commande
    - */
    + *  \file       htdocs/core/lib/import.lib.php
    + *  \brief      Ensemble de fonctions de base pour le module import
    + *  \ingroup    import
     
     /**
      * Function to return list of tabs for import pages
    
    From 70a98743e807a819fc8ec01fa92e5085f2d082c0 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sun, 14 Oct 2018 10:48:06 +0200
    Subject: [PATCH 199/433] Update functions.lib.php
    
    ---
     htdocs/core/lib/functions.lib.php | 6 ++++--
     1 file changed, 4 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
    index 9cbd8562949..cff0ef2b8ef 100644
    --- a/htdocs/core/lib/functions.lib.php
    +++ b/htdocs/core/lib/functions.lib.php
    @@ -13,6 +13,7 @@
      * Copyright (C) 2014		Cédric GROSS					<c.gross@kreiz-it.fr>
      * Copyright (C) 2014-2015	Marcos García				<marcosgdf@gmail.com>
      * Copyright (C) 2015		Jean-François Ferry			<jfefe@aternatik.fr>
    + * Copyright (C) 2018       Frédéric France             <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -5975,11 +5976,12 @@ function complete_head_from_modules($conf,$langs,$object,&$head,&$h,$type,$mode=
     	// No need to make a return $head. Var is modified as a reference
     	if (! empty($hookmanager))
     	{
    -		$parameters=array('object' => $object, 'mode' => $mode, 'head'=>$head);
    -		$reshook=$hookmanager->executeHooks('completeTabsHead',$parameters);
    +		$parameters=array('object' => $object, 'mode' => $mode, 'head' => $head);
    +		$reshook=$hookmanager->executeHooks('completeTabsHead', $parameters);
     		if ($reshook > 0)
     		{
     			$head = $hookmanager->resArray;
    +            $h = count($head);
     		}
     	}
     }
    
    From 787658ac98fcab578d70b69a2a64aff20f4f8015 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sun, 14 Oct 2018 10:56:03 +0200
    Subject: [PATCH 200/433] reduce complexity of payments.lib.php
    
    ---
     htdocs/core/lib/payments.lib.php | 15 ++++++++-------
     1 file changed, 8 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/core/lib/payments.lib.php b/htdocs/core/lib/payments.lib.php
    index ffb0aba36ca..bd460f8d53e 100644
    --- a/htdocs/core/lib/payments.lib.php
    +++ b/htdocs/core/lib/payments.lib.php
    @@ -1,6 +1,7 @@
     <?php
     /**
    - * Copyright (C) 2013	Marcos García	<marcosgdf@gmail.com>
    + * Copyright (C) 2013	    Marcos García	        <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -136,7 +137,7 @@ function getOnlinePaymentUrl($mode, $type, $ref='', $amount='9.99', $freetag='yo
     			else $out.='&securekey='.dol_hash($conf->global->PAYMENT_SECURITY_TOKEN, 2);
     		}
     	}
    -	if ($type == 'order')
    +	elseif ($type == 'order')
     	{
     		$out=DOL_MAIN_URL_ROOT.'/public/payment/newpayment.php?source=order&ref='.($mode?'<font color="#666666">':'');
     		if ($mode == 1) $out.='order_ref';
    @@ -154,7 +155,7 @@ function getOnlinePaymentUrl($mode, $type, $ref='', $amount='9.99', $freetag='yo
     			}
     		}
     	}
    -	if ($type == 'invoice')
    +	elseif ($type == 'invoice')
     	{
     		$out=DOL_MAIN_URL_ROOT.'/public/payment/newpayment.php?source=invoice&ref='.($mode?'<font color="#666666">':'');
     		if ($mode == 1) $out.='invoice_ref';
    @@ -172,7 +173,7 @@ function getOnlinePaymentUrl($mode, $type, $ref='', $amount='9.99', $freetag='yo
     			}
     		}
     	}
    -	if ($type == 'contractline')
    +	elseif ($type == 'contractline')
     	{
     		$out=DOL_MAIN_URL_ROOT.'/public/payment/newpayment.php?source=contractline&ref='.($mode?'<font color="#666666">':'');
     		if ($mode == 1) $out.='contractline_ref';
    @@ -190,7 +191,7 @@ function getOnlinePaymentUrl($mode, $type, $ref='', $amount='9.99', $freetag='yo
     			}
     		}
     	}
    -	if ($type == 'membersubscription')
    +	elseif ($type == 'membersubscription')
     	{
     		$out=DOL_MAIN_URL_ROOT.'/public/payment/newpayment.php?source=membersubscription&ref='.($mode?'<font color="#666666">':'');
     		if ($mode == 1) $out.='member_ref';
    @@ -289,14 +290,14 @@ function htmlPrintOnlinePaymentFooter($fromcompany,$langs,$addformmessage=0,$suf
     
         	$parammessageform='ONLINE_PAYMENT_MESSAGE_FORM_'.$suffix;
         	if (! empty($conf->global->$parammessageform)) print $langs->transnoentities($conf->global->$parammessageform);
    -    	else if (! empty($conf->global->ONLINE_PAYMENT_MESSAGE_FORM)) print $langs->transnoentities($conf->global->ONLINE_PAYMENT_MESSAGE_FORM);
    +    	elseif (! empty($conf->global->ONLINE_PAYMENT_MESSAGE_FORM)) print $langs->transnoentities($conf->global->ONLINE_PAYMENT_MESSAGE_FORM);
     
         	// Add other message if VAT exists
         	if ($object->total_vat != 0 || $object->total_tva != 0)
         	{
         		$parammessageform='ONLINE_PAYMENT_MESSAGE_FORMIFVAT_'.$suffix;
         		if (! empty($conf->global->$parammessageform)) print $langs->transnoentities($conf->global->$parammessageform);
    -    		else if (! empty($conf->global->ONLINE_PAYMENT_MESSAGE_FORMIFVAT)) print $langs->transnoentities($conf->global->ONLINE_PAYMENT_MESSAGE_FORMIFVAT);
    +    		elseif (! empty($conf->global->ONLINE_PAYMENT_MESSAGE_FORMIFVAT)) print $langs->transnoentities($conf->global->ONLINE_PAYMENT_MESSAGE_FORMIFVAT);
         	}
         }
     
    
    From 65c69c4564826669dd239698c22777734de9105d Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= <frederic.france@free.fr>
    Date: Sun, 14 Oct 2018 10:57:27 +0200
    Subject: [PATCH 201/433] fix standard prepare_head
    
    ---
     htdocs/asset/admin/assets_extrafields.php      | 2 +-
     htdocs/asset/admin/assets_type_extrafields.php | 2 +-
     htdocs/asset/admin/setup.php                   | 2 +-
     htdocs/asset/card.php                          | 2 +-
     htdocs/asset/document.php                      | 2 +-
     htdocs/asset/info.php                          | 2 +-
     htdocs/asset/note.php                          | 2 +-
     htdocs/core/lib/asset.lib.php                  | 4 ++--
     8 files changed, 9 insertions(+), 9 deletions(-)
    
    diff --git a/htdocs/asset/admin/assets_extrafields.php b/htdocs/asset/admin/assets_extrafields.php
    index 109b0f1e94f..f220d5cb849 100644
    --- a/htdocs/asset/admin/assets_extrafields.php
    +++ b/htdocs/asset/admin/assets_extrafields.php
    @@ -64,7 +64,7 @@ $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToM
     print load_fiche_titre($langs->trans("AssetsSetup"),$linkback,'title_setup');
     
     
    -$head = AssetsAdminPrepareHead();
    +$head = asset_admin_prepare_head();
     
     dol_fiche_head($head, 'attributes', $langs->trans("Assets"), -1, 'generic');
     
    diff --git a/htdocs/asset/admin/assets_type_extrafields.php b/htdocs/asset/admin/assets_type_extrafields.php
    index e8f1d71370b..a791078f37b 100644
    --- a/htdocs/asset/admin/assets_type_extrafields.php
    +++ b/htdocs/asset/admin/assets_type_extrafields.php
    @@ -63,7 +63,7 @@ $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToM
     print load_fiche_titre($langs->trans("AssetsSetup"),$linkback,'title_setup');
     
     
    -$head = AssetsAdminPrepareHead();
    +$head = asset_admin_prepare_head();
     
     dol_fiche_head($head, 'attributes_type', $langs->trans("Assets"), -1, 'generic');
     
    diff --git a/htdocs/asset/admin/setup.php b/htdocs/asset/admin/setup.php
    index 1168fd3ada3..57738309abd 100644
    --- a/htdocs/asset/admin/setup.php
    +++ b/htdocs/asset/admin/setup.php
    @@ -58,7 +58,7 @@ $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToM
     print load_fiche_titre($langs->trans("AssetsSetup"),$linkback,'title_setup');
     
     
    -$head = AssetsAdminPrepareHead();
    +$head = asset_admin_prepare_head();
     
     dol_fiche_head($head, 'settings', $langs->trans("Assets"), -1, 'generic');
     
    diff --git a/htdocs/asset/card.php b/htdocs/asset/card.php
    index 9af7638316f..4f7061aed20 100644
    --- a/htdocs/asset/card.php
    +++ b/htdocs/asset/card.php
    @@ -203,7 +203,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     {
     	$res = $object->fetch_optionals($object->id, $extralabels);
     
    -	$head = AssetsPrepareHead($object);
    +	$head = asset_prepare_head($object);
     	dol_fiche_head($head, 'card', $langs->trans("Asset"), -1, 'generic');
     
     	$formconfirm = '';
    diff --git a/htdocs/asset/document.php b/htdocs/asset/document.php
    index 784f65aa220..c1332ed10a2 100644
    --- a/htdocs/asset/document.php
    +++ b/htdocs/asset/document.php
    @@ -95,7 +95,7 @@ if ($object->id)
     	 * Show tabs
     	 */
     	if (! empty($conf->notification->enabled)) $langs->load("mails");
    -	$head = AssetsPrepareHead($object);
    +	$head = asset_prepare_head($object);
     
     	dol_fiche_head($head, 'document', $langs->trans("Asset"), -1, 'generic');
     
    diff --git a/htdocs/asset/info.php b/htdocs/asset/info.php
    index 9cc9495c1b9..e01316ae685 100644
    --- a/htdocs/asset/info.php
    +++ b/htdocs/asset/info.php
    @@ -55,7 +55,7 @@ $form = new Form($db);
     
     $object->info($id);
     
    -$head = AssetsPrepareHead($object);
    +$head = asset_prepare_head($object);
     
     dol_fiche_head($head, 'info', $langs->trans("Asset"), -1, 'generic');
     
    diff --git a/htdocs/asset/note.php b/htdocs/asset/note.php
    index e95e62aeaa4..f76c6ea028f 100644
    --- a/htdocs/asset/note.php
    +++ b/htdocs/asset/note.php
    @@ -78,7 +78,7 @@ if ($id > 0 || ! empty($ref))
     {
     	$object->fetch_thirdparty();
     
    -	$head = AssetsPrepareHead($object);
    +	$head = asset_prepare_head($object);
     
     	dol_fiche_head($head, 'note', $langs->trans("Asset"), -1, 'generic');
     
    diff --git a/htdocs/core/lib/asset.lib.php b/htdocs/core/lib/asset.lib.php
    index 7a4fd80158c..b0a4a6b81a9 100644
    --- a/htdocs/core/lib/asset.lib.php
    +++ b/htdocs/core/lib/asset.lib.php
    @@ -26,7 +26,7 @@
      *
      * @return array head array with tabs
      */
    -function AssetsAdminPrepareHead()
    +function asset_admin_prepare_head()
     {
     	global $langs, $conf;
     
    @@ -70,7 +70,7 @@ function AssetsAdminPrepareHead()
      *
      * @return array head array with tabs
      */
    -function AssetsPrepareHead()
    +function asset_prepare_head()
     {
     	global $langs, $conf;
     
    
    From b2677f08a45faa8f99e78f9f31c4e40e7c2d433b Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sun, 14 Oct 2018 12:47:26 +0200
    Subject: [PATCH 202/433] add links for set-up
    
    ---
     htdocs/accountancy/index.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
    index ac674eb95e0..431961a33bd 100644
    --- a/htdocs/accountancy/index.php
    +++ b/htdocs/accountancy/index.php
    @@ -61,13 +61,13 @@ if ($conf->accounting->enabled)
     
     	// STEPS
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("AccountingJournals").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/journals_list.php?id=35">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("AccountingJournals").'</strong>'.'</a>');
     	print "<br>\n";
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Pcg_version").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/accountmodel.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Pcg_version").'</strong>'.'</a>');
     	print "<br>\n";
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Chartofaccounts").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Chartofaccounts").'</strong>'.'</a>');
     	print "<br>\n";
     
     	print "<br>\n";
    
    From eecc56c1a371dcfd9c97ceb669e2f8d15e921605 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Sun, 14 Oct 2018 13:00:01 +0200
    Subject: [PATCH 203/433] highlight relevant text
    
    ---
     htdocs/accountancy/index.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
    index 431961a33bd..23dcc7f9932 100644
    --- a/htdocs/accountancy/index.php
    +++ b/htdocs/accountancy/index.php
    @@ -61,13 +61,13 @@ if ($conf->accounting->enabled)
     
     	// STEPS
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/journals_list.php?id=35">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("AccountingJournals").'</strong>'.'</a>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/journals_list.php?id=35">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("AccountingJournals").'</mark>'.'</strong>'.'</a>');
     	print "<br>\n";
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/accountmodel.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Pcg_version").'</strong>'.'</a>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/accountmodel.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("Pcg_version").'</mark>'.'</strong>'.'</a>');
     	print "<br>\n";
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Chartofaccounts").'</strong>'.'</a>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("Chartofaccounts").'</mark>'.'</strong>'.'</a>');
     	print "<br>\n";
     
     	print "<br>\n";
    
    From 26c9158ed7e0aa6872125b8871e6a680d982695f Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 14:20:28 +0200
    Subject: [PATCH 204/433] Label of DPO
    
    ---
     htdocs/langs/en_US/admin.lang | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index 93a48d763cd..724dbf61659 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -1802,7 +1802,7 @@ EnterCalculationRuleIfPreviousFieldIsYes=Enter calculation rule if previous fiel
     SeveralLangugeVariatFound=Several language variants found
     COMPANY_AQUARIUM_REMOVE_SPECIAL=Remove special characters
     COMPANY_AQUARIUM_CLEAN_REGEX=Regex filter to clean value (COMPANY_AQUARIUM_CLEAN_REGEX)
    -GDPRContact=Privacy Policies or GDPR contact
    +GDPRContact=Data Protection Officer (DPO, Data Privacy or GDPR contact)
     GDPRContactDesc=If you store data about European companies/citizen, you can store the contact who is responsible for the General Data Protection Regulation here
     HelpOnTooltip=Help text to show on tooltip
     HelpOnTooltipDesc=Put text or a translation key here for the text to show on a tooltip when this field appears in a form
    
    From 278910b66b70f60e0f60010cc0288a55cbd5ffeb Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 14:26:18 +0200
    Subject: [PATCH 205/433] Fix website
    
    ---
     htdocs/website/index.php | 7 ++++---
     1 file changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/website/index.php b/htdocs/website/index.php
    index 1d277c32ed7..0cf6380d1b8 100644
    --- a/htdocs/website/index.php
    +++ b/htdocs/website/index.php
    @@ -1943,6 +1943,7 @@ if (count($object->records) > 0)	// There is at least one web site
     
     				print '<input type="submit" class="button nobordertransp"'.$disabled.' value="'.dol_escape_htmltag($langs->trans("EditHTMLSource")).'" name="editsource">';
     
    +				print '<!-- button EditInLine and ShowSubcontainers -->'."\n";
     				print '<div class="websiteselectionsection inline-block">';
     				print '<div class="inline-block">';
     				print $langs->trans("EditInLine");
    @@ -1966,12 +1967,12 @@ if (count($object->records) > 0)	// There is at least one web site
     				print '</div>';
     				print '<div class="inline-block">';
     				print $langs->trans("ShowSubcontainers");
    -				if ($websitepage->grabbed_from)
    +				/*if ($websitepage->grabbed_from)
     				{
     					print '<a class="button nobordertransp opacitymedium nohoverborder"'.$disabled.' href="#" disabled="disabled" title="'.dol_escape_htmltag($langs->trans("OnlyEditionOfSourceForGrabbedContent")).'">'.img_picto($langs->trans("OnlyEditionOfSourceForGrabbedContent"),'switch_off','',false,0,0,'','nomarginleft').'</a>';
     				}
     				else
    -				{
    +				{*/
     					if (empty($conf->global->WEBSITE_SUBCONTAINERSINLINE))
     					{
     						print '<a class="button nobordertransp nohoverborder"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=setshowsubcontainers">'.img_picto($langs->trans("ShowSubContainersOff"),'switch_off','',false,0,0,'','nomarginleft').'</a>';
    @@ -1980,7 +1981,7 @@ if (count($object->records) > 0)	// There is at least one web site
     					{
     						print '<a class="button nobordertransp nohoverborder"'.$disabled.' href="'.$_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$websitepage->id.'&action=unsetshowsubcontainers">'.img_picto($langs->trans("ShowSubContainersOn"),'switch_on','',false,0,0,'','nomarginleft').'</a>';
     					}
    -				}
    +				/*}*/
     				print '</div>';
     				print '</div>';
     
    
    From 96d2950051829cae69591e19f2ecf82a27edeb21 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 16:10:02 +0200
    Subject: [PATCH 206/433] Better tooltip
    
    ---
     htdocs/website/index.php | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/website/index.php b/htdocs/website/index.php
    index 0cf6380d1b8..65a17be6281 100644
    --- a/htdocs/website/index.php
    +++ b/htdocs/website/index.php
    @@ -1749,7 +1749,7 @@ if (count($object->records) > 0)	// There is at least one web site
     
     		$htmltext = $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $urlint, $dataroot);
     		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    +		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
     		print '<a class="websitebuttonsitepreview" id="previewsite" href="'.$urlwithroot.'/public/website/index.php?website='.$websitekey.'" target="tab'.$websitekey.'" alt="'.dol_escape_htmltag($htmltext).'">';
     		print $form->textwithpicto('', $htmltext, 1, 'preview');
     		print '</a>';
    @@ -1760,7 +1760,7 @@ if (count($object->records) > 0)	// There is at least one web site
     		$htmltext =$langs->trans("SetHereVirtualHost", $dataroot);
     		$htmltext.='<br>';
     		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    +		$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
     		$htmltext.='<br>';
     		$htmltext.='<br>';
     		$htmltext.=$langs->trans("YouCanAlsoTestWithPHPS", $dataroot);
    @@ -1782,7 +1782,7 @@ if (count($object->records) > 0)	// There is at least one web site
     			$htmltext = $langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext?$urlext:'<span class="error">'.$langs->trans("VirtualHostUrlNotDefined").'</span>');
     			$htmltext.='<br>';
     			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    +			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
     			print '<a class="websitebuttonsitepreview'.($urlext?'':' websitebuttonsitepreviewdisabled cursornotallowed').'" id="previewsiteext" href="'.$urlext.'" target="tab'.$websitekey.'ext" alt="'.dol_escape_htmltag($langs->trans("PreviewSiteServedByWebServer", $langs->transnoentitiesnoconv("Site"), $langs->transnoentitiesnoconv("Site"), $dataroot, $urlext)).'">';
     			print $form->textwithpicto('', $htmltext, 1, 'preview_ext');
     			print '</a>';
    @@ -2003,7 +2003,7 @@ if (count($object->records) > 0)	// There is at least one web site
     
     			$htmltext = $langs->trans("PreviewSiteServedByDolibarr", $langs->transnoentitiesnoconv("Page"), $langs->transnoentitiesnoconv("Page"), $realpage, $dataroot);
     			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    +			$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
     
     			print '<a class="websitebuttonsitepreview" id="previewpage" href="'.$realpage.'&nocache='.dol_now().'" class="button" target="tab'.$websitekey.'" alt="'.dol_escape_htmltag($htmltext).'">';
     			print $form->textwithpicto('', $htmltext, 1, 'preview');
    @@ -2321,7 +2321,7 @@ if ($action == 'createsite')
     	$htmltext = $langs->trans("SetHereVirtualHost", DOL_DATA_ROOT.'/website/<i>websiteref</i>');
     	$htmltext.='<br>';
     	$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT);
    -	$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT);
    +	$htmltext.='<br>'.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website<br>'.DOL_DATA_ROOT.'/medias');
     
     	print $form->textwithpicto($langs->trans('Virtualhost'), $htmltext, 1, 'help', '', 0, 2, 'tooltipvirtual');
     	print '</td><td>';
    
    From 5654492ba88ca74ea46559f2f26ff2c702c67f75 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 16:45:45 +0200
    Subject: [PATCH 207/433] Update product.class.php
    
    ---
     htdocs/product/class/product.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index cdef8e18db7..3ed33ef5235 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -4085,7 +4085,7 @@ class Product extends CommonObject
         function load_virtual_stock()
         {
             // phpcs:enable
    -        global $conf, $action;
    +        global $conf, $hookmanager, $action;
     
             $stock_commande_client=0;
             $stock_commande_fournisseur=0;
    
    From 7e68d8df1b7ad8a8ed4e2ea9326820e4431db376 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 16:47:30 +0200
    Subject: [PATCH 208/433] Update product.class.php
    
    ---
     htdocs/product/class/product.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 3ed33ef5235..5bf2f45d31c 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -4144,7 +4144,7 @@ class Product extends CommonObject
     	$parameters=array('id'=>$this->id);
     	// Note that $action and $object may have been modified by some hooks
     	$reshook=$hookmanager->executeHooks('loadvirtualstock', $parameters, $this, $action);
    -	if ($reshook > 0) $this->stock_theorique+= $hookmanager->resPrint;
    +	if ($reshook > 0) $this->stock_theorique = $hookmanager->resArray['stock_theorique'];
     
         }
     
    
    From c66823d72fe76881274d8798daf90f07d504dc45 Mon Sep 17 00:00:00 2001
    From: Maxime Kohlhaas <maxime@atm-consulting.fr>
    Date: Sun, 14 Oct 2018 17:07:38 +0200
    Subject: [PATCH 209/433] Fix numbering of supplier credit notes (issue #9624)
    
    ---
     htdocs/admin/supplier_invoice.php                    |  7 +++++--
     .../mod_facture_fournisseur_tulip.php                | 12 ++++++------
     2 files changed, 11 insertions(+), 8 deletions(-)
    
    diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php
    index 75a917dd185..5dbe26596fe 100644
    --- a/htdocs/admin/supplier_invoice.php
    +++ b/htdocs/admin/supplier_invoice.php
    @@ -56,9 +56,12 @@ $specimenthirdparty->initAsSpecimen();
     if ($action == 'updateMask')
     {
         $maskconstinvoice=GETPOST('maskconstinvoice','alpha');
    -    $maskvalue=GETPOST('maskinvoice','alpha');
    +	$maskconstcredit=GETPOST('maskconstcredit','alpha');
    +    $maskinvoice=GETPOST('maskinvoice','alpha');
    +	$maskcredit=GETPOST('maskcredit','alpha');
     
    -    if ($maskconstinvoice)  $res = dolibarr_set_const($db,$maskconstinvoice,$maskvalue,'chaine',0,'',$conf->entity);
    +    if ($maskconstinvoice)  $res = dolibarr_set_const($db,$maskconstinvoice,$maskinvoice,'chaine',0,'',$conf->entity);
    +	if ($maskconstcredit)  $res = dolibarr_set_const($db,$maskconstcredit,$maskcredit,'chaine',0,'',$conf->entity);
     
         if (! $res > 0) $error++;
     
    diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
    index 2e155c04df8..7c595fe4e9d 100644
    --- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
    +++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php
    @@ -72,14 +72,18 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
     		$tooltip.=$langs->trans("GenericMaskCodes5");
     
     		// Parametrage du prefix
    -		$texte.= '<tr><td>'.$langs->trans("Mask");
    -		//$texte.= ' ('.$langs->trans("InvoiceStandard").')';
    +		$texte.= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceStandard").')';
     		$texte.= ':</td>';
     		$texte.= '<td align="right">'.$form->textwithpicto('<input type="text" class="flat" size="24" name="maskinvoice" value="'.$conf->global->SUPPLIER_INVOICE_TULIP_MASK.'">',$tooltip,1,1).'</td>';
     
     		$texte.= '<td align="left" rowspan="2">&nbsp; <input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button"></td>';
     
     		$texte.= '</tr>';
    +		
    +		// Parametrage du prefix des avoirs
    +		$texte.= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceAvoir").'):</td>';
    +		$texte.= '<td align="right">'.$form->textwithpicto('<input type="text" class="flat" size="24" name="maskcredit" value="'.$conf->global->SUPPLIER_CREDIT_TULIP_MASK.'">',$tooltip,1,1).'</td>';
    +		$texte.= '</tr>';
     
     		if ($conf->global->MAIN_FEATURE_LEVEL >= 2)
     		{
    @@ -88,10 +92,6 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices
         		$texte.= '<td align="right">'.$form->textwithpicto('<input type="text" class="flat" size="24" name="maskreplacement" value="'.$conf->global->SUPPLIER_REPLACEMENT_TULIP_MASK.'">',$tooltip,1,1).'</td>';
         		$texte.= '</tr>';
     
    -    		// Parametrage du prefix des avoirs
    -    		$texte.= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceAvoir").'):</td>';
    -    		$texte.= '<td align="right">'.$form->textwithpicto('<input type="text" class="flat" size="24" name="maskcredit" value="'.$conf->global->SUPPLIER_CREDIT_TULIP_MASK.'">',$tooltip,1,1).'</td>';
    -    		$texte.= '</tr>';
     
         		// Parametrage du prefix des acomptes
         		$texte.= '<tr><td>'.$langs->trans("Mask").' ('.$langs->trans("InvoiceDeposit").'):</td>';
    
    From b0569de1660fba102e01856006175e1069624e28 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 18:44:29 +0200
    Subject: [PATCH 210/433] Work on multilang support
    
    ---
     htdocs/core/website.inc.php                |  31 ++++
     htdocs/langs/en_US/website.lang            |   2 +
     htdocs/public/website/index.php            | 158 +++++++++++----------
     htdocs/website/class/websitepage.class.php |   3 +
     htdocs/website/index.php                   |  50 ++++++-
     5 files changed, 165 insertions(+), 79 deletions(-)
    
    diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php
    index ac4d6b35988..43c9116cea5 100644
    --- a/htdocs/core/website.inc.php
    +++ b/htdocs/core/website.inc.php
    @@ -19,6 +19,7 @@
     /**
      *	\file			htdocs/core/website.inc.php
      *  \brief			Common file loaded by all website pages (after master.inc.php). It set the new object $weblangs, using parameter 'l'.
    + *  				This file is included in top of all container pages.
      *  			    The global variable $websitekey must be defined.
      */
     
    @@ -34,6 +35,36 @@ if (! is_object($weblangs))
     {
     	$weblangs = dol_clone($langs);
     }
    +
    +// A lang was forced, so we change weblangs init
     if (GETPOST('l','aZ09')) $weblangs->setDefaultLang(GETPOST('l','aZ09'));
    +// A lang was forced, so we check to find if we must make a redirect on translation page
    +if (! defined('USEDOLIBARREDITOR'))
    +{
    +	if (GETPOST('l','aZ09'))
    +	{
    +		$sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
    +		$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp, ".MAIN_DB_PREFIX."website as w";
    +		$sql.=" WHERE w.rowid = wp.fk_website AND w.ref = '".$db->escape($websitekey)."' AND fk_page = '".$db->escape($pageid)."' AND lang = '".$db->escape(GETPOST('l','aZ09'))."'";
    +		$resql = $db->query($sql);
    +		if ($resql)
    +		{
    +			$obj = $db->fetch_object($resql);
    +			if ($obj)
    +			{
    +				//$pageid = $obj->rowid;
    +				//$pageref = $obj->pageurl;
    +				if (! defined('USEDOLIBARRSERVER')) {
    +					// TODO Redirect
    +				}
    +				else
    +				{
    +					// TODO Redirect
    +				}
    +			}
    +		}
    +	}
    +}
    +
     // Load websitepage class
     include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang
    index 55db08c3785..a14d05132cd 100644
    --- a/htdocs/langs/en_US/website.lang
    +++ b/htdocs/langs/en_US/website.lang
    @@ -91,3 +91,5 @@ ExternalURLMustStartWithHttp=External URL must start with http:// or https://
     ZipOfWebsitePackageToImport=Zip file of website package
     ShowSubcontainers=Show included containers
     InternalURLOfPage=Internal URL of page
    +ThisPageIsTranslationOf=This page/container is translation of
    +ThisPageHasTranslationPages=This page/container has translation
    \ No newline at end of file
    diff --git a/htdocs/public/website/index.php b/htdocs/public/website/index.php
    index 862d8ada71a..19abc48094b 100644
    --- a/htdocs/public/website/index.php
    +++ b/htdocs/public/website/index.php
    @@ -18,8 +18,7 @@
     /**
      *     	\file       htdocs/public/website/index.php
      *		\ingroup    website
    - *		\brief      Page to output pages
    - *		\author	    Laurent Destailleur
    + *		\brief      Wrapper to output pages when website is powered by Dolibarr instead of a native web server
      */
     
     if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL',1); // Disables token renewal
    @@ -59,88 +58,91 @@ $accessallowed = 1;
     $type='';
     
     
    -/*
    - * View
    - */
    +if (empty($pageid))
    +{
    +	require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
    +	require_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    +
    +	$object=new Website($db);
    +	$object->fetch(0, $websitekey);
    +
    +	if (empty($object->id))
    +	{
    +		if (empty($pageid))
    +		{
    +			// Return header 404
    +			header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    +
    +			include DOL_DOCUMENT_ROOT.'/public/error-404.php';
    +			exit;
    +		}
    +	}
    +
    +	$objectpage=new WebsitePage($db);
    +
    +	if ($pageref)
    +	{
    +		$result=$objectpage->fetch(0, $object->id, $pageref);
    +		if ($result > 0)
    +		{
    +			$pageid = $objectpage->id;
    +		}
    +		elseif($result == 0)
    +		{
    +			// Page not found from ref=pageurl, we try using alternative alias
    +			$result=$objectpage->fetch(0, $object->id, null, $pageref);
    +			if ($result > 0)
    +			{
    +				$pageid = $objectpage->id;
    +			}
    +		}
    +	}
    +	else
    +	{
    +		if ($object->fk_default_home > 0)
    +		{
    +			$result=$objectpage->fetch($object->fk_default_home);
    +			if ($result > 0)
    +			{
    +				$pageid = $objectpage->id;
    +			}
    +		}
    +
    +		if (empty($pageid))
    +		{
    +			$array=$objectpage->fetchAll($object->id);
    +			if (is_array($array) && count($array) > 0)
    +			{
    +				$firstrep=reset($array);
    +				$pageid=$firstrep->id;
    +			}
    +		}
    +	}
    +}
    +if (empty($pageid))
    +{
    +	// Return header 404
    +	header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    +
    +	$langs->load("website");
    +
    +	if (! GETPOSTISSET('pageref')) print $langs->trans("PreviewOfSiteNotYetAvailable", $websitekey);
    +
    +	include DOL_DOCUMENT_ROOT.'/public/error-404.php';
    +	exit;
    +}
     
     $appli=constant('DOL_APPLICATION_TITLE');
     if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE;
     
    +
    +
    +/*
    + * View
    + */
    +
     //print 'Directory with '.$appli.' websites.<br>';
     
    -if (empty($pageid))
    -{
    -    require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
    -    require_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    -
    -    $object=new Website($db);
    -    $object->fetch(0, $websitekey);
    -
    -	if (empty($object->id))
    -    {
    -        if (empty($pageid))
    -        {
    -            // Return header 404
    -            header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    -
    -            include DOL_DOCUMENT_ROOT.'/public/error-404.php';
    -            exit;
    -        }
    -    }
    -
    -    $objectpage=new WebsitePage($db);
    -
    -    if ($pageref)
    -    {
    -    	$result=$objectpage->fetch(0, $object->id, $pageref);
    -    	if ($result > 0)
    -	    {
    -	        $pageid = $objectpage->id;
    -	    }
    -	    elseif($result == 0)
    -	    {
    -	    	// Page not found from ref=pageurl, we try using alternative alias
    -	    	$result=$objectpage->fetch(0, $object->id, null, $pageref);
    -	    	if ($result > 0)
    -	    	{
    -	    		$pageid = $objectpage->id;
    -	    	}
    -	    }
    -    }
    -    else
    -    {
    -	    if ($object->fk_default_home > 0)
    -	    {
    -	        $result=$objectpage->fetch($object->fk_default_home);
    -	        if ($result > 0)
    -	        {
    -	            $pageid = $objectpage->id;
    -	        }
    -	    }
    -
    -	    if (empty($pageid))
    -	    {
    -	        $array=$objectpage->fetchAll($object->id);
    -	        if (is_array($array) && count($array) > 0)
    -	        {
    -	            $firstrep=reset($array);
    -	            $pageid=$firstrep->id;
    -	        }
    -	    }
    -    }
    -}
    -if (empty($pageid))
    -{
    -    // Return header 404
    -    header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
    -
    -    $langs->load("website");
    -
    -    if (! GETPOSTISSET('pageref')) print $langs->trans("PreviewOfSiteNotYetAvailable", $websitekey);
    -
    -    include DOL_DOCUMENT_ROOT.'/public/error-404.php';
    -    exit;
    -}
     
     // Security: Delete string ../ into $original_file
     global $dolibarr_main_data_root;
    diff --git a/htdocs/website/class/websitepage.class.php b/htdocs/website/class/websitepage.class.php
    index 4277a03167d..79ff3bc789d 100644
    --- a/htdocs/website/class/websitepage.class.php
    +++ b/htdocs/website/class/websitepage.class.php
    @@ -193,8 +193,11 @@ class WebsitePage extends CommonObject
     
     				$this->fk_website = $obj->fk_website;
     				$this->type_container = $obj->type_container;
    +
     				$this->pageurl = $obj->pageurl;
    +				$this->ref = $obj->pageurl;
     				$this->aliasalt = preg_replace('/,+$/', '', preg_replace('/^,+/', '', $obj->aliasalt));
    +
     				$this->title = $obj->title;
     				$this->description = $obj->description;
     				$this->keywords = $obj->keywords;
    diff --git a/htdocs/website/index.php b/htdocs/website/index.php
    index 65a17be6281..e9e14c4f888 100644
    --- a/htdocs/website/index.php
    +++ b/htdocs/website/index.php
    @@ -1926,10 +1926,11 @@ if (count($object->records) > 0)	// There is at least one web site
     					// Create an array for form
     					$preselectedlanguage = GETPOST('newlang', 'az09') ? GETPOST('newlang', 'az09') : ($objectpage->lang ? $objectpage->lang : $langs->defaultlang);
     					$formquestion = array(
    -						array('type' => 'text', 'tdclass'=>'maxwidth200', 'name' => 'pageurl', 'label'=> $langs->trans("WEBSITE_PAGENAME"), 'value'=> 'copy_of_'.$objectpage->pageurl),
    +						array('type' => 'hidden', 'name' => 'sourcepageurl', 'value'=> $objectpage->pageurl),
     						array('type' => 'checkbox', 'tdclass'=>'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0),
     						array('type' => 'other','name' => 'newlang', 'label' => $langs->trans("Language"), 'value' => $formadmin->select_language($preselectedlanguage, 'newlang', 0, null, 1, 0, 0, 'minwidth200', 0, 1)),
     						array('type' => 'other','name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)),
    +						array('type' => 'text', 'tdclass'=>'maxwidth200 fieldrequired', 'name' => 'pageurl', 'label'=> $langs->trans("WEBSITE_PAGENAME"), 'value'=> 'copy_of_'.$objectpage->pageurl),
     					);
     
     				   	$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?website='.$object->ref.'&pageid=' . $pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 300, 550);
    @@ -2518,6 +2519,53 @@ if ($action == 'editmeta' || $action == 'createcontainer')
     	print $formadmin->select_language($pagelang?$pagelang:$langs->defaultlang, 'WEBSITE_LANG', 0, null, '1');
     	print '</td></tr>';
     
    +	if ($action != 'createcontainer')
    +	{
    +		// Translation of
    +		if ($objectpage->fk_page > 0)
    +		{
    +			print '<tr><td>';
    +			print $langs->trans('ThisPageIsTranslationOf');
    +			print '</td><td>';
    +			$sourcepage=new WebsitePage($db);
    +			$result = $sourcepage->fetch($objectpage->fk_page);
    +			if ($result == 0)	// not found, we can reset value
    +			{
    +
    +			}
    +			elseif ($result > 0)
    +			{
    +				print $sourcepage->getNomUrl(1);
    +			}
    +			print '</td></tr>';
    +		}
    +
    +		// Has translation pages
    +		$sql='SELECT rowid, lang from '.MAIN_DB_PREFIX.'website_page where fk_page = '.$objectpage->id;
    +		$resql = $db->query($sql);
    +		if ($resql)
    +		{
    +			$num_rows = $db->num_rows($resql);
    +			if ($num_rows > 0)
    +			{
    +				print '<tr><td>';
    +				print $langs->trans('ThisPageHasTranslationPages');
    +				print '</td><td>';
    +				$i=0;
    +				while ($obj = $db->fetch_object($resql))
    +				{
    +					$tmppage=new WebsitePage($db);
    +					$tmppage->fetch($obj->rowid);
    +					if ($i > 0) print ' - ';
    +					print $tmppage->getNomUrl(1).' ('.$tmppage->lang.')';
    +					$i++;
    +				}
    +				print '</td></tr>';
    +			}
    +		}
    +		else dol_print_error($db);
    +	}
    +
     	print '<tr><td class="titlefieldcreate">';
     	$htmlhelp=$langs->trans("WEBSITE_ALIASALTDesc");
     	print $form->textwithpicto($langs->trans('WEBSITE_ALIASALT'), $htmlhelp, 1, 'help', '', 0, 2, 'htmlheadertooltip');
    
    From af813f82145befb310c35973efac5ab97ff213ea Mon Sep 17 00:00:00 2001
    From: Maxime Kohlhaas <maxime@atm-consulting.fr>
    Date: Sun, 14 Oct 2018 19:55:25 +0200
    Subject: [PATCH 211/433] Fix missing status_batch var on product lists #9606
    
    ---
     htdocs/product/index.php                 | 3 ++-
     htdocs/product/list.php                  | 1 +
     htdocs/product/reassortlot.php           | 1 +
     htdocs/product/stock/productlot_list.php | 4 +++-
     4 files changed, 7 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/product/index.php b/htdocs/product/index.php
    index 6eebc4d85e2..b998bdc3148 100644
    --- a/htdocs/product/index.php
    +++ b/htdocs/product/index.php
    @@ -273,7 +273,7 @@ print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
      */
     $max=15;
     $sql = "SELECT p.rowid, p.label, p.price, p.ref, p.fk_product_type, p.tosell, p.tobuy, p.fk_price_expression,";
    -$sql.= " p.entity,";
    +$sql.= " p.entity, p.tobatch,";
     $sql.= " p.tms as datem";
     $sql.= " FROM ".MAIN_DB_PREFIX."product as p";
     $sql.= " WHERE p.entity IN (".getEntity($product_static->element, 1).")";
    @@ -337,6 +337,7 @@ if ($result)
     			$product_static->label = $objp->label;
     			$product_static->type=$objp->fk_product_type;
                 $product_static->entity = $objp->entity;
    +			$product_static->status_batch = $objp->tobatch;
     			print $product_static->getNomUrl(1,'',16);
     			print "</td>\n";
     			print '<td>'.dol_trunc($objp->label,32).'</td>';
    diff --git a/htdocs/product/list.php b/htdocs/product/list.php
    index 178432addbc..071080edc58 100644
    --- a/htdocs/product/list.php
    +++ b/htdocs/product/list.php
    @@ -700,6 +700,7 @@ else
     				$product_static->status     = $obj->tosell;
     				$product_static->entity = $obj->entity;
     				$product_static->pmp = $obj->pmp;
    +				$product_static->status_batch = $obj->tobatch;
     
     				if ((! empty($conf->stock->enabled) && $user->rights->stock->lire && $search_type != 1) || ! empty($conf->global->STOCK_DISABLE_OPTIM_LOAD))	// To optimize call of load_stock
     				{
    diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php
    index fc2632fe5e2..d737ecf8bb3 100644
    --- a/htdocs/product/reassortlot.php
    +++ b/htdocs/product/reassortlot.php
    @@ -337,6 +337,7 @@ if ($resql)
             $product_static->label = $objp->label;
     		$product_static->type=$objp->fk_product_type;
     		$product_static->entity=$objp->entity;
    +		$product_static->status_batch=$objp->tobatch;
     
     		$product_lot_static->batch=$objp->batch;
     		$product_lot_static->product_id=$objp->rowid;
    diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php
    index 5934e8dff55..02260c8bf8b 100644
    --- a/htdocs/product/stock/productlot_list.php
    +++ b/htdocs/product/stock/productlot_list.php
    @@ -216,7 +216,8 @@ $sql.= " t.fk_user_modif,";
     $sql.= " t.import_key,";
     $sql.= " p.fk_product_type as product_type,";
     $sql.= " p.ref as product_ref,";
    -$sql.= " p.label as product_label";
    +$sql.= " p.label as product_label,";
    +$sql.= " p.tobatch";
     // Add fields for extrafields
     foreach ($extrafields->attribute_list as $key => $val) $sql.=",ef.".$key.' as options_'.$key;
     // Add fields from hooks
    @@ -430,6 +431,7 @@ if ($resql)
     				$productstatic->type=$obj->product_type;
     				$productstatic->ref=$obj->product_ref;
     				$productstatic->label=$obj->product_label;
    +				$productstatic->status_batch = $obj->tobatch;
     				print '<td>'.$productstatic->getNomUrl(1).'</td>';
     				if (! $i) $totalarray['nbfield']++;
     			}
    
    From 45860b24948d71bc96084d15fe9814f258228028 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 20:04:25 +0200
    Subject: [PATCH 212/433] Work on multilang
    
    ---
     htdocs/core/lib/website.lib.php        |  6 ++--
     htdocs/core/website.inc.php            | 47 +++++++++++++++++---------
     htdocs/website/class/website.class.php | 18 +++++++++-
     3 files changed, 51 insertions(+), 20 deletions(-)
    
    diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
    index 9f848fb68ee..ab0cbbdbdfb 100644
    --- a/htdocs/core/lib/website.lib.php
    +++ b/htdocs/core/lib/website.lib.php
    @@ -307,7 +307,7 @@ function includeContainer($containerref)
     {
     	global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $weblangs;	// Very important. Required to have var available when running inluded containers.
     	global $includehtmlcontentopened;
    -	global $websitekey;
    +	global $websitekey, $websitepagefile;
     
     	$MAXLEVEL=20;
     
    @@ -607,7 +607,7 @@ function dolSavePageContent($filetpl, $object, $objectpage)
     
     	$tplcontent ='';
     	$tplcontent.= "<?php // BEGIN PHP\n";
    -	$tplcontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    +	$tplcontent.= '$websitekey=basename(dirname(__FILE__)); $websitepagefile=__FILE__;'."\n";
     	$tplcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Not already loaded"."\n";
     	$tplcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
     	$tplcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
    @@ -672,7 +672,7 @@ function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper)
     	dol_delete_file($fileindex);
     	$indexcontent = '<?php'."\n";
     	$indexcontent.= "// BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper.\n";
    -	$indexcontent.= '$websitekey=basename(dirname(__FILE__));'."\n";
    +	$indexcontent.= '$websitekey=basename(dirname(__FILE__)); $websitepagefile=__FILE__;'."\n";
     	$indexcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load master if not already loaded\n";
     	$indexcontent.= 'if (! empty($_GET[\'pageref\']) || ! empty($_GET[\'pagealiasalt\']) || ! empty($_GET[\'pageid\'])) {'."\n";
     	$indexcontent.= "	require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
    diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php
    index 43c9116cea5..7ce4af6c9b2 100644
    --- a/htdocs/core/website.inc.php
    +++ b/htdocs/core/website.inc.php
    @@ -33,33 +33,48 @@ if (! is_object($website))
     }
     if (! is_object($weblangs))
     {
    -	$weblangs = dol_clone($langs);
    +	$weblangs = dol_clone($langs);	// TODO Use an object lang from a language set into $website object instead of backoffice
     }
     
     // A lang was forced, so we change weblangs init
     if (GETPOST('l','aZ09')) $weblangs->setDefaultLang(GETPOST('l','aZ09'));
     // A lang was forced, so we check to find if we must make a redirect on translation page
    -if (! defined('USEDOLIBARREDITOR'))
    +if ($_SERVER['PHP_SELF'] != DOL_URL_ROOT.'/website/index.php')	// If we browsing page using Dolibarr server or a Native web server
     {
    +	//print_r(get_defined_constants(true));exit;
     	if (GETPOST('l','aZ09'))
     	{
    -		$sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
    -		$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp, ".MAIN_DB_PREFIX."website as w";
    -		$sql.=" WHERE w.rowid = wp.fk_website AND w.ref = '".$db->escape($websitekey)."' AND fk_page = '".$db->escape($pageid)."' AND lang = '".$db->escape(GETPOST('l','aZ09'))."'";
    -		$resql = $db->query($sql);
    -		if ($resql)
    +		if (! $pageid && ! empty($websitepagefile))
     		{
    -			$obj = $db->fetch_object($resql);
    -			if ($obj)
    +			$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
    +		}
    +		if ($pageid > 0)
    +		{
    +			$sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
    +			$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp, ".MAIN_DB_PREFIX."website as w";
    +			$sql.=" WHERE w.rowid = wp.fk_website AND w.ref = '".$db->escape($websitekey)."' AND wp.lang = '".$db->escape(GETPOST('l','aZ09'))."'";
    +			$sql.=" AND wp.fk_page = ".$db->escape($pageid);
    +			//var_dump($sql);exit;
    +			$resql = $db->query($sql);
    +			if ($resql)
     			{
    -				//$pageid = $obj->rowid;
    -				//$pageref = $obj->pageurl;
    -				if (! defined('USEDOLIBARRSERVER')) {
    -					// TODO Redirect
    -				}
    -				else
    +				$obj = $db->fetch_object($resql);
    +				if ($obj)
     				{
    -					// TODO Redirect
    +					$newpageid = $obj->rowid;
    +					if ($newpageid != $pageid) 		// To avoid to make a redirect on same page (infinite loop)
    +					{
    +						if (defined('USEDOLIBARRSERVER')) {
    +							header("Location: ".DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$newpageid.'.php&l='.GETPOST('l','aZ09'));
    +							exit;
    +						}
    +						else
    +						{
    +							$newpageref = $obj->pageurl;
    +							header("Location: ".$newpageref.'.php?l='.GETPOST('l','aZ09'));
    +							exit;
    +						}
    +					}
     				}
     			}
     		}
    diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php
    index 843304fbe45..658e35edcd9 100644
    --- a/htdocs/website/class/website.class.php
    +++ b/htdocs/website/class/website.class.php
    @@ -1089,10 +1089,26 @@ class Website extends CommonObject
     	 */
     	public function componentSelectLang($languagecodes, $weblangs, $morecss='', $htmlname='')
     	{
    +		global $websitepagefile;
    +
     		if (! is_object($weblangs)) return 'ERROR componentSelectLang called with parameter $weblangs not defined';
     
    -		$languagecodeselected = $weblangs->defaultlang;
    +		$languagecodeselected= $weblangs->defaultlang;	// Becasue we must init with a value, but real value is the lang of main parent container
    +		if (! empty($websitepagefile))
    +		{
    +			$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
    +			if ($pageid > 0)
    +			{
    +				$tmppage=new WebsitePage($this->db);
    +				$tmppage->fetch($pageid);
    +
    +				$languagecodeselected=$tmppage->lang;
    +				$languagecodes[]=$tmppage->lang;	// We add language code of page into combo list
    +			}
    +		}
    +
     		$weblangs->load('languages');
    +		//var_dump($weblangs->defaultlang);
     
     		$url = $_SERVER["REQUEST_URI"];
     		$url = preg_replace('/(\?|&)l=([a-zA-Z_]*)/', '', $url);	// We remove param l from url
    
    From ac143b28aeb9c8249746f2c3b65e50b9202ac6cb Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 20:54:28 +0200
    Subject: [PATCH 213/433] Work on multilang
    
    ---
     htdocs/core/lib/website.lib.php        |  4 +-
     htdocs/website/class/website.class.php | 56 +++++++++++++++++++++-----
     2 files changed, 48 insertions(+), 12 deletions(-)
    
    diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
    index ab0cbbdbdfb..fc2a90bbeb1 100644
    --- a/htdocs/core/lib/website.lib.php
    +++ b/htdocs/core/lib/website.lib.php
    @@ -607,7 +607,7 @@ function dolSavePageContent($filetpl, $object, $objectpage)
     
     	$tplcontent ='';
     	$tplcontent.= "<?php // BEGIN PHP\n";
    -	$tplcontent.= '$websitekey=basename(dirname(__FILE__)); $websitepagefile=__FILE__;'."\n";
    +	$tplcontent.= '$websitekey=basename(dirname(__FILE__)); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
     	$tplcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Not already loaded"."\n";
     	$tplcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
     	$tplcontent.= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
    @@ -672,7 +672,7 @@ function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper)
     	dol_delete_file($fileindex);
     	$indexcontent = '<?php'."\n";
     	$indexcontent.= "// BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper.\n";
    -	$indexcontent.= '$websitekey=basename(dirname(__FILE__)); $websitepagefile=__FILE__;'."\n";
    +	$indexcontent.= '$websitekey=basename(dirname(__FILE__)); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
     	$indexcontent.= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load master if not already loaded\n";
     	$indexcontent.= 'if (! empty($_GET[\'pageref\']) || ! empty($_GET[\'pagealiasalt\']) || ! empty($_GET[\'pageid\'])) {'."\n";
     	$indexcontent.= "	require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
    diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php
    index 658e35edcd9..04bad804678 100644
    --- a/htdocs/website/class/website.class.php
    +++ b/htdocs/website/class/website.class.php
    @@ -1079,31 +1079,67 @@ class Website extends CommonObject
     	}
     
     	/**
    -	 * Component to select language (Full CSS Only)
    +	 * Component to select language inside a container (Full CSS Only)
     	 *
    -	 * @param	array		$languagecodes			Language codes array. Example: array('en_US','fr_FR','de_DE','es_ES')
    -	 * @param	Translate	$weblangs				Language Object
    -	 * @param	string		$morecss				More CSS class on component
    -	 * @param	string		$htmlname				Suffix for HTML name
    -	 * @return 	string								HTML select component
    +	 * @param	array|string	$languagecodes			'auto' to show all languages available for page or language codes array like array('en_US','fr_FR','de_DE','es_ES')
    +	 * @param	Translate		$weblangs				Language Object
    +	 * @param	string			$morecss				More CSS class on component
    +	 * @param	string			$htmlname				Suffix for HTML name
    +	 * @return 	string									HTML select component
     	 */
     	public function componentSelectLang($languagecodes, $weblangs, $morecss='', $htmlname='')
     	{
    -		global $websitepagefile;
    +		global $websitepagefile, $website;
     
     		if (! is_object($weblangs)) return 'ERROR componentSelectLang called with parameter $weblangs not defined';
     
    -		$languagecodeselected= $weblangs->defaultlang;	// Becasue we must init with a value, but real value is the lang of main parent container
    +		// Load tmppage if we have $websitepagefile defined
    +		$tmppage=new WebsitePage($this->db);
    +
    +		$pageid = 0;
     		if (! empty($websitepagefile))
     		{
     			$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
     			if ($pageid > 0)
     			{
    -				$tmppage=new WebsitePage($this->db);
     				$tmppage->fetch($pageid);
    +			}
    +		}
    +
    +		// Fill with existing translation, nothing if none
    +		if (! is_array($languagecodes) && $pageid > 0)
    +		{
    +			$languagecodes = array();
    +
    +			$sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
    +			$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp";
    +			$sql.=" WHERE wp.fk_website = ".$website->id;
    +			$sql.=" AND (wp.fk_page = ".$pageid." OR wp.rowid  = ".$pageid;
    +			if ($tmppage->fk_page > 0) $sql.=" OR wp.fk_page = ".$tmppage->fk_page." OR wp.rowid = ".$tmppage->fk_page;
    +			$sql.=")";
    +
    +			$resql = $this->db->query($sql);
    +			if ($resql)
    +			{
    +				while ($obj = $this->db->fetch_object($resql))
    +				{
    +					$newlang = $obj->lang;
    +					if ($obj->rowid == $pageid) $newlang = $obj->lang;
    +					if (! in_array($newlang, $languagecodes)) $languagecodes[]=$newlang;
    +				}
    +			}
    +		}
    +		// Now $languagecodes is always an array
    +
    +		$languagecodeselected= $weblangs->defaultlang;	// Because we must init with a value, but real value is the lang of main parent container
    +		if (! empty($websitepagefile))
    +		{
    +			$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
    +			if ($pageid > 0)
    +			{
     
     				$languagecodeselected=$tmppage->lang;
    -				$languagecodes[]=$tmppage->lang;	// We add language code of page into combo list
    +				if (! in_array($tmppage->lang, $languagecodes)) $languagecodes[]=$tmppage->lang;	// We add language code of page into combo list
     			}
     		}
     
    
    From ab807ada07717dc3e316f204b5df650dc424b316 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 23:26:57 +0200
    Subject: [PATCH 214/433] Work on translation
    
    ---
     htdocs/core/website.inc.php            | 16 ++++++++++++----
     htdocs/website/class/website.class.php |  2 +-
     2 files changed, 13 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php
    index 7ce4af6c9b2..4e382088da5 100644
    --- a/htdocs/core/website.inc.php
    +++ b/htdocs/core/website.inc.php
    @@ -50,11 +50,19 @@ if ($_SERVER['PHP_SELF'] != DOL_URL_ROOT.'/website/index.php')	// If we browsing
     		}
     		if ($pageid > 0)
     		{
    +			// Load tmppage if we have $websitepagefile defined
    +			include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    +			$tmppage=new WebsitePage($db);
    +			$tmppage->fetch($pageid);
    +
     			$sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
    -			$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp, ".MAIN_DB_PREFIX."website as w";
    -			$sql.=" WHERE w.rowid = wp.fk_website AND w.ref = '".$db->escape($websitekey)."' AND wp.lang = '".$db->escape(GETPOST('l','aZ09'))."'";
    -			$sql.=" AND wp.fk_page = ".$db->escape($pageid);
    -			//var_dump($sql);exit;
    +			$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp";
    +			$sql.=" WHERE wp.fk_website = ".$website->id;
    +			$sql.=" AND (wp.fk_page = ".$pageid." OR wp.rowid  = ".$pageid;
    +			if ($tmppage->fk_page > 0) $sql.=" OR wp.fk_page = ".$tmppage->fk_page." OR wp.rowid = ".$tmppage->fk_page;
    +			$sql.=")";
    +			$sql.= " AND wp.lang = '".$db->escape(GETPOST('l','aZ09'))."'";
    +
     			$resql = $db->query($sql);
     			if ($resql)
     			{
    diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php
    index 04bad804678..b9be32bcafa 100644
    --- a/htdocs/website/class/website.class.php
    +++ b/htdocs/website/class/website.class.php
    @@ -1081,7 +1081,7 @@ class Website extends CommonObject
     	/**
     	 * Component to select language inside a container (Full CSS Only)
     	 *
    -	 * @param	array|string	$languagecodes			'auto' to show all languages available for page or language codes array like array('en_US','fr_FR','de_DE','es_ES')
    +	 * @param	array|string	$languagecodes			'auto' to show all languages available for page, or language codes array like array('en_US','fr_FR','de_DE','es_ES')
     	 * @param	Translate		$weblangs				Language Object
     	 * @param	string			$morecss				More CSS class on component
     	 * @param	string			$htmlname				Suffix for HTML name
    
    From 8fc73d1b1be00a477ffe5856a8c12861879c380b Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 23:47:38 +0200
    Subject: [PATCH 215/433] Fix pagination show two times the same account on
     balance of accounts
    
    ---
     htdocs/accountancy/bookkeeping/balance.php    | 23 ++++++++++++-------
     .../accountancy/class/bookkeeping.class.php   |  9 ++++++--
     2 files changed, 22 insertions(+), 10 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php
    index 2b263ca166c..bfd65ee1be7 100644
    --- a/htdocs/accountancy/bookkeeping/balance.php
    +++ b/htdocs/accountancy/bookkeeping/balance.php
    @@ -42,6 +42,21 @@ $page = GETPOST("page");
     $sortorder = GETPOST("sortorder", 'alpha');
     $sortfield = GETPOST("sortfield", 'alpha');
     $action = GETPOST('action', 'alpha');
    +if (GETPOST("exportcsv",'alpha')) $action = 'export_csv';
    +
    +// Load variable for pagination
    +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
    +$sortfield = GETPOST('sortfield','alpha');
    +$sortorder = GETPOST('sortorder','alpha');
    +$page = GETPOST('page','int');
    +if (empty($page) || $page == -1 || GETPOST('button_search','alpha') || GETPOST('button_removefilter','alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; }     // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
    +$offset = $limit * $page;
    +$pageprev = $page - 1;
    +$pagenext = $page + 1;
    +//if (! $sortfield) $sortfield="p.date_fin";
    +//if (! $sortorder) $sortorder="DESC";
    +
    +
     $search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
     $search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
     
    @@ -54,14 +69,6 @@ if ($search_accountancy_code_end == - 1) {
     	$search_accountancy_code_end = '';
     }
     
    -if (GETPOST("exportcsv",'alpha')) $action = 'export_csv';
    -
    -
    -$limit = GETPOST('limit','int')?GETPOST('limit', 'int'):$conf->liste_limit;
    -if (empty($page) || $page < 0) { $page = 0; }
    -
    -$offset = $limit * $page;
    -
     $object = new BookKeeping($db);
     
     $formaccounting = new FormAccounting($db);
    diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
    index 5e9350b0366..a9bfcce027a 100644
    --- a/htdocs/accountancy/class/bookkeeping.class.php
    +++ b/htdocs/accountancy/class/bookkeeping.class.php
    @@ -1016,16 +1016,21 @@ class BookKeeping extends CommonObject
     		}
     
     		$resql = $this->db->query($sql);
    -		if ($resql) {
    +		if ($resql)
    +		{
     			$num = $this->db->num_rows($resql);
     
    -			while ( $obj = $this->db->fetch_object($resql) ) {
    +			$i = 0;
    +			while ($obj = $this->db->fetch_object($resql) && $i < $num)
    +			{
     				$line = new BookKeepingLine();
     
     				$line->numero_compte = $obj->numero_compte;
     				$line->debit = $obj->debit;
     				$line->credit = $obj->credit;
     				$this->lines[] = $line;
    +
    +				$i++;
     			}
     			$this->db->free($resql);
     
    
    From 995f4fa35fa3e4038ed4fabf33ff2e5b2595815b Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 23:57:07 +0200
    Subject: [PATCH 216/433] Fix limit
    
    ---
     htdocs/accountancy/class/bookkeeping.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
    index a9bfcce027a..b228588b90f 100644
    --- a/htdocs/accountancy/class/bookkeeping.class.php
    +++ b/htdocs/accountancy/class/bookkeeping.class.php
    @@ -1021,7 +1021,7 @@ class BookKeeping extends CommonObject
     			$num = $this->db->num_rows($resql);
     
     			$i = 0;
    -			while ($obj = $this->db->fetch_object($resql) && $i < $num)
    +			while (($obj = $this->db->fetch_object($resql)) && ($i < min($limit, $num)))
     			{
     				$line = new BookKeepingLine();
     
    
    From b13d9650f29a9515a25f83123dab4b83881ed193 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 00:06:16 +0200
    Subject: [PATCH 217/433] Fix pagination
    
    ---
     htdocs/accountancy/bookkeeping/balance.php | 33 +++++++++++++---------
     1 file changed, 19 insertions(+), 14 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php
    index bfd65ee1be7..21ae4759447 100644
    --- a/htdocs/accountancy/bookkeeping/balance.php
    +++ b/htdocs/accountancy/bookkeeping/balance.php
    @@ -104,23 +104,27 @@ if ($sortorder == "")
     if ($sortfield == "")
     	$sortfield = "t.numero_compte";
     
    -$options = '';
    +
    +$param='';
    +if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
    +if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit);
    +
     $filter = array ();
     if (! empty($search_date_start)) {
     	$filter['t.doc_date>='] = $search_date_start;
    -	$options .= '&amp;date_startmonth=' . GETPOST('date_startmonth', 'int') . '&amp;date_startday=' . GETPOST('date_startday', 'int') . '&amp;date_startyear=' . GETPOST('date_startyear', 'int');
    +	$param .= '&amp;date_startmonth=' . GETPOST('date_startmonth', 'int') . '&amp;date_startday=' . GETPOST('date_startday', 'int') . '&amp;date_startyear=' . GETPOST('date_startyear', 'int');
     }
     if (! empty($search_date_end)) {
     	$filter['t.doc_date<='] = $search_date_end;
    -	$options .= '&amp;date_endmonth=' . GETPOST('date_endmonth', 'int') . '&amp;date_endday=' . GETPOST('date_endday', 'int') . '&amp;date_endyear=' . GETPOST('date_endyear', 'int');
    +	$param .= '&amp;date_endmonth=' . GETPOST('date_endmonth', 'int') . '&amp;date_endday=' . GETPOST('date_endday', 'int') . '&amp;date_endyear=' . GETPOST('date_endyear', 'int');
     }
     if (! empty($search_accountancy_code_start)) {
     	$filter['t.numero_compte>='] = $search_accountancy_code_start;
    -	$options .= '&amp;search_accountancy_code_start=' . $search_accountancy_code_start;
    +	$param .= '&amp;search_accountancy_code_start=' . $search_accountancy_code_start;
     }
     if (! empty($search_accountancy_code_end)) {
     	$filter['t.numero_compte<='] = $search_accountancy_code_end;
    -	$options .= '&amp;search_accountancy_code_end=' . $search_accountancy_code_end;
    +	$param .= '&amp;search_accountancy_code_end=' . $search_accountancy_code_end;
     }
     
     
    @@ -137,8 +141,8 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
     	$filter = array();
     }
     
    -if ($action == 'export_csv') {
    -
    +if ($action == 'export_csv')
    +{
     	$sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
     
     	$filename = 'balance';
    @@ -200,7 +204,8 @@ if ($action != 'export_csv')
     	print '<input type="hidden" name="page" value="'.$page.'">';
     
     	$button = '<input type="submit" name="exportcsv" class="butAction" value="' . $langs->trans("Export") . ' ('.$conf->global->ACCOUNTING_EXPORT_FORMAT.')" />';
    -	print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $options, $sortfield, $sortorder, $button, $result, $result, 'title_accountancy', 0);
    +
    +	print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $button, $result, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
     
     	$moreforfilter = '';
     
    @@ -238,12 +243,12 @@ if ($action != 'export_csv')
     	print '</tr>';
     
     	print '<tr class="liste_titre">';
    -	print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Label", $_SERVER['PHP_SELF'], "t.label_operation", "", $options, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $options, 'align="right"', $sortfield, $sortorder);
    -	print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $options, 'align="right"', $sortfield, $sortorder);
    -	print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $options, "", 'align="right"', $sortfield, $sortorder);
    -	print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder);
    +	print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder);
    +	print_liste_field_titre("Label", $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder);
    +	print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'align="right"', $sortfield, $sortorder);
    +	print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'align="right"', $sortfield, $sortorder);
    +	print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'align="right"', $sortfield, $sortorder);
    +	print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder);
     	print "</tr>\n";
     
     	$total_debit = 0;
    
    From 35eeb32f5d87621819cd58dac2ba6815c1624584 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 00:08:28 +0200
    Subject: [PATCH 218/433] Fix pagination
    
    ---
     htdocs/accountancy/bookkeeping/balance.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php
    index 21ae4759447..fe797cc3e06 100644
    --- a/htdocs/accountancy/bookkeeping/balance.php
    +++ b/htdocs/accountancy/bookkeeping/balance.php
    @@ -274,7 +274,7 @@ if ($action != 'export_csv')
     		{
     			// Affiche un Sous-Total par compte comptable
     			if ($displayed_account != "") {
    -				print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit - $sous_total_debit) . '</td>';
    +				print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price(price2num($sous_total_credit - $sous_total_debit)) . '</td>';
     				print "<td>&nbsp;</td>\n";
     				print '</tr>';
     			}
    @@ -305,11 +305,11 @@ if ($action != 'export_csv')
     		$sous_total_credit += $line->credit;
     	}
     
    -	print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit - $sous_total_debit) . '</td>';
    +	print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("SubTotal") . ':</td><td class="nowrap" align="right">' . price($sous_total_debit) . '</td><td class="nowrap" align="right">' . price($sous_total_credit) . '</td><td class="nowrap" align="right">' . price(price2num($sous_total_credit - $sous_total_debit)) . '</td>';
     	print "<td>&nbsp;</td>\n";
     	print '</tr>';
     
    -	print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("AccountBalance") . ':</td><td class="nowrap" align="right">' . price($total_debit) . '</td><td class="nowrap" align="right">' . price($total_credit) . '</td><td class="nowrap" align="right">' . price($total_credit - $total_debit) . '</td>';
    +	print '<tr class="liste_total"><td align="right" colspan="2">' . $langs->trans("AccountBalance") . ':</td><td class="nowrap" align="right">' . price($total_debit) . '</td><td class="nowrap" align="right">' . price($total_credit) . '</td><td class="nowrap" align="right">' . price(price2num($total_credit - $total_debit)) . '</td>';
     	print "<td>&nbsp;</td>\n";
     	print '</tr>';
     
    
    From c881be847d6093c3770ef58046f0b67e15345357 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 01:47:44 +0200
    Subject: [PATCH 219/433] Fix remove step in accountancy if module expense
     report not used
    
    ---
     htdocs/accountancy/index.php | 9 ++++++---
     1 file changed, 6 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
    index ac674eb95e0..4dec253cb90 100644
    --- a/htdocs/accountancy/index.php
    +++ b/htdocs/accountancy/index.php
    @@ -146,9 +146,12 @@ if ($conf->accounting->enabled)
     	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsSuppliers"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("SuppliersVentilation").'</strong>')."\n";
     	print "<br>\n";
     
    -	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong>')."\n";
    -	print "<br>\n";
    +	if (! empty($conf->expensereport->enabled) || ! empty($conf->deplacement->enabled))
    +	{
    +		$step++;
    +		print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong>')."\n";
    +		print "<br>\n";
    +	}
     
     	$step++;
     	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescWriteRecords", chr(64+$step), $langs->transnoentitiesnoconv("Journalization"), $langs->transnoentitiesnoconv("WriteBookKeeping"))."\n";
    
    From 0a8f3051510d36cdd53ec7b0d1e2197655e1431a Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 02:40:49 +0200
    Subject: [PATCH 220/433] Trans
    
    ---
     htdocs/langs/en_US/admin.lang | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index 6b18dab5848..4630757dbad 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -229,7 +229,7 @@ DoNotStoreClearPassword=Do no store clear passwords in database but store only e
     MainDbPasswordFileConfEncrypted=Database password encrypted in conf.php (Activated recommended)
     InstrucToEncodePass=To have password encoded into the <b>conf.php</b> file, replace the line <br><b>$dolibarr_main_db_pass="...";</b><br>by<br><b>$dolibarr_main_db_pass="crypted:%s";</b>
     InstrucToClearPass=To have password decoded (clear) into the <b>conf.php</b> file, replace the line <br><b>$dolibarr_main_db_pass="crypted:...";</b><br>by<br><b>$dolibarr_main_db_pass="%s";</b>
    -ProtectAndEncryptPdfFiles=Protection of generated PDF files NOT recommended, breaks mass PDF generation)
    +ProtectAndEncryptPdfFiles=Protection of generated PDF files NOT recommended (breaks mass PDF generation)
     ProtectAndEncryptPdfFilesDesc=Protection of a PDF document keeps it available to read and print with any PDF browser. However, editing and copying is not possible anymore. Note that using this feature makes building of a global merged PDFs not working.
     Feature=Feature
     DolibarrLicense=License
    
    From c6163a389b8f8e27b1294017d325bba6a050fe05 Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Mon, 15 Oct 2018 06:22:28 +0200
    Subject: [PATCH 221/433] Revert "Remove MAIN_FEATURES_LEVEL > 1 on fiscal year
     access"
    
    This reverts commit 65e6b49abb30c14ceb868249fe9dde0443b52e54.
    ---
     htdocs/core/menus/standard/eldy.lib.php | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php
    index 303e2813245..51a9907a16e 100644
    --- a/htdocs/core/menus/standard/eldy.lib.php
    +++ b/htdocs/core/menus/standard/eldy.lib.php
    @@ -1019,7 +1019,10 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/export.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("ExportOptions"),2, $user->rights->accounting->chartofaccount, '', $mainmenu, 'accountancy_admin_export', 60);
     
     				// Fiscal year
    -				if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("FiscalPeriod"), 2, $user->rights->accounting->fiscalyear, '', $mainmenu, 'fiscalyear');
    +				if ($conf->global->MAIN_FEATURES_LEVEL > 1)     // Not yet used. In a future will lock some periods.
    +				{
    +					if ($usemenuhider || empty($leftmenu) || preg_match('/accountancy_admin/',$leftmenu)) $newmenu->add("/accountancy/admin/fiscalyear.php?mainmenu=accountancy&leftmenu=accountancy_admin", $langs->trans("FiscalPeriod"), 2, $user->rights->accounting->fiscalyear, '', $mainmenu, 'fiscalyear');
    +				}
     
     				// Binding
     				if (! empty($conf->facture->enabled))
    
    From c8b9c11a011c82f01afc1ed848a3667bcfb5aaf4 Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Mon, 15 Oct 2018 06:53:48 +0200
    Subject: [PATCH 222/433] Fix FEC Missing some subledger label on bookeeping
    
    ---
     .../journal/expensereportsjournal.php         | 16 +++++++--------
     .../accountancy/journal/purchasesjournal.php  |  2 +-
     htdocs/accountancy/journal/sellsjournal.php   | 20 +++++++++----------
     3 files changed, 19 insertions(+), 19 deletions(-)
    
    diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php
    index ef21557932b..520fd004f16 100644
    --- a/htdocs/accountancy/journal/expensereportsjournal.php
    +++ b/htdocs/accountancy/journal/expensereportsjournal.php
    @@ -1,11 +1,11 @@
     <?php
    -/* Copyright (C) 2007-2010  Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010  Jean Heimburger		<jean@tiaris.info>
    - * Copyright (C) 2011       Juanjo Menent		<jmenent@2byte.es>
    - * Copyright (C) 2012       Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2013-2017  Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2013-2016  Olivier Geffroy		<jeff@jeffinfo.com>
    - * Copyright (C) 2013-2016  Florian Henry		<florian.henry@open-concept.pro>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013-2017  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2013-2016  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2016  Florian Henry           <florian.henry@open-concept.pro>
      * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -208,7 +208,7 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->fk_doc = $key;
     					$bookkeeping->fk_docdet = $val["fk_expensereportdet"];
     					$bookkeeping->subledger_account = $tabuser[$key]['user_accountancy_code'];
    -					$bookkeeping->subledger_label = $tabuser[$key]['user_accountancy_code'];
    +					$bookkeeping->subledger_label = $tabuser[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
     					$bookkeeping->label_operation = $tabuser[$key]['name'];
     					$bookkeeping->montant = $mt;
    diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php
    index d8be52cef90..71bdb6a5bd4 100644
    --- a/htdocs/accountancy/journal/purchasesjournal.php
    +++ b/htdocs/accountancy/journal/purchasesjournal.php
    @@ -310,7 +310,7 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->fk_docdet = 0;    // Useless, can be several lines that are source of this record to add
     					$bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
     					$bookkeeping->subledger_account = $tabcompany[$key]['code_compta_fournisseur'];
    -					$bookkeeping->subledger_label = '';    // TODO To complete
    +					$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
     					$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("SubledgerAccount");
     					$bookkeeping->montant = $mt;
    diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php
    index b3b354be02d..dcfd11ac67a 100644
    --- a/htdocs/accountancy/journal/sellsjournal.php
    +++ b/htdocs/accountancy/journal/sellsjournal.php
    @@ -1,13 +1,13 @@
     <?php
    -/* Copyright (C) 2007-2010  Laurent Destailleur		<eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010  Jean Heimburger			<jean@tiaris.info>
    - * Copyright (C) 2011       Juanjo Menent			<jmenent@2byte.es>
    - * Copyright (C) 2012       Regis Houssin			<regis.houssin@capnetworks.com>
    - * Copyright (C) 2013       Christophe Battarel		<christophe.battarel@altairis.fr>
    - * Copyright (C) 2013-2017  Alexandre Spangaro		<aspangaro@zendsi.com>
    - * Copyright (C) 2013-2016  Florian Henry			<florian.henry@open-concept.pro>
    - * Copyright (C) 2013-2016  Olivier Geffroy			<jeff@jeffinfo.com>
    - * Copyright (C) 2014       Raphaël Doursenaud		<rdoursenaud@gpcsolutions.fr>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013       Christophe Battarel     <christophe.battarel@altairis.fr>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2013-2016  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2016  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2014       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -317,7 +317,7 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->fk_docdet = 0;	// Useless, can be several lines that are source of this record to add
     					$bookkeeping->thirdparty_code = $companystatic->code_client;
     					$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
    -					$bookkeeping->subledger_label = '';    // TODO To complete
    +					$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
     					$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("SubledgerAccount");
     					$bookkeeping->montant = $mt;
    
    From 4d6d3afbea46a3873f37fd0972888c2a7c0f7cf5 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 15 Oct 2018 08:39:46 +0200
    Subject: [PATCH 223/433] code comment
    
    ---
     htdocs/accountancy/class/accountancycategory.class.php | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/accountancy/class/accountancycategory.class.php b/htdocs/accountancy/class/accountancycategory.class.php
    index a7bab16b30d..db148cbac67 100644
    --- a/htdocs/accountancy/class/accountancycategory.class.php
    +++ b/htdocs/accountancy/class/accountancycategory.class.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (C) 2016		Jamal Elbaz			<jamelbaz@gmail.pro>
      * Copyright (C) 2016-2017	Alexandre Spangaro	<aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -539,9 +540,9 @@ class AccountancyCategory
     	/**
     	 * get cpts of category
     	 *
    -	 * @param int $cat_id Id accounting account category
    +	 * @param int $cat_id   Id accounting account category
     	 *
    -	 * @return array       Result in table
    +	 * @return array|int    Result in table or -1 if error
     	 */
     	public function getCptsCat($cat_id) {
     		global $mysoc;
    
    From 425e26ecb6661f6bc1472db385c06690f8511e47 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 15 Oct 2018 08:46:41 +0200
    Subject: [PATCH 224/433] Update bookkeeping.class.php
    
    ---
     htdocs/accountancy/class/bookkeeping.class.php | 16 ++++++++--------
     1 file changed, 8 insertions(+), 8 deletions(-)
    
    diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
    index b228588b90f..87d561b6add 100644
    --- a/htdocs/accountancy/class/bookkeeping.class.php
    +++ b/htdocs/accountancy/class/bookkeeping.class.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2014-2017 Olivier Geffroy		<jeff@jeffinfo.com>
    - * Copyright (C) 2015-2017 Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2015-2017 Florian Henry		<florian.henry@open-concept.pro>
    +/* Copyright (C) 2014-2017  Olivier Geffroy		<jeff@jeffinfo.com>
    + * Copyright (C) 2015-2017  Alexandre Spangaro	<aspangaro@zendsi.com>
    + * Copyright (C) 2015-2017  Florian Henry		<florian.henry@open-concept.pro>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -1640,9 +1641,9 @@ class BookKeeping extends CommonObject
     	/**
     	 * Transform transaction
     	 *
    -	 * @param  number   $direction     If 0 tmp => real, if 1 real => tmp
    -	 * @param  string   $piece_num     Piece num
    -	 * @return void
    +	 * @param  number   $direction      If 0 tmp => real, if 1 real => tmp
    +	 * @param  string   $piece_num      Piece num
    +	 * @return int                      int <0 if KO, >0 if OK
     	 */
     	public function transformTransaction($direction=0,$piece_num='')
     	{
    @@ -1678,8 +1679,7 @@ class BookKeeping extends CommonObject
     				$this->errors[] = 'Error ' . $this->db->lasterror();
     				dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
     			}
    -		}
    -		if ($direction==1) {
    +		} elseif ($direction==1) {
     			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element.'_tmp WHERE piece_num = '.$piece_num;
     			$resql = $this->db->query($sql);
     			if (! $resql) {
    
    From 5e7a330f163a165e35e8ebf5a63528cae29807f6 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 15 Oct 2018 08:53:47 +0200
    Subject: [PATCH 225/433] Update adherent.class.php
    
    ---
     htdocs/adherents/class/adherent.class.php | 23 ++++++++++++++++++++++-
     1 file changed, 22 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php
    index 888e3043de1..317d7697231 100644
    --- a/htdocs/adherents/class/adherent.class.php
    +++ b/htdocs/adherents/class/adherent.class.php
    @@ -7,7 +7,7 @@
      * Copyright (C) 2009-2017	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2014-2016	Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
      * Copyright (C) 2015		Marcos García			<marcosgdf@gmail.com>
    - * Copyright (C) 2015		Frederic France			<frederic.france@free.fr>
    + * Copyright (C) 2015-2018  Frédéric France			<frederic.france@netlogic.fr>
      * Copyright (C) 2015		Raphaël Doursenaud		<rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2016		Juanjo Menent			<jmenent@2byte.es>
      *
    @@ -93,10 +93,31 @@ class Adherent extends CommonObject
     	public $twitter;
     	public $facebook;
     
    +    /**
    +     * @var string Phone number
    +     */
     	public $phone;
    +
    +    /**
    +     * @var string Private Phone number
    +     */
     	public $phone_perso;
    +
    +    /**
    +     * @var string Mobile phone number
    +     */
     	public $phone_mobile;
     
    +    /**
    +     * @var string Fax number
    +     */
    +    public $fax;
    +
    +    /**
    +     * @var string Function
    +     */
    +    public $poste;
    +
     	public $morphy;
     	public $public;
     	public $statut;			// -1:brouillon, 0:resilie, >=1:valide,paye
    
    From 30072a98e96e2fc82244052ee97b303de50ca1ee Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 11:04:29 +0200
    Subject: [PATCH 226/433] FIX content lost when editing a label with "
    
    ---
     htdocs/projet/card.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php
    index dd18a115ab6..e2632fe244e 100644
    --- a/htdocs/projet/card.php
    +++ b/htdocs/projet/card.php
    @@ -765,7 +765,7 @@ elseif ($object->id > 0)
     
     		// Label
     		print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>';
    -		print '<td><input class="quatrevingtpercent" name="title" value="'.$object->title.'"></td></tr>';
    +		print '<td><input class="quatrevingtpercent" name="title" value="'.dol_escape_htmltag($object->title).'"></td></tr>';
     
     		// Status
     		print '<tr><td class="fieldrequired">'.$langs->trans("Status").'</td><td>';
    
    From 47d98ab69d504e6259036b6850438a7a62167301 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 11:04:29 +0200
    Subject: [PATCH 227/433] FIX content lost when editing a label with "
    
    ---
     htdocs/projet/card.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php
    index 449242f0594..b92df257dd7 100644
    --- a/htdocs/projet/card.php
    +++ b/htdocs/projet/card.php
    @@ -754,7 +754,7 @@ elseif ($object->id > 0)
     
     		// Label
     		print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>';
    -		print '<td><input class="quatrevingtpercent" name="title" value="'.$object->title.'"></td></tr>';
    +		print '<td><input class="quatrevingtpercent" name="title" value="'.dol_escape_htmltag($object->title).'"></td></tr>';
     
     		// Status
     		print '<tr><td class="fieldrequired">'.$langs->trans("Status").'</td><td>';
    
    From 9afc53ca06f366069ad9a057c878025dff6be208 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 01:47:44 +0200
    Subject: [PATCH 228/433] Fix remove step in accountancy if module expense
     report not used
    
    ---
     htdocs/accountancy/index.php | 9 ++++++---
     1 file changed, 6 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
    index 2881de98132..9a3767bd8e4 100644
    --- a/htdocs/accountancy/index.php
    +++ b/htdocs/accountancy/index.php
    @@ -146,9 +146,12 @@ if ($conf->accounting->enabled)
     	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsSuppliers"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("SuppliersVentilation").'</strong>')."\n";
     	print "<br>\n";
     
    -	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong>')."\n";
    -	print "<br>\n";
    +	if (! empty($conf->expensereport->enabled) || ! empty($conf->deplacement->enabled))
    +	{
    +		$step++;
    +		print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong>')."\n";
    +		print "<br>\n";
    +	}
     
     	$step++;
     	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescWriteRecords", chr(64+$step), $langs->transnoentitiesnoconv("Journalization"), $langs->transnoentitiesnoconv("WriteBookKeeping"))."\n";
    
    From aa6996e2d08ffff028304487b7a1c048b70ac24e Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 23:47:38 +0200
    Subject: [PATCH 229/433] Fix pagination show two times the same account on
     balance of accounts
    
    ---
     htdocs/accountancy/bookkeeping/balance.php    | 23 ++++++++++++-------
     .../accountancy/class/bookkeeping.class.php   |  9 ++++++--
     2 files changed, 22 insertions(+), 10 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php
    index 284ead4fb56..4022b9a9407 100644
    --- a/htdocs/accountancy/bookkeeping/balance.php
    +++ b/htdocs/accountancy/bookkeeping/balance.php
    @@ -41,6 +41,21 @@ $page = GETPOST("page");
     $sortorder = GETPOST("sortorder", 'alpha');
     $sortfield = GETPOST("sortfield", 'alpha');
     $action = GETPOST('action', 'alpha');
    +if (GETPOST("exportcsv",'alpha')) $action = 'export_csv';
    +
    +// Load variable for pagination
    +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
    +$sortfield = GETPOST('sortfield','alpha');
    +$sortorder = GETPOST('sortorder','alpha');
    +$page = GETPOST('page','int');
    +if (empty($page) || $page == -1 || GETPOST('button_search','alpha') || GETPOST('button_removefilter','alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; }     // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action
    +$offset = $limit * $page;
    +$pageprev = $page - 1;
    +$pagenext = $page + 1;
    +//if (! $sortfield) $sortfield="p.date_fin";
    +//if (! $sortorder) $sortorder="DESC";
    +
    +
     $search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
     $search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
     
    @@ -53,14 +68,6 @@ if ($search_accountancy_code_end == - 1) {
     	$search_accountancy_code_end = '';
     }
     
    -if (GETPOST("exportcsv",'alpha')) $action = 'export_csv';
    -
    -
    -$limit = GETPOST('limit','int')?GETPOST('limit', 'int'):$conf->liste_limit;
    -if (empty($page) || $page < 0) { $page = 0; }
    -
    -$offset = $limit * $page;
    -
     $object = new BookKeeping($db);
     
     $formaccounting = new FormAccounting($db);
    diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
    index f7fed2e2b5b..4a2037aa92c 100644
    --- a/htdocs/accountancy/class/bookkeeping.class.php
    +++ b/htdocs/accountancy/class/bookkeeping.class.php
    @@ -986,16 +986,21 @@ class BookKeeping extends CommonObject
     		}
     
     		$resql = $this->db->query($sql);
    -		if ($resql) {
    +		if ($resql)
    +		{
     			$num = $this->db->num_rows($resql);
     
    -			while ( $obj = $this->db->fetch_object($resql) ) {
    +			$i = 0;
    +			while ($obj = $this->db->fetch_object($resql) && $i < $num)
    +			{
     				$line = new BookKeepingLine();
     
     				$line->numero_compte = $obj->numero_compte;
     				$line->debit = $obj->debit;
     				$line->credit = $obj->credit;
     				$this->lines[] = $line;
    +
    +				$i++;
     			}
     			$this->db->free($resql);
     
    
    From e29fb85cec94ae39cfa775df23af8c652ba810bb Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 14 Oct 2018 23:57:07 +0200
    Subject: [PATCH 230/433] Fix limit
    
    ---
     htdocs/accountancy/class/bookkeeping.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
    index 4a2037aa92c..e751cf1899f 100644
    --- a/htdocs/accountancy/class/bookkeeping.class.php
    +++ b/htdocs/accountancy/class/bookkeeping.class.php
    @@ -991,7 +991,7 @@ class BookKeeping extends CommonObject
     			$num = $this->db->num_rows($resql);
     
     			$i = 0;
    -			while ($obj = $this->db->fetch_object($resql) && $i < $num)
    +			while (($obj = $this->db->fetch_object($resql)) && ($i < min($limit, $num)))
     			{
     				$line = new BookKeepingLine();
     
    
    From 2684767b19f6b715953ee9fab63251d343222f44 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 00:06:16 +0200
    Subject: [PATCH 231/433] Fix pagination
    
    Conflicts:
    	htdocs/accountancy/bookkeeping/balance.php
    ---
     htdocs/accountancy/bookkeeping/balance.php | 33 +++++++++++++---------
     1 file changed, 19 insertions(+), 14 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php
    index 4022b9a9407..fa1f4b396d5 100644
    --- a/htdocs/accountancy/bookkeeping/balance.php
    +++ b/htdocs/accountancy/bookkeeping/balance.php
    @@ -103,23 +103,27 @@ if ($sortorder == "")
     if ($sortfield == "")
     	$sortfield = "t.numero_compte";
     
    -$options = '';
    +
    +$param='';
    +if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage);
    +if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit);
    +
     $filter = array ();
     if (! empty($search_date_start)) {
     	$filter['t.doc_date>='] = $search_date_start;
    -	$options .= '&amp;date_startmonth=' . GETPOST('date_startmonth', 'int') . '&amp;date_startday=' . GETPOST('date_startday', 'int') . '&amp;date_startyear=' . GETPOST('date_startyear', 'int');
    +	$param .= '&amp;date_startmonth=' . GETPOST('date_startmonth', 'int') . '&amp;date_startday=' . GETPOST('date_startday', 'int') . '&amp;date_startyear=' . GETPOST('date_startyear', 'int');
     }
     if (! empty($search_date_end)) {
     	$filter['t.doc_date<='] = $search_date_end;
    -	$options .= '&amp;date_endmonth=' . GETPOST('date_endmonth', 'int') . '&amp;date_endday=' . GETPOST('date_endday', 'int') . '&amp;date_endyear=' . GETPOST('date_endyear', 'int');
    +	$param .= '&amp;date_endmonth=' . GETPOST('date_endmonth', 'int') . '&amp;date_endday=' . GETPOST('date_endday', 'int') . '&amp;date_endyear=' . GETPOST('date_endyear', 'int');
     }
     if (! empty($search_accountancy_code_start)) {
     	$filter['t.numero_compte>='] = $search_accountancy_code_start;
    -	$options .= '&amp;search_accountancy_code_start=' . $search_accountancy_code_start;
    +	$param .= '&amp;search_accountancy_code_start=' . $search_accountancy_code_start;
     }
     if (! empty($search_accountancy_code_end)) {
     	$filter['t.numero_compte<='] = $search_accountancy_code_end;
    -	$options .= '&amp;search_accountancy_code_end=' . $search_accountancy_code_end;
    +	$param .= '&amp;search_accountancy_code_end=' . $search_accountancy_code_end;
     }
     
     
    @@ -141,8 +145,8 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
      * View
      */
     
    -if ($action == 'export_csv') {
    -
    +if ($action == 'export_csv')
    +{
     	$sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
     
     	$filename = 'balance';
    @@ -194,7 +198,8 @@ else {
     	print '<input type="hidden" name="page" value="'.$page.'">';
     
     	$button = '<input type="submit" name="exportcsv" class="butAction" value="' . $langs->trans("Export") . ' ('.$conf->global->ACCOUNTING_EXPORT_FORMAT.')" />';
    -	print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $options, $sortfield, $sortorder, $button, $result, $result, 'title_accountancy', 0);
    +
    +	print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $button, $result, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
     
     	$moreforfilter = '';
     
    @@ -232,12 +237,12 @@ else {
     	print '</tr>';
     
     	print '<tr class="liste_titre">';
    -	print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $options, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Label", $_SERVER['PHP_SELF'], "t.label_operation", "", $options, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $options, 'align="right"', $sortfield, $sortorder);
    -	print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $options, 'align="right"', $sortfield, $sortorder);
    -	print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $options, "", 'align="right"', $sortfield, $sortorder);
    -	print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $options, "", 'width="60" align="center"', $sortfield, $sortorder);
    +	print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder);
    +	print_liste_field_titre("Label", $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder);
    +	print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'align="right"', $sortfield, $sortorder);
    +	print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'align="right"', $sortfield, $sortorder);
    +	print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'align="right"', $sortfield, $sortorder);
    +	print_liste_field_titre('', $_SERVER["PHP_SELF"], "", $param, "", 'width="60" align="center"', $sortfield, $sortorder);
     	print "</tr>\n";
     
     	$total_debit = 0;
    
    From c2814948fbf51f9095956eff7bb584bb5b346127 Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Mon, 15 Oct 2018 11:48:55 +0200
    Subject: [PATCH 232/433] Fix: name of fields used into the search criteria
     must always start with "search_"
    
    ---
     htdocs/product/list.php | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/product/list.php b/htdocs/product/list.php
    index 9028ceb15c2..36bf5a24ef9 100644
    --- a/htdocs/product/list.php
    +++ b/htdocs/product/list.php
    @@ -68,7 +68,7 @@ $type=GETPOST("type","int");
     
     //Show/hide child products
     if (!empty($conf->variants->enabled) && ! empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
    -	$show_childproducts = GETPOST('show_childproducts');
    +	$show_childproducts = GETPOST('search_show_childproducts');
     } else {
     	$show_childproducts = '';
     }
    @@ -404,7 +404,7 @@ if ($resql)
     	if ($search_tobuy != '') $param.="&search_tobuy=".urlencode($search_tobuy);
     	if ($fourn_id > 0) $param.=($fourn_id?"&fourn_id=".$fourn_id:"");
     	if ($seach_categ) $param.=($search_categ?"&search_categ=".urlencode($search_categ):"");
    -	if ($show_childproducts) $param.=($show_childproducts?"&show_childproducts=".urlencode($show_childproducts):"");
    +	if ($show_childproducts) $param.=($show_childproducts?"&search_show_childproducts=".urlencode($show_childproducts):"");
     	if ($type != '') $param.='&type='.urlencode($type);
     	if ($search_type != '') $param.='&search_type='.urlencode($search_type);
     	if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss);
    @@ -482,8 +482,8 @@ if ($resql)
     	//Show/hide child products. Hidden by default
     	if (!empty($conf->variants->enabled) && !empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD )) {
     		$moreforfilter.='<div class="divsearchfield">';
    -		$moreforfilter.= '<input type="checkbox" id="show_childproducts" name="show_childproducts"'.($show_childproducts ? 'checked="checked"':'').'>';
    -		$moreforfilter.= ' <label for="show_childproducts">'.$langs->trans('ShowChildProducts').'</label>';
    +		$moreforfilter.= '<input type="checkbox" id="search_show_childproducts" name="search_show_childproducts"'.($show_childproducts ? 'checked="checked"':'').'>';
    +		$moreforfilter.= ' <label for="search_show_childproducts">'.$langs->trans('ShowChildProducts').'</label>';
     		$moreforfilter.='</div>';
     	}
     
    
    From 06477b40a093f57a3e41d180f97604a7e4bb1b9e Mon Sep 17 00:00:00 2001
    From: atm-greg <gregory.blemand@atm-consulting.fr>
    Date: Mon, 15 Oct 2018 12:34:14 +0200
    Subject: [PATCH 233/433] modify parenting before task deletion
    
    ---
     htdocs/core/actions_massactions.inc.php | 11 +++++++++++
     1 file changed, 11 insertions(+)
    
    diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
    index 32d80bef672..b7bbc402b09 100644
    --- a/htdocs/core/actions_massactions.inc.php
    +++ b/htdocs/core/actions_massactions.inc.php
    @@ -598,6 +598,17 @@ if (! $error && $massaction == 'delete' && $permtodelete)
             $result=$objecttmp->fetch($toselectid);
             if ($result > 0)
             {
    +            if ($objectclass == "Task" && $objecttmp->hasChildren() > 0) {
    +                $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task SET fk_task_parent = 0 WHERE fk_task_parent = ".$objecttmp->id;
    +                $res = $db->query($sql);
    +                
    +                if (!$res)
    +                {
    +                    setEventMessage('ErrorRecordParentingNotModified', 'errors');
    +                    $error++;
    +                }
    +            }
    +            
                 if (in_array($objecttmp->element, array('societe','member'))) $result = $objecttmp->delete($objecttmp->id, $user, 1);
                 else $result = $objecttmp->delete($user);
                 if ($result <= 0)
    
    From 58cc9aa918435603a8c68cab0f813ed2aeaed8e4 Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Mon, 15 Oct 2018 12:45:40 +0200
    Subject: [PATCH 234/433] Fix: found 1 blank lines before brace
    
    ---
     htdocs/product/class/product.class.php | 19 +++++++++----------
     1 file changed, 9 insertions(+), 10 deletions(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 5d4cbd8e0bf..442ae55ac3a 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -4156,16 +4156,15 @@ class Product extends CommonObject
                 $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur;
             }
     
    -	if (! is_object($hookmanager)) {
    -	    include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
    -	    $hookmanager=new HookManager($this->db);
    -	}
    -	$hookmanager->initHooks(array('productdao'));
    -	$parameters=array('id'=>$this->id);
    -	// Note that $action and $object may have been modified by some hooks
    -	$reshook=$hookmanager->executeHooks('loadvirtualstock', $parameters, $this, $action);
    -	if ($reshook > 0) $this->stock_theorique = $hookmanager->resArray['stock_theorique'];
    -
    +		if (! is_object($hookmanager)) {
    +			include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
    +			$hookmanager=new HookManager($this->db);
    +		}
    +		$hookmanager->initHooks(array('productdao'));
    +		$parameters=array('id'=>$this->id);
    +		// Note that $action and $object may have been modified by some hooks
    +		$reshook=$hookmanager->executeHooks('loadvirtualstock', $parameters, $this, $action);
    +		if ($reshook > 0) $this->stock_theorique = $hookmanager->resArray['stock_theorique'];
         }
     
     
    
    From f59dba66e7b571b974fa58ac2dbb4131e4afbca3 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 13:23:35 +0200
    Subject: [PATCH 235/433] Fix phpcs
    
    ---
     htdocs/product/class/product.class.php | 92 +++++++++++++-------------
     1 file changed, 46 insertions(+), 46 deletions(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 5bf2f45d31c..5326fadd556 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -4750,51 +4750,51 @@ class Product extends CommonObject
     		}
     	}
     
    -    /**
    -     *  Load information for tab info
    -     *
    -     *  @param  int		$id     Id of thirdparty to load
    -     *  @return	void
    -     */
    -    function info($id)
    -    {
    -        $sql = "SELECT p.rowid, p.ref, p.datec as date_creation, p.tms as date_modification,";
    -        $sql.= " p.fk_user_author, p.fk_user_modif";
    -        $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as p";
    -        $sql.= " WHERE p.rowid = ".$id;
    +	/**
    +	 *  Load information for tab info
    +	 *
    +	 *  @param  int		$id     Id of thirdparty to load
    +	 *  @return	void
    +	 */
    +	function info($id)
    +	{
    +		$sql = "SELECT p.rowid, p.ref, p.datec as date_creation, p.tms as date_modification,";
    +		$sql.= " p.fk_user_author, p.fk_user_modif";
    +		$sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as p";
    +		$sql.= " WHERE p.rowid = ".$id;
     
    -        $result=$this->db->query($sql);
    -        if ($result)
    -        {
    -            if ($this->db->num_rows($result))
    -            {
    -                $obj = $this->db->fetch_object($result);
    -
    -                $this->id = $obj->rowid;
    -
    -                if ($obj->fk_user_author) {
    -                    $cuser = new User($this->db);
    -                    $cuser->fetch($obj->fk_user_author);
    -                    $this->user_creation     = $cuser;
    -                }
    -
    -                if ($obj->fk_user_modif) {
    -                    $muser = new User($this->db);
    -                    $muser->fetch($obj->fk_user_modif);
    -                    $this->user_modification = $muser;
    -                }
    -
    -                $this->ref			     = $obj->ref;
    -                $this->date_creation     = $this->db->jdate($obj->date_creation);
    -                $this->date_modification = $this->db->jdate($obj->date_modification);
    -            }
    -
    -            $this->db->free($result);
    -
    -        }
    -        else
    +		$result=$this->db->query($sql);
    +		if ($result)
     		{
    -            dol_print_error($this->db);
    -        }
    -    }
    -}
    +			if ($this->db->num_rows($result))
    +			{
    +				$obj = $this->db->fetch_object($result);
    +
    +				$this->id = $obj->rowid;
    +
    +				if ($obj->fk_user_author) {
    +					$cuser = new User($this->db);
    +					$cuser->fetch($obj->fk_user_author);
    +					$this->user_creation     = $cuser;
    +				}
    +
    +				if ($obj->fk_user_modif) {
    +					$muser = new User($this->db);
    +					$muser->fetch($obj->fk_user_modif);
    +					$this->user_modification = $muser;
    +				}
    +
    +				$this->ref			     = $obj->ref;
    +				$this->date_creation     = $this->db->jdate($obj->date_creation);
    +				$this->date_modification = $this->db->jdate($obj->date_modification);
    +			}
    +
    +			$this->db->free($result);
    +
    +		}
    +		else
    +		{
    +			dol_print_error($this->db);
    +		}
    +	}
    +}
    \ No newline at end of file
    
    From 6ab037c766c7c7a6e9b0e05c5385103bf8b2644f Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 13:26:18 +0200
    Subject: [PATCH 236/433] Fix code comment
    
    ---
     htdocs/product/class/product.class.php | 127 +++++++++++++------------
     1 file changed, 64 insertions(+), 63 deletions(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 5326fadd556..db367301120 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -4005,7 +4005,7 @@ class Product extends CommonObject
     	 *										'warehouseclosed' = Load stock from closed warehouses only,
     	 *										'warehouseinternal' = Load stock from warehouses for internal correction/transfer only
     	 *    @return     int                   < 0 if KO, > 0 if OK
    -	 *    @see		  load_virtual_stock, getBatchInfo
    +	 *    @see		  load_virtual_stock(), loadBatchInfo()
     	 */
     	function load_stock($option='')
     	{
    @@ -4074,79 +4074,80 @@ class Product extends CommonObject
     		}
     	}
     
    -    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
     	 *    Load value ->stock_theorique of a product. Property this->id must be defined.
     	 *    This function need a lot of load. If you use it on list, use a cache to execute it one for each product id.
     	 *
     	 *    @return   int             < 0 if KO, > 0 if OK
    -	 *    @see		load_stock, getBatchInfo
    +	 *    @see		load_stock(), loadBatchInfo()
     	 */
    -    function load_virtual_stock()
    -    {
    -        // phpcs:enable
    -        global $conf, $hookmanager, $action;
    +	function load_virtual_stock()
    +	{
    +		// phpcs:enable
    +		global $conf, $hookmanager, $action;
     
    -        $stock_commande_client=0;
    -        $stock_commande_fournisseur=0;
    -        $stock_sending_client=0;
    -        $stock_reception_fournisseur=0;
    +		$stock_commande_client=0;
    +		$stock_commande_fournisseur=0;
    +		$stock_sending_client=0;
    +		$stock_reception_fournisseur=0;
     
    -        if (! empty($conf->commande->enabled))
    -        {
    -            $result=$this->load_stats_commande(0,'1,2', 1);
    -            if ($result < 0) dol_print_error($this->db,$this->error);
    -            $stock_commande_client=$this->stats_commande['qty'];
    -        }
    -        if (! empty($conf->expedition->enabled))
    -        {
    -            $result=$this->load_stats_sending(0,'1,2', 1);
    -            if ($result < 0) dol_print_error($this->db,$this->error);
    -            $stock_sending_client=$this->stats_expedition['qty'];
    -        }
    -        if (! empty($conf->fournisseur->enabled))
    -        {
    -            $result=$this->load_stats_commande_fournisseur(0,'1,2,3,4', 1);
    -            if ($result < 0) dol_print_error($this->db,$this->error);
    -            $stock_commande_fournisseur=$this->stats_commande_fournisseur['qty'];
    +		if (! empty($conf->commande->enabled))
    +		{
    +			$result=$this->load_stats_commande(0,'1,2', 1);
    +			if ($result < 0) dol_print_error($this->db,$this->error);
    +			$stock_commande_client=$this->stats_commande['qty'];
    +		}
    +		if (! empty($conf->expedition->enabled))
    +		{
    +			$result=$this->load_stats_sending(0,'1,2', 1);
    +			if ($result < 0) dol_print_error($this->db,$this->error);
    +			$stock_sending_client=$this->stats_expedition['qty'];
    +		}
    +		if (! empty($conf->fournisseur->enabled))
    +		{
    +			$result=$this->load_stats_commande_fournisseur(0,'1,2,3,4', 1);
    +			if ($result < 0) dol_print_error($this->db,$this->error);
    +			$stock_commande_fournisseur=$this->stats_commande_fournisseur['qty'];
     
    -            $result=$this->load_stats_reception(0,'4', 1);
    -            if ($result < 0) dol_print_error($this->db,$this->error);
    -            $stock_reception_fournisseur=$this->stats_reception['qty'];
    -        }
    +			$result=$this->load_stats_reception(0,'4', 1);
    +			if ($result < 0) dol_print_error($this->db,$this->error);
    +			$stock_reception_fournisseur=$this->stats_reception['qty'];
    +		}
     
    -        // Stock decrease mode
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) {
    -            $this->stock_theorique=$this->stock_reel-$stock_commande_client+$stock_sending_client;
    -        }
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)) {
    -            $this->stock_theorique=$this->stock_reel;
    -        }
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
    -            $this->stock_theorique=$this->stock_reel-$stock_commande_client;
    -        }
    -        // Stock Increase mode
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) {
    -            $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur;
    -        }
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)) {
    -            $this->stock_theorique-=$stock_reception_fournisseur;
    -        }
    -        if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)) {
    -            $this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur;
    -        }
    +		// Stock decrease mode
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) {
    +			$this->stock_theorique=$this->stock_reel-$stock_commande_client+$stock_sending_client;
    +		}
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER)) {
    +			$this->stock_theorique=$this->stock_reel;
    +		}
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_BILL)) {
    +			$this->stock_theorique=$this->stock_reel-$stock_commande_client;
    +		}
    +		// Stock Increase mode
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) {
    +			$this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur;
    +		}
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER)) {
    +			$this->stock_theorique-=$stock_reception_fournisseur;
    +		}
    +		if (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL)) {
    +			$this->stock_theorique+=$stock_commande_fournisseur-$stock_reception_fournisseur;
    +		}
     
    -	if (! is_object($hookmanager)) {
    -	    include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
    -	    $hookmanager=new HookManager($this->db);
    +		if (! is_object($hookmanager)) {
    +			include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
    +			$hookmanager=new HookManager($this->db);
    +		}
    +		$hookmanager->initHooks(array('productdao'));
    +		$parameters=array('id'=>$this->id);
    +		// Note that $action and $object may have been modified by some hooks
    +		$reshook=$hookmanager->executeHooks('loadvirtualstock', $parameters, $this, $action);
    +		if ($reshook > 0) $this->stock_theorique = $hookmanager->resArray['stock_theorique'];
    +
    +		return 1;
     	}
    -	$hookmanager->initHooks(array('productdao'));
    -	$parameters=array('id'=>$this->id);
    -	// Note that $action and $object may have been modified by some hooks
    -	$reshook=$hookmanager->executeHooks('loadvirtualstock', $parameters, $this, $action);
    -	if ($reshook > 0) $this->stock_theorique = $hookmanager->resArray['stock_theorique'];
    -
    -    }
     
     
     	/**
    @@ -4154,7 +4155,7 @@ class Product extends CommonObject
     	 *
     	 *	@param		string		$batch		Lot/serial number
     	 *  @return     array					Array with record into product_batch
    -	 *  @see		load_stock, load_virtual_stock
    +	 *  @see		load_stock(), load_virtual_stock()
     	 */
         function loadBatchInfo($batch)
         {
    
    From cca87f3d5af853117b00d3582e0f88655c610bb4 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 13:27:17 +0200
    Subject: [PATCH 237/433] Fix phpcs
    
    ---
     htdocs/product/class/product.class.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index db367301120..fe0e9c3733c 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -299,7 +299,7 @@ class Product extends CommonObject
     
     	/**
     	 * @deprecated
    -	 * @see ref_supplier
    +	 * @see $ref_supplier
     	 */
     	public $ref_fourn;
     	public $ref_supplier;
    @@ -3282,7 +3282,7 @@ class Product extends CommonObject
     	 *
     	 *  @param	int		$fromId     Id product source
     	 *  @param  int		$toId       Id product target
    -	 *  @return nt         			< 0 if KO, > 0 if OK
    +	 *  @return int         			< 0 if KO, > 0 if OK
     	 */
     	function clone_price($fromId, $toId)
     	{
    
    From df4b3b09d2f5abfeadc8bf9e659a90d4715708ab Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 13:30:07 +0200
    Subject: [PATCH 238/433] Fix var not defined
    
    ---
     htdocs/compta/facture/class/facture.class.php | 22 +++++++++----------
     1 file changed, 11 insertions(+), 11 deletions(-)
    
    diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
    index e9cb7aa214e..9fa7fc988e2 100644
    --- a/htdocs/compta/facture/class/facture.class.php
    +++ b/htdocs/compta/facture/class/facture.class.php
    @@ -4116,18 +4116,18 @@ class Facture extends CommonInvoice
     
     		$langs->load("bills");
     
    -		if (! dol_strlen($modele)) {
    +		if (! dol_strlen($modele))
    +		{
    +			$modele = 'crabe';
    +			$thisTypeConfName = 'FACTURE_ADDON_PDF_'.$this->type;
     
    -		    $modele = 'crabe';
    -		    $thisTypeConfName = 'FACTURE_ADDON_PDF_'.$type;
    -		    
    -		    if ($this->modelpdf) {
    -		        $modele = $this->modelpdf;
    -		    }elseif (! empty($conf->global->{'FACTURE_ADDON_PDF_'.$this->type})){
    -		        $modele = $conf->global->{'FACTURE_ADDON_PDF_'.$this->type} ;
    -		    }elseif (! empty($conf->global->FACTURE_ADDON_PDF)) {
    -		        $modele = $conf->global->FACTURE_ADDON_PDF;
    -		    }
    +			if ($this->modelpdf) {
    +				$modele = $this->modelpdf;
    +			} elseif (! empty($conf->global->$thisTypeConfName)) {
    +				$modele = $conf->global->$thisTypeConfName;
    +			} elseif (! empty($conf->global->FACTURE_ADDON_PDF)) {
    +				$modele = $conf->global->FACTURE_ADDON_PDF;
    +			}
     		}
     
     		$modelpath = "core/modules/facture/doc/";
    
    From 5d9b77051186d918e9dc2429a2475d4179809fad Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 13:30:25 +0200
    Subject: [PATCH 239/433] phpcs
    
    ---
     htdocs/compta/facture/class/facture.class.php | 2 +-
     htdocs/core/class/utils.class.php             | 3 ++-
     2 files changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
    index 9fa7fc988e2..e225d1468c4 100644
    --- a/htdocs/compta/facture/class/facture.class.php
    +++ b/htdocs/compta/facture/class/facture.class.php
    @@ -4107,7 +4107,7 @@ class Facture extends CommonInvoice
     	 *  @param  int			$hidedetails    Hide details of lines
     	 *  @param  int			$hidedesc       Hide description
     	 *  @param  int			$hideref        Hide ref
    -	 * @param   null|array  $moreparams     Array to provide more information
    +	 *  @param   null|array  $moreparams     Array to provide more information
     	 *	@return int        					<0 if KO, >0 if OK
     	 */
     	public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
    diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php
    index 9f680ef4990..7904f485d6a 100644
    --- a/htdocs/core/class/utils.class.php
    +++ b/htdocs/core/class/utils.class.php
    @@ -284,8 +284,9 @@ class Utils
     			}
     
     			$errormsg='';
    +			$handle = '';
     
    -			// Debut appel methode execution
    +			// Start call method to execute dump
     			$fullcommandcrypted=$command." ".$paramcrypted." 2>&1";
     			$fullcommandclear=$command." ".$paramclear." 2>&1";
     			if ($compression == 'none') $handle = fopen($outputfile, 'w');
    
    From 4cd7119d1c91d5755d796c7f21d17584950a69da Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 13:38:50 +0200
    Subject: [PATCH 240/433] Not used var
    
    ---
     htdocs/datapolicies/class/datapolicies.class.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/datapolicies/class/datapolicies.class.php b/htdocs/datapolicies/class/datapolicies.class.php
    index df818db6f5e..e6b3af3bf25 100644
    --- a/htdocs/datapolicies/class/datapolicies.class.php
    +++ b/htdocs/datapolicies/class/datapolicies.class.php
    @@ -149,7 +149,7 @@ Class DataPolicies extends Contact
          	$error = 0;
     
          	$from = $user->getFullName($langs) . ' <' . $user->email . '>';
    -     	$replyto = $from;
    +
          	$sendto = $contact->email;
          	$code= md5($contact->email);
          	if (!empty($contact->default_lang)) {
    @@ -225,7 +225,7 @@ Class DataPolicies extends Contact
          	$error = 0;
     
          	$from = $user->getFullName($langs) . ' <' . $user->email . '>';
    -     	$replyto = $from;
    +
          	$sendto = $societe->email;
     
          	$code= md5($societe->email);
    @@ -297,7 +297,7 @@ Class DataPolicies extends Contact
         	$error = 0;
     
         	$from = $user->getFullName($langs) . ' <' . $user->email . '>';
    -    	$replyto = $from;
    +
         	$sendto = $adherent->email;
     
         	$code= md5($adherent->email);
    
    From a20498126aabeece85bf30cf953ec9dd2943c0d3 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 13:40:22 +0200
    Subject: [PATCH 241/433] Fix init var
    
    ---
     htdocs/website/class/website.class.php | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php
    index b9be32bcafa..3f51f669829 100644
    --- a/htdocs/website/class/website.class.php
    +++ b/htdocs/website/class/website.class.php
    @@ -1155,7 +1155,8 @@ class Website extends CommonObject
     		$MAXHEIGHT = 4 * $HEIGHTOPTION;
     		$nboflanguage = count($languagecodes);
     
    -		$out.='<!-- componentSelectLang'.$htmlname.' -->'."\n";
    +		$out ='<!-- componentSelectLang'.$htmlname.' -->'."\n";
    +
     		$out.= '<style>';
     		$out.= '.componentSelectLang'.$htmlname.':hover { height: '.min($MAXHEIGHT, ($HEIGHTOPTION * $nboflanguage)).'px; overflow-x: hidden; overflow-y: '.((($HEIGHTOPTION * $nboflanguage) > $MAXHEIGHT) ? ' scroll' : 'hidden').'; }'."\n";
     		$out.= '.componentSelectLang'.$htmlname.' li { line-height: '.$HEIGHTOPTION.'px; }'."\n";
    
    From 6d4d8a0342492441ccd062b2546cad2a5802e84c Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 14:04:42 +0200
    Subject: [PATCH 242/433] Dolibarize data privacy policy module
    
    ---
     ...cies.class.php => modDataPolicy.class.php} | 126 +++++++++---------
     .../langs/en_US/datapolicies.lang             |  93 -------------
     .../langs/fr_FR/datapolicies.lang             |  97 --------------
     .../langs/it_IT/datapolicies.lang             |  80 -----------
     .../{datapolicies => datapolicy}/ChangeLog.md |   0
     .../admin/setup.php                           |  70 +++++-----
     .../admin/setupmail.php                       |  14 +-
     .../class/actions_datapolicy.class.php}       |  76 +++++------
     .../class/datapolicy.class.php}               |  58 ++++----
     .../class/datapolicycron.class.php}           |  16 +--
     .../img/datapolicy.png}                       | Bin
     .../{datapolicies => datapolicy}/img/gfdl.png | Bin
     .../img/gplv3.png                             | Bin
     .../img/object_datapolicy.png}                | Bin
     .../img/object_inoveaconseil.png              | Bin
     htdocs/datapolicy/langs/en_US/datapolicy.lang |  92 +++++++++++++
     htdocs/datapolicy/langs/fr_FR/datapolicy.lang |  97 ++++++++++++++
     htdocs/datapolicy/langs/it_IT/datapolicy.lang |  78 +++++++++++
     .../lib/datapolicy.lib.php}                   |  18 +--
     .../{datapolicies => datapolicy}/mailing.php  |  12 +-
     .../modulebuilder.txt                         |   0
     .../public/index.php                          |  58 ++++----
     22 files changed, 492 insertions(+), 493 deletions(-)
     rename htdocs/core/modules/{modDataPolicies.class.php => modDataPolicy.class.php} (59%)
     delete mode 100644 htdocs/datapolicies/langs/en_US/datapolicies.lang
     delete mode 100644 htdocs/datapolicies/langs/fr_FR/datapolicies.lang
     delete mode 100644 htdocs/datapolicies/langs/it_IT/datapolicies.lang
     rename htdocs/{datapolicies => datapolicy}/ChangeLog.md (100%)
     rename htdocs/{datapolicies => datapolicy}/admin/setup.php (71%)
     rename htdocs/{datapolicies => datapolicy}/admin/setupmail.php (94%)
     rename htdocs/{datapolicies/class/actions_datapolicies.class.php => datapolicy/class/actions_datapolicy.class.php} (83%)
     rename htdocs/{datapolicies/class/datapolicies.class.php => datapolicy/class/datapolicy.class.php} (80%)
     rename htdocs/{datapolicies/class/datapoliciescron.class.php => datapolicy/class/datapolicycron.class.php} (98%)
     rename htdocs/{datapolicies/img/datapolicies.png => datapolicy/img/datapolicy.png} (100%)
     rename htdocs/{datapolicies => datapolicy}/img/gfdl.png (100%)
     rename htdocs/{datapolicies => datapolicy}/img/gplv3.png (100%)
     rename htdocs/{datapolicies/img/object_datapolicies.png => datapolicy/img/object_datapolicy.png} (100%)
     rename htdocs/{datapolicies => datapolicy}/img/object_inoveaconseil.png (100%)
     create mode 100644 htdocs/datapolicy/langs/en_US/datapolicy.lang
     create mode 100644 htdocs/datapolicy/langs/fr_FR/datapolicy.lang
     create mode 100644 htdocs/datapolicy/langs/it_IT/datapolicy.lang
     rename htdocs/{datapolicies/lib/datapolicies.lib.php => datapolicy/lib/datapolicy.lib.php} (72%)
     rename htdocs/{datapolicies => datapolicy}/mailing.php (81%)
     rename htdocs/{datapolicies => datapolicy}/modulebuilder.txt (100%)
     rename htdocs/{datapolicies => datapolicy}/public/index.php (66%)
    
    diff --git a/htdocs/core/modules/modDataPolicies.class.php b/htdocs/core/modules/modDataPolicy.class.php
    similarity index 59%
    rename from htdocs/core/modules/modDataPolicies.class.php
    rename to htdocs/core/modules/modDataPolicy.class.php
    index 74bbe0ba7d2..2ecb5da4336 100644
    --- a/htdocs/core/modules/modDataPolicies.class.php
    +++ b/htdocs/core/modules/modDataPolicy.class.php
    @@ -18,12 +18,12 @@
      */
     
     /**
    - * 	\defgroup   datapolicies     Module datapolicies
    - *  \brief      datapolicies module descriptor.
    + * 	\defgroup   datapolicy     Module datapolicy
    + *  \brief      datapolicy module descriptor.
      *
    - *  \file       htdocs/datapolicies/core/modules/modGdpr.class.php
    - *  \ingroup    datapolicies
    - *  \brief      Description and activation file for module DATAPOLICIES
    + *  \file       htdocs/datapolicy/core/modules/modDataPolicy.class.php
    + *  \ingroup    datapolicy
    + *  \brief      Description and activation file for module DATAPOLICY
      */
     include_once DOL_DOCUMENT_ROOT . '/core/modules/DolibarrModules.class.php';
     
    @@ -33,9 +33,9 @@ include_once DOL_DOCUMENT_ROOT . '/core/modules/DolibarrModules.class.php';
     // so we ignore the Squiz.Classes.ValidClassName.NotCamelCaps rule.
     // @codingStandardsIgnoreStart
     /**
    - *  Description and activation class for module datapolicies
    + *  Description and activation class for module datapolicy
      */
    -class modDataPolicies extends DolibarrModules {
    +class modDataPolicy extends DolibarrModules {
     
         // @codingStandardsIgnoreEnd
         /**
    @@ -53,7 +53,7 @@ class modDataPolicies extends DolibarrModules {
             // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
             $this->numero = 4100;
             // Key text used to identify module (for permissions, menus, etc...)
    -        $this->rights_class = 'datapolicies';
    +        $this->rights_class = 'datapolicy';
     
             // Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
             // It is used to group modules by family in module setup page
    @@ -62,16 +62,16 @@ class modDataPolicies extends DolibarrModules {
             $this->module_position = '70';
             // Gives the possibility to the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
             //$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
    -        // Module label (no space allowed), used if translation string 'ModuledatapoliciesName' not found (MyModue is name of module).
    +        // Module label (no space allowed), used if translation string 'ModuledatapolicyName' not found (MyModue is name of module).
             $this->name = preg_replace('/^mod/i', '', get_class($this));
    -        // Module description, used if translation string 'ModuledatapoliciesDesc' not found (MyModue is name of module).
    -        $this->description = "Module to manage Data policies (for compliance with GDPR in Europe or other Data policies rules)";
    +        // Module description, used if translation string 'ModuledatapolicyDesc' not found (MyModue is name of module).
    +        $this->description = "Module to manage Data policy (for compliance with GDPR in Europe or other Data policy rules)";
             // Used only if file README.md and README-LL.md not found.
             $this->descriptionlong = "";
     
             // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
             $this->version = 'development';
    -        // Key used in llx_const table to save module status enabled/disabled (where datapolicies is value of property name of module in uppercase)
    +        // Key used in llx_const table to save module status enabled/disabled (where datapolicy is value of property name of module in uppercase)
             $this->const_name = 'MAIN_MODULE_' . strtoupper($this->name);
             // Name of image file used for this module.
             // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
    @@ -79,9 +79,9 @@ class modDataPolicies extends DolibarrModules {
             $this->picto = 'generic';
     
             // Defined all module parts (triggers, login, substitutions, menus, css, etc...)
    -        // for default path (eg: /datapolicies/core/xxxxx) (0=disable, 1=enable)
    -        // for specific path of parts (eg: /datapolicies/core/modules/barcode)
    -        // for specific css file (eg: /datapolicies/css/datapolicies.css.php)
    +        // for default path (eg: /datapolicy/core/xxxxx) (0=disable, 1=enable)
    +        // for specific path of parts (eg: /datapolicy/core/modules/barcode)
    +        // for specific css file (eg: /datapolicy/css/datapolicy.css.php)
             $this->module_parts = array(
                 'triggers' => 0, // Set this to 1 if module has its own trigger directory (core/triggers)
                 'login' => 0, // Set this to 1 if module has its own login method file (core/login)
    @@ -95,41 +95,41 @@ class modDataPolicies extends DolibarrModules {
             );
     
             // Data directories to create when module is enabled.
    -        // Example: this->dirs = array("/datapolicies/temp","/datapolicies/subdir");
    -        $this->dirs = array("/datapolicies/temp");
    +        // Example: this->dirs = array("/datapolicy/temp","/datapolicy/subdir");
    +        $this->dirs = array("/datapolicy/temp");
     
    -        // Config pages. Put here list of php page, stored into datapolicies/admin directory, to use to setup module.
    -        $this->config_page_url = array("setup.php@datapolicies");
    +        // Config pages. Put here list of php page, stored into datapolicy/admin directory, to use to setup module.
    +        $this->config_page_url = array("setup.php@datapolicy");
     
             // Dependencies
             $this->hidden = false;   // A condition to hide module
             $this->depends = array();  // List of module class names as string that must be enabled if this module is enabled
             $this->requiredby = array(); // List of module ids to disable if this one is disabled
             $this->conflictwith = array(); // List of module class names as string this module is in conflict with
    -        $this->langfiles = array("datapolicies@datapolicies");
    +        $this->langfiles = array("datapolicy@datapolicy");
             $this->phpmin = array(5, 3);     // Minimum version of PHP required by module
             $this->need_dolibarr_version = array(4, 0); // Minimum version of Dolibarr required by module
             $this->warnings_activation = array();                     // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
             $this->warnings_activation_ext = array();                 // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
    -        //$this->automatic_activation = array('FR'=>'datapoliciesWasAutomaticallyActivatedBecauseOfYourCountryChoice');
    +        //$this->automatic_activation = array('FR'=>'datapolicyWasAutomaticallyActivatedBecauseOfYourCountryChoice');
             //$this->always_enabled = true;								// If true, can't be disabled
             // Constants
             // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
    -        // Example: $this->const=array(0=>array('datapolicies_MYNEWCONST1','chaine','myvalue','This is a constant to add',1),
    -        //                             1=>array('datapolicies_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
    +        // Example: $this->const=array(0=>array('datapolicy_MYNEWCONST1','chaine','myvalue','This is a constant to add',1),
    +        //                             1=>array('datapolicy_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1)
             // );
             $this->const = array(
    -            array('DATAPOLICIES_TIERS_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_TIERS_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_TIERS_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_TIERS_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_CONTACT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_CONTACT_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_CONTACT_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_CONTACT_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    -            array('DATAPOLICIES_ADHERENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_TIERS_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_TIERS_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_TIERS_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_TIERS_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_TIERS_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_PROSPECT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_PROSPECT_CLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_CONTACT_FOURNISSEUR', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
    +            array('DATAPOLICY_ADHERENT', 'chaine', '', $langs->trans('NUMBER_MONTH_BEFORE_DELETION'), 0),
             );
     
             $country = explode(":", $conf->global->MAIN_INFO_SOCIETE_COUNTRY);
    @@ -140,17 +140,17 @@ class modDataPolicies extends DolibarrModules {
               'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
               ) */
     
    -        if (!isset($conf->datapolicies) || !isset($conf->datapolicies->enabled)) {
    -            $conf->datapolicies = new stdClass();
    -            $conf->datapolicies->enabled = 0;
    +        if (!isset($conf->datapolicy) || !isset($conf->datapolicy->enabled)) {
    +            $conf->datapolicy = new stdClass();
    +            $conf->datapolicy->enabled = 0;
             }
     
     
             // Array to add new pages in new tabs
             $this->tabs = array();
             // Example:
    -        // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@datapolicies:$user->rights->datapolicies->read:/datapolicies/mynewtab1.php?id=__ID__');  					// To add a new tab identified by code tabname1
    -        // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@datapolicies:$user->rights->othermodule->read:/datapolicies/mynewtab2.php?id=__ID__',  	// To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
    +        // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@datapolicy:$user->rights->datapolicy->read:/datapolicy/mynewtab1.php?id=__ID__');  					// To add a new tab identified by code tabname1
    +        // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@datapolicy:$user->rights->othermodule->read:/datapolicy/mynewtab2.php?id=__ID__',  	// To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
             // $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove');                                                     										// To remove an existing tab identified by code tabname
             //
             // Where objecttype can be
    @@ -177,7 +177,7 @@ class modDataPolicies extends DolibarrModules {
             $this->dictionaries = array();
             /* Example:
               $this->dictionaries=array(
    -          'langs'=>'mylangfile@datapolicies',
    +          'langs'=>'mylangfile@datapolicy',
               'tabname'=>array(MAIN_DB_PREFIX."table1",MAIN_DB_PREFIX."table2",MAIN_DB_PREFIX."table3"),		// List of tables we want to see into dictonnary editor
               'tablib'=>array("Table1","Table2","Table3"),													// Label of tables
               'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'),	// Request to select fields
    @@ -186,21 +186,21 @@ class modDataPolicies extends DolibarrModules {
               'tabfieldvalue'=>array("code,label","code,label","code,label"),																				// List of fields (list of fields to edit a record)
               'tabfieldinsert'=>array("code,label","code,label","code,label"),																			// List of fields (list of fields for insert)
               'tabrowid'=>array("rowid","rowid","rowid"),																									// Name of columns with primary key (try to always name it 'rowid')
    -          'tabcond'=>array($conf->datapolicies->enabled,$conf->datapolicies->enabled,$conf->datapolicies->enabled)												// Condition to show each dictionary
    +          'tabcond'=>array($conf->datapolicy->enabled,$conf->datapolicy->enabled,$conf->datapolicy->enabled)												// Condition to show each dictionary
               );
              */
     
     
             // Boxes/Widgets
    -        // Add here list of php file(s) stored in datapolicies/core/boxes that contains class to show a widget.
    +        // Add here list of php file(s) stored in datapolicy/core/boxes that contains class to show a widget.
             $this->boxes = array();
     
     
             // Cronjobs (List of cron jobs entries to add when module is enabled)
             // unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
             $this->cronjobs = array(
    -            0 => array('label' => 'DATAPOLICIES Cron', 'jobtype' => 'method', 'class' => '/datapolicies/class/datapoliciesCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'exec', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 1, 'test' => true),
    -            1 => array('label' => 'DATAPOLICIES Mailing', 'jobtype' => 'method', 'class' => '/datapolicies/class/datapoliciesCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'sendMailing', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 0, 'test' => true)
    +            0 => array('label' => 'DATAPOLICY Cron', 'jobtype' => 'method', 'class' => '/datapolicy/class/datapolicyCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'exec', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 1, 'test' => true),
    +            1 => array('label' => 'DATAPOLICY Mailing', 'jobtype' => 'method', 'class' => '/datapolicy/class/datapolicyCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'sendMailing', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 0, 'test' => true)
             );
             // Example: $this->cronjobs=array(0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>true),
             //                                1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>true)
    @@ -224,7 +224,7 @@ class modDataPolicies extends DolibarrModules {
         {
         	global $langs;
     
    -    	$this->_load_tables('/datapolicies/sql/');
    +    	$this->_load_tables('/datapolicy/sql/');
     
             // Create extrafields
             include_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
    @@ -232,28 +232,28 @@ class modDataPolicies extends DolibarrModules {
     
     
             // Extrafield contact
    -        //$result1=$extrafields->addExtraField('datapolicies_separate', "DATAPOLICIES_BLOCKCHECKBOX", 'separate', 100,  1, 'thirdparty',   0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_consentement', $langs->trans("DATAPOLICIES_consentement"), 'boolean', 101, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_opposition_traitement', $langs->trans("DATAPOLICIES_opposition_traitement"), 'boolean', 102, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_opposition_prospection', $langs->trans("DATAPOLICIES_opposition_prospection"), 'boolean', 103, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_date', $langs->trans("DATAPOLICIES_date"), 'date', 104, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0);
    -        $result1 = $extrafields->addExtraField('datapolicies_send', $langs->trans("DATAPOLICIES_send"), 'date', 105, 3, 'thirdparty', 0, 0, '', '', 0, '', '0', 0);
    +        //$result1=$extrafields->addExtraField('datapolicy_separate', "DATAPOLICY_BLOCKCHECKBOX", 'separate', 100,  1, 'thirdparty',   0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0);
    +        $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'thirdparty', 0, 0, '', '', 0, '', '0', 0);
     
             // Extrafield Tiers
    -        //$result1=$extrafields->addExtraField('datapolicies_separate', "DATAPOLICIES_BLOCKCHECKBOX", 'separate', 100,  1, 'contact',   0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_consentement', $langs->trans("DATAPOLICIES_consentement"), 'boolean', 101, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_opposition_traitement', $langs->trans("DATAPOLICIES_opposition_traitement"), 'boolean', 102, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_opposition_prospection', $langs->trans("DATAPOLICIES_opposition_prospection"), 'boolean', 103, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_date', $langs->trans("DATAPOLICIES_date"), 'date', 104, 3, 'contact', 0, 0, '', '', 1, '', '3', 0);
    -        $result1 = $extrafields->addExtraField('datapolicies_send', $langs->trans("DATAPOLICIES_send"), 'date', 105, 3, 'contact', 0, 0, '', '', 0, '', '0', 0);
    +        //$result1=$extrafields->addExtraField('datapolicy_separate', "DATAPOLICY_BLOCKCHECKBOX", 'separate', 100,  1, 'contact',   0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'contact', 0, 0, '', '', 1, '', '3', 0);
    +        $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'contact', 0, 0, '', '', 0, '', '0', 0);
     
             // Extrafield Adherent
    -        //$result1=$extrafields->addExtraField('datapolicies_separate', "DATAPOLICIES_BLOCKCHECKBOX", 'separate', 100,  1, 'adherent',   0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_consentement', $langs->trans("DATAPOLICIES_consentement"), 'boolean', 101, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_opposition_traitement', $langs->trans("DATAPOLICIES_opposition_traitement"), 'boolean', 102, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_opposition_prospection', $langs->trans("DATAPOLICIES_opposition_prospection"), 'boolean', 103, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicies@datapolicies', '$conf->datapolicies->enabled');
    -        $result1 = $extrafields->addExtraField('datapolicies_date', $langs->trans("DATAPOLICIES_date"), 'date', 104, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0);
    -        $result1 = $extrafields->addExtraField('datapolicies_send', $langs->trans("DATAPOLICIES_send"), 'date', 105, 3, 'adherent', 0, 0, '', '', 0, '', '0', 0);
    +        //$result1=$extrafields->addExtraField('datapolicy_separate', "DATAPOLICY_BLOCKCHECKBOX", 'separate', 100,  1, 'adherent',   0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    +        $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0);
    +        $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'adherent', 0, 0, '', '', 0, '', '0', 0);
     
             $sql = array();
     
    diff --git a/htdocs/datapolicies/langs/en_US/datapolicies.lang b/htdocs/datapolicies/langs/en_US/datapolicies.lang
    deleted file mode 100644
    index 164581bcca5..00000000000
    --- a/htdocs/datapolicies/langs/en_US/datapolicies.lang
    +++ /dev/null
    @@ -1,93 +0,0 @@
    -# Copyright (C) 2018 Nicolas ZABOURI    <info@inovea-conseil.com>
    -#
    -# This program is free software: you can redistribute it and/or modify
    -# it under the terms of the GNU General Public License as published by
    -# the Free Software Foundation, either version 3 of the License, or
    -# (at your option) any later version.
    -#
    -# This program is distributed in the hope that it will be useful,
    -# but WITHOUT ANY WARRANTY; without even the implied warranty of
    -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -# GNU General Public License for more details.
    -#
    -# You should have received a copy of the GNU General Public License
    -# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    -
    -# Module label 'ModulergpdName'
    -ModulergpdName = GDPR
    -# Module description 'ModulergpdDesc'
    -ModulergpdDesc = Conformity with the GDPR
    -
    -#
    -# Page d'administration
    -#
    -rgpdSetup = Module Setup
    -Settings_DATAPOLICIES = Settings of DATAPOLICIES module
    -rgpdSetupPage = According to <a href="http://www.privacy-regulation.eu/en/5.htm" target="_blank">Article 5</a> of the GDPR, personal data must be kept for a period not exceeding that necessary for the purposes for which they were processed, except for archival purposes.
    -The deletion will be done automatically after a certain duration without event (the duration which you will have indicated below).
    -NB_MONTHS = %s months
    -ONE_YEAR = 1 year
    -NB_YEARS = %s years
    -DATAPOLICIES_TIERS_CLIENT = Customer
    -DATAPOLICIES_TIERS_PROSPECT = Prospect
    -DATAPOLICIES_TIERS_PROSPECT_CLIENT = Prospect/Customer
    -DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT = Nor prospect/Nor customer
    -DATAPOLICIES_TIERS_FOURNISSEUR = Supplier
    -DATAPOLICIES_CONTACT_CLIENT = Customer
    -DATAPOLICIES_CONTACT_PROSPECT = Prospect
    -DATAPOLICIES_CONTACT_PROSPECT_CLIENT = Prospect/Customer
    -DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT = Nor prospect/Nor customer
    -DATAPOLICIES_CONTACT_FOURNISSEUR = Supplier
    -DATAPOLICIES_ADHERENT = Member
    -DATAPOLICIES_Tooltip_SETUP = Type of contact - Indicate your choices for each type.
    -DATAPOLICIESMail=Emails Setup
    -DATAPOLICIESSUBJECTMAIL=Subject of email
    -DATAPOLICIESCONTENTMAIL=Content of the email
    -DATAPOLICIESSUBSITUTION=You can use the following variables in your email (LINKACCEPT allows to create a link recording the agreement of the person, LINKREFUSED makes it possible to record the refusal of the person):
    -DATAPOLICIESACCEPT=Message after agreement
    -DATAPOLICIESREFUSE=Message after desagreement
    -SendAgreementText=You can send a GDPR email to all your relevant contacts (who have not yet received an email and for which you have not registered anything about their GDPR agreement). To do this, use the following button.
    -SendAgreement=Send emails
    -AllAgreementSend = All emails have been sent
    -TXTLINKDATAPOLICIESACCEPT= Text for the link "agreement" 
    -TXTLINKDATAPOLICIESREFUSE= Text for the link "desagreement" 
    -
    -
    -#
    -# Extrafield
    -#
    -DATAPOLICIES_BLOCKCHECKBOX = GDPR : Processing of personal data
    -DATAPOLICIES_consentement = Consent obtained for the processing of personal data 
    -DATAPOLICIES_opposition_traitement = Opposes the processing of his personal data
    -DATAPOLICIES_opposition_prospection = Opposes the processing of his personal data for the purposes of prospecting
    -
    -#
    -# Popup
    -#
    -DATAPOLICIES_POPUP_ANONYME_TITLE = Anonymize a thirdparty
    -DATAPOLICIES_POPUP_ANONYME_TEXTE = You can not delete this contact from Dolibarr because there are related items. In accordance with the GDPR, you will make all this data anonymous to respect your obligations. Would you like to continue ?
    -
    -#
    -# Bouton portabilité
    -# 
    -DATAPOLICIES_PORTABILITE = Portability GDPR
    -DATAPOLICIES_PORTABILITE_TITLE = Export of personal data
    -DATAPOLICIES_PORTABILITE_CONFIRMATION = You want to export the personal data of this contact. Are you sure ?
    -
    -#
    -# Note ajoutés lors d'une anonymisation
    -#
    -ANONYMISER_AT = Anonymised the %s
    -
    -#V2
    -DATAPOLICIESReturn=GDPR Validation
    -DATAPOLICIES_date = Date of agreement/desagreement GDPR
    -DATAPOLICIES_send = Date sending agreement email
    -DATAPOLICIESReturn = GDPR Return
    -DATAPOLICIES_SEND = Send GDPR email
    -MailSent = Email has been sent
    -
    -#ERROR
    -ErrorSubjectIsRequired= Error : The subject of email is required. Indicate it in the module setup
    -=Due to a technical problem, we were unable to register your choice. We apologize for that. Contact us to send us your choice.
    -NUMBER_MONTH_BEFORE_DELETION = Number of month before deletion
    diff --git a/htdocs/datapolicies/langs/fr_FR/datapolicies.lang b/htdocs/datapolicies/langs/fr_FR/datapolicies.lang
    deleted file mode 100644
    index 916cdffb776..00000000000
    --- a/htdocs/datapolicies/langs/fr_FR/datapolicies.lang
    +++ /dev/null
    @@ -1,97 +0,0 @@
    -# Copyright (C) 2018  INOVEA CONSEil info@inovea-conseil.com
    -#
    -# This program is free software: you can redistribute it and/or modify
    -# it under the terms of the GNU General Public License as published by
    -# the Free Software Foundation, either version 3 of the License, or
    -# (at your option) any later version.
    -#
    -# This program is distributed in the hope that it will be useful,
    -# but WITHOUT ANY WARRANTY; without even the implied warranty of
    -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -# GNU General Public License for more details.
    -#
    -# You should have received a copy of the GNU General Public License
    -# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    -
    -#
    -# Générique
    -#
    -
    -# Module label 'ModulergpdName'
    -ModulergpdName = DATAPOLICIES
    -# Module description 'ModulergpdDesc'
    -Module432452Desc = Module de mise en conformité avec le DATAPOLICIES
    -
    -#
    -# Page d'administration
    -#
    -rgpdSetup = Configuration du module DATAPOLICIES
    -Settings_DATAPOLICIES = Paramétrage du module DATAPOLICIES
    -rgpdSetupPage = Selon <a href="http://www.privacy-regulation.eu/fr/5.htm" target="_blank">l’article 5</a> du DATAPOLICIES, les données à caractère personnel doivent être conservées pendant une durée n’excédant pas celle nécessaire au regard des finalités pour lesquelles elles ont été traitées, à l’exception de fins archivistiques. La suppression se fera automatiquement après une certaine durée sans évènement (la durée que vous aurez indiquée ci-dessous).
    -NB_MONTHS = %s mois
    -ONE_YEAR = 1 an
    -NB_YEARS = %s ans
    -DATAPOLICIES_TIERS_CLIENT = Client
    -DATAPOLICIES_TIERS_PROSPECT = Prospect
    -DATAPOLICIES_TIERS_PROSPECT_CLIENT = Prospect/Client
    -DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT = Ni prospect / Ni client
    -DATAPOLICIES_TIERS_FOURNISSEUR = Fournisseur
    -DATAPOLICIES_CONTACT_CLIENT = Client
    -DATAPOLICIES_CONTACT_PROSPECT = Prospect
    -DATAPOLICIES_CONTACT_PROSPECT_CLIENT = Prospect/Client
    -DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT = Ni prospect / Ni client
    -DATAPOLICIES_CONTACT_FOURNISSEUR = Fournisseur
    -DATAPOLICIES_ADHERENT = Adhérent
    -DATAPOLICIES_Tooltip_SETUP = Type du contact - Indiquez vos choix pour chaque type.
    -DATAPOLICIESMail=Paramétrage des emails
    -DATAPOLICIESSUBJECTMAIL=Objet du mail
    -DATAPOLICIESCONTENTMAIL=Contenu du mail
    -DATAPOLICIESSUBSITUTION=Vous pouvez utiliser les variables suivantes dans votre email (LINKACCEPT permet de créer un lien enregistrant l'acceptation de la personne, LINKREFUSED permet d'enregistrer le refus de la personne) :
    -DATAPOLICIESACCEPT=Message suite acceptation
    -DATAPOLICIESREFUSE=Message suite opposition
    -SendAgreementText=Vous pouvez envoyer un email DATAPOLICIES à tous vos contacts concernés (qui n'ont pas encore reçus de mail et pour lesquels vous n'avez rien enregistré concernant leur accord/désaccord DATAPOLICIES). Pour cela, utilisez le bouton suivant.
    -SendAgreement=Envoyer les emails
    -AllAgreementSend = Tous les e-mails de consentement ont été envoyés
    -TXTLINKDATAPOLICIESACCEPT= Texte du lien d'acceptation
    -TXTLINKDATAPOLICIESREFUSE= Texte du lien d'opposition
    -
    -
    -
    -#
    -# Extrafield
    -#
    -DATAPOLICIES_BLOCKCHECKBOX = DATAPOLICIES : Traitement des données à caractère personnel
    -DATAPOLICIES_consentement = Consentement recueilli pour le traitement des données à caractère personnel le concernant
    -DATAPOLICIES_opposition_traitement = S’oppose au traitement de ses données à caractère personnel
    -DATAPOLICIES_opposition_prospection = S’oppose au traitement de ses données à caractère personnel à des fins de prospection
    -
    -#
    -# Popup
    -#
    -DATAPOLICIES_POPUP_ANONYME_TITLE = Anonymiser un tiers
    -DATAPOLICIES_POPUP_ANONYME_TEXTE = Vous ne pouvez pas supprimer ce contact de Dolibarr car des éléments y sont liés. Conformément au DATAPOLICIES, vous allez rendre toutes ces données anonymes afin de respecter vos obligations. Souhaitez-vous continuer ?
    -
    -#
    -# Bouton portabilité
    -# 
    -DATAPOLICIES_PORTABILITE = Portabilité DATAPOLICIES
    -DATAPOLICIES_PORTABILITE_TITLE = Export des données à caractère personnel
    -DATAPOLICIES_PORTABILITE_CONFIRMATION = Vous souhaitez exporter les données à caractère personnel de ce contact. Etes-vous sûr ?
    -
    -#
    -# Note ajoutés lors d'une anonymisation
    -#
    -ANONYMISER_AT = Anonymisé le %s
    -
    -#V2
    -DATAPOLICIESReturn=Validation DATAPOLICIES
    -DATAPOLICIES_date=Date d'accord/opposition au traitement
    -DATAPOLICIES_send=Date envoi consentement
    -DATAPOLICIESReturn=Retour DATAPOLICIES
    -DATAPOLICIES_SEND=Envoyer l'email de consentement
    -MailSent=L'email a bien été envoyé
    -
    -#ERROR
    -ErrorSubjectIsRequired=Erreur : vous n'avez pas indiqué l'objet de l'email dans la configuration
    -=Suite à un problème technique, nous n'avons pas pu enregistrer votre choix. Nous nous en excusons. Contactez-nous pour nous transmettre votre choix.
    -NUMBER_MONTH_BEFORE_DELETION = Nombre de mois avant suppression des données
    diff --git a/htdocs/datapolicies/langs/it_IT/datapolicies.lang b/htdocs/datapolicies/langs/it_IT/datapolicies.lang
    deleted file mode 100644
    index a979c931c41..00000000000
    --- a/htdocs/datapolicies/langs/it_IT/datapolicies.lang
    +++ /dev/null
    @@ -1,80 +0,0 @@
    -# Copyright (C) 2018 INOVEA CONSEIl info@inovea-conseil.com - Thanks to Claudio Aschieri
    -#
    -# # Module label 'ModulergpdName'
    -ModulergpdName = GDPR
    -# Module description 'ModulergpdDesc'
    -ModulergpdDesc = Conformità con GDPR
    -Module432452Name=GDPR
    -Module432452Desc=Conformità con GDPR (Regolamento Generale sulla protezione di dati)
    -
    -#
    -# Page d'administration
    -#
    -rgpdSetup = Module Setup
    -Settings_DATAPOLICIES = Configurazione modulo GDPR 
    -rgpdSetupPage = In accordo con <a href="http://www.privacy-regulation.eu/it/5.htm" target="_blank">l'art 5 del GDPR </a> i dati personali devono essere conservati per un periodo di tempo che .... ed eliminati se non sono più utili agli scopi per cui sono stati processati.
    -NB_MONTHS = %s mesi
    -ONE_YEAR = 1 anno
    -NB_YEARS = %s anni
    -DATAPOLICIES_TIERS_CLIENT = Cliente
    -DATAPOLICIES_TIERS_PROSPECT = Fornitore
    -DATAPOLICIES_TIERS_PROSPECT_CLIENT = Potenziale Cliente / Cliente
    -DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT = Nè potenziale cliente / Nè cliente
    -DATAPOLICIES_TIERS_FOURNISSEUR = Fornitore
    -DATAPOLICIES_CONTACT_CLIENT = Cliente
    -DATAPOLICIES_CONTACT_PROSPECT = Potenziale cliente
    -DATAPOLICIES_CONTACT_PROSPECT_CLIENT = Potenziale Cliente / Cliente
    -DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT = Nè potenziale cliente / Nè cliente
    -DATAPOLICIES_CONTACT_FOURNISSEUR = Fornitore
    -DATAPOLICIES_ADHERENT = Membri
    -DATAPOLICIES_Tooltip_SETUP = Tipo di contatto - Indica la scelta per ogni tipologia
    -DATAPOLICIESMail=Configurazione Email
    -DATAPOLICIESSUBJECTMAIL=Subject dell'e-mail
    -DATAPOLICIESCONTENTMAIL=Contenuto dell'e-mail
    -DATAPOLICIESSUBSITUTION=Puoi utilizzare le seguenti variabili nella tua email (LINKACCEPT consente di creare un link per registrare l'accettazione della persona, LINKREFUSED consente di registrare il rifiuto della persona):
    -DATAPOLICIESACCEPT= Messaggio dopo il consenso
    -DATAPOLICIESREFUSE=Messaggio dopo il rifiuto
    -SendAgreementText=Puoi inviare un'email GDPR a tutti i tuoi contatti rilevanti (che non hanno ancora ricevuto un'e-mail e per i quali non hai registrato nulla sul loro accordo GDPR). Per fare ciò, utilizzare il seguente pulsante.
    -SendAgreement=Invia emails
    -AllAgreementSend = Tutte le email sono state inviate
    -TXTLINKDATAPOLICIESACCEPT= Testo per il link "Consenso" 
    -TXTLINKDATAPOLICIESREFUSE= Testo per il link "Consenso negato" 
    -
    -#
    -# Extrafield
    -#
    -DATAPOLICIES_BLOCKCHECKBOX = GDPR : Trattamento dei dati personali
    -DATAPOLICIES_consentement = Consenso ottenuto al Trattamento dei dati personali
    -DATAPOLICIES_opposition_traitement = Consenso negato al trattamento dei dati personali
    -DATAPOLICIES_opposition_prospection = Consenso negato al trattamento dei dati personali a fini commerciali
    -
    -#
    -# Popup
    -#
    -DATAPOLICIES_POPUP_ANONYME_TITLE = Anonimizza un soggetto terzo
    -DATAPOLICIES_POPUP_ANONYME_TEXTE = Impossibile eliminare questo contatto da Dolibarr perchè vi sono elementi collegati. In conformità con il GDPR, renderai tutti questi dati anonimi per rispettare i tuoi obblighi. Vuoi continuare?
    -
    -
    -#
    -# Bouton portabilité
    -# 
    -DATAPOLICIES_PORTABILITE = Portabilità GDPR
    -DATAPOLICIES_PORTABILITE_TITLE = Esporta i dati personali
    -DATAPOLICIES_PORTABILITE_CONFIRMATION = Vuoi davvero esportare i dati personali di questo contatto?
    -
    -#
    -# Note ajoutée lors d'une anonymisation
    -#
    -ANONYMISER_AT = Anonimizzato il %s
    -
    -#V2
    -DATAPOLICIESReturn=GDPR Validazione
    -DATAPOLICIES_date = Data di accordo / disaccordo GDPR
    -DATAPOLICIES_send = Data di invio del consenso (e-mail)
    -DATAPOLICIESReturn = GDPR ritorno
    -DATAPOLICIES_SEND = Inviare GDPR e-mail
    -MailSent=L'email è stata inviata
    -
    -#ERROR
    -ErrorSubjectIsRequired= Errore: L'oggetto della mail è obbligatorio. Inserisci l'oggetto nella configurazione del modulo.
    -=A causa di un problema tecnico, non siamo stati in grado di registrare la tua scelta. Ci scusiamo per questo. Contattaci per inviarci la tua scelta.
    diff --git a/htdocs/datapolicies/ChangeLog.md b/htdocs/datapolicy/ChangeLog.md
    similarity index 100%
    rename from htdocs/datapolicies/ChangeLog.md
    rename to htdocs/datapolicy/ChangeLog.md
    diff --git a/htdocs/datapolicies/admin/setup.php b/htdocs/datapolicy/admin/setup.php
    similarity index 71%
    rename from htdocs/datapolicies/admin/setup.php
    rename to htdocs/datapolicy/admin/setup.php
    index f6edd5b3e90..777fa6cb893 100644
    --- a/htdocs/datapolicies/admin/setup.php
    +++ b/htdocs/datapolicy/admin/setup.php
    @@ -17,21 +17,21 @@
      */
     
     /**
    - * \file    datapolicies/admin/setup.php
    - * \ingroup datapolicies
    - * \brief   datapolicies setup page.
    + * \file    datapolicy/admin/setup.php
    + * \ingroup datapolicy
    + * \brief   datapolicy setup page.
      */
     
     require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
    -require_once '../lib/datapolicies.lib.php';
    +require_once '../lib/datapolicy.lib.php';
     //require_once "../class/myclass.class.php";
     
     // Translations
     $langs->load('admin');
     $langs->load('companies');
     $langs->load('members');
    -$langs->load('datapolicies@datapolicies');
    +$langs->load('datapolicy@datapolicy');
     
     // Access control
     if (! $user->admin) accessforbidden();
    @@ -41,17 +41,17 @@ $action = GETPOST('action', 'alpha');
     $backtopage = GETPOST('backtopage', 'alpha');
     
     $arrayofparameters=array(
    -    'DATAPOLICIES_TIERS_CLIENT'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
    -    'DATAPOLICIES_ADHERENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_TIERS_CLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
    +    'DATAPOLICY_ADHERENT'=>array('css'=>'minwidth200'),
     );
     
     
    @@ -81,26 +81,26 @@ if (DOL_VERSION < '7' && $action == 'update') {
     
     $arrayofparameters=array(
         'ThirdParty' => array(
    -        'DATAPOLICIES_TIERS_CLIENT'=>array('css'=>'minwidth200'),
    -        'DATAPOLICIES_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
    -        'DATAPOLICIES_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    -        'DATAPOLICIES_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    -        'DATAPOLICIES_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_TIERS_CLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_TIERS_PROSPECT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_TIERS_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_TIERS_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_TIERS_FOURNISSEUR'=>array('css'=>'minwidth200'),
         ),
         'Contact' => array(
    -        'DATAPOLICIES_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
    -        'DATAPOLICIES_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
    -        'DATAPOLICIES_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    -        'DATAPOLICIES_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    -        'DATAPOLICIES_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_CONTACT_CLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_CONTACT_PROSPECT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_CONTACT_PROSPECT_CLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_CONTACT_FOURNISSEUR'=>array('css'=>'minwidth200'),
         ),
         'Member' => array(
    -        'DATAPOLICIES_ADHERENT'=>array('css'=>'minwidth200'),
    +        'DATAPOLICY_ADHERENT'=>array('css'=>'minwidth200'),
         )
     );
     
     $valTab = array(
    -    '' => $langs->trans('None'),
    +    '' => $langs->trans('Never'),
         '6' => $langs->trans('NB_MONTHS', 6),
         '12' => $langs->trans('ONE_YEAR'),
         '24' => $langs->trans('NB_YEARS', 2),
    @@ -108,6 +108,8 @@ $valTab = array(
         '48' => $langs->trans('NB_YEARS', 4),
         '60' => $langs->trans('NB_YEARS', 5),
         '120' => $langs->trans('NB_YEARS', 10),
    +	'180' => $langs->trans('NB_YEARS', 15),
    +	'240' => $langs->trans('NB_YEARS', 20),
     );
     
     
    @@ -115,20 +117,20 @@ $valTab = array(
      * View
      */
     
    -$page_name = "datapoliciesSetup";
    +$page_name = "datapolicySetup";
     llxHeader('', $langs->trans($page_name));
     
     // Subheader
     $linkback = '<a href="'.($backtopage?$backtopage:DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1').'">'.$langs->trans("BackToModuleList").'</a>';
     
    -print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicies@datapolicies');
    +print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicy@datapolicy');
     
     // Configuration header
    -$head = datapoliciesAdminPrepareHead();
    -dol_fiche_head($head, 'settings', '', -1, "datapolicies@datapolicies");
    +$head = datapolicyAdminPrepareHead();
    +dol_fiche_head($head, 'settings', '', -1, "datapolicy@datapolicy");
     
     // Setup page goes here
    -echo $langs->trans("datapoliciesSetupPage");
    +echo '<span class="opacitymedium">'.$langs->trans("datapolicySetupPage").'</span><br><br>';
     
     
     if ($action == 'edit')
    @@ -180,7 +182,7 @@ else
             foreach($tab as $key => $val)
             {
                 print '<tr class="oddeven"><td>';
    -            print $form->textwithpicto($langs->trans($key),$langs->trans('DATAPOLICIES_Tooltip_SETUP'));
    +            print $form->textwithpicto($langs->trans($key),$langs->trans('DATAPOLICY_Tooltip_SETUP'));
                 print '</td><td>' . ($conf->global->$key == '' ? $langs->trans('None') : $valTab[$conf->global->$key]) . '</td></tr>';
             }
     
    diff --git a/htdocs/datapolicies/admin/setupmail.php b/htdocs/datapolicy/admin/setupmail.php
    similarity index 94%
    rename from htdocs/datapolicies/admin/setupmail.php
    rename to htdocs/datapolicy/admin/setupmail.php
    index a6560c1f7d5..214f673a15f 100644
    --- a/htdocs/datapolicies/admin/setupmail.php
    +++ b/htdocs/datapolicy/admin/setupmail.php
    @@ -22,10 +22,10 @@ require '../../main.inc.php';
     require_once DOL_DOCUMENT_ROOT . "/core/lib/admin.lib.php";
     require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formadmin.class.php';
    -require_once '../lib/datapolicies.lib.php';
    +require_once '../lib/datapolicy.lib.php';
     
     // Translations
    -$langs->loadLangs(array('admin', 'companies', 'members', 'datapolicies'));
    +$langs->loadLangs(array('admin', 'companies', 'members', 'datapolicy'));
     
     
     // Parameters
    @@ -78,17 +78,17 @@ if ($action == 'setvalue' && $user->admin) {
      * View
      */
     
    -$page_name = "datapoliciesSetup";
    +$page_name = "datapolicySetup";
     llxHeader('', $langs->trans($page_name));
     
     // Subheader
     $linkback = '<a href="' . ($backtopage ? $backtopage : DOL_URL_ROOT . '/admin/modules.php?restore_lastsearch_values=1') . '">' . $langs->trans("BackToModuleList") . '</a>';
     
    -print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicies@datapolicies');
    +print load_fiche_titre($langs->trans($page_name), $linkback, 'object_datapolicy@datapolicy');
     
     // Configuration header
    -$head = datapoliciesAdminPrepareHead();
    -dol_fiche_head($head, 'settings', '', -1, "datapolicies@datapolicies");
    +$head = datapolicyAdminPrepareHead();
    +dol_fiche_head($head, 'settings', '', -1, "datapolicy@datapolicy");
     
     
     
    @@ -161,7 +161,7 @@ dol_fiche_end();
     print '<br><br>';
     
     print $langs->trans('SendAgreementText');
    -print '<a class="button" href="'.dol_buildpath('/datapolicies/mailing.php').'">'.$langs->trans('SendAgreement').'</a>';
    +print '<a class="button" href="'.dol_buildpath('/datapolicy/mailing.php').'">'.$langs->trans('SendAgreement').'</a>';
     
     llxFooter();
     $db->close();
    diff --git a/htdocs/datapolicies/class/actions_datapolicies.class.php b/htdocs/datapolicy/class/actions_datapolicy.class.php
    similarity index 83%
    rename from htdocs/datapolicies/class/actions_datapolicies.class.php
    rename to htdocs/datapolicy/class/actions_datapolicy.class.php
    index 45e443cb274..5a19b039602 100644
    --- a/htdocs/datapolicies/class/actions_datapolicies.class.php
    +++ b/htdocs/datapolicy/class/actions_datapolicy.class.php
    @@ -17,15 +17,15 @@
      */
     
     /**
    - * \file    datapolicies/class/actions_datapolicies.class.php
    - * \ingroup datapolicies
    + * \file    datapolicy/class/actions_datapolicy.class.php
    + * \ingroup datapolicy
      * \brief   Example hook overload.
      */
     
     /**
    - * Class ActionsDatapolicies
    + * Class ActionsDatapolicy
      */
    -class ActionsDatapolicies
    +class ActionsDatapolicy
     {
         /**
          * @var DoliDB Database handler.
    @@ -91,7 +91,7 @@ class ActionsDatapolicies
         public function doActions($parameters, &$object, &$action, $hookmanager)
         {
             global $conf, $user, $langs;
    -        $langs->load('datapolicies@datapolicies');
    +        $langs->load('datapolicy@datapolicy');
             $error = 0; // Error counter
     
             if (GETPOST('socid') && $parameters['currentcontext'] == 'thirdpartycard') {
    @@ -129,9 +129,9 @@ class ActionsDatapolicies
                         header('Location:' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id);
                     }
                 }
    -        } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'datapolicies_portabilite') {
    +        } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'datapolicy_portabilite') {
                 header('Content-Type: application/csv');
    -            header('Content-Disposition: attachment; filename=datapolicies_portabilite.csv');
    +            header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv');
                 header('Pragma: no-cache');
                 $object->fetch(GETPOST('socid'));
                 echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;' . PHP_EOL;
    @@ -152,9 +152,9 @@ class ActionsDatapolicies
                 echo $object->skype . ';';
                 echo ';';
                 exit;
    -        } elseif ($parameters['currentcontext'] == 'membercard' && $action == 'datapolicies_portabilite') {
    +        } elseif ($parameters['currentcontext'] == 'membercard' && $action == 'datapolicy_portabilite') {
                 header('Content-Type: application/csv');
    -            header('Content-Disposition: attachment; filename=datapolicies_portabilite.csv');
    +            header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv');
                 header('Pragma: no-cache');
                 $soc = $object->fetch_thirdparty();
     
    @@ -176,10 +176,10 @@ class ActionsDatapolicies
                 echo $object->skype . ';';
                 echo dol_print_date($object->birth) . ';';
                 exit;
    -        } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'datapolicies_portabilite') {
    +        } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'datapolicy_portabilite') {
                 $object->fetch(GETPOST('id'));
                 header('Content-Type: application/csv');
    -            header('Content-Disposition: attachment; filename=datapolicies_portabilite.csv');
    +            header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv');
                 header('Pragma: no-cache');
                 $soc = $object->fetch_thirdparty();
                 echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;' . PHP_EOL;
    @@ -200,23 +200,23 @@ class ActionsDatapolicies
                 echo $object->jabberid . ';';
                 echo dol_print_date($object->birth) . ';';
                 exit;
    -        } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'send_datapolicies') {
    +        } elseif ($parameters['currentcontext'] == 'contactcard' && $action == 'send_datapolicy') {
                 $object->fetch(GETPOST('id'));
     
                 require_once  DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
    -            require_once  DOL_DOCUMENT_ROOT . '/datapolicies/class/datapolicies.class.php';
    -            DataPolicies::sendMailDataPoliciesContact($object);
    +            require_once  DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
    +            DataPolicy::sendMailDataPolicyContact($object);
             }
    -         elseif ($parameters['currentcontext'] == 'membercard' && $action == 'send_datapolicies') {
    +         elseif ($parameters['currentcontext'] == 'membercard' && $action == 'send_datapolicy') {
                  $object->fetch(GETPOST('id'));
                 require_once  DOL_DOCUMENT_ROOT . '/adherents/class/adherent.class.php';
    -            require_once  DOL_DOCUMENT_ROOT . '/datapolicies/class/datapolicies.class.php';
    -            DataPolicies::sendMailDataPoliciesAdherent($object);
    -        } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'send_datapolicies') {
    +            require_once  DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
    +            DataPolicy::sendMailDataPolicyAdherent($object);
    +        } elseif ($parameters['currentcontext'] == 'thirdpartycard' && $action == 'send_datapolicy') {
                 $object->fetch(GETPOST('socid'));
                 require_once  DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
    -            require_once  DOL_DOCUMENT_ROOT . '/datapolicies/class/datapolicies.class.php';
    -            DataPolicies::sendMailDataPoliciesCompany($object);
    +            require_once  DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
    +            DataPolicy::sendMailDataPolicyCompany($object);
             }
     
     
    @@ -280,7 +280,7 @@ class ActionsDatapolicies
     
             /* print_r($parameters); print_r($object); echo "action: " . $action; */
             if (in_array($parameters['currentcontext'], array('somecontext1', 'somecontext2'))) {  // do something only for the context 'somecontext1' or 'somecontext2'
    -            $this->resprints = '<option value="0"' . ($disabled ? ' disabled="disabled"' : '') . '>' . $langs->trans("datapoliciesMassAction") . '</option>';
    +            $this->resprints = '<option value="0"' . ($disabled ? ' disabled="disabled"' : '') . '>' . $langs->trans("datapolicyMassAction") . '</option>';
             }
     
             if (!$error) {
    @@ -361,18 +361,18 @@ class ActionsDatapolicies
         function addMoreActionsButtons($parameters, &$object, &$action, $hookmanager)
         {
             global $conf, $user, $langs;
    -        $langs->load('datapolicies@datapolicies');
    +        $langs->load('datapolicy@datapolicy');
     
             if (! empty($conf->global->DATAPOLICIES_ENABLE_EMAILS))
             {
    -	        $dialog = '<div id="dialogdatapolicies" style="display:none;" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">';
    +	        $dialog = '<div id="dialogdatapolicy" style="display:none;" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">';
     	        $dialog .= '<div class="confirmmessage">' . img_help('', '') . ' ' . $langs->trans('DATAPOLICIES_PORTABILITE_CONFIRMATION') . '</div>';
     	        $dialog .= "</div>";
     	        $dialog .= '<script>
     	                  $( function() {
     	                    $("#rpgpdbtn").on("click", function(){
     	                        var href = $(this).attr("href");
    -	                        $( "#dialogdatapolicies" ).dialog({
    +	                        $( "#dialogdatapolicy" ).dialog({
     	                          modal: true,
     	                          buttons: {
     	                            "OK": function() {
    @@ -392,18 +392,18 @@ class ActionsDatapolicies
     	                  </script>';
     	        echo $dialog;
     	        if ($parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
    -	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=datapolicies_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    +	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=datapolicy_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
     	        } elseif ($parameters['currentcontext'] == 'membercard') {
    -	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=datapolicies_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    +	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=datapolicy_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
     	        } elseif ($parameters['currentcontext'] == 'contactcard') {
    -	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=datapolicies_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
    +	            echo '<div class="inline-block divButAction"><a target="_blank" id="rpgpdbtn" class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=datapolicy_portabilite" title="' . $langs->trans('DATAPOLICIES_PORTABILITE_TITLE') . '">' . $langs->trans("DATAPOLICIES_PORTABILITE") . '</a></div>';
     	        }
    -	        if (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
    -	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=send_datapolicies" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    -	        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'membercard') {
    -	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=send_datapolicies" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    -	        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicies_send']) && $parameters['currentcontext'] == 'contactcard') {
    -	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=send_datapolicies" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	        if (!empty($object->mail) && empty($object->array_options['options_datapolicy_send']) && $parameters['currentcontext'] == 'thirdpartycard' && in_array($object->forme_juridique_code, array(11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005)) || $object->typent_id == 8) {
    +	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?socid=" . $object->id . '&action=send_datapolicy" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicy_send']) && $parameters['currentcontext'] == 'membercard') {
    +	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?rowid=" . $object->id . '&action=send_datapolicy" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
    +	        } elseif (!empty($object->mail) && empty($object->array_options['options_datapolicy_send']) && $parameters['currentcontext'] == 'contactcard') {
    +	            echo '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . "?id=" . $object->id . '&action=send_datapolicy" title="' . $langs->trans('DATAPOLICIES_SEND') . '">' . $langs->trans("DATAPOLICIES_SEND") . '</a></div>';
     	        }
             }
         }
    @@ -425,11 +425,11 @@ class ActionsDatapolicies
             if ($parameters['currentcontext'] == 'thirdpartycard') {
                 if (GETPOST('action') == 'create' || GETPOST('action') == 'edit' || GETPOST('action') == '') {
                     $jsscript .= '<script>';
    -                $jsscript .= "var elementToHide = 'tr.societe_extras_datapolicies_consentement, tr.societe_extras_datapolicies_opposition_traitement, tr.societe_extras_datapolicies_opposition_prospection';" . PHP_EOL;
    +                $jsscript .= "var elementToHide = 'tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection';" . PHP_EOL;
                     $jsscript .= "var forme_juridique = [" . PHP_EOL;
                     $jsscript .= "11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005" . PHP_EOL;
                     $jsscript .= "];" . PHP_EOL;
    -                $jsscript .= "function hideRgPD() { if ($('#typent_id').val() == 8 || forme_juridique.indexOf(parseInt($('#forme_juridique_code').val())) > -1) { console.log(elementToHide); $('tr.societe_extras_datapolicies_consentement, tr.societe_extras_datapolicies_opposition_traitement, tr.societe_extras_datapolicies_opposition_prospection').show(); } else { $('tr.societe_extras_datapolicies_consentement, tr.societe_extras_datapolicies_opposition_traitement, tr.societe_extras_datapolicies_opposition_prospection').hide(); }}" . PHP_EOL;
    +                $jsscript .= "function hideRgPD() { if ($('#typent_id').val() == 8 || forme_juridique.indexOf(parseInt($('#forme_juridique_code').val())) > -1) { console.log(elementToHide); $('tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection').show(); } else { $('tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection').hide(); }}" . PHP_EOL;
                     $jsscript .= "hideRgPD();" . PHP_EOL;
                     $jsscript .= "$('#forme_juridique_code, #typent_id').change(function(){ hideRgPD(); });" . PHP_EOL;
                     $jsscript .= '</script>';
    @@ -457,7 +457,7 @@ class ActionsDatapolicies
     
                         require_once DOL_DOCUMENT_ROOT . '/core/class/html.form.class.php';
                         $jsscript .= '<script>';
    -                    $jsscript .= "var elementToHide = 'td.societe_extras_datapolicies_opposition_traitement, td.societe_extras_datapolicies_opposition_prospection, td.societe_extras_datapolicies_consentement';" . PHP_EOL;
    +                    $jsscript .= "var elementToHide = 'td.societe_extras_datapolicy_opposition_traitement, td.societe_extras_datapolicy_opposition_prospection, td.societe_extras_datapolicy_consentement';" . PHP_EOL;
                         $jsscript .= "$(elementToHide).parent('tr').hide();" . PHP_EOL;
                         $jsscript .= '</script>';
                     }
    @@ -465,8 +465,8 @@ class ActionsDatapolicies
             } elseif ($parameters['currentcontext'] == 'contactcard') {
                 if (GETPOST('action') == 'create' || GETPOST('action') == 'edit') {
                     $jsscript .= '<script>';
    -                $jsscript .= "$('#options_datapolicies_opposition_traitement, #options_datapolicies_opposition_prospection, input[name=\"options_datapolicies_opposition_traitement\"], input[name=\"options_datapolicies_opposition_prospection\"]').change(function(){
    -                    if($('#options_datapolicies_opposition_traitement').prop('checked') == true || $('input[name=options_datapolicies_opposition_traitement]').prop('checked') || $('#options_datapolicies_opposition_prospection').prop('checked') || $('input[name=options_datapolicies_opposition_prospection]').prop('checked')) {
    +                $jsscript .= "$('#options_datapolicy_opposition_traitement, #options_datapolicy_opposition_prospection, input[name=\"options_datapolicy_opposition_traitement\"], input[name=\"options_datapolicy_opposition_prospection\"]').change(function(){
    +                    if($('#options_datapolicy_opposition_traitement').prop('checked') == true || $('input[name=options_datapolicy_opposition_traitement]').prop('checked') || $('#options_datapolicy_opposition_prospection').prop('checked') || $('input[name=options_datapolicy_opposition_prospection]').prop('checked')) {
                             $('#no_email').val(1);
                         }
                     });";
    diff --git a/htdocs/datapolicies/class/datapolicies.class.php b/htdocs/datapolicy/class/datapolicy.class.php
    similarity index 80%
    rename from htdocs/datapolicies/class/datapolicies.class.php
    rename to htdocs/datapolicy/class/datapolicy.class.php
    index e6b3af3bf25..3bebdff9302 100644
    --- a/htdocs/datapolicies/class/datapolicies.class.php
    +++ b/htdocs/datapolicy/class/datapolicy.class.php
    @@ -16,9 +16,9 @@
      */
     
     /**
    - * \file    datapolicies/class/datapolicies.class.php
    - * \ingroup datapolicies
    - * \brief   Class to manage feature of Data Policies module.
    + * \file    datapolicy/class/datapolicy.class.php
    + * \ingroup datapolicy
    + * \brief   Class to manage feature of Data Policy module.
      */
     include_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
     include_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
    @@ -26,9 +26,9 @@ include_once DOL_DOCUMENT_ROOT . '/adherents/class/adherent.class.php';
     
     
     /**
    - * Class DataPolicies
    + * Class DataPolicy
      */
    -Class DataPolicies extends Contact
    +Class DataPolicy extends Contact
     {
     	/**
     	 * getAllContactNotInformed
    @@ -45,8 +45,8 @@ Class DataPolicies extends Contact
             $sql .= " FROM " . MAIN_DB_PREFIX . "socpeople as c";
             $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as s ON c.fk_soc = s.rowid";
             $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "socpeople_extrafields as spe ON spe.fk_object = c.rowid";
    -        $sql .= " WHERE (c.statut=1 AND c.no_email=0 AND (spe.datapolicies_consentement=0 OR spe.datapolicies_consentement IS NULL) AND (spe.datapolicies_opposition_traitement=0 OR spe.datapolicies_opposition_traitement IS NULL) AND (spe.datapolicies_opposition_prospection=0 OR spe.datapolicies_opposition_prospection IS NULL))";
    -        $sql .= " AND spe.datapolicies_send IS NULL";
    +        $sql .= " WHERE (c.statut=1 AND c.no_email=0 AND (spe.datapolicy_consentement=0 OR spe.datapolicy_consentement IS NULL) AND (spe.datapolicy_opposition_traitement=0 OR spe.datapolicy_opposition_traitement IS NULL) AND (spe.datapolicy_opposition_prospection=0 OR spe.datapolicy_opposition_prospection IS NULL))";
    +        $sql .= " AND spe.datapolicy_send IS NULL";
             $sql .= " AND c.entity=" . $conf->entity;
             $resql = $this->db->query($sql);
             if ($resql) {
    @@ -57,7 +57,7 @@ Class DataPolicies extends Contact
                     $contact = new Contact($db);
                     $contact->fetch($obj->rowid);
     
    -                DataPolicies::sendMailDataPoliciesContact($contact);
    +                DataPolicy::sendMailDataPolicyContact($contact);
                     $i++;
                 }
             } else {
    @@ -80,8 +80,8 @@ Class DataPolicies extends Contact
             $sql = "SELECT s.rowid";
             $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s";
             $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_extrafields as se ON se.fk_object = s.rowid";
    -        $sql .= " WHERE s.statut=0 AND (se.datapolicies_consentement=0 OR se.datapolicies_consentement IS NULL) AND (se.datapolicies_opposition_traitement=0 OR se.datapolicies_opposition_traitement IS NULL) AND (se.datapolicies_opposition_prospection=0 OR se.datapolicies_opposition_prospection IS NULL)";
    -        $sql .= " AND se.datapolicies_send IS NULL";
    +        $sql .= " WHERE s.statut=0 AND (se.datapolicy_consentement=0 OR se.datapolicy_consentement IS NULL) AND (se.datapolicy_opposition_traitement=0 OR se.datapolicy_opposition_traitement IS NULL) AND (se.datapolicy_opposition_prospection=0 OR se.datapolicy_opposition_prospection IS NULL)";
    +        $sql .= " AND se.datapolicy_send IS NULL";
             $sql .= " AND s.entity=" . $conf->entity;
             $resql = $this->db->query($sql);
             if ($resql) {
    @@ -92,7 +92,7 @@ Class DataPolicies extends Contact
                     $societe = new Societe($db);
                     $societe->fetch($obj->rowid);
     
    -                DataPolicies::sendMailDataPoliciesCompany($societe);
    +                DataPolicy::sendMailDataPolicyCompany($societe);
                     $i++;
                 }
             } else {
    @@ -115,8 +115,8 @@ Class DataPolicies extends Contact
             $sql = "SELECT a.rowid";
             $sql .= " FROM " . MAIN_DB_PREFIX . "adherent as a";
             $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "adherent_extrafields as ae ON ae.fk_object = a.rowid";
    -        $sql .= " WHERE a.statut=0 AND (ae.datapolicies_consentement=0 OR ae.datapolicies_consentement IS NULL) AND (ae.datapolicies_opposition_traitement=0 OR ae.datapolicies_opposition_traitement IS NULL) AND (ae.datapolicies_opposition_prospection=0 OR ae.datapolicies_opposition_prospection IS NULL)";
    -        $sql .= " AND ae.datapolicies_send IS NULL";
    +        $sql .= " WHERE a.statut=0 AND (ae.datapolicy_consentement=0 OR ae.datapolicy_consentement IS NULL) AND (ae.datapolicy_opposition_traitement=0 OR ae.datapolicy_opposition_traitement IS NULL) AND (ae.datapolicy_opposition_prospection=0 OR ae.datapolicy_opposition_prospection IS NULL)";
    +        $sql .= " AND ae.datapolicy_send IS NULL";
             $sql .= " AND a.entity=" . $conf->entity;
             $resql = $this->db->query($sql);
             if ($resql) {
    @@ -127,7 +127,7 @@ Class DataPolicies extends Contact
                     $adherent = new Adherent($db);
                     $adherent->fetch($obj->rowid);
     
    -                DataPolicies::sendMailDataPoliciesAdherent($adherent);
    +                DataPolicy::sendMailDataPolicyAdherent($adherent);
                     $i++;
                 }
             } else {
    @@ -137,12 +137,12 @@ Class DataPolicies extends Contact
         }
     
         /**
    -     * sendMailDataPoliciesContact
    +     * sendMailDataPolicyContact
          *
          * @param 	mixed		$contact		Contact
          * @return	void
          */
    -    function sendMailDataPoliciesContact($contact)
    +    function sendMailDataPolicyContact($contact)
         {
          	global $langs, $conf, $db, $user;
     
    @@ -171,8 +171,8 @@ Class DataPolicies extends Contact
          	$deliveryreceipt = 0;
     
          	$substitutionarray = array(
    -     	'__LINKACCEPT__' => '<a href="'.dol_buildpath('/datapolicies/public/index.php?action=1&c='.$contact->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linka.'</a>',
    -     	'__LINKREFUSED__' => '<a href="'.dol_buildpath('/datapolicies/public/index.php?action=2&c='.$contact->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linkr.'</a>',
    +     	'__LINKACCEPT__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=1&c='.$contact->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linka.'</a>',
    +     	'__LINKREFUSED__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=2&c='.$contact->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linkr.'</a>',
          	'__FIRSTNAME__' => $contact->firstname,
          	'__NAME__' => $contact->lastname,
          	'__CIVILITY__' => $contact->civility,
    @@ -202,7 +202,7 @@ Class DataPolicies extends Contact
          		if (!$error) {
     
          			$resultmasssend .= $langs->trans("MailSent") . ': ' . $sendto . "<br>";
    -     			$contact->array_options['options_datapolicies_send'] = date('Y-m-d', time());
    +     			$contact->array_options['options_datapolicy_send'] = date('Y-m-d', time());
          			$contact->update($contact->id);
     
          		} else {
    @@ -213,12 +213,12 @@ Class DataPolicies extends Contact
         }
     
         /**
    -     * sendMailDataPoliciesCompany
    +     * sendMailDataPolicyCompany
          *
          * @param Societe	$societe	Object societe
          * @return	void
          */
    -    function sendMailDataPoliciesCompany($societe)
    +    function sendMailDataPolicyCompany($societe)
         {
          	global $langs, $conf, $db, $user;
     
    @@ -248,8 +248,8 @@ Class DataPolicies extends Contact
          	$deliveryreceipt = 0;
     
          	$substitutionarray = array(
    -            '__LINKACCEPT__' => '<a href="'.dol_buildpath('/datapolicies/public/index.php?action=1&s='.$societe->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linka.'</a>',
    -            '__LINKREFUSED__' => '<a href="'.dol_buildpath('/datapolicies/public/index.php?action=2&s='.$societe->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linkr.'</a>',
    +            '__LINKACCEPT__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=1&s='.$societe->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linka.'</a>',
    +            '__LINKREFUSED__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=2&s='.$societe->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linkr.'</a>',
          	);
          	$subject = make_substitutions($subject, $substitutionarray);
          	$message = make_substitutions($message, $substitutionarray);
    @@ -275,7 +275,7 @@ Class DataPolicies extends Contact
     
          		if (!$error) {
          			$resultmasssend .= $langs->trans("MailSent") . ': ' . $sendto . "<br>";
    -     			$societe->array_options['options_datapolicies_send'] = date('Y-m-d', time());
    +     			$societe->array_options['options_datapolicy_send'] = date('Y-m-d', time());
          			$societe->update($societe->id);
          		} else {
          			dol_print_error($db);
    @@ -285,12 +285,12 @@ Class DataPolicies extends Contact
         }
     
         /**
    -     * sendMailDataPoliciesAdherent
    +     * sendMailDataPolicyAdherent
          *
          * @param Adherent	$adherent		Member
          * @return void
          */
    -    function sendMailDataPoliciesAdherent($adherent)
    +    function sendMailDataPolicyAdherent($adherent)
         {
         	global $langs, $conf, $db, $user;
     
    @@ -318,8 +318,8 @@ Class DataPolicies extends Contact
         	$deliveryreceipt = 0;
     
         	$substitutionarray = array(
    -            '__LINKACCEPT__' => '<a href="'.dol_buildpath('/datapolicies/public/index.php?action=1&a='.$adherent->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linka.'</a>',
    -            '__LINKREFUSED__' => '<a href="'.dol_buildpath('/datapolicies/public/index.php?action=2&a='.$adherent->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linkr.'</a>',
    +            '__LINKACCEPT__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=1&a='.$adherent->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linka.'</a>',
    +            '__LINKREFUSED__' => '<a href="'.dol_buildpath('/datapolicy/public/index.php?action=2&a='.$adherent->id.'&l='.$l.'&key='.$code,3).'" target="_blank">'.$linkr.'</a>',
         	);
         	$subject = make_substitutions($subject, $substitutionarray);
         	$message = make_substitutions($message, $substitutionarray);
    @@ -346,7 +346,7 @@ Class DataPolicies extends Contact
     
         		if (!$error) {
         			$resultmasssend .= $langs->trans("MailSent") . ': ' . $sendto . "<br>";
    -    			$adherent->array_options['options_datapolicies_send'] = date('Y-m-d', time());
    +    			$adherent->array_options['options_datapolicy_send'] = date('Y-m-d', time());
         			$adherent->update($user);
     
         		} else {
    diff --git a/htdocs/datapolicies/class/datapoliciescron.class.php b/htdocs/datapolicy/class/datapolicycron.class.php
    similarity index 98%
    rename from htdocs/datapolicies/class/datapoliciescron.class.php
    rename to htdocs/datapolicy/class/datapolicycron.class.php
    index c87df67498d..f6de8b9b498 100644
    --- a/htdocs/datapolicies/class/datapoliciescron.class.php
    +++ b/htdocs/datapolicy/class/datapolicycron.class.php
    @@ -17,15 +17,15 @@
      */
     
     /**
    - * \file    datapolicies/class/datapoliciescron.class.php
    - * \ingroup datapolicies
    + * \file    datapolicy/class/datapolicycron.class.php
    + * \ingroup datapolicy
      * \brief   Example hook overload.
      */
     
     /**
    - * Class DataPoliciesCron
    + * Class DataPolicyCron
      */
    -class DataPoliciesCron
    +class DataPolicyCron
     {
     	/**
     	 * Function exec
    @@ -36,7 +36,7 @@ class DataPoliciesCron
         {
             global $conf, $db, $langs, $user;
     
    -        $langs->load('datapolicies@datapolicies');
    +        $langs->load('datapolicy@datapolicy');
     
             // FIXME Removed hardcoded values of id
             $arrayofparameters=array(
    @@ -510,11 +510,11 @@ class DataPoliciesCron
         {
             global $conf, $db, $langs, $user;
     
    -        $langs->load('datapolicies@datapolicies');
    +        $langs->load('datapolicy@datapolicy');
     
    -        require_once DOL_DOCUMENT_ROOT . '/datapolicies/class/datapolicies.class.php';
    +        require_once DOL_DOCUMENT_ROOT . '/datapolicy/class/datapolicy.class.php';
     
    -        $contacts = new DataPolicies($db);
    +        $contacts = new DataPolicy($db);
             $contacts->getAllContactNotInformed();
             $contacts->getAllCompaniesNotInformed();
             $contacts->getAllAdherentsNotInformed();
    diff --git a/htdocs/datapolicies/img/datapolicies.png b/htdocs/datapolicy/img/datapolicy.png
    similarity index 100%
    rename from htdocs/datapolicies/img/datapolicies.png
    rename to htdocs/datapolicy/img/datapolicy.png
    diff --git a/htdocs/datapolicies/img/gfdl.png b/htdocs/datapolicy/img/gfdl.png
    similarity index 100%
    rename from htdocs/datapolicies/img/gfdl.png
    rename to htdocs/datapolicy/img/gfdl.png
    diff --git a/htdocs/datapolicies/img/gplv3.png b/htdocs/datapolicy/img/gplv3.png
    similarity index 100%
    rename from htdocs/datapolicies/img/gplv3.png
    rename to htdocs/datapolicy/img/gplv3.png
    diff --git a/htdocs/datapolicies/img/object_datapolicies.png b/htdocs/datapolicy/img/object_datapolicy.png
    similarity index 100%
    rename from htdocs/datapolicies/img/object_datapolicies.png
    rename to htdocs/datapolicy/img/object_datapolicy.png
    diff --git a/htdocs/datapolicies/img/object_inoveaconseil.png b/htdocs/datapolicy/img/object_inoveaconseil.png
    similarity index 100%
    rename from htdocs/datapolicies/img/object_inoveaconseil.png
    rename to htdocs/datapolicy/img/object_inoveaconseil.png
    diff --git a/htdocs/datapolicy/langs/en_US/datapolicy.lang b/htdocs/datapolicy/langs/en_US/datapolicy.lang
    new file mode 100644
    index 00000000000..ddcd2180cb0
    --- /dev/null
    +++ b/htdocs/datapolicy/langs/en_US/datapolicy.lang
    @@ -0,0 +1,92 @@
    +# Copyright (C) 2018 Nicolas ZABOURI    <info@inovea-conseil.com>
    +#
    +# This program is free software: you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation, either version 3 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +
    +# Module label 'ModuledatapolicyName'
    +Module4100Name = Data Privacy Policy
    +# Module description 'ModuledatapolicyDesc'
    +Module4100Desc = Module to manage Data Privacy (Conformity with the GDPR)
    +
    +#
    +# Page d'administration
    +#
    +datapolicySetup = Module Data Privacy Policy Setup
    +Deletion = Deletion of data
    +datapolicySetupPage = Depending of laws of your countries (Example <a href="http://www.privacy-regulation.eu/en/5.htm" target="_blank">Article 5</a> of the GDPR), personal data must be kept for a period not exceeding that necessary for the purposes for which they were collected, except for archival purposes.<br>The deletion will be done automatically after a certain duration without event (the duration which you will have indicated below).
    +NB_MONTHS = %s months
    +ONE_YEAR = 1 year
    +NB_YEARS = %s years
    +DATAPOLICY_TIERS_CLIENT = Customer
    +DATAPOLICY_TIERS_PROSPECT = Prospect
    +DATAPOLICY_TIERS_PROSPECT_CLIENT = Prospect/Customer
    +DATAPOLICY_TIERS_NIPROSPECT_NICLIENT = Nor prospect/Nor customer
    +DATAPOLICY_TIERS_FOURNISSEUR = Supplier
    +DATAPOLICY_CONTACT_CLIENT = Customer
    +DATAPOLICY_CONTACT_PROSPECT = Prospect
    +DATAPOLICY_CONTACT_PROSPECT_CLIENT = Prospect/Customer
    +DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT = Nor prospect/Nor customer
    +DATAPOLICY_CONTACT_FOURNISSEUR = Supplier
    +DATAPOLICY_ADHERENT = Member
    +DATAPOLICY_Tooltip_SETUP = Type of contact - Indicate your choices for each type.
    +DATAPOLICYMail=Emails Setup
    +DATAPOLICYSUBJECTMAIL=Subject of email
    +DATAPOLICYCONTENTMAIL=Content of the email
    +DATAPOLICYSUBSITUTION=You can use the following variables in your email (LINKACCEPT allows to create a link recording the agreement of the person, LINKREFUSED makes it possible to record the refusal of the person):
    +DATAPOLICYACCEPT=Message after agreement
    +DATAPOLICYREFUSE=Message after desagreement
    +SendAgreementText=You can send a GDPR email to all your relevant contacts (who have not yet received an email and for which you have not registered anything about their GDPR agreement). To do this, use the following button.
    +SendAgreement=Send emails
    +AllAgreementSend = All emails have been sent
    +TXTLINKDATAPOLICYACCEPT= Text for the link "agreement" 
    +TXTLINKDATAPOLICYREFUSE= Text for the link "desagreement" 
    +
    +
    +#
    +# Extrafield
    +#
    +DATAPOLICY_BLOCKCHECKBOX = GDPR : Processing of personal data
    +DATAPOLICY_consentement = Consent obtained for the processing of personal data 
    +DATAPOLICY_opposition_traitement = Opposes the processing of his personal data
    +DATAPOLICY_opposition_prospection = Opposes the processing of his personal data for the purposes of prospecting
    +
    +#
    +# Popup
    +#
    +DATAPOLICY_POPUP_ANONYME_TITLE = Anonymize a thirdparty
    +DATAPOLICY_POPUP_ANONYME_TEXTE = You can not delete this contact from Dolibarr because there are related items. In accordance with the GDPR, you will make all this data anonymous to respect your obligations. Would you like to continue ?
    +
    +#
    +# Bouton portabilité
    +# 
    +DATAPOLICY_PORTABILITE = Portability GDPR
    +DATAPOLICY_PORTABILITE_TITLE = Export of personal data
    +DATAPOLICY_PORTABILITE_CONFIRMATION = You want to export the personal data of this contact. Are you sure ?
    +
    +#
    +# Note ajoutés lors d'une anonymisation
    +#
    +ANONYMISER_AT = Anonymised the %s
    +
    +#V2
    +DATAPOLICYReturn=GDPR Validation
    +DATAPOLICY_date = Date of agreement/desagreement GDPR
    +DATAPOLICY_send = Date sending agreement email
    +DATAPOLICYReturn = GDPR Return
    +DATAPOLICY_SEND = Send GDPR email
    +MailSent = Email has been sent
    +
    +#ERROR
    +ErrorSubjectIsRequired= Error : The subject of email is required. Indicate it in the module setup
    +=Due to a technical problem, we were unable to register your choice. We apologize for that. Contact us to send us your choice.
    +NUMBER_MONTH_BEFORE_DELETION = Number of month before deletion
    diff --git a/htdocs/datapolicy/langs/fr_FR/datapolicy.lang b/htdocs/datapolicy/langs/fr_FR/datapolicy.lang
    new file mode 100644
    index 00000000000..7ee710aae2e
    --- /dev/null
    +++ b/htdocs/datapolicy/langs/fr_FR/datapolicy.lang
    @@ -0,0 +1,97 @@
    +# Copyright (C) 2018  INOVEA CONSEil info@inovea-conseil.com
    +#
    +# This program is free software: you can redistribute it and/or modify
    +# it under the terms of the GNU General Public License as published by
    +# the Free Software Foundation, either version 3 of the License, or
    +# (at your option) any later version.
    +#
    +# This program is distributed in the hope that it will be useful,
    +# but WITHOUT ANY WARRANTY; without even the implied warranty of
    +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +# GNU General Public License for more details.
    +#
    +# You should have received a copy of the GNU General Public License
    +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
    +
    +#
    +# Générique
    +#
    +
    +# Module label 'ModuledatapolicyName'
    +Module4100Name = Protection des Données
    +# Module description 'ModuledatapolicyDesc'
    +Module4100Desc = Module de gestion de la protection des données (RGPD)
    +
    +#
    +# Page d'administration
    +#
    +datapolicySetup = Configuration du module Protection des données
    +Settings_DATAPOLICY = Paramétrage du module Protection des données
    +datapolicySetupPage = Selon la loi de votre pays (Exemple <a href="http://www.privacy-regulation.eu/fr/5.htm" target="_blank">l’article 5</a> du RGPD), les données à caractère personnel doivent être conservées pendant une durée n’excédant pas celle nécessaire au regard des finalités pour lesquelles elles ont été traitées, à l’exception de fins archivistiques. La suppression se fera automatiquement après une certaine durée sans évènement (la durée que vous aurez indiquée ci-dessous).
    +NB_MONTHS = %s mois
    +ONE_YEAR = 1 an
    +NB_YEARS = %s ans
    +DATAPOLICY_TIERS_CLIENT = Client
    +DATAPOLICY_TIERS_PROSPECT = Prospect
    +DATAPOLICY_TIERS_PROSPECT_CLIENT = Prospect/Client
    +DATAPOLICY_TIERS_NIPROSPECT_NICLIENT = Ni prospect / Ni client
    +DATAPOLICY_TIERS_FOURNISSEUR = Fournisseur
    +DATAPOLICY_CONTACT_CLIENT = Client
    +DATAPOLICY_CONTACT_PROSPECT = Prospect
    +DATAPOLICY_CONTACT_PROSPECT_CLIENT = Prospect/Client
    +DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT = Ni prospect / Ni client
    +DATAPOLICY_CONTACT_FOURNISSEUR = Fournisseur
    +DATAPOLICY_ADHERENT = Adhérent
    +DATAPOLICY_Tooltip_SETUP = Type du contact - Indiquez vos choix pour chaque type.
    +DATAPOLICYMail=Paramétrage des emails
    +DATAPOLICYSUBJECTMAIL=Objet du mail
    +DATAPOLICYCONTENTMAIL=Contenu du mail
    +DATAPOLICYSUBSITUTION=Vous pouvez utiliser les variables suivantes dans votre email (LINKACCEPT permet de créer un lien enregistrant l'acceptation de la personne, LINKREFUSED permet d'enregistrer le refus de la personne) :
    +DATAPOLICYACCEPT=Message suite acceptation
    +DATAPOLICYREFUSE=Message suite opposition
    +SendAgreementText=Vous pouvez envoyer un email DATAPOLICY à tous vos contacts concernés (qui n'ont pas encore reçus de mail et pour lesquels vous n'avez rien enregistré concernant leur accord/désaccord DATAPOLICY). Pour cela, utilisez le bouton suivant.
    +SendAgreement=Envoyer les emails
    +AllAgreementSend = Tous les e-mails de consentement ont été envoyés
    +TXTLINKDATAPOLICYACCEPT= Texte du lien d'acceptation
    +TXTLINKDATAPOLICYREFUSE= Texte du lien d'opposition
    +
    +
    +
    +#
    +# Extrafield
    +#
    +DATAPOLICY_BLOCKCHECKBOX = DATAPOLICY : Traitement des données à caractère personnel
    +DATAPOLICY_consentement = Consentement recueilli pour le traitement des données à caractère personnel le concernant
    +DATAPOLICY_opposition_traitement = S’oppose au traitement de ses données à caractère personnel
    +DATAPOLICY_opposition_prospection = S’oppose au traitement de ses données à caractère personnel à des fins de prospection
    +
    +#
    +# Popup
    +#
    +DATAPOLICY_POPUP_ANONYME_TITLE = Anonymiser un tiers
    +DATAPOLICY_POPUP_ANONYME_TEXTE = Vous ne pouvez pas supprimer ce contact de Dolibarr car des éléments y sont liés. Conformément au DATAPOLICY, vous allez rendre toutes ces données anonymes afin de respecter vos obligations. Souhaitez-vous continuer ?
    +
    +#
    +# Bouton portabilité
    +# 
    +DATAPOLICY_PORTABILITE = Portabilité DATAPOLICY
    +DATAPOLICY_PORTABILITE_TITLE = Export des données à caractère personnel
    +DATAPOLICY_PORTABILITE_CONFIRMATION = Vous souhaitez exporter les données à caractère personnel de ce contact. Etes-vous sûr ?
    +
    +#
    +# Note ajoutés lors d'une anonymisation
    +#
    +ANONYMISER_AT = Anonymisé le %s
    +
    +#V2
    +DATAPOLICYReturn=Validation DATAPOLICY
    +DATAPOLICY_date=Date d'accord/opposition au traitement
    +DATAPOLICY_send=Date envoi consentement
    +DATAPOLICYReturn=Retour DATAPOLICY
    +DATAPOLICY_SEND=Envoyer l'email de consentement
    +MailSent=L'email a bien été envoyé
    +
    +#ERROR
    +ErrorSubjectIsRequired=Erreur : vous n'avez pas indiqué l'objet de l'email dans la configuration
    +=Suite à un problème technique, nous n'avons pas pu enregistrer votre choix. Nous nous en excusons. Contactez-nous pour nous transmettre votre choix.
    +NUMBER_MONTH_BEFORE_DELETION = Nombre de mois avant suppression des données
    diff --git a/htdocs/datapolicy/langs/it_IT/datapolicy.lang b/htdocs/datapolicy/langs/it_IT/datapolicy.lang
    new file mode 100644
    index 00000000000..d8858b56c5b
    --- /dev/null
    +++ b/htdocs/datapolicy/langs/it_IT/datapolicy.lang
    @@ -0,0 +1,78 @@
    +# Copyright (C) 2018 INOVEA CONSEIl info@inovea-conseil.com - Thanks to Claudio Aschieri
    +#
    +# # Module label 'ModuledatapolicyName'
    +Module4100Name = Data Policy
    +# Module description 'ModuledatapolicyDesc'
    +Module4100Desc = Conformità con GDPR
    +
    +#
    +# Page d'administration
    +#
    +datapolicySetup = Module Setup
    +Settings_DATAPOLICY = Configurazione modulo GDPR 
    +datapolicySetupPage = In accordo con <a href="http://www.privacy-regulation.eu/it/5.htm" target="_blank">l'art 5 del GDPR </a> i dati personali devono essere conservati per un periodo di tempo che .... ed eliminati se non sono più utili agli scopi per cui sono stati processati.
    +NB_MONTHS = %s mesi
    +ONE_YEAR = 1 anno
    +NB_YEARS = %s anni
    +DATAPOLICY_TIERS_CLIENT = Cliente
    +DATAPOLICY_TIERS_PROSPECT = Fornitore
    +DATAPOLICY_TIERS_PROSPECT_CLIENT = Potenziale Cliente / Cliente
    +DATAPOLICY_TIERS_NIPROSPECT_NICLIENT = Nè potenziale cliente / Nè cliente
    +DATAPOLICY_TIERS_FOURNISSEUR = Fornitore
    +DATAPOLICY_CONTACT_CLIENT = Cliente
    +DATAPOLICY_CONTACT_PROSPECT = Potenziale cliente
    +DATAPOLICY_CONTACT_PROSPECT_CLIENT = Potenziale Cliente / Cliente
    +DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT = Nè potenziale cliente / Nè cliente
    +DATAPOLICY_CONTACT_FOURNISSEUR = Fornitore
    +DATAPOLICY_ADHERENT = Membri
    +DATAPOLICY_Tooltip_SETUP = Tipo di contatto - Indica la scelta per ogni tipologia
    +DATAPOLICYMail=Configurazione Email
    +DATAPOLICYSUBJECTMAIL=Subject dell'e-mail
    +DATAPOLICYCONTENTMAIL=Contenuto dell'e-mail
    +DATAPOLICYSUBSITUTION=Puoi utilizzare le seguenti variabili nella tua email (LINKACCEPT consente di creare un link per registrare l'accettazione della persona, LINKREFUSED consente di registrare il rifiuto della persona):
    +DATAPOLICYACCEPT= Messaggio dopo il consenso
    +DATAPOLICYREFUSE=Messaggio dopo il rifiuto
    +SendAgreementText=Puoi inviare un'email GDPR a tutti i tuoi contatti rilevanti (che non hanno ancora ricevuto un'e-mail e per i quali non hai registrato nulla sul loro accordo GDPR). Per fare ciò, utilizzare il seguente pulsante.
    +SendAgreement=Invia emails
    +AllAgreementSend = Tutte le email sono state inviate
    +TXTLINKDATAPOLICYACCEPT= Testo per il link "Consenso" 
    +TXTLINKDATAPOLICYREFUSE= Testo per il link "Consenso negato" 
    +
    +#
    +# Extrafield
    +#
    +DATAPOLICY_BLOCKCHECKBOX = GDPR : Trattamento dei dati personali
    +DATAPOLICY_consentement = Consenso ottenuto al Trattamento dei dati personali
    +DATAPOLICY_opposition_traitement = Consenso negato al trattamento dei dati personali
    +DATAPOLICY_opposition_prospection = Consenso negato al trattamento dei dati personali a fini commerciali
    +
    +#
    +# Popup
    +#
    +DATAPOLICY_POPUP_ANONYME_TITLE = Anonimizza un soggetto terzo
    +DATAPOLICY_POPUP_ANONYME_TEXTE = Impossibile eliminare questo contatto da Dolibarr perchè vi sono elementi collegati. In conformità con il GDPR, renderai tutti questi dati anonimi per rispettare i tuoi obblighi. Vuoi continuare?
    +
    +
    +#
    +# Bouton portabilité
    +# 
    +DATAPOLICY_PORTABILITE = Portabilità GDPR
    +DATAPOLICY_PORTABILITE_TITLE = Esporta i dati personali
    +DATAPOLICY_PORTABILITE_CONFIRMATION = Vuoi davvero esportare i dati personali di questo contatto?
    +
    +#
    +# Note ajoutée lors d'une anonymisation
    +#
    +ANONYMISER_AT = Anonimizzato il %s
    +
    +#V2
    +DATAPOLICYReturn=GDPR Validazione
    +DATAPOLICY_date = Data di accordo / disaccordo GDPR
    +DATAPOLICY_send = Data di invio del consenso (e-mail)
    +DATAPOLICYReturn = GDPR ritorno
    +DATAPOLICY_SEND = Inviare GDPR e-mail
    +MailSent=L'email è stata inviata
    +
    +#ERROR
    +ErrorSubjectIsRequired= Errore: L'oggetto della mail è obbligatorio. Inserisci l'oggetto nella configurazione del modulo.
    +=A causa di un problema tecnico, non siamo stati in grado di registrare la tua scelta. Ci scusiamo per questo. Contattaci per inviarci la tua scelta.
    diff --git a/htdocs/datapolicies/lib/datapolicies.lib.php b/htdocs/datapolicy/lib/datapolicy.lib.php
    similarity index 72%
    rename from htdocs/datapolicies/lib/datapolicies.lib.php
    rename to htdocs/datapolicy/lib/datapolicy.lib.php
    index cca255801a8..41c92299989 100644
    --- a/htdocs/datapolicies/lib/datapolicies.lib.php
    +++ b/htdocs/datapolicy/lib/datapolicy.lib.php
    @@ -16,9 +16,9 @@
      */
     
     /**
    - * \file    datapolicies/lib/datapolicies.lib.php
    - * \ingroup datapolicies
    - * \brief   Library files with common functions for datapolicies
    + * \file    datapolicy/lib/datapolicy.lib.php
    + * \ingroup datapolicy
    + * \brief   Library files with common functions for datapolicy
      */
     
     /**
    @@ -26,29 +26,29 @@
      *
      * @return array
      */
    -function datapoliciesAdminPrepareHead()
    +function datapolicyAdminPrepareHead()
     {
     	global $langs, $conf;
     
    -	$langs->load("datapolicies@datapolicies");
    +	$langs->load("datapolicy@datapolicy");
     
     	$h = 0;
     	$head = array();
     
    -	$head[$h][0] = dol_buildpath("/datapolicies/admin/setup.php", 1);
    -	$head[$h][1] = $langs->trans("Settings_DATAPOLICIES");
    +	$head[$h][0] = dol_buildpath("/datapolicy/admin/setup.php", 1);
    +	$head[$h][1] = $langs->trans("Deletion");
     	$head[$h][2] = 'settings';
     	$h++;
     
     	if (! empty($conf->global->DATAPOLICIES_ENABLE_EMAILS))
     	{
    -		$head[$h][0] = dol_buildpath("/datapolicies/admin/setupmail.php", 1);
    +		$head[$h][0] = dol_buildpath("/datapolicy/admin/setupmail.php", 1);
     		$head[$h][1] = $langs->trans("DATAPOLICIESMail");
     		$head[$h][2] = 'settings';
     		$h++;
     	}
     
    -	complete_head_from_modules($conf, $langs, $object, $head, $h, 'datapolicies');
    +	complete_head_from_modules($conf, $langs, $object, $head, $h, 'datapolicy');
     
     	return $head;
     }
    diff --git a/htdocs/datapolicies/mailing.php b/htdocs/datapolicy/mailing.php
    similarity index 81%
    rename from htdocs/datapolicies/mailing.php
    rename to htdocs/datapolicy/mailing.php
    index 08c24d9aceb..d65b2bdced4 100644
    --- a/htdocs/datapolicies/mailing.php
    +++ b/htdocs/datapolicy/mailing.php
    @@ -16,26 +16,26 @@
      */
     
     /**
    - * \file    datapolicies/mailing.php
    - * \ingroup datapolicies
    - * \brief   datapolicies mailing page.
    + * \file    datapolicy/mailing.php
    + * \ingroup datapolicy
    + * \brief   datapolicy mailing page.
      */
     
     require '../../main.inc.php';
     dol_include_once('/contact/class/contact.class.php');
    -dol_include_once('/datapolicies/class/datapolicies.class.php');
    +dol_include_once('/datapolicy/class/datapolicy.class.php');
     
     $idcontact = GETPOST('idc');
     
     if(!empty($idcontact)){
         $contact = new Contact($db);
         $contact->fetch($idcontact);
    -    DataPolicies::sendMailDataPoliciesContact($contact);
    +    DataPolicy::sendMailDataPolicyContact($contact);
     
     
     }else{
     
    -    $contacts = new DataPolicies($db);
    +    $contacts = new DataPolicy($db);
         $contacts->getAllContactNotInformed();
         $contacts->getAllCompaniesNotInformed();
         $contacts->getAllAdherentsNotInformed();
    diff --git a/htdocs/datapolicies/modulebuilder.txt b/htdocs/datapolicy/modulebuilder.txt
    similarity index 100%
    rename from htdocs/datapolicies/modulebuilder.txt
    rename to htdocs/datapolicy/modulebuilder.txt
    diff --git a/htdocs/datapolicies/public/index.php b/htdocs/datapolicy/public/index.php
    similarity index 66%
    rename from htdocs/datapolicies/public/index.php
    rename to htdocs/datapolicy/public/index.php
    index 7ecceeb9940..58f7968f05d 100644
    --- a/htdocs/datapolicies/public/index.php
    +++ b/htdocs/datapolicy/public/index.php
    @@ -17,9 +17,9 @@
      */
     
     /**
    - * \file    datapolicies/admin/setup.php
    - * \ingroup datapolicies
    - * \brief   datapolicies setup page.
    + * \file    datapolicy/admin/setup.php
    + * \ingroup datapolicy
    + * \brief   datapolicy setup page.
      */
     
     if (!defined('NOLOGIN'))
    @@ -34,7 +34,7 @@ dol_include_once('/contact/class/contact.class.php');
     dol_include_once('/societe/class/societe.class.php');
     dol_include_once('/adherents/class/adherent.class.php');
     dol_include_once('/user/class/user.class.php');
    -dol_include_once('/datapolicies/class/datapolicies.class.php');
    +dol_include_once('/datapolicy/class/datapolicy.class.php');
     
     $idc = GETPOST('c', 'int');
     $ids = GETPOST('s', 'int');
    @@ -45,7 +45,7 @@ $code = GETPOST('key', 'alpha');
     
     $acc = "DATAPOLICIESACCEPT_" . $lang;
     $ref = "DATAPOLICIESREFUSE_" . $lang;
    -$langs->load('datapolicies@datapolicies',0,0,$lang);
    +$langs->load('datapolicy@datapolicy',0,0,$lang);
     
     if (empty($action) || (empty($idc) && empty($ids) && empty($ida))) {
         return 0;
    @@ -56,18 +56,18 @@ if (empty($action) || (empty($idc) && empty($ids) && empty($ida))) {
         if ($check != $code) {
             $return = $langs->trans('ErrorEmailDATAPOLICIES');
         } elseif ($action == 1) {
    -        $contact->array_options['options_datapolicies_consentement'] = 1;
    -        $contact->array_options['options_datapolicies_opposition_traitement'] = 0;
    -        $contact->array_options['options_datapolicies_opposition_prospection'] = 0;
    -        $contact->array_options['options_datapolicies_date'] = date('Y-m-d', time());
    +        $contact->array_options['options_datapolicy_consentement'] = 1;
    +        $contact->array_options['options_datapolicy_opposition_traitement'] = 0;
    +        $contact->array_options['options_datapolicy_opposition_prospection'] = 0;
    +        $contact->array_options['options_datapolicy_date'] = date('Y-m-d', time());
     
             $return = $conf->global->$acc;
         } elseif ($action == 2) {
             $contact->no_email = 1;
    -        $contact->array_options['options_datapolicies_consentement'] = 0;
    -        $contact->array_options['options_datapolicies_opposition_traitement'] = 1;
    -        $contact->array_options['options_datapolicies_opposition_prospection'] = 1;
    -        $contact->array_options['options_datapolicies_date'] = date('Y-m-d', time());
    +        $contact->array_options['options_datapolicy_consentement'] = 0;
    +        $contact->array_options['options_datapolicy_opposition_traitement'] = 1;
    +        $contact->array_options['options_datapolicy_opposition_prospection'] = 1;
    +        $contact->array_options['options_datapolicy_date'] = date('Y-m-d', time());
     
             $return = $conf->global->$ref;
         }
    @@ -79,16 +79,16 @@ if (empty($action) || (empty($idc) && empty($ids) && empty($ida))) {
         if ($check != $code) {
             $return = $langs->trans('ErrorEmailDATAPOLICIES');
         } elseif ($action == 1) {
    -        $societe->array_options['options_datapolicies_consentement'] = 1;
    -        $societe->array_options['options_datapolicies_opposition_traitement'] = 0;
    -        $societe->array_options['options_datapolicies_opposition_prospection'] = 0;
    -        $societe->array_options['options_datapolicies_date'] = date('Y-m-d', time());
    +        $societe->array_options['options_datapolicy_consentement'] = 1;
    +        $societe->array_options['options_datapolicy_opposition_traitement'] = 0;
    +        $societe->array_options['options_datapolicy_opposition_prospection'] = 0;
    +        $societe->array_options['options_datapolicy_date'] = date('Y-m-d', time());
             $return = $conf->global->$acc;
         } elseif ($action == 2) {
    -        $societe->array_options['options_datapolicies_consentement'] = 0;
    -        $societe->array_options['options_datapolicies_opposition_traitement'] = 1;
    -        $societe->array_options['options_datapolicies_opposition_prospection'] = 1;
    -        $societe->array_options['options_datapolicies_date'] = date('Y-m-d', time());
    +        $societe->array_options['options_datapolicy_consentement'] = 0;
    +        $societe->array_options['options_datapolicy_opposition_traitement'] = 1;
    +        $societe->array_options['options_datapolicy_opposition_prospection'] = 1;
    +        $societe->array_options['options_datapolicy_date'] = date('Y-m-d', time());
     
             $return = $conf->global->$ref;
         }
    @@ -100,16 +100,16 @@ if (empty($action) || (empty($idc) && empty($ids) && empty($ida))) {
         if ($check != $code) {
             $return = $langs->trans('ErrorEmailDATAPOLICIES');
         } elseif ($action == 1) {
    -        $adherent->array_options['options_datapolicies_consentement'] = 1;
    -        $adherent->array_options['options_datapolicies_opposition_traitement'] = 0;
    -        $adherent->array_options['options_datapolicies_opposition_prospection'] = 0;
    -        //$adherent->array_options['options_datapolicies_date'] = date('Y-m-d', time());
    +        $adherent->array_options['options_datapolicy_consentement'] = 1;
    +        $adherent->array_options['options_datapolicy_opposition_traitement'] = 0;
    +        $adherent->array_options['options_datapolicy_opposition_prospection'] = 0;
    +        //$adherent->array_options['options_datapolicy_date'] = date('Y-m-d', time());
             $return = $conf->global->$acc;
         } elseif ($action == 2) {
    -        $adherent->array_options['options_datapolicies_consentement'] = 0;
    -        $adherent->array_options['options_datapolicies_opposition_traitement'] = 1;
    -        $adherent->array_options['options_datapolicies_opposition_prospection'] = 1;
    -        //$adherent->array_options['options_datapolicies_date'] = date('Y-m-d', time());
    +        $adherent->array_options['options_datapolicy_consentement'] = 0;
    +        $adherent->array_options['options_datapolicy_opposition_traitement'] = 1;
    +        $adherent->array_options['options_datapolicy_opposition_prospection'] = 1;
    +        //$adherent->array_options['options_datapolicy_date'] = date('Y-m-d', time());
     
             $return = $conf->global->$ref;
         }
    
    From 970c581bc9a8709f5ab9fc0806ab708fad278c98 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 16:40:07 +0200
    Subject: [PATCH 243/433] css
    
    ---
     htdocs/core/tpl/contacts.tpl.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php
    index 99ae9a699a1..cc361be5e60 100644
    --- a/htdocs/core/tpl/contacts.tpl.php
    +++ b/htdocs/core/tpl/contacts.tpl.php
    @@ -199,12 +199,12 @@ if ($permission) {
     			if ($tab[$i]['source']=='internal')
     			{
     				$userstatic->fetch($tab[$i]['id']);
    -				echo $userstatic->getNomUrl(-1);
    +				echo $userstatic->getNomUrl(-1, '', 0, 0, 0, 0, '', 'valignmiddle');
     			}
     			if ($tab[$i]['source']=='external')
     			{
     				$contactstatic->fetch($tab[$i]['id']);
    -				echo $contactstatic->getNomUrl(1);
    +				echo $contactstatic->getNomUrl(1, '', 0, 0, 0, 0, '', 'valignmiddle');
     			}
     			?>
     		</div>
    
    From 743d4d7c019a50260fd421f40b932c12270e3e11 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 16:40:40 +0200
    Subject: [PATCH 244/433] NEW add option PROPOSAL_AUTO_ADD_AUTHOR_AS_CONTACT
    
    ---
     htdocs/comm/propal/card.php | 24 +++++++++++++++++-------
     1 file changed, 17 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php
    index 4c6fbb2045c..3233dff3a4b 100644
    --- a/htdocs/comm/propal/card.php
    +++ b/htdocs/comm/propal/card.php
    @@ -348,13 +348,13 @@ if (empty($reshook))
     			// If we select proposal to clone during creation (when option PROPAL_CLONE_ON_CREATE_PAGE is on)
     			if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal'))
     			{
    -				if ($object->fetch(GETPOST('copie_propal')) > 0) {
    +				if ($object->fetch(GETPOST('copie_propal','int')) > 0) {
     					$object->ref = GETPOST('ref');
     					$object->datep = $datep;
     					$object->date_livraison = $date_delivery;
     					$object->availability_id = GETPOST('availability_id');
     					$object->demand_reason_id = GETPOST('demand_reason_id');
    -					$object->fk_delivery_address = GETPOST('fk_address');
    +					$object->fk_delivery_address = GETPOST('fk_address','int');
     					$object->shipping_method_id = GETPOST('shipping_method_id', 'int');
     					$object->duree_validite = $duration;
     					$object->cond_reglement_id = GETPOST('cond_reglement_id');
    @@ -362,9 +362,9 @@ if (empty($reshook))
     					$object->fk_account = GETPOST('fk_account', 'int');
     					$object->remise_percent = GETPOST('remise_percent');
     					$object->remise_absolue = GETPOST('remise_absolue');
    -					$object->socid = GETPOST('socid');
    -					$object->contactid = GETPOST('contactid');
    -					$object->fk_project = GETPOST('projectid');
    +					$object->socid = GETPOST('socid','int');
    +					$object->contactid = GETPOST('contactid','int');
    +					$object->fk_project = GETPOST('projectid','int');
     					$object->modelpdf = GETPOST('model');
     					$object->author = $user->id; // deprecated
     					$object->note_private = GETPOST('note_private','none');
    @@ -391,8 +391,8 @@ if (empty($reshook))
     				$object->cond_reglement_id = GETPOST('cond_reglement_id');
     				$object->mode_reglement_id = GETPOST('mode_reglement_id');
     				$object->fk_account = GETPOST('fk_account', 'int');
    -				$object->contactid = GETPOST('contactid');
    -				$object->fk_project = GETPOST('projectid');
    +				$object->contactid = GETPOST('contactid','int');
    +				$object->fk_project = GETPOST('projectid','int');
     				$object->modelpdf = GETPOST('model');
     				$object->author = $user->id; // deprecated
     				$object->note_private = GETPOST('note_private','none');
    @@ -566,6 +566,16 @@ if (empty($reshook))
     						}
     					}
     
    +					if (! empty($conf->global->PROPOSAL_AUTO_ADD_AUTHOR_AS_CONTACT))
    +					{
    +						$result = $object->add_contact($user->id, 'SALESREPFOLL', 'internal');
    +						if ($result < 0)
    +						{
    +							$error++;
    +							setEventMessages($langs->trans("ErrorFailedToAddUserAsContact"), null, 'errors');
    +						}
    +					}
    +
     					if (! $error)
     					{
     						$db->commit();
    
    From dfe239bf8df84e079d938dd823890a02442133cd Mon Sep 17 00:00:00 2001
    From: Maxime Kohlhaas <maxime@atm-consulting.fr>
    Date: Mon, 15 Oct 2018 16:58:53 +0200
    Subject: [PATCH 245/433] Fix refused proposals were counted in totals in
     project overview
    
    ---
     htdocs/projet/element.php | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php
    index 713e5ec74f1..130a0ad711e 100644
    --- a/htdocs/projet/element.php
    +++ b/htdocs/projet/element.php
    @@ -609,6 +609,10 @@ foreach ($listofreferent as $key => $value)
     				{
     					if (! empty($element->close_code) && $element->close_code == 'replaced') $qualifiedfortotal=false;	// Replacement invoice, do not include into total
     				}
    +				if ($key == 'propal')
    +				{
    +					if ($element->statut == Propal::STATUS_NOTSIGNED) $qualifiedfortotal=false;	// Refused proposal must not be included in total
    +				}
     
     				if ($qualifiedfortotal) $total_ht = $total_ht + $total_ht_by_line;
     
    
    From 96ddebad4acbb2d21f76d9c2c584daf75a9ef361 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 17:48:39 +0200
    Subject: [PATCH 246/433] Set canonical tag
    
    ---
     htdocs/core/lib/website.lib.php | 1 +
     htdocs/website/index.php        | 1 +
     2 files changed, 2 insertions(+)
    
    diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
    index fc2a90bbeb1..42ed566915f 100644
    --- a/htdocs/core/lib/website.lib.php
    +++ b/htdocs/core/lib/website.lib.php
    @@ -624,6 +624,7 @@ function dolSavePageContent($filetpl, $object, $objectpage)
     	$tplcontent.= '<meta name="title" content="'.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').'" />'."\n";
     	$tplcontent.= '<meta name="description" content="'.dol_string_nohtmltag($objectpage->description, 0, 'UTF-8').'" />'."\n";
     	$tplcontent.= '<meta name="generator" content="'.DOL_APPLICATION_TITLE.' '.DOL_VERSION.' (https://www.dolibarr.org)" />'."\n";
    +	$tplcontent.= '<link href="/'.$objectpage->pageurl.'.php" rel="canonical" />'."\n";
     	$tplcontent.= '<!-- Include link to CSS file -->'."\n";
     	$tplcontent.= '<link rel="stylesheet" href="styles.css.php?website=<?php echo $websitekey; ?>" type="text/css" />'."\n";
     	$tplcontent.= '<!-- Include HTML header from common file -->'."\n";
    diff --git a/htdocs/website/index.php b/htdocs/website/index.php
    index e9e14c4f888..dc8209bcb01 100644
    --- a/htdocs/website/index.php
    +++ b/htdocs/website/index.php
    @@ -459,6 +459,7 @@ if ($action == 'addcontainer')
     				//$objectpage->htmlheader = preg_replace('/<meta name="msvalidate.01[^>]*>\n*/ims', '', $objectpage->htmlheader);
     				$objectpage->htmlheader = preg_replace('/<title>[^<]*<\/title>\n*/ims', '', $objectpage->htmlheader);
     				$objectpage->htmlheader = preg_replace('/<link[^>]*rel="shortcut[^>]*>\n/ims', '', $objectpage->htmlheader);
    +				$objectpage->htmlheader = preg_replace('/<link[^>]*rel="canonical[^>]*>\n/ims', '', $objectpage->htmlheader);
     
     				// Now loop to fetch JS
     				$tmp = $objectpage->htmlheader;
    
    From 7492d42ad8efd029363776ba88962f1b255e5c6a Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 15 Oct 2018 18:47:12 +0200
    Subject: [PATCH 247/433] do not trim int
    
    ---
     htdocs/compta/tva/class/tva.class.php | 33 ++++++++++++++-------------
     1 file changed, 17 insertions(+), 16 deletions(-)
    
    diff --git a/htdocs/compta/tva/class/tva.class.php b/htdocs/compta/tva/class/tva.class.php
    index df5e8dfe76c..c78e0d8dd7a 100644
    --- a/htdocs/compta/tva/class/tva.class.php
    +++ b/htdocs/compta/tva/class/tva.class.php
    @@ -1,8 +1,9 @@
     <?php
    -/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2008 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2011-2017 Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2018      Philippe Grand       <philippe.grand@atoo-net.com>
    +/* Copyright (C) 2002-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2008  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2011-2017  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Philippe Grand          <philippe.grand@atoo-net.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -103,9 +104,9 @@ class Tva extends CommonObject
     		$this->amount=trim($this->amount);
     		$this->label=trim($this->label);
     		$this->note=trim($this->note);
    -		$this->fk_bank=trim($this->fk_bank);
    -		$this->fk_user_creat=trim($this->fk_user_creat);
    -		$this->fk_user_modif=trim($this->fk_user_modif);
    +		$this->fk_bank = (int) $this->fk_bank;
    +		$this->fk_user_creat = (int) $this->fk_user_creat;
    +		$this->fk_user_modif = (int) $this->fk_user_modif;
     
     		// Check parameters
     		// Put here code to add control on parameters values
    @@ -182,9 +183,9 @@ class Tva extends CommonObject
     		$this->amount=trim($this->amount);
     		$this->label=trim($this->label);
     		$this->note=trim($this->note);
    -		$this->fk_bank=trim($this->fk_bank);
    -		$this->fk_user_creat=trim($this->fk_user_creat);
    -		$this->fk_user_modif=trim($this->fk_user_modif);
    +		$this->fk_bank = (int) $this->fk_bank;
    +		$this->fk_user_creat = (int) $this->fk_user_creat;
    +		$this->fk_user_modif = (int) $this->fk_user_modif;
     
     		// Check parameters
     		// Put here code to add control on parameters values
    @@ -519,9 +520,9 @@ class Tva extends CommonObject
             $this->amount=price2num(trim($this->amount));
             $this->label=trim($this->label);
     		$this->note=trim($this->note);
    -		$this->fk_bank=trim($this->fk_bank);
    -		$this->fk_user_creat=trim($this->fk_user_creat);
    -		$this->fk_user_modif=trim($this->fk_user_modif);
    +		$this->fk_bank = (int) $this->fk_bank;
    +		$this->fk_user_creat = (int) $this->fk_user_creat;
    +		$this->fk_user_modif = (int) $this->fk_user_modif;
     		if (empty($this->datec)) $this->datec = dol_now();
     
             // Check parameters
    @@ -663,8 +664,8 @@ class Tva extends CommonObject
     	function update_fk_bank($id_bank)
     	{
             // phpcs:enable
    -		$sql = 'UPDATE '.MAIN_DB_PREFIX.'tva SET fk_bank = '.$id_bank;
    -		$sql.= ' WHERE rowid = '.$this->id;
    +		$sql = 'UPDATE '.MAIN_DB_PREFIX.'tva SET fk_bank = '.(int) $id_bank;
    +		$sql.= ' WHERE rowid = '.(int) $this->id;
     		$result = $this->db->query($sql);
     		if ($result)
     		{
    @@ -769,7 +770,7 @@ class Tva extends CommonObject
     	{
     		$sql = "SELECT t.rowid, t.tms, t.fk_user_modif, t.datec, t.fk_user_creat";
     		$sql.= " FROM ".MAIN_DB_PREFIX."tva as t";
    -		$sql.= " WHERE t.rowid = ".$id;
    +		$sql.= " WHERE t.rowid = ".(int) $id;
     
     		dol_syslog(get_class($this)."::info", LOG_DEBUG);
     		$result=$this->db->query($sql);
    
    From 7ea4f7ea0ba7e05e9e2515759029c3d145ae090e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= <frederic.france@free.fr>
    Date: Mon, 15 Oct 2018 20:36:11 +0200
    Subject: [PATCH 248/433] clean loan code
    
    ---
     htdocs/loan/calcmens.php                 |   3 +-
     htdocs/loan/class/loan.class.php         |  38 +++++---
     htdocs/loan/class/loanschedule.class.php | 112 ++++++++++++++---------
     htdocs/loan/class/paymentloan.class.php  | 100 +++++++++++++-------
     htdocs/loan/createschedule.php           |   9 +-
     htdocs/loan/payment/payment.php          |   4 +-
     6 files changed, 172 insertions(+), 94 deletions(-)
    
    diff --git a/htdocs/loan/calcmens.php b/htdocs/loan/calcmens.php
    index fbe1cecab2d..df6db76e1f2 100644
    --- a/htdocs/loan/calcmens.php
    +++ b/htdocs/loan/calcmens.php
    @@ -50,7 +50,7 @@ $echance++;
     $capital=$cap_rest;
     while ($echance<=$nbterm) {
     
    -	$mens = round($object->calc_mens($capital,$rate,$nbterm-$echance+1),2,PHP_ROUND_HALF_UP);
    +	$mens = round($object->calcMonthlyPayments($capital, $rate, $nbterm-$echance+1), 2, PHP_ROUND_HALF_UP);
     
     	$int = ($capital*($rate/12));
     	$int = round($int,2,PHP_ROUND_HALF_UP);
    @@ -63,4 +63,3 @@ while ($echance<=$nbterm) {
     }
     
     echo json_encode($output);
    -
    diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php
    index dd066f0064c..20cccfdc232 100644
    --- a/htdocs/loan/class/loan.class.php
    +++ b/htdocs/loan/class/loan.class.php
    @@ -51,7 +51,7 @@ class Loan extends CommonObject
     	public $datestart;
     	public $dateend;
     
    -	/**
    +    /**
          * @var string Loan label
          */
         public $label;
    @@ -66,10 +66,26 @@ class Loan extends CommonObject
     	public $date_creation;
     	public $date_modification;
     	public $date_validation;
    -	public $fk_bank;
    -	public $fk_user_creat;
    -	public $fk_user_modif;
    -	public $fk_project;
    +
    +    /**
    +     * @var int Bank ID
    +     */
    +    public $fk_bank;
    +
    +    /**
    +     * @var int User ID
    +     */
    +    public $fk_user_creat;
    +
    +    /**
    +     * @var int User ID
    +     */
    +    public $fk_user_modif;
    +
    +    /**
    +     * @var int Project ID
    +     */
    +    public $fk_project;
     
     
     	/**
    @@ -158,10 +174,10 @@ class Loan extends CommonObject
     		if (isset($this->account_capital)) $this->account_capital = trim($this->account_capital);
     		if (isset($this->account_insurance)) $this->account_insurance = trim($this->account_insurance);
     		if (isset($this->account_interest)) $this->account_interest = trim($this->account_interest);
    -		if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank);
    -		if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat);
    -		if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif);
    -		if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project);
    +		if (isset($this->fk_bank)) $this->fk_bank = (int) $this->fk_bank;
    +		if (isset($this->fk_user_creat)) $this->fk_user_creat = (int) $this->fk_user_creat;
    +		if (isset($this->fk_user_modif)) $this->fk_user_modif = (int) $this->fk_user_modif;
    +		if (isset($this->fk_project)) $this->fk_project = (int) $this->fk_project;
     
     		// Check parameters
     		if (! $newcapital > 0 || empty($this->datestart) || empty($this->dateend))
    @@ -445,9 +461,9 @@ class Loan extends CommonObject
     
     		$tooltip = '<u>' . $langs->trans("ShowLoan") . '</u>';
     		if (! empty($this->ref))
    -			$tooltip .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
    +			$tooltip .= '<br><strong>' . $langs->trans('Ref') . ':</strong> ' . $this->ref;
     		if (! empty($this->label))
    -			$tooltip .= '<br><b>' . $langs->trans('Label') . ':</b> ' . $this->label;
    +			$tooltip .= '<br><strong>' . $langs->trans('Label') . ':</strong> ' . $this->label;
     
     		$linkstart = '<a href="'.DOL_URL_ROOT.'/loan/card.php?id='.$this->id.'" title="'.str_replace('\n', '', dol_escape_htmltag($tooltip, 1)).'" class="classfortooltip">';
     		$linkend = '</a>';
    diff --git a/htdocs/loan/class/loanschedule.class.php b/htdocs/loan/class/loanschedule.class.php
    index 2f37b1a870c..cf95b72715c 100644
    --- a/htdocs/loan/class/loanschedule.class.php
    +++ b/htdocs/loan/class/loanschedule.class.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2017	Florian HENRY <florian.henry@atm-consulting.fr>
    +/* Copyright (C) 2017       Florian HENRY           <florian.henry@atm-consulting.fr>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -39,20 +40,53 @@ class LoanSchedule extends CommonObject
     	 */
     	public $table_element='loan_schedule';
     
    -	var $fk_loan;
    -	var $datec='';
    -	var $tms='';
    -	var $datep='';
    -    var $amounts=array();   // Array of amounts
    -    var $amount_capital;    // Total amount of payment
    -	var $amount_insurance;
    -	var $amount_interest;
    -	var $fk_typepayment;
    -	var $num_payment;
    -	var $fk_bank;
    -	var $fk_user_creat;
    -	var $fk_user_modif;
    -	var $lines=array();
    +    /**
    +     * @var int Loan ID
    +     */
    +    public $fk_loan;
    +
    +    /**
    +     * @var string Create date
    +     */
    +    public $datec='';
    +	public $tms='';
    +
    +    /**
    +     * @var string Payment date
    +     */
    +    public $datep='';
    +
    +    public $amounts=array();   // Array of amounts
    +    public $amount_capital;    // Total amount of payment
    +	public $amount_insurance;
    +	public $amount_interest;
    +
    +    /**
    +     * @var int Payment Type ID
    +     */
    +    public $fk_typepayment;
    +
    +    /**
    +     * @var int Payment ID
    +     */
    +    public $num_payment;
    +
    +    /**
    +     * @var int Bank ID
    +     */
    +    public $fk_bank;
    +
    +    /**
    +     * @var int Bank ID
    +     */
    +    public $fk_user_creat;
    +
    +    /**
    +     * @var int User ID
    +     */
    +    public $fk_user_modif;
    +
    +	public $lines=array();
     
     	/**
     	 * @deprecated
    @@ -65,7 +99,7 @@ class LoanSchedule extends CommonObject
     	 *
     	 *  @param		DoliDB		$db      Database handler
     	 */
    -	function __construct($db)
    +	public function __construct($db)
     	{
     		$this->db = $db;
     	}
    @@ -77,7 +111,7 @@ class LoanSchedule extends CommonObject
     	 *  @param      User		$user   User making payment
     	 *  @return     int     			<0 if KO, id of payment if OK
     	 */
    -	function create($user)
    +	public function create($user)
     	{
     		global $conf, $langs;
     
    @@ -86,21 +120,21 @@ class LoanSchedule extends CommonObject
             $now=dol_now();
     
             // Validate parameters
    -		if (! $this->datepaid)
    +		if (! $this->datep)
     		{
     			$this->error='ErrorBadValueForParameter';
     			return -1;
     		}
     
     		// Clean parameters
    -		if (isset($this->fk_loan)) 			$this->fk_loan = trim($this->fk_loan);
    +		if (isset($this->fk_loan)) $this->fk_loan = (int) $this->fk_loan;
     		if (isset($this->amount_capital))	$this->amount_capital = trim($this->amount_capital?$this->amount_capital:0);
     		if (isset($this->amount_insurance))	$this->amount_insurance = trim($this->amount_insurance?$this->amount_insurance:0);
     		if (isset($this->amount_interest))	$this->amount_interest = trim($this->amount_interest?$this->amount_interest:0);
    -		if (isset($this->fk_typepayment))	$this->fk_typepayment = trim($this->fk_typepayment);
    -		if (isset($this->fk_bank))			$this->fk_bank = trim($this->fk_bank);
    -		if (isset($this->fk_user_creat))	$this->fk_user_creat = trim($this->fk_user_creat);
    -		if (isset($this->fk_user_modif))	$this->fk_user_modif = trim($this->fk_user_modif);
    +		if (isset($this->fk_typepayment)) $this->fk_typepayment = (int) $this->fk_typepayment;
    +		if (isset($this->fk_bank)) $this->fk_bank = (int) $this->fk_bank;
    +		if (isset($this->fk_user_creat)) $this->fk_user_creat = (int) $this->fk_user_creat;
    +		if (isset($this->fk_user_modif)) $this->fk_user_modif = (int) $this->fk_user_modif;
     
             $totalamount = $this->amount_capital + $this->amount_insurance + $this->amount_interest;
             $totalamount = price2num($totalamount);
    @@ -119,7 +153,7 @@ class LoanSchedule extends CommonObject
     			$sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." (fk_loan, datec, datep, amount_capital, amount_insurance, amount_interest,";
     			$sql.= " fk_typepayment, fk_user_creat, fk_bank)";
     			$sql.= " VALUES (".$this->fk_loan.", '".$this->db->idate($now)."',";
    -			$sql.= " '".$this->db->idate($this->datepaid)."',";
    +			$sql.= " '".$this->db->idate($this->datep)."',";
     			$sql.= " ".$this->amount_capital.",";
     			$sql.= " ".$this->amount_insurance.",";
     			$sql.= " ".$this->amount_interest.",";
    @@ -162,7 +196,7 @@ class LoanSchedule extends CommonObject
     	 *  @param	int		$id         Id object
     	 *  @return int         		<0 if KO, >0 if OK
     	 */
    -	function fetch($id)
    +	public function fetch($id)
     	{
     		global $langs;
     		$sql = "SELECT";
    @@ -215,8 +249,8 @@ class LoanSchedule extends CommonObject
                     $this->type_code = $obj->type_code;
                     $this->type_libelle = $obj->type_libelle;
     
    -                $this->bank_account   = $obj->fk_account;
    -                $this->bank_line      = $obj->fk_bank;
    +                $this->bank_account = $obj->fk_account;
    +                $this->bank_line = $obj->fk_bank;
                 }
                 $this->db->free($resql);
     
    @@ -237,7 +271,7 @@ class LoanSchedule extends CommonObject
     	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
     	 *  @return int         			<0 if KO, >0 if OK
     	 */
    -	function update($user=0, $notrigger=0)
    +	public function update($user=0, $notrigger=0)
     	{
     		global $conf, $langs;
     		$error=0;
    @@ -321,7 +355,7 @@ class LoanSchedule extends CommonObject
     	 *  @param  int		$notrigger		0=launch triggers after, 1=disable triggers
     	 *  @return int						<0 if KO, >0 if OK
     	 */
    -	function delete($user, $notrigger=0)
    +	public function delete($user, $notrigger=0)
     	{
     		global $conf, $langs;
     		$error=0;
    @@ -372,18 +406,16 @@ class LoanSchedule extends CommonObject
     		}
     	}
     
    -	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 * Calculate mensuality
    +	 * Calculate Monthly Payments
     	 *
     	 * @param   double  $capital        Capital
     	 * @param   double  $rate           rate
     	 * @param   int     $nbterm         nb term
     	 * @return  double                  mensuality
     	 */
    -	function calc_mens($capital, $rate, $nbterm)
    +	public function calcMonthlyPayments($capital, $rate, $nbterm)
     	{
    -        // phpcs:enable
     		$result='';
     
     		if (!empty($capital) && !empty($rate) && !empty($nbterm)) {
    @@ -400,7 +432,7 @@ class LoanSchedule extends CommonObject
     	 *  @param	int		$loanid     Id object
     	 *  @return int         		<0 if KO, >0 if OK
     	 */
    -	function fetchAll($loanid)
    +	public function fetchAll($loanid)
     	{
     		global $langs;
     
    @@ -461,15 +493,13 @@ class LoanSchedule extends CommonObject
     		}
     	}
     
    -    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
    -	 *  trans_paiment
    +	 *  transPayment
     	 *
     	 *  @return void
     	 */
    -	function trans_paiment()
    +	private function transPayment()
     	{
    -        // phpcs:enable
     		require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/loan.lib.php';
     		require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
    @@ -505,12 +535,12 @@ class LoanSchedule extends CommonObject
     
     
     	/**
    -	 *  trans_paiment
    +	 *  transPayment
     	 *
     	 *  @param  int    $loanid     Loan id
     	 *  @return int                < 0 if KO, Date > 0 if OK
     	 */
    -	function lastpaiment($loanid)
    +	public function lastpaiment($loanid)
     	{
     		$sql = "SELECT p.datep";
     		$sql.= " FROM ".MAIN_DB_PREFIX."payment_loan as p ";
    @@ -535,7 +565,7 @@ class LoanSchedule extends CommonObject
     	 *  @param  int        $datemax    Date max
     	 *  @return array                  Array of id
     	 */
    -	function paimenttorecord($loanid, $datemax)
    +	public function paimenttorecord($loanid, $datemax)
     	{
     		$sql = "SELECT p.rowid";
     		$sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as p ";
    diff --git a/htdocs/loan/class/paymentloan.class.php b/htdocs/loan/class/paymentloan.class.php
    index add1aef496d..c4c29c99dce 100644
    --- a/htdocs/loan/class/paymentloan.class.php
    +++ b/htdocs/loan/class/paymentloan.class.php
    @@ -1,6 +1,6 @@
     <?php
     /* Copyright (C) 2014-2018  Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2015       Frederic France      <frederic.france@free.fr>
    + * Copyright (C) 2015-2018  Frederic France      <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -40,32 +40,68 @@ class PaymentLoan extends CommonObject
     	 */
     	public $table_element='payment_loan';
     
    -	var $fk_loan;
    -	var $datec='';
    -	var $tms='';
    -	var $datep='';
    -	var $amounts=array();   // Array of amounts
    -	var $amount_capital;    // Total amount of payment
    -	var $amount_insurance;
    -	var $amount_interest;
    -	var $fk_typepayment;
    -	var $num_payment;
    -	var $fk_bank;
    -	var $fk_user_creat;
    -	var $fk_user_modif;
    +    /**
    +     * @var int Loan ID
    +     */
    +    public $fk_loan;
    +
    +    /**
    +     * @var string Create date
    +     */
    +    public $datec='';
    +
    +    public $tms='';
    +
    +    /**
    +     * @var string Payment date
    +     */
    +    public $datep='';
    +
    +    public $amounts=array();   // Array of amounts
    +
    +    public $amount_capital;    // Total amount of payment
    +
    +    public $amount_insurance;
    +
    +    public $amount_interest;
    +
    +    /**
    +     * @var int Payment type ID
    +     */
    +    public $fk_typepayment;
    +
    +    /**
    +     * @var int Payment ID
    +     */
    +    public $num_payment;
    +
    +    /**
    +     * @var int Bank ID
    +     */
    +    public $fk_bank;
    +
    +    /**
    +     * @var int User ID
    +     */
    +    public $fk_user_creat;
    +
    +    /**
    +     * @var int user ID
    +     */
    +    public $fk_user_modif;
     
     	/**
     	 * @deprecated
     	 * @see amount, amounts
     	 */
    -	var $total;
    +    public $total;
     
     	/**
     	 *	Constructor
     	 *
     	 *  @param		DoliDB		$db      Database handler
     	 */
    -	function __construct($db)
    +	public function __construct($db)
     	{
     		$this->db = $db;
     	}
    @@ -86,24 +122,24 @@ class PaymentLoan extends CommonObject
     		$now=dol_now();
     
     		// Validate parameters
    -		if (! $this->datepaid)
    +		if (! $this->datep)
     		{
     			$this->error='ErrorBadValueForParameter';
     			return -1;
     		}
     
     		// Clean parameters
    -		if (isset($this->fk_loan)) 			$this->fk_loan = trim($this->fk_loan);
    +		if (isset($this->fk_loan)) $this->fk_loan = (int) $this->fk_loan;
     		if (isset($this->amount_capital))	$this->amount_capital = price2num($this->amount_capital?$this->amount_capital:0);
    -		if (isset($this->amount_insurance))	$this->amount_insurance = price2num($this->amount_insurance?$this->amount_insurance:0);
    +		if (isset($this->amount_insurance)) $this->amount_insurance = price2num($this->amount_insurance?$this->amount_insurance:0);
     		if (isset($this->amount_interest))	$this->amount_interest = price2num($this->amount_interest?$this->amount_interest:0);
    -		if (isset($this->fk_typepayment))	$this->fk_typepayment = trim($this->fk_typepayment);
    -		if (isset($this->num_payment))		$this->num_payment = trim($this->num_payment);
    +		if (isset($this->fk_typepayment)) $this->fk_typepayment = (int) $this->fk_typepayment;
    +		if (isset($this->num_payment)) $this->num_payment = (int) $this->num_payment;
     		if (isset($this->note_private))     $this->note_private = trim($this->note_private);
     		if (isset($this->note_public))      $this->note_public = trim($this->note_public);
    -		if (isset($this->fk_bank))			$this->fk_bank = trim($this->fk_bank);
    -		if (isset($this->fk_user_creat))	$this->fk_user_creat = trim($this->fk_user_creat);
    -		if (isset($this->fk_user_modif))	$this->fk_user_modif = trim($this->fk_user_modif);
    +		if (isset($this->fk_bank)) $this->fk_bank = (int) $this->fk_bank;
    +		if (isset($this->fk_user_creat)) $this->fk_user_creat = (int) $this->fk_user_creat;
    +		if (isset($this->fk_user_modif)) $this->fk_user_modif = (int) $this->fk_user_modif;
     
     		$totalamount = $this->amount_capital + $this->amount_insurance + $this->amount_interest;
     		$totalamount = price2num($totalamount);
    @@ -119,7 +155,7 @@ class PaymentLoan extends CommonObject
     			$sql = "INSERT INTO ".MAIN_DB_PREFIX."payment_loan (fk_loan, datec, datep, amount_capital, amount_insurance, amount_interest,";
     			$sql.= " fk_typepayment, num_payment, note_private, note_public, fk_user_creat, fk_bank)";
     			$sql.= " VALUES (".$this->chid.", '".$this->db->idate($now)."',";
    -			$sql.= " '".$this->db->idate($this->datepaid)."',";
    +			$sql.= " '".$this->db->idate($this->datep)."',";
     			$sql.= " ".$this->amount_capital.",";
     			$sql.= " ".$this->amount_insurance.",";
     			$sql.= " ".$this->amount_interest.",";
    @@ -244,17 +280,17 @@ class PaymentLoan extends CommonObject
     		$error=0;
     
     		// Clean parameters
    -		if (isset($this->fk_loan)) $this->fk_loan=trim($this->fk_loan);
    +		if (isset($this->fk_loan)) $this->fk_loan = (int) $this->fk_loan;
     		if (isset($this->amount_capital)) $this->amount_capital=trim($this->amount_capital);
     		if (isset($this->amount_insurance)) $this->amount_insurance=trim($this->amount_insurance);
     		if (isset($this->amount_interest)) $this->amount_interest=trim($this->amount_interest);
    -		if (isset($this->fk_typepayment)) $this->fk_typepayment=trim($this->fk_typepayment);
    -		if (isset($this->num_payment)) $this->num_payment=trim($this->num_payment);
    +		if (isset($this->fk_typepayment)) $this->fk_typepayment = (int) $this->fk_typepayment;
    +		if (isset($this->num_payment)) $this->num_payment = (int) $this->num_payment;
     		if (isset($this->note_private)) $this->note=trim($this->note_private);
     		if (isset($this->note_public)) $this->note=trim($this->note_public);
    -		if (isset($this->fk_bank)) $this->fk_bank=trim($this->fk_bank);
    -		if (isset($this->fk_user_creat)) $this->fk_user_creat=trim($this->fk_user_creat);
    -		if (isset($this->fk_user_modif)) $this->fk_user_modif=trim($this->fk_user_modif);
    +		if (isset($this->fk_bank)) $this->fk_bank = (int) $this->fk_bank;
    +		if (isset($this->fk_user_creat)) $this->fk_user_creat = (int) $this->fk_user_creat;
    +		if (isset($this->fk_user_modif)) $this->fk_user_modif = (int) $this->fk_user_modif;
     
     		// Check parameters
     
    @@ -418,7 +454,7 @@ class PaymentLoan extends CommonObject
     
     			// Insert payment into llx_bank
     			$bank_line_id = $acc->addline(
    -				$this->datepaid,
    +				$this->datep,
     				$this->paymenttype,  // Payment mode id or code ("CHQ or VIR for example")
     				$label,
     				$total,
    diff --git a/htdocs/loan/createschedule.php b/htdocs/loan/createschedule.php
    index 08ca019f00e..7cfd54ab998 100644
    --- a/htdocs/loan/createschedule.php
    +++ b/htdocs/loan/createschedule.php
    @@ -51,7 +51,7 @@ if ($action == 'createecheancier') {
     		$echeance->fk_loan = $object->id;
     		$echeance->datec = dol_now();
     		$echeance->tms = dol_now();
    -		$echeance->datepaid = $date;
    +		$echeance->datep = $date;
     		$echeance->amount_capital = $mens-$int;
     		$echeance->amount_insurance = 0;
     		$echeance->amount_interest = $int;
    @@ -61,7 +61,7 @@ if ($action == 'createecheancier') {
     		$echeance->fk_user_modif = $user->id;
     		$result=$echeance->create($user);
     		if ($result<0) {
    -			setEventMessages(null, $echeance->errors,'errors');
    +			setEventMessages($echeance->error, $echeance->errors,'errors');
     		}
     		$i++;
     	}
    @@ -165,7 +165,7 @@ if ($object->nbterm > 0 && count($echeance->lines)==0)
     	$capital = $object->capital;
     	while($i <$object->nbterm+1)
     	{
    -		$mens = price2num($echeance->calc_mens($capital, $object->rate/100, $object->nbterm-$i+1), 'MT');
    +		$mens = price2num($echeance->calcMonthlyPayments($capital, $object->rate/100, $object->nbterm-$i+1), 'MT');
     		$int = ($capital*($object->rate/12))/100;
     		$int = price2num($int, 'MT');
     		$cap_rest = price2num($capital - ($mens-$int), 'MT');
    @@ -213,6 +213,3 @@ print '</form>';
     // End of page
     llxFooter();
     $db->close();
    -
    -
    -
    diff --git a/htdocs/loan/payment/payment.php b/htdocs/loan/payment/payment.php
    index d84ea4ae26b..08937c1f389 100644
    --- a/htdocs/loan/payment/payment.php
    +++ b/htdocs/loan/payment/payment.php
    @@ -93,12 +93,12 @@ if ($action == 'add_payment')
         		// Create a line of payments
         		$payment = new PaymentLoan($db);
         		$payment->chid				= $chid;
    -    		$payment->datepaid			= $datepaid;
    +    		$payment->datep = $datepaid;
                 $payment->label             = $loan->label;
     			$payment->amount_capital	= GETPOST('amount_capital');
     			$payment->amount_insurance	= GETPOST('amount_insurance');
     			$payment->amount_interest	= GETPOST('amount_interest');
    -			$payment->paymenttype		= GETPOST('paymenttype');
    +			$payment->paymenttype = GETPOST('paymenttype', 'int');
         		$payment->num_payment		= GETPOST('num_payment');
         		$payment->note_private      = GETPOST('note_private','none');
         		$payment->note_public       = GETPOST('note_public','none');
    
    From 2e6f0d3d19b0f2f1d51acb8d02a29fd31a055620 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= <frederic.france@free.fr>
    Date: Mon, 15 Oct 2018 20:40:59 +0200
    Subject: [PATCH 249/433] clean loan code
    
    ---
     htdocs/loan/class/loanschedule.class.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/loan/class/loanschedule.class.php b/htdocs/loan/class/loanschedule.class.php
    index cf95b72715c..208f325a384 100644
    --- a/htdocs/loan/class/loanschedule.class.php
    +++ b/htdocs/loan/class/loanschedule.class.php
    @@ -513,7 +513,7 @@ class LoanSchedule extends CommonObject
     
     		if($resql){
     			while($obj = $this->db->fetch_object($resql)){
    -				$lastrecorded = $this->lastpaiment($obj->rowid);
    +				$lastrecorded = $this->lastPayment($obj->rowid);
     				$toinsert = $this->paimenttorecord($obj->rowid, $lastrecorded);
     				if(count($toinsert)>0){
     					foreach ($toinsert as $echid){
    @@ -535,12 +535,12 @@ class LoanSchedule extends CommonObject
     
     
     	/**
    -	 *  transPayment
    +	 *  lastpayment
     	 *
     	 *  @param  int    $loanid     Loan id
     	 *  @return int                < 0 if KO, Date > 0 if OK
     	 */
    -	public function lastpaiment($loanid)
    +	private function lastPayment($loanid)
     	{
     		$sql = "SELECT p.datep";
     		$sql.= " FROM ".MAIN_DB_PREFIX."payment_loan as p ";
    
    From aa20d6d359a35c4cd6341021b4a4cdc436bb39be Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 15 Oct 2018 21:30:57 +0200
    Subject: [PATCH 250/433] add errors def in mailman class
    
    ---
     .../mailmanspip/class/mailmanspip.class.php   | 20 ++++++++++++-------
     1 file changed, 13 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/mailmanspip/class/mailmanspip.class.php b/htdocs/mailmanspip/class/mailmanspip.class.php
    index de075eb2dc5..848fc9e8d47 100644
    --- a/htdocs/mailmanspip/class/mailmanspip.class.php
    +++ b/htdocs/mailmanspip/class/mailmanspip.class.php
    @@ -1,11 +1,12 @@
     <?php
    -/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2002-2003 Jean-Louis Bergamo   <jlb@j1b.org>
    - * Copyright (C) 2004-2013 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2004      Sebastien Di Cintio  <sdicintio@ressource-toi.org>
    - * Copyright (C) 2004      Benoit Mortier       <benoit.mortier@opensides.be>
    - * Copyright (C) 2009      Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2012      Marcos García        <marcosgdf@gmail.com>
    +/* Copyright (C) 2002-2003  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2002-2003  Jean-Louis Bergamo      <jlb@j1b.org>
    + * Copyright (C) 2004-2013  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2004       Sebastien Di Cintio     <sdicintio@ressource-toi.org>
    + * Copyright (C) 2004       Benoit Mortier          <benoit.mortier@opensides.be>
    + * Copyright (C) 2009       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2012       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -48,6 +49,11 @@ class MailmanSpip
     	 */
     	public $error='';
     
    +    /**
    +	 * @var string[]	Array of error strings
    +	 */
    +	public $errors = array();
    +
         public $mladded_ok;
         public $mladded_ko;
         public $mlremoved_ok;
    
    From 00fdf9d3fd045b76270921f2943ce94e0184f9b9 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 15 Oct 2018 21:32:27 +0200
    Subject: [PATCH 251/433] Update mailmanspip.class.php
    
    ---
     htdocs/mailmanspip/class/mailmanspip.class.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/mailmanspip/class/mailmanspip.class.php b/htdocs/mailmanspip/class/mailmanspip.class.php
    index 848fc9e8d47..2e6cae459c1 100644
    --- a/htdocs/mailmanspip/class/mailmanspip.class.php
    +++ b/htdocs/mailmanspip/class/mailmanspip.class.php
    @@ -50,9 +50,9 @@ class MailmanSpip
     	public $error='';
     
         /**
    -	 * @var string[]	Array of error strings
    -	 */
    -	public $errors = array();
    +     * @var string[]	Array of error strings
    +     */
    +    public $errors = array();
     
         public $mladded_ok;
         public $mladded_ko;
    
    From 9133d97e337bc2a44cb53295144e94a7025ab02d Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 15 Oct 2018 21:40:27 +0200
    Subject: [PATCH 252/433] add errors def in htmlformsms
    
    ---
     htdocs/core/class/html.formsms.class.php | 74 +++++++++++++-----------
     1 file changed, 40 insertions(+), 34 deletions(-)
    
    diff --git a/htdocs/core/class/html.formsms.class.php b/htdocs/core/class/html.formsms.class.php
    index a04da7caf08..4ef6208723d 100644
    --- a/htdocs/core/class/html.formsms.class.php
    +++ b/htdocs/core/class/html.formsms.class.php
    @@ -1,20 +1,21 @@
     <?php
    -/* Copyright (C) 2005-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2010      Juanjo Menent        <jmenent@2byte.es>
    -*
    -* This program is free software; you can redistribute it and/or modify
    -* it under the terms of the GNU General Public License as published by
    -* the Free Software Foundation; either version 3 of the License, or
    -* (at your option) any later version.
    -*
    -* This program is distributed in the hope that it will be useful,
    -* but WITHOUT ANY WARRANTY; without even the implied warranty of
    -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -* GNU General Public License for more details.
    -*
    -* You should have received a copy of the GNU General Public License
    -* along with this program. If not, see <http://www.gnu.org/licenses/>.
    -*/
    +/* Copyright (C) 2005-2011  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2010       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; either version 3 of the License, or
    + * (at your option) any later version.
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    + * GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    + */
     
     /**
      *       \file       htdocs/core/class/html.formsms.class.php
    @@ -37,33 +38,38 @@ class FormSms
          */
         public $db;
     
    -    var $fromname;
    -    var $fromsms;
    -    var $replytoname;
    -    var $replytomail;
    -    var $toname;
    -    var $tomail;
    +    public $fromname;
    +    public $fromsms;
    +    public $replytoname;
    +    public $replytomail;
    +    public $toname;
    +    public $tomail;
     
    -    var $withsubstit;			// Show substitution array
    -    var $withfrom;
    -    var $withto;
    -    var $withtopic;
    -    var $withbody;
    +    public $withsubstit;			// Show substitution array
    +    public $withfrom;
    +    public $withto;
    +    public $withtopic;
    +    public $withbody;
     
    -    var $withfromreadonly;
    -    var $withreplytoreadonly;
    -    var $withtoreadonly;
    -    var $withtopicreadonly;
    -    var $withcancel;
    +    public $withfromreadonly;
    +    public $withreplytoreadonly;
    +    public $withtoreadonly;
    +    public $withtopicreadonly;
    +    public $withcancel;
     
    -    var $substit=array();
    -    var $param=array();
    +    public $substit=array();
    +    public $param=array();
     
         /**
          * @var string Error code (or message)
          */
         public $error='';
     
    +    /**
    +     * @var string[]	Array of error strings
    +     */
    +    public $errors=array();
    +
     
         /**
          *	Constructor
    
    From c246ef38c08520e9346ade49bfd2f729060acd8a Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 21:42:43 +0200
    Subject: [PATCH 253/433] Fix canonical
    
    ---
     htdocs/core/lib/website.lib.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
    index 42ed566915f..1d141fe128e 100644
    --- a/htdocs/core/lib/website.lib.php
    +++ b/htdocs/core/lib/website.lib.php
    @@ -624,7 +624,7 @@ function dolSavePageContent($filetpl, $object, $objectpage)
     	$tplcontent.= '<meta name="title" content="'.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').'" />'."\n";
     	$tplcontent.= '<meta name="description" content="'.dol_string_nohtmltag($objectpage->description, 0, 'UTF-8').'" />'."\n";
     	$tplcontent.= '<meta name="generator" content="'.DOL_APPLICATION_TITLE.' '.DOL_VERSION.' (https://www.dolibarr.org)" />'."\n";
    -	$tplcontent.= '<link href="/'.$objectpage->pageurl.'.php" rel="canonical" />'."\n";
    +	$tplcontent.= '<link href="/'.($objectpage->id == $object->fk_default_home ? '' : ($objectpage->pageurl.'.php')).'" rel="canonical" />'."\n";
     	$tplcontent.= '<!-- Include link to CSS file -->'."\n";
     	$tplcontent.= '<link rel="stylesheet" href="styles.css.php?website=<?php echo $websitekey; ?>" type="text/css" />'."\n";
     	$tplcontent.= '<!-- Include HTML header from common file -->'."\n";
    
    From 568197656f52b47dcc56a0c69b1881a9b7163a85 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 15 Oct 2018 21:43:01 +0200
    Subject: [PATCH 254/433] Fix canonical of home
    
    ---
     htdocs/core/lib/website.lib.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
    index 1d141fe128e..0fe56afd9dd 100644
    --- a/htdocs/core/lib/website.lib.php
    +++ b/htdocs/core/lib/website.lib.php
    @@ -624,7 +624,7 @@ function dolSavePageContent($filetpl, $object, $objectpage)
     	$tplcontent.= '<meta name="title" content="'.dol_string_nohtmltag($objectpage->title, 0, 'UTF-8').'" />'."\n";
     	$tplcontent.= '<meta name="description" content="'.dol_string_nohtmltag($objectpage->description, 0, 'UTF-8').'" />'."\n";
     	$tplcontent.= '<meta name="generator" content="'.DOL_APPLICATION_TITLE.' '.DOL_VERSION.' (https://www.dolibarr.org)" />'."\n";
    -	$tplcontent.= '<link href="/'.($objectpage->id == $object->fk_default_home ? '' : ($objectpage->pageurl.'.php')).'" rel="canonical" />'."\n";
    +	$tplcontent.= '<link href="/'.(($objectpage->id == $object->fk_default_home) ? '' : ($objectpage->pageurl.'.php')).'" rel="canonical" />'."\n";
     	$tplcontent.= '<!-- Include link to CSS file -->'."\n";
     	$tplcontent.= '<link rel="stylesheet" href="styles.css.php?website=<?php echo $websitekey; ?>" type="text/css" />'."\n";
     	$tplcontent.= '<!-- Include HTML header from common file -->'."\n";
    
    From 3a6824da68b8effacbbbf3a0583d8b7152a4fc01 Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Mon, 15 Oct 2018 21:50:05 +0200
    Subject: [PATCH 255/433] Fix FEC Missing label_compte & label_operation
    
    ---
     htdocs/accountancy/journal/bankjournal.php | 77 ++++++++++++++++------
     1 file changed, 58 insertions(+), 19 deletions(-)
    
    diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
    index 4e52481b287..f0e6aa8455d 100644
    --- a/htdocs/accountancy/journal/bankjournal.php
    +++ b/htdocs/accountancy/journal/bankjournal.php
    @@ -1,12 +1,12 @@
     <?php
    -/* Copyright (C) 2007-2010  Laurent Destailleur <eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010  Jean Heimburger     <jean@tiaris.info>
    - * Copyright (C) 2011       Juanjo Menent       <jmenent@2byte.es>
    - * Copyright (C) 2012       Regis Houssin       <regis.houssin@capnetworks.com>
    - * Copyright (C) 2013       Christophe Battarel <christophe.battarel@altairis.fr>
    - * Copyright (C) 2013-2018  Alexandre Spangaro  <aspangaro@zendsi.com>
    - * Copyright (C) 2013-2014  Florian Henry       <florian.henry@open-concept.pro>
    - * Copyright (C) 2013-2014  Olivier Geffroy     <jeff@jeffinfo.com>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013       Christophe Battarel     <christophe.battarel@altairis.fr>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2013-2014  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2014  Olivier Geffroy         <jeff@jeffinfo.com>
      * Copyright (C) 2017-2018  Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -33,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT . '/core/lib/report.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/bank.lib.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
    +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
     require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
     require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
    @@ -155,6 +156,8 @@ $accountingjournalstatic->fetch($id_journal);
     $journal = $accountingjournalstatic->code;
     $journal_label = $accountingjournalstatic->label;
     
    +$accountingaccountstatic = new AccountingAccount($db);
    +
     dol_syslog("accountancy/journal/bankjournal.php", LOG_DEBUG);
     $result = $db->query($sql);
     if ($result) {
    @@ -461,7 +464,12 @@ if (! $error && $action == 'writebookkeeping') {
     					$bookkeeping->fk_doc = $key;
     					$bookkeeping->fk_docdet = $val["fk_bank"];
     					$bookkeeping->numero_compte = $k;
    -					$bookkeeping->label_compte = $langs->trans("Bank");
    +
    +					$accountingaccountstatic->fetch('',$k,1);
    +					$accountingaccount_label = $accountingaccountstatic->label;
    +					$bookkeeping->label_compte = $accountingaccount_label;
    +
    +					$bookkeeping->label_operation = $reflabel;
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
     					$bookkeeping->debit = ($mt >= 0 ? $mt : 0);
    @@ -517,6 +525,7 @@ if (! $error && $action == 'writebookkeeping') {
     						$bookkeeping->doc_type = 'bank';
     						$bookkeeping->fk_doc = $key;
     						$bookkeeping->fk_docdet = $val["fk_bank"];
    +						$bookkeeping->label_operation = $reflabel;
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
     						$bookkeeping->debit = ($mt < 0 ? - $mt : 0);
    @@ -530,22 +539,34 @@ if (! $error && $action == 'writebookkeeping') {
     							$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
     							$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccountstatic->fetch('',$conf->global->ACCOUNTING_ACCOUNT_CUSTOMER,1);
    +							$accountingaccount_label = $accountingaccountstatic->label;
    +							$bookkeeping->label_compte = $accountingaccount_label;
     						} else if ($tabtype[$key] == 'payment_supplier') {		   // If payment is payment of supplier invoice, we get ref of invoice
     							$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
     							$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccountstatic->fetch('',$conf->global->ACCOUNTING_ACCOUNT_SUPPLIER,1);
    +							$accountingaccount_label = $accountingaccountstatic->label;
    +							$bookkeeping->label_compte = $accountingaccount_label;
     						} else if ($tabtype[$key] == 'payment_expensereport') {
     							$bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
     							$bookkeeping->subledger_label = $tabuser[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccountstatic->fetch('',$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT,1);
    +							$accountingaccount_label = $accountingaccountstatic->label;
    +							$bookkeeping->label_compte = $accountingaccount_label;
     						} else if ($tabtype[$key] == 'payment_salary') {
     							$bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
     							$bookkeeping->subledger_label = $tabuser[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccountstatic->fetch('',$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT,1);
    +							$accountingaccount_label = $accountingaccountstatic->label;
    +							$bookkeeping->label_compte = $accountingaccount_label;
     						} else if (in_array($tabtype[$key], array('sc', 'payment_sc'))) {   // If payment is payment of social contribution
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
    @@ -555,27 +576,42 @@ if (! $error && $action == 'writebookkeeping') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccountstatic->fetch($k,'',1);
    +							$accountingaccount_label = $accountingaccountstatic->label;
    +							$bookkeeping->label_compte = $accountingaccount_label;
     						} else if ($tabtype[$key] == 'payment_donation') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccountstatic->fetch($k,'',1);
    +							$accountingaccount_label = $accountingaccountstatic->label;
    +							$bookkeeping->label_compte = $accountingaccount_label;
     						} else if ($tabtype[$key] == 'payment_loan') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccountstatic->fetch($k,'',1);
    +							$accountingaccount_label = $accountingaccountstatic->label;
    +							$bookkeeping->label_compte = $accountingaccount_label;
     						} else if ($tabtype[$key] == 'payment_various') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccountstatic->fetch($k,'',1);
    +							$accountingaccount_label = $accountingaccountstatic->label;
    +							$bookkeeping->label_compte = $accountingaccount_label;
     						} else if ($tabtype[$key] == 'banktransfert') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
    -							$bookkeeping->label_compte = '';
    +
    +							$accountingaccountstatic->fetch($k,'',1);
    +							$accountingaccount_label = $accountingaccountstatic->label;
    +							$bookkeeping->label_compte = $accountingaccount_label;
     						} else {
     							if ($tabtype[$key] == 'unknown')	// Unknown transaction, we will use a waiting account for thirdparty.
     							{
    @@ -583,7 +619,10 @@ if (! $error && $action == 'writebookkeeping') {
     								$bookkeeping->subledger_account = '';
     								$bookkeeping->subledger_label = '';
     								$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE;
    -								$bookkeeping->label_compte = '';
    +
    +								$accountingaccountstatic->fetch('',$conf->global->ACCOUNTING_ACCOUNT_SUSPENSE,1);
    +								$accountingaccount_label = $accountingaccountstatic->label;
    +								$bookkeeping->label_compte = $accountingaccount_label;
     							}
     						}
     						$bookkeeping->label_operation = $reflabel;
    
    From cab9c81ce24a1a6f674e837406fbc7893f197b0a Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 15 Oct 2018 21:53:54 +0200
    Subject: [PATCH 256/433] Update actioncomm.class.php
    
    ---
     htdocs/comm/action/class/actioncomm.class.php | 116 ++++++++++--------
     1 file changed, 64 insertions(+), 52 deletions(-)
    
    diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php
    index c175ad900ea..969cb705bac 100644
    --- a/htdocs/comm/action/class/actioncomm.class.php
    +++ b/htdocs/comm/action/class/actioncomm.class.php
    @@ -1,10 +1,11 @@
     <?php
    -/* Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2011 Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@capnetworks.com>
    - * Copyright (C) 2011-2017 Juanjo Menent        <jmenent@2byte.es>
    - * Copyright (C) 2015	   Marcos García		<marcosgdf@gmail.com>
    - * Copyright (C) 2018	   Nicolas ZABOURI	<info@inovea-conseil.com>
    +/* Copyright (C) 2002-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2011  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005-2012  Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2011-2017  Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2015	    Marcos García		    <marcosgdf@gmail.com>
    + * Copyright (C) 2018	    Nicolas ZABOURI	        <info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -67,7 +68,7 @@ class ActionComm extends CommonObject
          * Id of the event
          * @var int
          */
    -	  public $id;
    +    public $id;
     
         /**
          * Id of the event. Use $id as possible
    @@ -75,11 +76,12 @@ class ActionComm extends CommonObject
          */
         public $ref;
     
    -    var $type_id;		// Id into parent table llx_c_actioncomm (used only if option to use type is set)
    -    var $type_code;		// Code into parent table llx_c_actioncomm (used only if option to use type is set). With default setup, should be AC_OTH_AUTO or AC_OTH.
    -    var $type;			// Label into parent table llx_c_actioncomm (used only if option to use type is set)
    -    var $type_color;	// Color into parent table llx_c_actioncomm (used only if option to use type is set)
    -    var $code;			// Free code to identify action. Ie: Agenda trigger add here AC_TRIGGERNAME ('AC_COMPANY_CREATE', 'AC_PROPAL_VALIDATE', ...)
    +    public $type_id;		// Id into parent table llx_c_actioncomm (used only if option to use type is set)
    +    public $type_code;		// Code into parent table llx_c_actioncomm (used only if option to use type is set). With default setup, should be AC_OTH_AUTO or AC_OTH.
    +    public $type_label;
    +    public $type;			// Label into parent table llx_c_actioncomm (used only if option to use type is set)
    +    public $type_color;	// Color into parent table llx_c_actioncomm (used only if option to use type is set)
    +    public $code;			// Free code to identify action. Ie: Agenda trigger add here AC_TRIGGERNAME ('AC_COMPANY_CREATE', 'AC_PROPAL_VALIDATE', ...)
     
         /**
          * @var string Agenda event label
    @@ -93,8 +95,8 @@ class ActionComm extends CommonObject
          */
         public $libelle;
     
    -    var $datec;			// Date creation record (datec)
    -    var $datem;			// Date modification record (tms)
    +    public $datec;			// Date creation record (datec)
    +    public $datem;			// Date modification record (tms)
     
         /**
          * Object user that create action
    @@ -102,7 +104,7 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see authorid
          */
    -    var $author;
    +    public $author;
     
         /**
          * Object user that modified action
    @@ -110,39 +112,49 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see usermodid
          */
    -    var $usermod;
    -    var $authorid;		// Id user that create action
    -    var $usermodid;		// Id user that modified action
    +    public $usermod;
     
    -    var $datep;			// Date action start (datep)
    -    var $datef;			// Date action end (datep2)
    +    /**
    +     * Id user that create action
    +     * @var int
    +     */
    +    public $authorid;
    +
    +    /**
    +     * Id user that modified action
    +     * @var int
    +     */
    +    public $usermodid;
    +
    +    public $datep;			// Date action start (datep)
    +    public $datef;			// Date action end (datep2)
     
         /**
          * @var int -1=Unkown duration
          * @deprecated
          */
    -    var $durationp = -1;
    -    var $fulldayevent = 0;    // 1=Event on full day
    +    public $durationp = -1;
    +    public $fulldayevent = 0;    // 1=Event on full day
     
         /**
          * Milestone
          * @var int
          * @deprecated Milestone is already event with end date = start date
          */
    -    var $punctual = 1;
    -    var $percentage;    // Percentage
    -    var $location;      // Location
    +    public $punctual = 1;
    +    public $percentage;    // Percentage
    +    public $location;      // Location
     
    -	var $transparency;	// Transparency (ical standard). Used to say if people assigned to event are busy or not by event. 0=available, 1=busy, 2=busy (refused events)
    -    var $priority;      // Small int (0 By default)
    +	public $transparency;	// Transparency (ical standard). Used to say if people assigned to event are busy or not by event. 0=available, 1=busy, 2=busy (refused events)
    +    public $priority;      // Small int (0 By default)
     
    -	var $userassigned = array();	// Array of user ids
    -    var $userownerid;	// Id of user owner = fk_user_action into table
    -    var $userdoneid;	// Id of user done (deprecated)
    +	public $userassigned = array();	// Array of user ids
    +    public $userownerid;	// Id of user owner = fk_user_action into table
    +    public $userdoneid;	// Id of user done (deprecated)
     
    -    var $socpeopleassigned = array(); // Array of contact ids
    +    public $socpeopleassigned = array(); // Array of contact ids
     
    -    var $otherassigned = array(); // Array of other contact emails (not user, not contact)
    +    public $otherassigned = array(); // Array of other contact emails (not user, not contact)
     
     
     	/**
    @@ -151,7 +163,7 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see userownerid
          */
    -    var $usertodo;
    +    public $usertodo;
     
         /**
          * Object user that did action
    @@ -159,10 +171,10 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see userdoneid
          */
    -    var $userdone;
    +    public $userdone;
     
    -    var $socid;
    -    var $contactid;
    +    public $socid;
    +    public $contactid;
     
         /**
          * Company linked to action (optional)
    @@ -170,7 +182,7 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see socid
          */
    -    var $societe;
    +    public $societe;
     
         /**
          * Contact linked to action (optional)
    @@ -178,28 +190,28 @@ class ActionComm extends CommonObject
          * @deprecated
          * @see contactid
          */
    -    var $contact;
    +    public $contact;
     
         // Properties for links to other objects
    -    var $fk_element;    // Id of record
    -    var $elementid;    // Id of record alternative for API
    -    var $elementtype;   // Type of record. This if property ->element of object linked to.
    +    public $fk_element;    // Id of record
    +    public $elementid;    // Id of record alternative for API
    +    public $elementtype;   // Type of record. This if property ->element of object linked to.
     
         // Ical
    -    var $icalname;
    -    var $icalcolor;
    +    public $icalname;
    +    public $icalcolor;
     
    -    var $actions=array();
    +    public $actions=array();
     
         // Fields for emails
    -    var $email_msgid;
    -    var $email_from;
    -    var $email_sender;
    -    var $email_to;
    -    var $email_tocc;
    -    var $email_tobcc;
    -    var $email_subject;
    -    var $errors_to;
    +    public $email_msgid;
    +    public $email_from;
    +    public $email_sender;
    +    public $email_to;
    +    public $email_tocc;
    +    public $email_tobcc;
    +    public $email_subject;
    +    public $errors_to;
     
     
         /**
    
    From c8607a74bfb97b149754f02e5971f4b34a3741b7 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 01:39:04 +0200
    Subject: [PATCH 257/433] Load websitepage
    
    ---
     htdocs/core/lib/website.lib.php |  2 +-
     htdocs/core/website.inc.php     | 70 ++++++++++++++++-----------------
     2 files changed, 36 insertions(+), 36 deletions(-)
    
    diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
    index 0fe56afd9dd..350014b3eb9 100644
    --- a/htdocs/core/lib/website.lib.php
    +++ b/htdocs/core/lib/website.lib.php
    @@ -305,7 +305,7 @@ function redirectToContainer($containerref, $containeraliasalt='',$containerid=0
      */
     function includeContainer($containerref)
     {
    -	global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $weblangs;	// Very important. Required to have var available when running inluded containers.
    +	global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs;	// Very important. Required to have var available when running inluded containers.
     	global $includehtmlcontentopened;
     	global $websitekey, $websitepagefile;
     
    diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php
    index 4e382088da5..71550d4d118 100644
    --- a/htdocs/core/website.inc.php
    +++ b/htdocs/core/website.inc.php
    @@ -25,16 +25,28 @@
     
     // Load website class
     include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
    -// Define $website and $weblangs
    +// Define $website
     if (! is_object($website))
     {
     	$website=new Website($db);
     	$website->fetch(0,$websitekey);
     }
    +// Define $weblangs
     if (! is_object($weblangs))
     {
     	$weblangs = dol_clone($langs);	// TODO Use an object lang from a language set into $website object instead of backoffice
     }
    +// Define $websitepage if we have $websitepagefile defined
    +if (! $pageid && ! empty($websitepagefile))
    +{
    +	$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
    +}
    +if ($pageid > 0)
    +{
    +	include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    +	$websitepage=new WebsitePage($db);
    +	$websitepage->fetch($pageid);
    +}
     
     // A lang was forced, so we change weblangs init
     if (GETPOST('l','aZ09')) $weblangs->setDefaultLang(GETPOST('l','aZ09'));
    @@ -44,44 +56,32 @@ if ($_SERVER['PHP_SELF'] != DOL_URL_ROOT.'/website/index.php')	// If we browsing
     	//print_r(get_defined_constants(true));exit;
     	if (GETPOST('l','aZ09'))
     	{
    -		if (! $pageid && ! empty($websitepagefile))
    -		{
    -			$pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile));
    -		}
    -		if ($pageid > 0)
    -		{
    -			// Load tmppage if we have $websitepagefile defined
    -			include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
    -			$tmppage=new WebsitePage($db);
    -			$tmppage->fetch($pageid);
    +		$sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
    +		$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp";
    +		$sql.=" WHERE wp.fk_website = ".$website->id;
    +		$sql.=" AND (wp.fk_page = ".$pageid." OR wp.rowid  = ".$pageid;
    +		if (is_object($websitepage) && $websitepage->fk_page > 0) $sql.=" OR wp.fk_page = ".$websitepage->fk_page." OR wp.rowid = ".$websitepage->fk_page;
    +		$sql.=")";
    +		$sql.= " AND wp.lang = '".$db->escape(GETPOST('l','aZ09'))."'";
     
    -			$sql ="SELECT wp.rowid, wp.lang, wp.pageurl, wp.fk_page";
    -			$sql.=" FROM ".MAIN_DB_PREFIX."website_page as wp";
    -			$sql.=" WHERE wp.fk_website = ".$website->id;
    -			$sql.=" AND (wp.fk_page = ".$pageid." OR wp.rowid  = ".$pageid;
    -			if ($tmppage->fk_page > 0) $sql.=" OR wp.fk_page = ".$tmppage->fk_page." OR wp.rowid = ".$tmppage->fk_page;
    -			$sql.=")";
    -			$sql.= " AND wp.lang = '".$db->escape(GETPOST('l','aZ09'))."'";
    -
    -			$resql = $db->query($sql);
    -			if ($resql)
    +		$resql = $db->query($sql);
    +		if ($resql)
    +		{
    +			$obj = $db->fetch_object($resql);
    +			if ($obj)
     			{
    -				$obj = $db->fetch_object($resql);
    -				if ($obj)
    +				$newpageid = $obj->rowid;
    +				if ($newpageid != $pageid) 		// To avoid to make a redirect on same page (infinite loop)
     				{
    -					$newpageid = $obj->rowid;
    -					if ($newpageid != $pageid) 		// To avoid to make a redirect on same page (infinite loop)
    +					if (defined('USEDOLIBARRSERVER')) {
    +						header("Location: ".DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$newpageid.'.php&l='.GETPOST('l','aZ09'));
    +						exit;
    +					}
    +					else
     					{
    -						if (defined('USEDOLIBARRSERVER')) {
    -							header("Location: ".DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$newpageid.'.php&l='.GETPOST('l','aZ09'));
    -							exit;
    -						}
    -						else
    -						{
    -							$newpageref = $obj->pageurl;
    -							header("Location: ".$newpageref.'.php?l='.GETPOST('l','aZ09'));
    -							exit;
    -						}
    +						$newpageref = $obj->pageurl;
    +						header("Location: ".$newpageref.'.php?l='.GETPOST('l','aZ09'));
    +						exit;
     					}
     				}
     			}
    
    From 12cb60040b86ae9b2339ca04e40a52a49a5125d9 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 01:52:22 +0200
    Subject: [PATCH 258/433] Fix multilang
    
    ---
     htdocs/core/website.inc.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php
    index 71550d4d118..1338104de0b 100644
    --- a/htdocs/core/website.inc.php
    +++ b/htdocs/core/website.inc.php
    @@ -74,7 +74,7 @@ if ($_SERVER['PHP_SELF'] != DOL_URL_ROOT.'/website/index.php')	// If we browsing
     				if ($newpageid != $pageid) 		// To avoid to make a redirect on same page (infinite loop)
     				{
     					if (defined('USEDOLIBARRSERVER')) {
    -						header("Location: ".DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$newpageid.'.php&l='.GETPOST('l','aZ09'));
    +						header("Location: ".DOL_URL_ROOT.'/public/website/index.php?website='.$websitekey.'&pageid='.$newpageid.'&l='.GETPOST('l','aZ09'));
     						exit;
     					}
     					else
    
    From 35f9371343a983085cfc54fb76151a750701074d Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 03:30:17 +0200
    Subject: [PATCH 259/433] Fix missing es translation string
    
    ---
     htdocs/core/class/notify.class.php | 37 ++++++++++++++++--------------
     htdocs/langs/es_ES/other.lang      |  1 +
     2 files changed, 21 insertions(+), 17 deletions(-)
    
    diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php
    index 7a1b55f5bd2..5a5356b2dd5 100644
    --- a/htdocs/core/class/notify.class.php
    +++ b/htdocs/core/class/notify.class.php
    @@ -368,6 +368,7 @@ class Notify
     						{
     							$outputlangs = new Translate('', $conf);
     							$outputlangs->setDefaultLang($obj->default_lang);
    +							$outputlangs->load("other");
     						}
     
     						$subject = '['.$mysoc->name.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification");
    @@ -377,72 +378,72 @@ class Notify
     								$link='/compta/facture/card.php?facid='.$object->id;
     								$dir_output = $conf->facture->dir_output;
     								$object_type = 'facture';
    -								$mesg = $langs->transnoentitiesnoconv("EMailTextInvoiceValidated",$newref);
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoiceValidated",$newref);
     								break;
     							case 'BILL_PAYED':
     								$link='/compta/facture/card.php?facid='.$object->id;
     								$dir_output = $conf->facture->dir_output;
     								$object_type = 'facture';
    -								$mesg = $langs->transnoentitiesnoconv("EMailTextInvoicePayed",$newref);
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoicePayed",$newref);
     								break;
     							case 'ORDER_VALIDATE':
     								$link='/commande/card.php?id='.$object->id;
     								$dir_output = $conf->commande->dir_output;
     								$object_type = 'order';
    -								$mesg = $langs->transnoentitiesnoconv("EMailTextOrderValidated",$newref);
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextOrderValidated",$newref);
     								break;
     							case 'PROPAL_VALIDATE':
     								$link='/comm/propal/card.php?id='.$object->id;
     								$dir_output = $conf->propal->multidir_output[$object->entity];
     								$object_type = 'propal';
    -								$mesg = $langs->transnoentitiesnoconv("EMailTextProposalValidated",$newref);
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalValidated",$newref);
     								break;
     							case 'PROPAL_CLOSE_SIGNED':
     								$link='/comm/propal/card.php?id='.$object->id;
     								$dir_output = $conf->propal->multidir_output[$object->entity];
     								$object_type = 'propal';
    -								$mesg = $langs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref);
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned",$newref);
     								break;
     							case 'FICHINTER_ADD_CONTACT':
     								$link='/fichinter/card.php?id='.$object->id;
     								$dir_output = $conf->ficheinter->dir_output;
     								$object_type = 'ficheinter';
    -								$mesg = $langs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$object->ref);
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionAddedContact",$newref);
     								break;
     							case 'FICHINTER_VALIDATE':
     								$link='/fichinter/card.php?id='.$object->id;
     								$dir_output = $conf->ficheinter->dir_output;
     								$object_type = 'ficheinter';
    -								$mesg = $langs->transnoentitiesnoconv("EMailTextInterventionValidated",$object->ref);
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionValidated",$newref);
     								break;
     							case 'ORDER_SUPPLIER_VALIDATE':
     								$link='/fourn/commande/card.php?id='.$object->id;
     								$dir_output = $conf->fournisseur->commande->dir_output;
     								$object_type = 'order_supplier';
    -								$mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
    -								$mesg.= $langs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$object->ref,$user->getFullName($langs));
    -								$mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
    +								$mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
    +								$mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderValidatedBy",$newref,$user->getFullName($langs));
    +								$mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
     								break;
     							case 'ORDER_SUPPLIER_APPROVE':
     								$link='/fourn/commande/card.php?id='.$object->id;
     								$dir_output = $conf->fournisseur->commande->dir_output;
     								$object_type = 'order_supplier';
    -								$mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
    -								$mesg.= $langs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$newref,$user->getFullName($langs));
    -								$mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
    +								$mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
    +								$mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderApprovedBy",$newref,$user->getFullName($langs));
    +								$mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
     								break;
     							case 'ORDER_SUPPLIER_REFUSE':
     								$link='/fourn/commande/card.php?id='.$object->id;
     								$dir_output = $conf->fournisseur->commande->dir_output;
     								$object_type = 'order_supplier';
    -								$mesg = $langs->transnoentitiesnoconv("Hello").",\n\n";
    -								$mesg.= $langs->transnoentitiesnoconv("EMailTextOrderRefusedBy",$newref,$user->getFullName($langs));
    -								$mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n";
    +								$mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n";
    +								$mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderRefusedBy",$newref,$user->getFullName($langs));
    +								$mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n";
     								break;
     							case 'SHIPPING_VALIDATE':
     								$dir_output = $conf->expedition->dir_output.'/sending/';
     								$object_type = 'order_supplier';
    -								$mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
     								break;
     						}
     						$ref = dol_sanitizeFileName($newref);
    @@ -651,6 +652,8 @@ class Notify
     				$message.= $langs->transnoentities("YouReceiveMailBecauseOfNotification2",$application,$mysoc->name)."\n";
     				$message.= "\n";
     				$message.= $mesg;
    +				//if ($link) $message.= "\n" . $urlwithroot . $link;	// link already added around the ref into the text
    +
     				$message = nl2br($message);
     
     				// Replace keyword __SUPERVISOREMAIL__
    diff --git a/htdocs/langs/es_ES/other.lang b/htdocs/langs/es_ES/other.lang
    index 137bbac42d6..acdc769a7c5 100644
    --- a/htdocs/langs/es_ES/other.lang
    +++ b/htdocs/langs/es_ES/other.lang
    @@ -188,6 +188,7 @@ NumberOfUnitsSupplierInvoices=Número de unidades en las facturas de proveedores
     EMailTextInterventionAddedContact=Se le ha asignado la intervención %s
     EMailTextInterventionValidated=Ficha intervención %s validada
     EMailTextInvoiceValidated=Factura %s validada
    +EMailTextInvoicePayed=La factura %s ha sido pagada.
     EMailTextProposalValidated=El presupuesto %s que le concierne ha sido validado.
     EMailTextProposalClosedSigned=El presupuesto %s ha sido cerrado y firmado.
     EMailTextOrderValidated=El pedido %s que le concierne ha sido validado.
    
    From 70366e9d91fd675b7f21a80ff923b105208474bc Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 03:31:33 +0200
    Subject: [PATCH 260/433] Missing translation
    
    ---
     htdocs/core/class/notify.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php
    index 5a5356b2dd5..c226fb647d0 100644
    --- a/htdocs/core/class/notify.class.php
    +++ b/htdocs/core/class/notify.class.php
    @@ -368,7 +368,7 @@ class Notify
     						{
     							$outputlangs = new Translate('', $conf);
     							$outputlangs->setDefaultLang($obj->default_lang);
    -							$outputlangs->load("other");
    +							$outputlangs->loadLangs(array("main","other"));
     						}
     
     						$subject = '['.$mysoc->name.'] '.$outputlangs->transnoentitiesnoconv("DolibarrNotification");
    
    From a971a2afe6432a2c330aa3c70bd2e3f1e9f8d9a5 Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Tue, 16 Oct 2018 06:32:55 +0200
    Subject: [PATCH 261/433] Fix FEC
    
    ---
     htdocs/accountancy/journal/bankjournal.php    | 58 ++++++++-----------
     .../journal/expensereportsjournal.php         | 13 ++++-
     .../accountancy/journal/purchasesjournal.php  | 29 ++++++----
     3 files changed, 52 insertions(+), 48 deletions(-)
    
    diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
    index f0e6aa8455d..7b4248630ae 100644
    --- a/htdocs/accountancy/journal/bankjournal.php
    +++ b/htdocs/accountancy/journal/bankjournal.php
    @@ -150,13 +150,14 @@ $paymentvariousstatic = new PaymentVarious($db);
     $paymentloanstatic = new PaymentLoan($db);
     $accountLinestatic=new AccountLine($db);
     
    +$accountingaccount = new AccountingAccount($db);
    +
     // Get code of finance journal
     $accountingjournalstatic = new AccountingJournal($db);
     $accountingjournalstatic->fetch($id_journal);
     $journal = $accountingjournalstatic->code;
     $journal_label = $accountingjournalstatic->label;
     
    -$accountingaccountstatic = new AccountingAccount($db);
     
     dol_syslog("accountancy/journal/bankjournal.php", LOG_DEBUG);
     $result = $db->query($sql);
    @@ -465,9 +466,8 @@ if (! $error && $action == 'writebookkeeping') {
     					$bookkeeping->fk_docdet = $val["fk_bank"];
     					$bookkeeping->numero_compte = $k;
     
    -					$accountingaccountstatic->fetch('',$k,1);
    -					$accountingaccount_label = $accountingaccountstatic->label;
    -					$bookkeeping->label_compte = $accountingaccount_label;
    +					$accountingaccount->fetch(null, $k, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
     
     					$bookkeeping->label_operation = $reflabel;
     					$bookkeeping->montant = $mt;
    @@ -540,33 +540,29 @@ if (! $error && $action == 'writebookkeeping') {
     							$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
     
    -							$accountingaccountstatic->fetch('',$conf->global->ACCOUNTING_ACCOUNT_CUSTOMER,1);
    -							$accountingaccount_label = $accountingaccountstatic->label;
    -							$bookkeeping->label_compte = $accountingaccount_label;
    +							$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_supplier') {		   // If payment is payment of supplier invoice, we get ref of invoice
     							$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
     							$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
     
    -							$accountingaccountstatic->fetch('',$conf->global->ACCOUNTING_ACCOUNT_SUPPLIER,1);
    -							$accountingaccount_label = $accountingaccountstatic->label;
    -							$bookkeeping->label_compte = $accountingaccount_label;
    +							$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_expensereport') {
     							$bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
     							$bookkeeping->subledger_label = $tabuser[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
     
    -							$accountingaccountstatic->fetch('',$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT,1);
    -							$accountingaccount_label = $accountingaccountstatic->label;
    -							$bookkeeping->label_compte = $accountingaccount_label;
    +							$accountingaccount->fetch(null ,$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_salary') {
     							$bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
     							$bookkeeping->subledger_label = $tabuser[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
     
    -							$accountingaccountstatic->fetch('',$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT,1);
    -							$accountingaccount_label = $accountingaccountstatic->label;
    -							$bookkeeping->label_compte = $accountingaccount_label;
    +							$accountingaccount->fetch(null ,$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if (in_array($tabtype[$key], array('sc', 'payment_sc'))) {   // If payment is payment of social contribution
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
    @@ -577,41 +573,36 @@ if (! $error && $action == 'writebookkeeping') {
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
     
    -							$accountingaccountstatic->fetch($k,'',1);
    -							$accountingaccount_label = $accountingaccountstatic->label;
    -							$bookkeeping->label_compte = $accountingaccount_label;
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_donation') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
     
    -							$accountingaccountstatic->fetch($k,'',1);
    -							$accountingaccount_label = $accountingaccountstatic->label;
    -							$bookkeeping->label_compte = $accountingaccount_label;
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_loan') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
     
    -							$accountingaccountstatic->fetch($k,'',1);
    -							$accountingaccount_label = $accountingaccountstatic->label;
    -							$bookkeeping->label_compte = $accountingaccount_label;
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_various') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
     
    -							$accountingaccountstatic->fetch($k,'',1);
    -							$accountingaccount_label = $accountingaccountstatic->label;
    -							$bookkeeping->label_compte = $accountingaccount_label;
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'banktransfert') {
     							$bookkeeping->subledger_account = '';
     							$bookkeeping->subledger_label = '';
     							$bookkeeping->numero_compte = $k;
     
    -							$accountingaccountstatic->fetch($k,'',1);
    -							$accountingaccount_label = $accountingaccountstatic->label;
    -							$bookkeeping->label_compte = $accountingaccount_label;
    +							$accountingaccount->fetch($k, null, true);
    +							$bookkeeping->label_compte = $accountingaccount->label;
     						} else {
     							if ($tabtype[$key] == 'unknown')	// Unknown transaction, we will use a waiting account for thirdparty.
     							{
    @@ -620,9 +611,8 @@ if (! $error && $action == 'writebookkeeping') {
     								$bookkeeping->subledger_label = '';
     								$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE;
     
    -								$accountingaccountstatic->fetch('',$conf->global->ACCOUNTING_ACCOUNT_SUSPENSE,1);
    -								$accountingaccount_label = $accountingaccountstatic->label;
    -								$bookkeeping->label_compte = $accountingaccount_label;
    +								$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_SUSPENSE, true);
    +								$bookkeeping->label_compte = $accountingaccount->label;
     							}
     						}
     						$bookkeeping->label_operation = $reflabel;
    diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php
    index 520fd004f16..6fb8aed5c31 100644
    --- a/htdocs/accountancy/journal/expensereportsjournal.php
    +++ b/htdocs/accountancy/journal/expensereportsjournal.php
    @@ -3,7 +3,7 @@
      * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
      * Copyright (C) 2011       Juanjo Menent           <jmenent@2byte.es>
      * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    - * Copyright (C) 2013-2017  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
      * Copyright (C) 2013-2016  Olivier Geffroy         <jeff@jeffinfo.com>
      * Copyright (C) 2013-2016  Florian Henry           <florian.henry@open-concept.pro>
      * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
    @@ -61,6 +61,7 @@ if ($user->societe_id > 0)
     /*
      * Actions
      */
    +$accountingaccount = new AccountingAccount($db);
     
     // Get informations of journal
     $accountingjournalstatic = new AccountingJournal($db);
    @@ -210,6 +211,10 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->subledger_account = $tabuser[$key]['user_accountancy_code'];
     					$bookkeeping->subledger_label = $tabuser[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
    +
    +					$accountingaccount->fetch(null ,$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
    +
     					$bookkeeping->label_operation = $tabuser[$key]['name'];
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
    @@ -248,7 +253,6 @@ if ($action == 'writebookkeeping') {
     			foreach ( $tabht[$key] as $k => $mt ) {
     				if ($mt) {
     					// get compte id and label
    -					$accountingaccount = new AccountingAccount($db);
     					if ($accountingaccount->fetch(null, $k, true)) {
     						$bookkeeping = new BookKeeping($db);
     						$bookkeeping->doc_date = $val["date"];
    @@ -260,6 +264,7 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +						$bookkeeping->label_compte = $accountingaccount->label;
     						$bookkeeping->label_operation = $accountingaccount->label;
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
    @@ -316,6 +321,10 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->subledger_account = '';
     					$bookkeeping->subledger_label = '';
     					$bookkeeping->numero_compte = $k;
    +
    +					$accountingaccount->fetch($k, null, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
    +
     					$bookkeeping->label_operation = $langs->trans("VAT"). ' '.join(', ',$def_tva[$key][$k]).' %';
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
    diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php
    index 71bdb6a5bd4..beb9891276f 100644
    --- a/htdocs/accountancy/journal/purchasesjournal.php
    +++ b/htdocs/accountancy/journal/purchasesjournal.php
    @@ -1,11 +1,11 @@
     <?php
    -/* Copyright (C) 2007-2010  Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2007-2010  Jean Heimburger		<jean@tiaris.info>
    - * Copyright (C) 2011       Juanjo Menent		<jmenent@2byte.es>
    - * Copyright (C) 2012       Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2013-2017  Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2013-2016  Olivier Geffroy		<jeff@jeffinfo.com>
    - * Copyright (C) 2013-2016  Florian Henry		<florian.henry@open-concept.pro>
    +/* Copyright (C) 2007-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2007-2010  Jean Heimburger         <jean@tiaris.info>
    + * Copyright (C) 2011       Juanjo Menent           <jmenent@2byte.es>
    + * Copyright (C) 2012       Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2013-2017  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2013-2016  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2016  Florian Henry           <florian.henry@open-concept.pro>
      * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -66,10 +66,7 @@ $parameters=array();
      */
     $reshook=$hookmanager->executeHooks('doActions',$parameters,$user,$action);    // Note that $action and $object may have been modified by some hooks
     
    -
    -/*
    - * Views
    - */
    +$accountingaccount = new AccountingAccount($db);
     
     // Get informations of journal
     $accountingjournalstatic = new AccountingJournal($db);
    @@ -312,6 +309,10 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->subledger_account = $tabcompany[$key]['code_compta_fournisseur'];
     					$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
    +
    +					$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
    +
     					$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("SubledgerAccount");
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
    @@ -352,7 +353,6 @@ if ($action == 'writebookkeeping') {
     			foreach ( $tabht[$key] as $k => $mt ) {
     				//if ($mt) {
     					// get compte id and label
    -					$accountingaccount = new AccountingAccount($db);
     					if ($accountingaccount->fetch(null, $k, true)) {
     						$bookkeeping = new BookKeeping($db);
     						$bookkeeping->doc_date = $val["date"];
    @@ -366,6 +366,7 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +						$bookkeeping->label_compte = $accountingaccount->label;
     						$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $accountingaccount->label;
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
    @@ -426,6 +427,10 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +
    +						$accountingaccount->fetch($k, null, true);
    +						$bookkeeping->label_compte = $accountingaccount->label;
    +
     						$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("VAT").' '.join(', ',$def_tva[$key][$k]) .' %' . ($numtax?' - Localtax '.$numtax:'');
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
    
    From 5f37e075405db98b01f76376f9e1e848b709aed3 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Tue, 16 Oct 2018 14:42:36 +0200
    Subject: [PATCH 262/433] add links and highlight relevant text
    
    ---
     htdocs/accountancy/index.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
    index 29c05eb5516..bc09c33483c 100644
    --- a/htdocs/accountancy/index.php
    +++ b/htdocs/accountancy/index.php
    @@ -76,15 +76,15 @@ if ($conf->accounting->enabled)
     	print "<br>\n";
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/defaultaccounts.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</mark>'.'</strong>'.'</a>');
     	print "<br>\n";
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuBankAccounts").'</strong>')."\n";
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '<a href="'.DOL_URL_ROOT.'/compta/bank/list.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("MenuBankAccounts").'</mark>'.'</strong>'.'</a>')."\n";
     	print "<br>\n";
     
     	$step++;
    -	$textlink = '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuVatAccounts").'</strong>';
    +	$textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=10&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.'<mark>'.$langs->transnoentitiesnoconv("MenuVatAccounts").'</mark>'.'</strong>'.'</a>';
     	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescVat", $step, $textlink);
     	print "<br>\n";
     	if (! empty($conf->tax->enabled))
    
    From 059c72c678e9dcbfedcd0a540740c56ba64a090e Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Tue, 16 Oct 2018 14:55:29 +0200
    Subject: [PATCH 263/433] add links and highlight relevant text
    
    ---
     htdocs/accountancy/index.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
    index bc09c33483c..eac0f23a845 100644
    --- a/htdocs/accountancy/index.php
    +++ b/htdocs/accountancy/index.php
    @@ -89,7 +89,7 @@ if ($conf->accounting->enabled)
     	print "<br>\n";
     	if (! empty($conf->tax->enabled))
     	{
    -	    $textlink = '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</strong>';
    +	     $textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=7&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.'<mark>'.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</mark>'.'</strong>'.'</a>';
     	    $step++;
     	    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescContrib", $step, $textlink);
     	    print "<br>\n";
    @@ -105,7 +105,7 @@ if ($conf->accounting->enabled)
     	if (! empty($conf->expensereport->enabled))  // TODO Move this in the default account page because this is only one accounting account per purpose, not several.
     	{
     	    $step++;
    -	    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</strong>');
    +	    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=17&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</mark>'.'</strong>'.'</a>');
     	    print "<br>\n";
     	}
     	/*
    @@ -123,7 +123,7 @@ if ($conf->accounting->enabled)
     	}*/
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("ProductsBinding").'</strong>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/productaccount.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("ProductsBinding").'</mark>'.'</strong>'.'</a>');
     	print "<br>\n";
     
     
    
    From bd3315528eec2762768727118b1a1e941fbde681 Mon Sep 17 00:00:00 2001
    From: Philippe GRAND <philippe.grand@atoo-net.com>
    Date: Tue, 16 Oct 2018 15:08:06 +0200
    Subject: [PATCH 264/433] add links and highlight relevant text
    
    ---
     htdocs/accountancy/index.php | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
    index eac0f23a845..b2dfdb91e05 100644
    --- a/htdocs/accountancy/index.php
    +++ b/htdocs/accountancy/index.php
    @@ -139,18 +139,18 @@ if ($conf->accounting->enabled)
     	$langs->loadLangs(array('bills', 'trips'));
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsCustomers"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("CustomersVentilation").'</strong>')."\n";
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsCustomers"), '<a href="'.DOL_URL_ROOT.'/accountancy/customer/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".'<mark>'.$langs->transnoentitiesnoconv("CustomersVentilation").'</mark>'.'</strong>'.'</a>')."\n";
     	print "<br>\n";
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsSuppliers"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("SuppliersVentilation").'</strong>')."\n";
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsSuppliers"), '<a href="'.DOL_URL_ROOT.'/accountancy/supplier/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".'<mark>'.$langs->transnoentitiesnoconv("SuppliersVentilation").'</mark>'.'</strong>'.'</a>')."\n";
     	print "<br>\n";
     
     	if (! empty($conf->expensereport->enabled) || ! empty($conf->deplacement->enabled))
     	{
     		$step++;
    -		print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong>')."\n";
    -		print "<br>\n";
    +		print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<a href="'.DOL_URL_ROOT.'/accountancy/expensereport/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".'<mark>'.$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</mark>'.'</strong>'.'</a>')."\n";
    +	    print "<br>\n";
     	}
     
     	$step++;
    
    From 4bdcb17694ef6d1bbf3b033e5bb5204e80fd7559 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 15:38:26 +0200
    Subject: [PATCH 265/433] Trans
    
    ---
     htdocs/langs/en_US/website.lang | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang
    index a14d05132cd..bee23264d7a 100644
    --- a/htdocs/langs/en_US/website.lang
    +++ b/htdocs/langs/en_US/website.lang
    @@ -51,7 +51,7 @@ NoPageYet=No pages yet
     YouCanCreatePageOrImportTemplate=You can create a new page or import a full website template
     SyntaxHelp=Help on specific syntax tips
     YouCanEditHtmlSourceckeditor=You can edit HTML source code using the "Source" button in editor.
    -YouCanEditHtmlSource=<br><span class="fa fa-bug"></span> You can include PHP code into this source using tags <strong>&lt;?php ?&gt;</strong>. The following global variables are available: $conf, $db, $mysoc, $user, $website, $weblangs.<br><br><span class="fa fa-bug"></span> You can also include content of another Page/Container with the following syntax:<br><strong>&lt;?php includeContainer('alias_of_container_to_include'); ?&gt;</strong><br><br><span class="fa fa-bug"></span> You can make a redirect to another Page/Container with the following syntax (Note: do not output any content before a redirect):<br><strong>&lt;?php redirectToContainer('alias_of_container_to_redirect_to'); ?&gt;</strong><br><br><span class="fa fa-link"></span> To add a link to another page, use the syntax:<br><strong>&lt;a href="alias_of_page_to_link_to.php"&gt;mylink&lt;a&gt;</strong><br><br><span class="fa fa-download"></span> To include a <strong>link to download</strong> a file stored into the <strong>documents</strong> directory, use the <strong>document.php</strong> wrapper:<br>Example, for a file into documents/ecm (need to be logged), syntax is:<br><strong>&lt;a href="/document.php?modulepart=ecm&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file into documents/medias (open directory for public access), syntax is:<br><strong>&lt;a href="/document.php?modulepart=medias&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file shared with a share link (open access using the sharing hash key of file), syntax is:<br><strong>&lt;a href="/document.php?hashp=publicsharekeyoffile"&gt;</strong><br><br><span class="fa fa-picture-o"></span> To include an <strong>image</strong> stored into the <strong>documents</strong> directory, use the <strong>viewimage.php</strong> wrapper:<br>Example, for an image into documents/medias (open directory for public access), syntax is:<br><strong>&lt;img src="/viewimage.php?modulepart=medias&amp;file=[relative_dir/]filename.ext"&gt;</strong><br>
    +YouCanEditHtmlSource=<br><span class="fa fa-bug"></span> You can include PHP code into this source using tags <strong>&lt;?php ?&gt;</strong>. The following global variables are available: $conf, $db, $mysoc, $user, $website, $websitepage, $weblangs.<br><br><span class="fa fa-bug"></span> You can also include content of another Page/Container with the following syntax:<br><strong>&lt;?php includeContainer('alias_of_container_to_include'); ?&gt;</strong><br><br><span class="fa fa-bug"></span> You can make a redirect to another Page/Container with the following syntax (Note: do not output any content before a redirect):<br><strong>&lt;?php redirectToContainer('alias_of_container_to_redirect_to'); ?&gt;</strong><br><br><span class="fa fa-link"></span> To add a link to another page, use the syntax:<br><strong>&lt;a href="alias_of_page_to_link_to.php"&gt;mylink&lt;a&gt;</strong><br><br><span class="fa fa-download"></span> To include a <strong>link to download</strong> a file stored into the <strong>documents</strong> directory, use the <strong>document.php</strong> wrapper:<br>Example, for a file into documents/ecm (need to be logged), syntax is:<br><strong>&lt;a href="/document.php?modulepart=ecm&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file into documents/medias (open directory for public access), syntax is:<br><strong>&lt;a href="/document.php?modulepart=medias&file=[relative_dir/]filename.ext"&gt;</strong><br>For a file shared with a share link (open access using the sharing hash key of file), syntax is:<br><strong>&lt;a href="/document.php?hashp=publicsharekeyoffile"&gt;</strong><br><br><span class="fa fa-picture-o"></span> To include an <strong>image</strong> stored into the <strong>documents</strong> directory, use the <strong>viewimage.php</strong> wrapper:<br>Example, for an image into documents/medias (open directory for public access), syntax is:<br><strong>&lt;img src="/viewimage.php?modulepart=medias&amp;file=[relative_dir/]filename.ext"&gt;</strong><br>
     ClonePage=Clone page/container
     CloneSite=Clone site
     SiteAdded=Web site added
    
    From dc0aaf48d730b7ce7f7fed403be993708bc351b0 Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Tue, 16 Oct 2018 16:08:20 +0200
    Subject: [PATCH 266/433] FIX and dolibarize
    
    ---
     htdocs/stripe/class/stripe.class.php | 31 ++++++++++++++--------------
     1 file changed, 15 insertions(+), 16 deletions(-)
    
    diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php
    index db2553ee167..e0928b91376 100644
    --- a/htdocs/stripe/class/stripe.class.php
    +++ b/htdocs/stripe/class/stripe.class.php
    @@ -346,10 +346,10 @@ class Stripe extends CommonObject
     	/**
     	 * Create charge with public/payment/newpayment.php, stripe/card.php, cronjobs or REST API
     	 *
    -	 * @param	int 	$amount									Amount to pay
    +	 * @param	int 	$stripeamount									Amount to pay
     	 * @param	string 	$currency								EUR, GPB...
    -	 * @param	string 	$origin									Object type to pay (order, invoice, contract...)
    -	 * @param	int 	$item									Object id to pay
    +	 * @param	string 	$dol_type									Object type to pay (order, invoice, contract...)
    +	 * @param	int 	$dol_id									Object id to pay
     	 * @param	string 	$source									src_xxxxx or card_xxxxx
     	 * @param	string 	$customer								Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe()
     	 * @param	string 	$account								Stripe account ref 'acc_xxxxxxxxxxxxx' via  getStripeAccount()
    @@ -358,7 +358,7 @@ class Stripe extends CommonObject
     	 * @param	boolean	$capture								Set capture flag to true (take payment) or false (wait)
     	 * @return Stripe
     	 */
    -	public function createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status=0, $usethirdpartyemailforreceiptemail=0, $capture=true)
    +	public function createPaymentStripe($stripeamount, $currency, $dol_type, $dol_id, $source, $customer, $account, $status=0, $usethirdpartyemailforreceiptemail=0, $capture=true)
     	{
     		global $conf;
     
    @@ -387,29 +387,28 @@ class Stripe extends CommonObject
     		}
     
     		$arrayzerounitcurrency=array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
    -		if (! in_array($currency, $arrayzerounitcurrency)) $stripeamount=$amount * 100;
    -		else $stripeamount = $amount;
    +		if (! in_array($currency, $arrayzerounitcurrency)) $stripeamount=$stripeamount * 100;
     
     		$societe = new Societe($this->db);
     		if ($key > 0) $societe->fetch($key);
     
     		$description = "";
     		$ref = "";
    -		if ($origin == order) {
    +		if ($dol_type == order) {
     			$order = new Commande($this->db);
    -			$order->fetch($item);
    +			$order->fetch($dol_id);
     			$ref = $order->ref;
     			$description = "ORD=" . $ref . ".CUS=" . $societe->id.".PM=stripe";
    -		} elseif ($origin == invoice) {
    +		} elseif ($dol_type == invoice) {
     			$invoice = new Facture($this->db);
    -			$invoice->fetch($item);
    +			$invoice->fetch($dol_id);
     			$ref = $invoice->ref;
     			$description = "INV=" . $ref . ".CUS=" . $societe->id.".PM=stripe";
     		}
     
     		$metadata = array(
    -			"dol_id" => "" . $item . "",
    -			"dol_type" => "" . $origin . "",
    +			"dol_id" => "" . $dol_id . "",
    +			"dol_type" => "" . $dol_type . "",
     			"dol_thirdparty_id" => "" . $societe->id . "",
     			'dol_thirdparty_name' => $societe->name,
     			'dol_version'=>DOL_VERSION,
    @@ -427,7 +426,7 @@ class Stripe extends CommonObject
     				if (preg_match('/acct_/i', $source))
     				{
     					$charge = \Stripe\Charge::create(array(
    -						"amount" => "$stripeamount",
    +						"amount" => price2num($stripeamount, 'MU'),
     						"currency" => "$currency",
     						"statement_descriptor" => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 8, 'right', 'UTF-8', 1).' '.$description, 22, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt
     						"description" => "Stripe payment: ".$description,
    @@ -437,7 +436,7 @@ class Stripe extends CommonObject
     					));
     				} else {
     					$paymentarray = array(
    -						"amount" => "$stripeamount",
    +						"amount" => price2num($stripeamount, 'MU'),
     						"currency" => "$currency",
     						"statement_descriptor" => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 8, 'right', 'UTF-8', 1).' '.$description, 22, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt
     						"description" => "Stripe payment: ".$description,
    @@ -456,13 +455,13 @@ class Stripe extends CommonObject
     				}
     			} else {
     
    -				$fee = round(($amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100);
    +				$fee = round(($stripeamount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100);
     				if ($fee < ($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100)) {
     					$fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100);
     				}
     
             		$paymentarray = array(
    -						"amount" => "$stripeamount",
    +						"amount" => price2num($stripeamount, 'MU'),
     						"currency" => "$currency",
     						"statement_descriptor" => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 8, 'right', 'UTF-8', 1).' '.$description, 22, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt
     						"description" => "Stripe payment: ".$description,
    
    From d377fc26b4ed91bfd85e24f0cb5ae03efdbb770d Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Tue, 16 Oct 2018 16:55:25 +0200
    Subject: [PATCH 267/433] ADD support of external modepayment
    
    ---
     htdocs/compta/paiement/class/paiement.class.php | 13 ++++++++++---
     1 file changed, 10 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
    index 952f478087b..cc60c2cba8e 100644
    --- a/htdocs/compta/paiement/class/paiement.class.php
    +++ b/htdocs/compta/paiement/class/paiement.class.php
    @@ -7,6 +7,7 @@
      * Copyright (C) 2014      Marcos García 		 <marcosgdf@gmail.com>
      * Copyright (C) 2015      Juanjo Menent		 <jmenent@2byte.es>
      * Copyright (C) 2018      Ferran Marcet		 <fmarcet@2byte.es>
    + * Copyright (C) 2018      Thibault FOUCART		 <support@ptibogxiv.net>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -75,6 +76,8 @@ class Paiement extends CommonObject
     	//paiement de llx_c_paiement
     	public $num_paiement;	// Numero du CHQ, VIR, etc...
     	public $num_payment;	// Numero du CHQ, VIR, etc...
    +  public $payment_id;	// Id of external modepayment
    +  public $payment_site;	// name of external modepayment
     	public $bank_account;	// Id compte bancaire du paiement
     	public $bank_line;     // Id de la ligne d'ecriture bancaire
     	// fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...)
    @@ -102,7 +105,7 @@ class Paiement extends CommonObject
     	 */
     	function fetch($id, $ref='', $fk_bank='')
     	{
    -		$sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.fk_bank,';
    +		$sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.ext_payment_id, p.ext_payment_site, p.fk_bank,';
     		$sql.= ' c.code as type_code, c.libelle as type_libelle,';
     		$sql.= ' p.num_paiement as num_payment, p.note,';
     		$sql.= ' b.fk_account';
    @@ -135,6 +138,8 @@ class Paiement extends CommonObject
     				$this->type_libelle   = $obj->type_libelle;
     				$this->type_code      = $obj->type_code;
     				$this->statut         = $obj->statut;
    +        $this->payment_id     = $obj->ext_payment_id;
    +        $this->payment_site   = $obj->ext_payment_site;
     
     				$this->bank_account   = $obj->fk_account; // deprecated
     				$this->fk_account     = $obj->fk_account;
    @@ -228,9 +233,11 @@ class Paiement extends CommonObject
     			$mtotal = $totalamount;
     		}
     		$note = ($this->note_public?$this->note_public:$this->note);
    +    $payment_id = $this->payment_id ? $this->payment_id : null;
    +    $payment_site = $this->payment_site ? $this->payment_site : null;
     
    -		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, fk_user_creat)";
    -		$sql.= " VALUES (".$conf->entity.", '".$this->ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($note)."', ".$user->id.")";
    +		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat)";
    +		$sql.= " VALUES (".$conf->entity.", '".$this->ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($note)."', '".$this->payment_id."', '".$this->payment_site."', ".$user->id.")";
     
     		dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
     		$resql = $this->db->query($sql);
    
    From 00f839e8b4ee58d9c8722f73ae5a59068facca06 Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Tue, 16 Oct 2018 16:57:16 +0200
    Subject: [PATCH 268/433] add external modepayment  in payment
    
    ---
     htdocs/public/payment/paymentok.php | 6 ++++--
     1 file changed, 4 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php
    index 9b844d8d8b9..15e77502625 100644
    --- a/htdocs/public/payment/paymentok.php
    +++ b/htdocs/public/payment/paymentok.php
    @@ -629,8 +629,10 @@ if ($ispaymentok)
     				}
     				$paiement->paiementid   = $paymentTypeId;
     				$paiement->num_paiement = '';
    -				$paiement->note_public  = 'Online payment '.dol_print_date($now, 'standard').' using '.$paymentmethod.' from '.$ipaddress.' - Transaction ID = '.$TRANSACTIONID;
    -
    +				$paiement->note_public  = 'Online payment '.dol_print_date($now, 'standard').' from '.$ipaddress;
    +				$paiement->payment_id = $TRANSACTIONID;
    +				$paiement->payment_site = $paymentmethod;
    +        
     				if (! $error)
     				{
     					$paiement_id = $paiement->create($user, 1);    // This include closing invoices and regenerating documents
    
    From 96fce2828e3bd521bf42696d9b19f635f0a090c4 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 17:02:36 +0200
    Subject: [PATCH 269/433] Prepare 9.0
    
    ---
     build/rpm/dolibarr_fedora.spec   | 2 ++
     build/rpm/dolibarr_generic.spec  | 6 ++++--
     build/rpm/dolibarr_mandriva.spec | 2 ++
     build/rpm/dolibarr_opensuse.spec | 2 ++
     4 files changed, 10 insertions(+), 2 deletions(-)
    
    diff --git a/build/rpm/dolibarr_fedora.spec b/build/rpm/dolibarr_fedora.spec
    index d5a9189229e..727875485b4 100755
    --- a/build/rpm/dolibarr_fedora.spec
    +++ b/build/rpm/dolibarr_fedora.spec
    @@ -177,6 +177,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/core
     %_datadir/dolibarr/htdocs/cron
     %_datadir/dolibarr/htdocs/custom
    +%_datadir/dolibarr/htdocs/datapolicy
     %_datadir/dolibarr/htdocs/dav
     %_datadir/dolibarr/htdocs/don
     %_datadir/dolibarr/htdocs/ecm
    @@ -212,6 +213,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/supplier_proposal
     %_datadir/dolibarr/htdocs/support
     %_datadir/dolibarr/htdocs/theme
    +%_datadir/dolibarr/htdocs/takepos
     %_datadir/dolibarr/htdocs/ticket
     %_datadir/dolibarr/htdocs/user
     %_datadir/dolibarr/htdocs/variants
    diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec
    index 673d5919d1a..3fb68d06a15 100755
    --- a/build/rpm/dolibarr_generic.spec
    +++ b/build/rpm/dolibarr_generic.spec
    @@ -54,7 +54,7 @@ BuildRequires: desktop-file-utils
     Group: Applications/Productivity
     Requires: apache-base, apache-mod_php, php-cgi, php-cli, php-bz2, php-gd, php-ldap, php-imap, php-mysqli, php-openssl, fonts-ttf-dejavu 
     Requires: mysql, mysql-client 
    -%else
    +%else%_datadir/dolibarr/htdocs/datapolicy
     %if 0%{?suse_version}
     # Voir http://en.opensuse.org/openSUSE:Packaging_Conventions_RPM_Macros
     Group: Productivity/Office/Management
    @@ -124,7 +124,7 @@ cui hai bisogno ed essere facile da usare.
     
     %if 0%{?sles_version}
     %{__rm} -rf $RPM_BUILD_ROOT
    -%{__mkdir} $RPM_BUILD_ROOT
    +%{__mkdir} $RPM_BUILD_ROOT%_datadir/dolibarr/htdocs/datapolicy
     %{__mkdir} $RPM_BUILD_ROOT%{_sysconfdir}
     %{__mkdir} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}
     %else
    @@ -257,6 +257,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/core
     %_datadir/dolibarr/htdocs/cron
     %_datadir/dolibarr/htdocs/custom
    +%_datadir/dolibarr/htdocs/datapolicy
     %_datadir/dolibarr/htdocs/dav
     %_datadir/dolibarr/htdocs/don
     %_datadir/dolibarr/htdocs/ecm
    @@ -292,6 +293,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/supplier_proposal
     %_datadir/dolibarr/htdocs/support
     %_datadir/dolibarr/htdocs/theme
    +%_datadir/dolibarr/htdocs/takepos
     %_datadir/dolibarr/htdocs/ticket
     %_datadir/dolibarr/htdocs/user
     %_datadir/dolibarr/htdocs/variants
    diff --git a/build/rpm/dolibarr_mandriva.spec b/build/rpm/dolibarr_mandriva.spec
    index e3d2a849db2..a4004273211 100755
    --- a/build/rpm/dolibarr_mandriva.spec
    +++ b/build/rpm/dolibarr_mandriva.spec
    @@ -174,6 +174,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/core
     %_datadir/dolibarr/htdocs/cron
     %_datadir/dolibarr/htdocs/custom
    +%_datadir/dolibarr/htdocs/datapolicy
     %_datadir/dolibarr/htdocs/dav
     %_datadir/dolibarr/htdocs/don
     %_datadir/dolibarr/htdocs/ecm
    @@ -209,6 +210,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/supplier_proposal
     %_datadir/dolibarr/htdocs/support
     %_datadir/dolibarr/htdocs/theme
    +%_datadir/dolibarr/htdocs/takepos
     %_datadir/dolibarr/htdocs/ticket
     %_datadir/dolibarr/htdocs/user
     %_datadir/dolibarr/htdocs/variants
    diff --git a/build/rpm/dolibarr_opensuse.spec b/build/rpm/dolibarr_opensuse.spec
    index 5a64bec2e78..478a889c8d6 100755
    --- a/build/rpm/dolibarr_opensuse.spec
    +++ b/build/rpm/dolibarr_opensuse.spec
    @@ -185,6 +185,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/core
     %_datadir/dolibarr/htdocs/cron
     %_datadir/dolibarr/htdocs/custom
    +%_datadir/dolibarr/htdocs/datapolicy
     %_datadir/dolibarr/htdocs/dav
     %_datadir/dolibarr/htdocs/don
     %_datadir/dolibarr/htdocs/ecm
    @@ -220,6 +221,7 @@ done >>%{name}.lang
     %_datadir/dolibarr/htdocs/supplier_proposal
     %_datadir/dolibarr/htdocs/support
     %_datadir/dolibarr/htdocs/theme
    +%_datadir/dolibarr/htdocs/takepos
     %_datadir/dolibarr/htdocs/ticket
     %_datadir/dolibarr/htdocs/user
     %_datadir/dolibarr/htdocs/variants
    
    From f5029bf52b7f3e81e935d34f70418c4a676b856f Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 17:46:14 +0200
    Subject: [PATCH 270/433] Fix template
    
    ---
     .../modulebuilder/template/core/modules/modMyModule.class.php   | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
    index b83580f4017..e81b75c1815 100644
    --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
    +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php
    @@ -72,7 +72,7 @@ class modMyModule extends DolibarrModules
     		$this->version = '1.0';
     
             //Url to the file with your last numberversion of this module
    -        $this->url_last_version = 'http://www.example.com/versionmodule.txt';
    +        //$this->url_last_version = 'http://www.example.com/versionmodule.txt';
     		// Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
     		$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
     		// Name of image file used for this module.
    
    From 2cf87db10ae1916893caaacdf0626f3947d1f3f0 Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Tue, 16 Oct 2018 17:59:58 +0200
    Subject: [PATCH 271/433] Add source link in stripe
    
    ---
     htdocs/societe/paymentmodes.php | 8 +++++++-
     1 file changed, 7 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php
    index 604012a24c3..0fcd7b120db 100644
    --- a/htdocs/societe/paymentmodes.php
    +++ b/htdocs/societe/paymentmodes.php
    @@ -960,7 +960,13 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     					print '</td>';
     				}
     				print '<td>';
    -				print $src->id;
    +        if (!empty($stripeacc)) $connect=$stripeacc.'/';
    +      $url='https://dashboard.stripe.com/'.$connect.'test/sources/'.$src->id;
    +			if ($servicestatus)
    +			{
    +				$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
    +			}
    +				print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'object_globe')." ".$src->id."</a>";
     				print '</td>';
     				print '<td>';
     				if ($src->object=='card')
    
    From 502c52b78fc58a401c10826825a4ae9baabb7ea3 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 18:09:43 +0200
    Subject: [PATCH 272/433] Show real path of module if not into custom
    
    ---
     htdocs/langs/en_US/modulebuilder.lang | 1 +
     htdocs/modulebuilder/index.php        | 9 ++++++++-
     2 files changed, 9 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang
    index 940088368d5..6aef75a5746 100644
    --- a/htdocs/langs/en_US/modulebuilder.lang
    +++ b/htdocs/langs/en_US/modulebuilder.lang
    @@ -99,3 +99,4 @@ InitStructureFromExistingTable=Build the structure array string of an existing t
     UseAboutPage=Disable the about page
     UseDocFolder=Disable the documentation folder
     UseSpecificReadme=Use a specific ReadMe
    +RealPathOfModule=Real path of module
    diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
    index d325e52a343..182cb6b08ff 100644
    --- a/htdocs/modulebuilder/index.php
    +++ b/htdocs/modulebuilder/index.php
    @@ -1154,9 +1154,16 @@ elseif (! empty($module))
     		$head2[$h][2] = 'buildpackage';
     		$h++;
     
    +		// Link to enable / disable
     		print $modulestatusinfo;
     		print ' '.$linktoenabledisable;
    -		print '<br><br>';
    +		print '<br>';
    +
    +		if (realpath($dirread.'/'.$modulelowercase) != $dirread.'/'.$modulelowercase)
    +		{
    +			print $langs->trans("RealPathOfModule").' : <strong>'.realpath($dirread.'/'.$modulelowercase).'</strong><br>';
    +		}
    +		print '<br>';
     
     		if ($tab == 'description')
     		{
    
    From 72dd182b1fed79a2fc8ad126c976e00b745a6a9c Mon Sep 17 00:00:00 2001
    From: atm-ph <phf@atm-consulting.fr>
    Date: Tue, 16 Oct 2018 18:22:43 +0200
    Subject: [PATCH 273/433] Fix list from 'Contacts/Addresses' on company may
     show duplicate value for extrafields
    
    ---
     htdocs/core/class/commonobject.class.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
    index b99c2f8ccd8..32a528c27dc 100644
    --- a/htdocs/core/class/commonobject.class.php
    +++ b/htdocs/core/class/commonobject.class.php
    @@ -4459,6 +4459,7 @@ abstract class CommonObject
     			$resql=$this->db->query($sql);
     			if ($resql)
     			{
    +				$this->array_options = array();
     				$numrows=$this->db->num_rows($resql);
     				if ($numrows)
     				{
    
    From 08fa0deb2459a56dfe805139c199adeb151eab74 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 18:41:50 +0200
    Subject: [PATCH 274/433] FIX Bad label on delete button
    
    ---
     htdocs/expensereport/payment/card.php | 23 +++++++++++++----------
     1 file changed, 13 insertions(+), 10 deletions(-)
    
    diff --git a/htdocs/expensereport/payment/card.php b/htdocs/expensereport/payment/card.php
    index 2876d512c52..29ac7e38862 100644
    --- a/htdocs/expensereport/payment/card.php
    +++ b/htdocs/expensereport/payment/card.php
    @@ -42,6 +42,13 @@ if ($user->societe_id) $socid=$user->societe_id;
     
     $object = new PaymentExpenseReport($db);
     
    +if ($id > 0)
    +{
    +	$result=$object->fetch($id);
    +	if (! $result) dol_print_error($db,'Failed to get payment id '.$id);
    +}
    +
    +
     /*
      * Actions
      */
    @@ -77,10 +84,10 @@ if ($action == 'confirm_valide' && $confirm == 'yes' && $user->rights->expensere
     		$db->commit();
     
     		$factures=array();	// TODO Get all id of invoices linked to this payment
    -		foreach($factures as $id)
    +		foreach($factures as $invoiceid)
     		{
     			$fac = new Facture($db);
    -			$fac->fetch($id);
    +			$fac->fetch($invoiceid);
     
     			$outputlangs = $langs;
     			if (! empty($_REQUEST['lang_id']))
    @@ -110,12 +117,6 @@ if ($action == 'confirm_valide' && $confirm == 'yes' && $user->rights->expensere
     
     llxHeader('', $langs->trans("ExpenseReportPayment"));
     
    -if ($id > 0)
    -{
    -	$result=$object->fetch($id);
    -	if (! $result) dol_print_error($db,'Failed to get payment id '.$id);
    -}
    -
     $form = new Form($db);
     
     $head = payment_expensereport_prepare_head($object);
    @@ -265,9 +266,11 @@ if ($resql)
     			print '<td align="center">'.$expensereport->getLibStatut(4,$objp->amount).'</td>';
     
     			print "</tr>\n";
    +
     			if ($objp->paid == 1)	// If at least one invoice is paid, disable delete
     			{
    -				$disable_delete = 1;
    +				$disable_delete = 2;
    +				$title_button = $langs->trans("CantRemovePaymentWithOneInvoicePaid");
     			}
     			$total = $total + $objp->amount;
     			$i++;
    @@ -303,7 +306,7 @@ if ($action == '')
     		}
     		else
     		{
    -			print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("CantRemovePaymentWithOneInvoicePaid")).'">'.$langs->trans('Delete').'</a>';
    +			print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($title_button).'">'.$langs->trans('Delete').'</a>';
     		}
     	}
     }
    
    From 5a4338ad1d65c5fdebd3244c119259abb3814c35 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 19:20:51 +0200
    Subject: [PATCH 275/433] Revert "FIX and dolibarize"
    
    ---
     htdocs/stripe/class/stripe.class.php | 31 ++++++++++++++--------------
     1 file changed, 16 insertions(+), 15 deletions(-)
    
    diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php
    index e0928b91376..db2553ee167 100644
    --- a/htdocs/stripe/class/stripe.class.php
    +++ b/htdocs/stripe/class/stripe.class.php
    @@ -346,10 +346,10 @@ class Stripe extends CommonObject
     	/**
     	 * Create charge with public/payment/newpayment.php, stripe/card.php, cronjobs or REST API
     	 *
    -	 * @param	int 	$stripeamount									Amount to pay
    +	 * @param	int 	$amount									Amount to pay
     	 * @param	string 	$currency								EUR, GPB...
    -	 * @param	string 	$dol_type									Object type to pay (order, invoice, contract...)
    -	 * @param	int 	$dol_id									Object id to pay
    +	 * @param	string 	$origin									Object type to pay (order, invoice, contract...)
    +	 * @param	int 	$item									Object id to pay
     	 * @param	string 	$source									src_xxxxx or card_xxxxx
     	 * @param	string 	$customer								Stripe customer ref 'cus_xxxxxxxxxxxxx' via customerStripe()
     	 * @param	string 	$account								Stripe account ref 'acc_xxxxxxxxxxxxx' via  getStripeAccount()
    @@ -358,7 +358,7 @@ class Stripe extends CommonObject
     	 * @param	boolean	$capture								Set capture flag to true (take payment) or false (wait)
     	 * @return Stripe
     	 */
    -	public function createPaymentStripe($stripeamount, $currency, $dol_type, $dol_id, $source, $customer, $account, $status=0, $usethirdpartyemailforreceiptemail=0, $capture=true)
    +	public function createPaymentStripe($amount, $currency, $origin, $item, $source, $customer, $account, $status=0, $usethirdpartyemailforreceiptemail=0, $capture=true)
     	{
     		global $conf;
     
    @@ -387,28 +387,29 @@ class Stripe extends CommonObject
     		}
     
     		$arrayzerounitcurrency=array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
    -		if (! in_array($currency, $arrayzerounitcurrency)) $stripeamount=$stripeamount * 100;
    +		if (! in_array($currency, $arrayzerounitcurrency)) $stripeamount=$amount * 100;
    +		else $stripeamount = $amount;
     
     		$societe = new Societe($this->db);
     		if ($key > 0) $societe->fetch($key);
     
     		$description = "";
     		$ref = "";
    -		if ($dol_type == order) {
    +		if ($origin == order) {
     			$order = new Commande($this->db);
    -			$order->fetch($dol_id);
    +			$order->fetch($item);
     			$ref = $order->ref;
     			$description = "ORD=" . $ref . ".CUS=" . $societe->id.".PM=stripe";
    -		} elseif ($dol_type == invoice) {
    +		} elseif ($origin == invoice) {
     			$invoice = new Facture($this->db);
    -			$invoice->fetch($dol_id);
    +			$invoice->fetch($item);
     			$ref = $invoice->ref;
     			$description = "INV=" . $ref . ".CUS=" . $societe->id.".PM=stripe";
     		}
     
     		$metadata = array(
    -			"dol_id" => "" . $dol_id . "",
    -			"dol_type" => "" . $dol_type . "",
    +			"dol_id" => "" . $item . "",
    +			"dol_type" => "" . $origin . "",
     			"dol_thirdparty_id" => "" . $societe->id . "",
     			'dol_thirdparty_name' => $societe->name,
     			'dol_version'=>DOL_VERSION,
    @@ -426,7 +427,7 @@ class Stripe extends CommonObject
     				if (preg_match('/acct_/i', $source))
     				{
     					$charge = \Stripe\Charge::create(array(
    -						"amount" => price2num($stripeamount, 'MU'),
    +						"amount" => "$stripeamount",
     						"currency" => "$currency",
     						"statement_descriptor" => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 8, 'right', 'UTF-8', 1).' '.$description, 22, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt
     						"description" => "Stripe payment: ".$description,
    @@ -436,7 +437,7 @@ class Stripe extends CommonObject
     					));
     				} else {
     					$paymentarray = array(
    -						"amount" => price2num($stripeamount, 'MU'),
    +						"amount" => "$stripeamount",
     						"currency" => "$currency",
     						"statement_descriptor" => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 8, 'right', 'UTF-8', 1).' '.$description, 22, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt
     						"description" => "Stripe payment: ".$description,
    @@ -455,13 +456,13 @@ class Stripe extends CommonObject
     				}
     			} else {
     
    -				$fee = round(($stripeamount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100);
    +				$fee = round(($amount * ($conf->global->STRIPE_APPLICATION_FEE_PERCENT / 100) + $conf->global->STRIPE_APPLICATION_FEE) * 100);
     				if ($fee < ($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100)) {
     					$fee = round($conf->global->STRIPE_APPLICATION_FEE_MINIMAL * 100);
     				}
     
             		$paymentarray = array(
    -						"amount" => price2num($stripeamount, 'MU'),
    +						"amount" => "$stripeamount",
     						"currency" => "$currency",
     						"statement_descriptor" => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 8, 'right', 'UTF-8', 1).' '.$description, 22, 'right', 'UTF-8', 1),     // 22 chars that appears on bank receipt
     						"description" => "Stripe payment: ".$description,
    
    From f0c0c4779bd82d18dfe1713ba7a202f028cdd132 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 19:32:35 +0200
    Subject: [PATCH 276/433] Fix remove yellow alert
    
    ---
     htdocs/accountancy/index.php | 24 ++++++++++++------------
     1 file changed, 12 insertions(+), 12 deletions(-)
    
    diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php
    index b2dfdb91e05..2d34ec816e3 100644
    --- a/htdocs/accountancy/index.php
    +++ b/htdocs/accountancy/index.php
    @@ -61,13 +61,13 @@ if ($conf->accounting->enabled)
     
     	// STEPS
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/journals_list.php?id=35">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("AccountingJournals").'</mark>'.'</strong>'.'</a>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/journals_list.php?id=35">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("AccountingJournals").'</strong>'.'</a>');
     	print "<br>\n";
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/accountmodel.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("Pcg_version").'</mark>'.'</strong>'.'</a>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/accountmodel.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Pcg_version").'</strong>'.'</a>');
     	print "<br>\n";
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("Chartofaccounts").'</mark>'.'</strong>'.'</a>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("Chartofaccounts").'</strong>'.'</a>');
     	print "<br>\n";
     
     	print "<br>\n";
    @@ -76,20 +76,20 @@ if ($conf->accounting->enabled)
     	print "<br>\n";
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/defaultaccounts.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</mark>'.'</strong>'.'</a>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/defaultaccounts.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>'.'</a>');
     	print "<br>\n";
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '<a href="'.DOL_URL_ROOT.'/compta/bank/list.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("MenuBankAccounts").'</mark>'.'</strong>'.'</a>')."\n";
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '<a href="'.DOL_URL_ROOT.'/compta/bank/list.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuBankAccounts").'</strong>'.'</a>')."\n";
     	print "<br>\n";
     
     	$step++;
    -	$textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=10&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.'<mark>'.$langs->transnoentitiesnoconv("MenuVatAccounts").'</mark>'.'</strong>'.'</a>';
    +	$textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=10&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuVatAccounts").'</strong>'.'</a>';
     	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescVat", $step, $textlink);
     	print "<br>\n";
     	if (! empty($conf->tax->enabled))
     	{
    -	     $textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=7&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.'<mark>'.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</mark>'.'</strong>'.'</a>';
    +	     $textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=7&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup").'-'.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</strong>'.'</a>';
     	    $step++;
     	    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescContrib", $step, $textlink);
     	    print "<br>\n";
    @@ -105,7 +105,7 @@ if ($conf->accounting->enabled)
     	if (! empty($conf->expensereport->enabled))  // TODO Move this in the default account page because this is only one accounting account per purpose, not several.
     	{
     	    $step++;
    -	    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=17&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</mark>'.'</strong>'.'</a>');
    +	    print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=17&from=accountancy">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</strong>'.'</a>');
     	    print "<br>\n";
     	}
     	/*
    @@ -123,7 +123,7 @@ if ($conf->accounting->enabled)
     	}*/
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/productaccount.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".'<mark>'.$langs->transnoentitiesnoconv("ProductsBinding").'</mark>'.'</strong>'.'</a>');
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '<a href="'.DOL_URL_ROOT.'/accountancy/admin/productaccount.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("ProductsBinding").'</strong>'.'</a>');
     	print "<br>\n";
     
     
    @@ -139,17 +139,17 @@ if ($conf->accounting->enabled)
     	$langs->loadLangs(array('bills', 'trips'));
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsCustomers"), '<a href="'.DOL_URL_ROOT.'/accountancy/customer/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".'<mark>'.$langs->transnoentitiesnoconv("CustomersVentilation").'</mark>'.'</strong>'.'</a>')."\n";
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsCustomers"), '<a href="'.DOL_URL_ROOT.'/accountancy/customer/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("CustomersVentilation").'</strong>'.'</a>')."\n";
     	print "<br>\n";
     
     	$step++;
    -	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsSuppliers"), '<a href="'.DOL_URL_ROOT.'/accountancy/supplier/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".'<mark>'.$langs->transnoentitiesnoconv("SuppliersVentilation").'</mark>'.'</strong>'.'</a>')."\n";
    +	print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("BillsSuppliers"), '<a href="'.DOL_URL_ROOT.'/accountancy/supplier/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("SuppliersVentilation").'</strong>'.'</a>')."\n";
     	print "<br>\n";
     
     	if (! empty($conf->expensereport->enabled) || ! empty($conf->deplacement->enabled))
     	{
     		$step++;
    -		print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<a href="'.DOL_URL_ROOT.'/accountancy/expensereport/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".'<mark>'.$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</mark>'.'</strong>'.'</a>')."\n";
    +		print img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64+$step), $langs->transnoentitiesnoconv("ExpenseReports"), '<a href="'.DOL_URL_ROOT.'/accountancy/expensereport/index.php">'.'<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy")."-".$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong>'.'</a>')."\n";
     	    print "<br>\n";
     	}
     
    
    From 78d7ea459d15ae9d7ee5c3514f297a63b145c52e Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 19:49:16 +0200
    Subject: [PATCH 277/433] Update paymentmodes.php
    
    ---
     htdocs/societe/paymentmodes.php | 18 ++++++++++--------
     1 file changed, 10 insertions(+), 8 deletions(-)
    
    diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php
    index 0fcd7b120db..1acc31cc8ec 100644
    --- a/htdocs/societe/paymentmodes.php
    +++ b/htdocs/societe/paymentmodes.php
    @@ -959,15 +959,17 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     					print '<td>';
     					print '</td>';
     				}
    +				// Src ID
     				print '<td>';
    -        if (!empty($stripeacc)) $connect=$stripeacc.'/';
    -      $url='https://dashboard.stripe.com/'.$connect.'test/sources/'.$src->id;
    -			if ($servicestatus)
    -			{
    -				$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
    -			}
    +				if (!empty($stripeacc)) $connect=$stripeacc.'/';
    +				$url='https://dashboard.stripe.com/'.$connect.'test/sources/'.$src->id;
    +				if ($servicestatus)
    +				{
    +					$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
    +				}
     				print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'object_globe')." ".$src->id."</a>";
     				print '</td>';
    +				// Img of credit card
     				print '<td>';
     				if ($src->object=='card')
     				{
    @@ -981,8 +983,8 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     				{
     					print '<span class="fa fa-university fa-2x fa-fw"></span>';
     				}
    -
    -				print'</td><td valign="middle">';
    +				print'</td>';
    +				print '<td valign="middle">';
     				if ($src->object=='card')
     				{
     					print '....'.$src->last4.' - '.$src->exp_month.'/'.$src->exp_year.'';
    
    From 44d8333633e5f0a547987ce58f6efbfca22c3be6 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 20:00:53 +0200
    Subject: [PATCH 278/433] Fix external link must be after label
    
    ---
     htdocs/societe/paymentmodes.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php
    index 1acc31cc8ec..13fdf048382 100644
    --- a/htdocs/societe/paymentmodes.php
    +++ b/htdocs/societe/paymentmodes.php
    @@ -557,7 +557,7 @@ if (empty($reshook))
     			$sql.= " SET key_account = '".$db->escape(GETPOST('key_account', 'alpha'))."'";
     			$sql.= " WHERE site = 'stripe' AND fk_soc = ".$object->id." AND status = ".$servicestatus." AND entity = ".$conf->entity;	// Keep = here for entity. Only 1 record must be modified !
                     }
    -     
    +
     			$resql = $db->query($sql);
     			$num = $db->num_rows($resql);
     			if (empty($num) && !empty($newcu))
    @@ -967,7 +967,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard'
     				{
     					$url='https://dashboard.stripe.com/'.$connect.'sources/'.$src->id;
     				}
    -				print "<a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'object_globe')." ".$src->id."</a>";
    +				print $src->id." <a href='".$url."' target='_stripe'>".img_picto($langs->trans('ShowInStripe'), 'object_globe')."</a>";
     				print '</td>';
     				// Img of credit card
     				print '<td>';
    
    From f470068d9d7e95299648b46254b7835acc3fa50c Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Tue, 16 Oct 2018 20:10:13 +0200
    Subject: [PATCH 279/433] fix phpcs
    
    ---
     htdocs/accountancy/journal/expensereportsjournal.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php
    index 6fb8aed5c31..9c39016f008 100644
    --- a/htdocs/accountancy/journal/expensereportsjournal.php
    +++ b/htdocs/accountancy/journal/expensereportsjournal.php
    @@ -212,7 +212,7 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->subledger_label = $tabuser[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
     
    -					$accountingaccount->fetch(null ,$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
    +					$accountingaccount->fetch(null, $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
     					$bookkeeping->label_compte = $accountingaccount->label;
     
     					$bookkeeping->label_operation = $tabuser[$key]['name'];
    
    From a40271e475bf2df2510b719643bbd149b1444932 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Tue, 16 Oct 2018 20:11:32 +0200
    Subject: [PATCH 280/433] Update bankjournal.php
    
    ---
     htdocs/accountancy/journal/bankjournal.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php
    index 7b4248630ae..3b86835e927 100644
    --- a/htdocs/accountancy/journal/bankjournal.php
    +++ b/htdocs/accountancy/journal/bankjournal.php
    @@ -554,14 +554,14 @@ if (! $error && $action == 'writebookkeeping') {
     							$bookkeeping->subledger_label = $tabuser[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
     
    -							$accountingaccount->fetch(null ,$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
    +							$accountingaccount->fetch(null, $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
     							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if ($tabtype[$key] == 'payment_salary') {
     							$bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
     							$bookkeeping->subledger_label = $tabuser[$key]['name'];
     							$bookkeeping->numero_compte = $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT;
     
    -							$accountingaccount->fetch(null ,$conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
    +							$accountingaccount->fetch(null, $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT, true);
     							$bookkeeping->label_compte = $accountingaccount->label;
     						} else if (in_array($tabtype[$key], array('sc', 'payment_sc'))) {   // If payment is payment of social contribution
     							$bookkeeping->subledger_account = '';
    
    From 57bb8bcfcdabc6324990e9a636b1d480818476c9 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 20:27:33 +0200
    Subject: [PATCH 281/433] Disabled action are hidden with reason
    
    ---
     htdocs/product/stock/product.php | 34 +++++++++++++++++++++++++-------
     htdocs/variants/combinations.php | 13 +++++++-----
     2 files changed, 35 insertions(+), 12 deletions(-)
    
    diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
    index dc291eb0fdc..70a37a4bba6 100644
    --- a/htdocs/product/stock/product.php
    +++ b/htdocs/product/stock/product.php
    @@ -766,17 +766,37 @@ if (empty($reshook))
     	{
     	    print "<div class=\"tabsAction\">\n";
     
    -		if (! $variants) {
    -
    -			if ($user->rights->stock->mouvement->creer) {
    +		if ($user->rights->stock->mouvement->creer)
    +		{
    +			if (! $variants) {
     				print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=correction">' . $langs->trans("CorrectStock") . '</a>';
     			}
    -
    -			//if (($user->rights->stock->mouvement->creer) && ! $object->hasbatch())
    -			if ($user->rights->stock->mouvement->creer) {
    -				print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=transfert">' . $langs->trans("TransferStock") . '</a>';
    +			else
    +			{
    +				print '<a class="butActionRefused" href="#" title="'.$langs->trans("ActionAvailableOnVariantProductOnly").'">' . $langs->trans("CorrectStock") . '</a>';
     			}
     		}
    +		else
    +		{
    +			print '<a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">' . $langs->trans("CorrectStock") . '</a>';
    +		}
    +
    +		//if (($user->rights->stock->mouvement->creer) && ! $object->hasbatch())
    +		if ($user->rights->stock->mouvement->creer)
    +		{
    +			if (! $variants) {
    +				print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=transfert">' . $langs->trans("TransferStock") . '</a>';
    +			}
    +			else
    +			{
    +				print '<a class="butActionRefused" href="#" title="'.$langs->trans("ActionAvailableOnVariantProductOnly").'">' . $langs->trans("TransferStock") . '</a>';
    +			}
    +		}
    +		else
    +		{
    +			print '<a class="butActionRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">' . $langs->trans("CorrectStock") . '</a>';
    +		}
    +
     		print '</div>';
     	}
     
    diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php
    index f5c0d813995..848e5ee70fe 100644
    --- a/htdocs/variants/combinations.php
    +++ b/htdocs/variants/combinations.php
    @@ -326,7 +326,7 @@ if (! empty($id) || ! empty($ref))
     
     		if ($action == 'add') {
     			$title = $langs->trans('NewProductCombination');
    -			print dol_fiche_head();
    +			//print dol_fiche_head();
     			$features = $_SESSION['addvariant_'.$object->id];
     			//First, sanitize
     			print '<div id="parttoaddvariant">';
    @@ -347,7 +347,8 @@ if (! empty($id) || ! empty($ref))
     				}
     			}
     			print '</div>';
    -			print dol_fiche_end();
    +			print '<br><br>';
    +			//print dol_fiche_end();
     		} else {
     			$title = $langs->trans('EditProductCombination');
     		}
    @@ -633,12 +634,14 @@ if (! empty($id) || ! empty($ref))
     		print '<div class="tabsAction">';
     
     		print '	<div class="inline-block divButAction">';
    -		if ($productCombinations) {
    -		    print '<a href="combinations.php?id='.$object->id.'&action=copy" class="butAction">'.$langs->trans('PropagateVariant').'</a>';
    -		}
     
     		print '<a href="combinations.php?id='.$object->id.'&action=add" class="butAction">'.$langs->trans('NewProductCombination').'</a>'; // NewVariant
     
    +		if ($productCombinations)
    +		{
    +			print '<a href="combinations.php?id='.$object->id.'&action=copy" class="butAction">'.$langs->trans('PropagateVariant').'</a>';
    +		}
    +
     		// Too much bugged page.
     		/*
     		print '<a href="generator.php?id='.$object->id.'" class="butAction">'.$langs->trans('ProductCombinationGenerator').'</a>';
    
    From c9aaf01a7c6dceb13f40c74145384c92c5488cbd Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Tue, 16 Oct 2018 20:56:10 +0200
    Subject: [PATCH 282/433] MOVE ticket dictionnary in API /setup
    
    ---
     htdocs/api/class/api_setup.class.php | 181 +++++++++++++++++++++++++++
     1 file changed, 181 insertions(+)
    
    diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php
    index ef2b4c8bb6d..a8c7456cf05 100644
    --- a/htdocs/api/class/api_setup.class.php
    +++ b/htdocs/api/class/api_setup.class.php
    @@ -578,7 +578,188 @@ class Setup extends DolibarrApi
     
             return $list;
         }
    +	
    +if ($conf->ticket->enabled) {    
    +     /**
    +     * Get the list of tickets categories.
    +     *
    +     * @param string    $sortfield  Sort field
    +     * @param string    $sortorder  Sort order
    +     * @param int       $limit      Number of items per page
    +     * @param int       $page       Page number (starting from zero)
    +     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    +     * @return List of events types
    +     *
    +     * @url     GET dictionary/ticket_categories
    +     *
    +     * @throws RestException
    +     */
    +    function getTicketsCategories($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
    +    	$list = array();
     
    +    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
    +    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_category as t";
    +    	$sql.= " WHERE t.active = 1";
    +    	// Add sql filters
    +    	if ($sqlfilters)
    +    	{
    +    		if (! DolibarrApi::_checkFilters($sqlfilters))
    +    		{
    +    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    +    		}
    +    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    +    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    +    	}
    +
    +
    +    	$sql.= $this->db->order($sortfield, $sortorder);
    +
    +    	if ($limit) {
    +    		if ($page < 0) {
    +    			$page = 0;
    +    		}
    +    		$offset = $limit * $page;
    +
    +    		$sql .= $this->db->plimit($limit, $offset);
    +    	}
    +
    +    	$result = $this->db->query($sql);
    +
    +    	if ($result) {
    +    		$num = $this->db->num_rows($result);
    +    		$min = min($num, ($limit <= 0 ? $num : $limit));
    +    		for ($i = 0; $i < $min; $i++) {
    +    			$list[] = $this->db->fetch_object($result);
    +    		}
    +    	} else {
    +    		throw new RestException(503, 'Error when retrieving list of ticket categories : '.$this->db->lasterror());
    +    	}
    +
    +    	return $list;
    +    }
    +
    +    /**
    +     * Get the list of tickets severity.
    +     *
    +     * @param string    $sortfield  Sort field
    +     * @param string    $sortorder  Sort order
    +     * @param int       $limit      Number of items per page
    +     * @param int       $page       Page number (starting from zero)
    +     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    +     * @return List of events types
    +     *
    +     * @url     GET dictionary/ticket_severities
    +     *
    +     * @throws RestException
    +     */
    +    function getTicketsSeverities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
    +    	$list = array();
    +
    +    	$sql = "SELECT rowid, code, pos,  label, use_default, color, description";
    +    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_severity as t";
    +    	$sql.= " WHERE t.active = 1";
    +    	// Add sql filters
    +    	if ($sqlfilters)
    +    	{
    +    		if (! DolibarrApi::_checkFilters($sqlfilters))
    +    		{
    +    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    +    		}
    +    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    +    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    +    	}
    +
    +
    +    	$sql.= $this->db->order($sortfield, $sortorder);
    +
    +    	if ($limit) {
    +    		if ($page < 0) {
    +    			$page = 0;
    +    		}
    +    		$offset = $limit * $page;
    +
    +    		$sql .= $this->db->plimit($limit, $offset);
    +    	}
    +
    +    	$result = $this->db->query($sql);
    +
    +    	if ($result) {
    +    		$num = $this->db->num_rows($result);
    +    		$min = min($num, ($limit <= 0 ? $num : $limit));
    +    		for ($i = 0; $i < $min; $i++) {
    +    			$list[] = $this->db->fetch_object($result);
    +    		}
    +    	} else {
    +    		throw new RestException(503, 'Error when retrieving list of ticket severities : '.$this->db->lasterror());
    +    	}
    +
    +    	return $list;
    +    }
    +
    +    /**
    +     * Get the list of tickets types.
    +     *
    +     * @param string    $sortfield  Sort field
    +     * @param string    $sortorder  Sort order
    +     * @param int       $limit      Number of items per page
    +     * @param int       $page       Page number (starting from zero)
    +     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    +     * @return List of events types
    +     *
    +     * @url     GET dictionary/ticket_types
    +     *
    +     * @throws RestException
    +     */
    +    function getTicketsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    +    {
    +    	$list = array();
    +
    +    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
    +    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_type as t";
    +    	$sql.= " WHERE t.active = 1";
    +    	if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'";
    +    	if ($module)    $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'";
    +    	// Add sql filters
    +    	if ($sqlfilters)
    +    	{
    +    		if (! DolibarrApi::_checkFilters($sqlfilters))
    +    		{
    +    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    +    		}
    +    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    +    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    +    	}
    +
    +
    +    	$sql.= $this->db->order($sortfield, $sortorder);
    +
    +    	if ($limit) {
    +    		if ($page < 0) {
    +    			$page = 0;
    +    		}
    +    		$offset = $limit * $page;
    +
    +    		$sql .= $this->db->plimit($limit, $offset);
    +    	}
    +
    +    	$result = $this->db->query($sql);
    +
    +    	if ($result) {
    +    		$num = $this->db->num_rows($result);
    +    		$min = min($num, ($limit <= 0 ? $num : $limit));
    +    		for ($i = 0; $i < $min; $i++) {
    +    			$list[] = $this->db->fetch_object($result);
    +    		}
    +    	} else {
    +    		throw new RestException(503, 'Error when retrieving list of ticket types : '.$this->db->lasterror());
    +    	}
    +
    +    	return $list;
    +    }
    +
    +}	
     
         /**
          * Do a test of integrity for files and setup.
    
    From 0e6d3a0f48cef76ec61fbb1d0990e73501b31b22 Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Tue, 16 Oct 2018 20:59:06 +0200
    Subject: [PATCH 283/433] FIX delete dictionnary in ticket API
    
    ---
     htdocs/ticket/class/api_tickets.class.php | 184 ----------------------
     1 file changed, 184 deletions(-)
    
    diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php
    index c75ab7e2450..110c27a5cce 100644
    --- a/htdocs/ticket/class/api_tickets.class.php
    +++ b/htdocs/ticket/class/api_tickets.class.php
    @@ -473,190 +473,6 @@ class Tickets extends DolibarrApi
             );
         }
     
    -
    -    /**
    -     * Get the list of tickets categories.
    -     *
    -     * @param string    $sortfield  Sort field
    -     * @param string    $sortorder  Sort order
    -     * @param int       $limit      Number of items per page
    -     * @param int       $page       Page number (starting from zero)
    -     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    -     * @return List of events types
    -     *
    -     * @url     GET setup/dictionary/categories
    -     *
    -     * @throws RestException
    -     */
    -    function getTicketsCategories($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    -    {
    -    	$list = array();
    -
    -    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
    -    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_category as t";
    -    	$sql.= " WHERE t.active = 1";
    -    	// Add sql filters
    -    	if ($sqlfilters)
    -    	{
    -    		if (! DolibarrApi::_checkFilters($sqlfilters))
    -    		{
    -    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    -    		}
    -    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    -    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    -    	}
    -
    -
    -    	$sql.= $this->db->order($sortfield, $sortorder);
    -
    -    	if ($limit) {
    -    		if ($page < 0) {
    -    			$page = 0;
    -    		}
    -    		$offset = $limit * $page;
    -
    -    		$sql .= $this->db->plimit($limit, $offset);
    -    	}
    -
    -    	$result = $this->db->query($sql);
    -
    -    	if ($result) {
    -    		$num = $this->db->num_rows($result);
    -    		$min = min($num, ($limit <= 0 ? $num : $limit));
    -    		for ($i = 0; $i < $min; $i++) {
    -    			$list[] = $this->db->fetch_object($result);
    -    		}
    -    	} else {
    -    		throw new RestException(503, 'Error when retrieving list of ticket categories : '.$this->db->lasterror());
    -    	}
    -
    -    	return $list;
    -    }
    -
    -    /**
    -     * Get the list of tickets severity.
    -     *
    -     * @param string    $sortfield  Sort field
    -     * @param string    $sortorder  Sort order
    -     * @param int       $limit      Number of items per page
    -     * @param int       $page       Page number (starting from zero)
    -     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    -     * @return List of events types
    -     *
    -     * @url     GET setup/dictionary/severities
    -     *
    -     * @throws RestException
    -     */
    -    function getTicketsSeverities($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    -    {
    -    	$list = array();
    -
    -    	$sql = "SELECT rowid, code, pos,  label, use_default, color, description";
    -    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_severity as t";
    -    	$sql.= " WHERE t.active = 1";
    -    	// Add sql filters
    -    	if ($sqlfilters)
    -    	{
    -    		if (! DolibarrApi::_checkFilters($sqlfilters))
    -    		{
    -    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    -    		}
    -    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    -    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    -    	}
    -
    -
    -    	$sql.= $this->db->order($sortfield, $sortorder);
    -
    -    	if ($limit) {
    -    		if ($page < 0) {
    -    			$page = 0;
    -    		}
    -    		$offset = $limit * $page;
    -
    -    		$sql .= $this->db->plimit($limit, $offset);
    -    	}
    -
    -    	$result = $this->db->query($sql);
    -
    -    	if ($result) {
    -    		$num = $this->db->num_rows($result);
    -    		$min = min($num, ($limit <= 0 ? $num : $limit));
    -    		for ($i = 0; $i < $min; $i++) {
    -    			$list[] = $this->db->fetch_object($result);
    -    		}
    -    	} else {
    -    		throw new RestException(503, 'Error when retrieving list of ticket severities : '.$this->db->lasterror());
    -    	}
    -
    -    	return $list;
    -    }
    -
    -    /**
    -     * Get the list of tickets types.
    -     *
    -     * @param string    $sortfield  Sort field
    -     * @param string    $sortorder  Sort order
    -     * @param int       $limit      Number of items per page
    -     * @param int       $page       Page number (starting from zero)
    -     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    -     * @return List of events types
    -     *
    -     * @url     GET setup/dictionary/types
    -     *
    -     * @throws RestException
    -     */
    -    function getTicketsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
    -    {
    -    	$list = array();
    -
    -    	$sql = "SELECT rowid, code, pos,  label, use_default, description";
    -    	$sql.= " FROM ".MAIN_DB_PREFIX."c_ticket_type as t";
    -    	$sql.= " WHERE t.active = 1";
    -    	if ($type) $sql.=" AND t.type LIKE '%" . $this->db->escape($type) . "%'";
    -    	if ($module)    $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'";
    -    	// Add sql filters
    -    	if ($sqlfilters)
    -    	{
    -    		if (! DolibarrApi::_checkFilters($sqlfilters))
    -    		{
    -    			throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    -    		}
    -    		$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    -    		$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    -    	}
    -
    -
    -    	$sql.= $this->db->order($sortfield, $sortorder);
    -
    -    	if ($limit) {
    -    		if ($page < 0) {
    -    			$page = 0;
    -    		}
    -    		$offset = $limit * $page;
    -
    -    		$sql .= $this->db->plimit($limit, $offset);
    -    	}
    -
    -    	$result = $this->db->query($sql);
    -
    -    	if ($result) {
    -    		$num = $this->db->num_rows($result);
    -    		$min = min($num, ($limit <= 0 ? $num : $limit));
    -    		for ($i = 0; $i < $min; $i++) {
    -    			$list[] = $this->db->fetch_object($result);
    -    		}
    -    	} else {
    -    		throw new RestException(503, 'Error when retrieving list of ticket types : '.$this->db->lasterror());
    -    	}
    -
    -    	return $list;
    -    }
    -
    -
    -
    -
    -
         /**
          * Validate fields before create or update object
          *
    
    From e2a6c9e332c83967cb9bf5608f27007edcf096f4 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= <frederic.france@free.fr>
    Date: Tue, 16 Oct 2018 21:05:15 +0200
    Subject: [PATCH 284/433] cut long lines >500
    
    ---
     htdocs/datapolicy/class/actions_datapolicy.class.php | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/datapolicy/class/actions_datapolicy.class.php b/htdocs/datapolicy/class/actions_datapolicy.class.php
    index 5a19b039602..21fcb4a5a44 100644
    --- a/htdocs/datapolicy/class/actions_datapolicy.class.php
    +++ b/htdocs/datapolicy/class/actions_datapolicy.class.php
    @@ -429,7 +429,10 @@ class ActionsDatapolicy
                     $jsscript .= "var forme_juridique = [" . PHP_EOL;
                     $jsscript .= "11, 12, 13, 15, 17, 18, 19, 35, 60, 200, 311, 312, 316, 401, 600, 700, 1005" . PHP_EOL;
                     $jsscript .= "];" . PHP_EOL;
    -                $jsscript .= "function hideRgPD() { if ($('#typent_id').val() == 8 || forme_juridique.indexOf(parseInt($('#forme_juridique_code').val())) > -1) { console.log(elementToHide); $('tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection').show(); } else { $('tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection').hide(); }}" . PHP_EOL;
    +                $jsscript .= "function hideRgPD() {" . PHP_EOL;
    +                $jsscript .= " if ($('#typent_id').val() == 8 || forme_juridique.indexOf(parseInt($('#forme_juridique_code').val())) > -1) {" . PHP_EOL;
    +                $jsscript .= " console.log(elementToHide);" . PHP_EOL;
    +                $jsscript .= " $('tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection').show(); } else { $('tr.societe_extras_datapolicy_consentement, tr.societe_extras_datapolicy_opposition_traitement, tr.societe_extras_datapolicy_opposition_prospection').hide(); }}" . PHP_EOL;
                     $jsscript .= "hideRgPD();" . PHP_EOL;
                     $jsscript .= "$('#forme_juridique_code, #typent_id').change(function(){ hideRgPD(); });" . PHP_EOL;
                     $jsscript .= '</script>';
    
    From eb4ffcf1a706d0590c58b49178ac6e41f5f2fe95 Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Tue, 16 Oct 2018 21:17:00 +0200
    Subject: [PATCH 285/433] Fix FEC Missing some information in bookkeeping
    
    ---
     htdocs/accountancy/journal/sellsjournal.php | 12 +++++++++++-
     1 file changed, 11 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php
    index dcfd11ac67a..10cb339c2d6 100644
    --- a/htdocs/accountancy/journal/sellsjournal.php
    +++ b/htdocs/accountancy/journal/sellsjournal.php
    @@ -70,6 +70,8 @@ $parameters=array();
     
     $reshook=$hookmanager->executeHooks('doActions',$parameters,$user,$action);    // Note that $action and $object may have been modified by some hooks
     
    +$accountingaccount = new AccountingAccount($db);
    +
     // Get informations of journal
     $accountingjournalstatic = new AccountingJournal($db);
     $accountingjournalstatic->fetch($id_journal);
    @@ -319,6 +321,10 @@ if ($action == 'writebookkeeping') {
     					$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
     					$bookkeeping->subledger_label = $tabcompany[$key]['name'];
     					$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
    +
    +					$accountingaccount->fetch(null, $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER, true);
    +					$bookkeeping->label_compte = $accountingaccount->label;
    +
     					$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("SubledgerAccount");
     					$bookkeeping->montant = $mt;
     					$bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
    @@ -359,7 +365,6 @@ if ($action == 'writebookkeeping') {
     			foreach ( $tabht[$key] as $k => $mt ) {
     				//if ($mt) {
     					// get compte id and label
    -					$accountingaccount = new AccountingAccount($db);
     					if ($accountingaccount->fetch(null, $k, true)) {
     						$bookkeeping = new BookKeeping($db);
     						$bookkeeping->doc_date = $val["date"];
    @@ -373,6 +378,7 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +						$bookkeeping->label_compte = $accountingaccount->label;
     						$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $accountingaccount->label;
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
    @@ -432,6 +438,10 @@ if ($action == 'writebookkeeping') {
     						$bookkeeping->subledger_account = '';
     						$bookkeeping->subledger_label = '';
     						$bookkeeping->numero_compte = $k;
    +
    +						$accountingaccount->fetch($k, null, true);
    +						$bookkeeping->label_compte = $accountingaccount->label;
    +
     						$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("VAT").' '.join(', ',$def_tva[$key][$k]) .' %' . ($numtax?' - Localtax '.$numtax:'');
     						$bookkeeping->montant = $mt;
     						$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
    
    From 5e20390e15b37eabc57dc2652dd8330301a6f702 Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Tue, 16 Oct 2018 21:33:42 +0200
    Subject: [PATCH 286/433] FIX call of bankaccount class
    
    ---
     htdocs/societe/class/api_thirdparties.class.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php
    index 0b640fe1085..fdd9b1f5294 100644
    --- a/htdocs/societe/class/api_thirdparties.class.php
    +++ b/htdocs/societe/class/api_thirdparties.class.php
    @@ -18,6 +18,7 @@
     
     use Luracast\Restler\RestException;
     
    +require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
     
     /**
      * API class for thirdparties
    
    From 737bbf6e7c0835ef5877ef1d5ea13ece4aaaa50b Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 21:38:27 +0200
    Subject: [PATCH 287/433] Update api_setup.class.php
    
    ---
     htdocs/api/class/api_setup.class.php | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php
    index a8c7456cf05..b9a100972ac 100644
    --- a/htdocs/api/class/api_setup.class.php
    +++ b/htdocs/api/class/api_setup.class.php
    @@ -579,7 +579,8 @@ class Setup extends DolibarrApi
             return $list;
         }
     	
    -if ($conf->ticket->enabled) {    
    +if (! empty($conf->ticket->enabled))
    +{    
          /**
          * Get the list of tickets categories.
          *
    
    From 2ce1aaaebfd7ed438477c321127cdbe65bee5900 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 21:43:40 +0200
    Subject: [PATCH 288/433] Update api_thirdparties.class.php
    
    ---
     htdocs/societe/class/api_thirdparties.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php
    index fdd9b1f5294..365073726bc 100644
    --- a/htdocs/societe/class/api_thirdparties.class.php
    +++ b/htdocs/societe/class/api_thirdparties.class.php
    @@ -18,7 +18,6 @@
     
     use Luracast\Restler\RestException;
     
    -require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
     
     /**
      * API class for thirdparties
    @@ -53,6 +52,7 @@ class Thirdparties extends DolibarrApi
     		require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
     		require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
     		require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
    +		require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
     
     		$this->company = new Societe($this->db);
     
    
    From f80de9e65ee8afacb9638ecc8aefa9cbd8052d21 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Tue, 16 Oct 2018 21:49:26 +0200
    Subject: [PATCH 289/433] fix syntax error and phpcs
    
    ---
     htdocs/api/class/api_setup.class.php | 6 ++----
     1 file changed, 2 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php
    index fff8d7df7aa..3ec618dc92a 100644
    --- a/htdocs/api/class/api_setup.class.php
    +++ b/htdocs/api/class/api_setup.class.php
    @@ -3,6 +3,7 @@
      * Copyright (C) 2016	Laurent Destailleur		<eldy@users.sourceforge.net>
      * Copyright (C) 2017	Regis Houssin	        <regis.houssin@capnetworks.com>
      * Copyright (C) 2017	Neil Orley	            <neil.orley@oeris.fr>
    + * Copyright (C) 2018   Frédéric France         <frederic.france@netlogic.fr>
      *
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -580,9 +581,7 @@ class Setup extends DolibarrApi
     
             return $list;
         }
    -	
    -if (! empty($conf->ticket->enabled))
    -{    
    +
          /**
          * Get the list of tickets categories.
          *
    @@ -762,7 +761,6 @@ if (! empty($conf->ticket->enabled))
         	return $list;
         }
     
    -}	
     
         /**
          * Do a test of integrity for files and setup.
    
    From 00dc78dd01e0b7f1741f093557c84811349b2cd2 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 16 Oct 2018 21:58:33 +0200
    Subject: [PATCH 290/433] Fix responsive
    
    ---
     htdocs/user/card.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/user/card.php b/htdocs/user/card.php
    index cf733932129..6a8e0d4f14a 100644
    --- a/htdocs/user/card.php
    +++ b/htdocs/user/card.php
    @@ -1383,7 +1383,7 @@ else
     			// Password
     			print '<tr><td>'.$langs->trans("Password").'</td>';
     
    -			print '<td>';
    +			print '<td class="wordbreak">';
     			$valuetoshow='';
     			if (preg_match('/ldap/',$dolibarr_main_authentication))
     			{
    
    From 4e14c2817c5c8522aa11e1c742c3f485fe5d46dd Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Tue, 16 Oct 2018 22:09:11 +0200
    Subject: [PATCH 291/433] add errors def to form class
    
    ---
     htdocs/core/class/html.form.class.php | 5 +++++
     1 file changed, 5 insertions(+)
    
    diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
    index edcb68ca3a7..1cc02f0939a 100644
    --- a/htdocs/core/class/html.form.class.php
    +++ b/htdocs/core/class/html.form.class.php
    @@ -58,6 +58,11 @@ class Form
     	 */
     	public $error='';
     
    +    /**
    +     * @var string[]    Array of error strings
    +     */
    +    public $errors = array();
    +
     	public $num;
     
     	// Cache arrays
    
    From 2d542d028f88e157ab909c26b59506e80920edc5 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Tue, 16 Oct 2018 22:22:57 +0200
    Subject: [PATCH 292/433] Update html.formmail.class.php
    
    ---
     htdocs/core/class/html.formmail.class.php | 13 ++++++++-----
     1 file changed, 8 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
    index c80358315c6..f9e5c111878 100644
    --- a/htdocs/core/class/html.formmail.class.php
    +++ b/htdocs/core/class/html.formmail.class.php
    @@ -44,6 +44,14 @@ class FormMail extends Form
     
     	public $fromname;
     	public $frommail;
    +    /**
    +     * @var string user, company, robot
    +     */
    +    public $fromtype;
    +    /**
    +     * @var int ID
    +     */
    +    public $fromid;
     	public $replytoname;
     	public $replytomail;
     	public $toname;
    @@ -91,11 +99,6 @@ class FormMail extends Form
     	public $withtouser=array();
     	public $withtoccuser=array();
     
    -	/**
    -	 * @var string Error code (or message)
    -	 */
    -	public $error='';
    -
     	public $lines_model;
     
     
    
    From a5ebcff2eea5de9dd12ffe989967845c9cad3f8e Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Tue, 16 Oct 2018 22:27:34 +0200
    Subject: [PATCH 293/433] Fix lettering function
    
    ---
     htdocs/accountancy/bookkeeping/list.php       | 30 +++++++-
     ....php => thirdparty_lettering_customer.php} | 73 ++++---------------
     ....php => thirdparty_lettering_supplier.php} | 52 ++-----------
     htdocs/accountancy/class/lettering.class.php  | 16 ++--
     htdocs/core/lib/company.lib.php               | 18 ++---
     htdocs/langs/en_US/accountancy.lang           |  1 +
     htdocs/langs/en_US/main.lang                  |  2 +
     7 files changed, 67 insertions(+), 125 deletions(-)
     rename htdocs/accountancy/bookkeeping/{thirdparty_lettrage.php => thirdparty_lettering_customer.php} (76%)
     rename htdocs/accountancy/bookkeeping/{thirdparty_lettrage_supplier.php => thirdparty_lettering_supplier.php} (82%)
    
    diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php
    index 132aa4e0afa..dad4089b6d2 100644
    --- a/htdocs/accountancy/bookkeeping/list.php
    +++ b/htdocs/accountancy/bookkeeping/list.php
    @@ -1,8 +1,8 @@
     <?php
    -/* Copyright (C) 2013-2016  Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013-2016  Florian Henry        <florian.henry@open-concept.pro>
    - * Copyright (C) 2013-2017  Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2016-2017  Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2013-2016  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2016  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2016-2017  Laurent Destailleur     <eldy@users.sourceforge.net>
      * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -79,6 +79,7 @@ $search_direction = GETPOST('search_direction', 'alpha');
     $search_debit = GETPOST('search_debit', 'alpha');
     $search_credit = GETPOST('search_credit', 'alpha');
     $search_ledger_code = GETPOST('search_ledger_code', 'alpha');
    +$search_lettering_code = GETPOST('search_lettering_code', 'alpha');
     
     // Load variable for pagination
     $limit = GETPOST('limit','int')?GETPOST('limit', 'int'):(empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION)?$conf->liste_limit:$conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
    @@ -138,6 +139,7 @@ $arrayfields=array(
     	't.label_operation'=>array('label'=>$langs->trans("Label"), 'checked'=>1),
     	't.debit'=>array('label'=>$langs->trans("Debit"), 'checked'=>1),
     	't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1),
    +	't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1),
     	't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1),
     	't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0),
     	't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0),
    @@ -176,6 +178,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
     	$search_date_modification_end = '';
     	$search_debit = '';
     	$search_credit = '';
    +	$search_lettering_code = '';
     }
     
     // Must be after the remove filter action, before the export.
    @@ -272,6 +275,10 @@ if (! empty($search_credit)) {
     	$filter['t.credit'] = $search_credit;
     	$param .= '&search_credit=' . urlencode($search_credit);
     }
    +if (! empty($search_lettering_code)) {
    +	$filter['t.lettering_code'] = $search_lettering_code;
    +	$param .= '&search_lettering_code=' . urlencode($search_lettering_code);
    + }
     
     
     if ($action == 'delbookkeeping') {
    @@ -546,6 +553,13 @@ if (! empty($arrayfields['t.credit']['checked']))
     	print '<input type="text" class="flat" name="search_credit" size="4" value="'.dol_escape_htmltag($search_credit).'">';
     	print '</td>';
     }
    +// Lettering code
    +if (! empty($arrayfields['t.lettering_code']['checked']))
    +{
    +	print '<td class="liste_titre center">';
    +	print '<input type="text" size="3" class="flat" name="search_lettering_code" value="' . $search_lettering_code . '"/>';
    +	print '</td>';
    +}
     // Code journal
     if (! empty($arrayfields['t.code_journal']['checked']))
     {
    @@ -595,6 +609,7 @@ if (! empty($arrayfields['t.subledger_account']['checked']))	print_liste_field_t
     if (! empty($arrayfields['t.label_operation']['checked']))		print_liste_field_titre($arrayfields['t.label_operation']['label'], $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder);
     if (! empty($arrayfields['t.debit']['checked']))				print_liste_field_titre($arrayfields['t.debit']['label'], $_SERVER['PHP_SELF'], "t.debit", "", $param, 'align="right"', $sortfield, $sortorder);
     if (! empty($arrayfields['t.credit']['checked']))				print_liste_field_titre($arrayfields['t.credit']['label'], $_SERVER['PHP_SELF'], "t.credit", "", $param, 'align="right"', $sortfield, $sortorder);
    +if (! empty($arrayfields['t.lettering_code']['checked']))		print_liste_field_titre($arrayfields['t.lettering_code']['label'], $_SERVER['PHP_SELF'], "t.lettering_code", "", $param, 'align="center"', $sortfield, $sortorder);
     if (! empty($arrayfields['t.code_journal']['checked']))			print_liste_field_titre($arrayfields['t.code_journal']['label'], $_SERVER['PHP_SELF'], "t.code_journal", "", $param, 'align="center"', $sortfield, $sortorder);
     if (! empty($arrayfields['t.date_creation']['checked']))		print_liste_field_titre($arrayfields['t.date_creation']['label'], $_SERVER['PHP_SELF'], "t.date_creation", "", $param, 'align="center"', $sortfield, $sortorder);
     if (! empty($arrayfields['t.tms']['checked']))					print_liste_field_titre($arrayfields['t.tms']['label'], $_SERVER['PHP_SELF'], "t.tms", "", $param, 'align="center"', $sortfield, $sortorder);
    @@ -680,6 +695,13 @@ if ($num > 0)
     			$totalarray['totalcredit'] += $line->credit;
     		}
     
    +		// Lettering code
    +		if (! empty($arrayfields['t.lettering_code']['checked']))
    +		{
    +			print '<td align="center">' . $line->lettering_code . '</td>';
    +			if (! $i) $totalarray['nbfield']++;
    +		}
    +
     		// Journal code
     		if (! empty($arrayfields['t.code_journal']['checked']))
     		{
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettrage.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    similarity index 76%
    rename from htdocs/accountancy/bookkeeping/thirdparty_lettrage.php
    rename to htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    index be335107839..fa41b404f03 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettrage.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    @@ -1,9 +1,9 @@
     <?php
    -/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2005      Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013      Florian Henry	    <florian.henry@open-concept.pro>
    - * Copyright (C) 2013      Alexandre Spangaro   <alexandre.spangaro@gmail.com>
    +/* Copyright (C) 2004-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2005       Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2013       Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -21,9 +21,9 @@
      */
     
     /**
    - * \file accountancy/bookkeeping/thirdparty_lettrage.php
    - * \ingroup Advanced accountancy
    - * \brief Onglet de gestion de parametrages des ventilations
    + * \file        accountancy/bookkeeping/thirdparty_lettering_customer.php
    + * \ingroup     Advanced accountancy
    + * \brief       Onglet de gestion de parametrages des ventilations
      */
     require '../../main.inc.php';
     
    @@ -107,7 +107,7 @@ if ($action == 'lettering') {
     
     if ($action == 'autolettrage') {
     
    -	$result = $BookKeeping->lettrageTiers($socid);
    +	$result = $BookKeeping->lettering_thirdparty($socid);
     
     	if ($result < 0) {
     		setEventMessages('', $BookKeeping->errors, 'errors');
    @@ -124,55 +124,15 @@ $head = societe_prepare_head($object);
     
     dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error');
     
    -dol_fiche_head($head, 'accounting', $langs->trans("ThirdParty"), 0, 'company');
    +dol_fiche_head($head, 'lettering_customer', $langs->trans("ThirdParty"), 0, 'company');
     
    -print '<table width="100%" class="border">';
    -print '<tr><td width="30%">' . $langs->trans("ThirdPartyName") . '</td><td width="70%" colspan="3">';
    -$object->next_prev_filter = "te.fournisseur = 1";
    -print $form->showrefnav($object, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom', '', '');
    -print '</td></tr>';
    +$linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
     
    -if (! empty($conf->global->SOCIETE_USEPREFIX)) // Old not used prefix field
    -{
    -	print '<tr><td>' . $langs->trans('Prefix') . '</td><td colspan="3">' . $object->prefix_comm . '</td></tr>';
    -}
    +dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom');
     
    -print '<tr>';
    -print '<td class="nowrap">' . $langs->trans("CustomerCode") . '</td><td colspan="3">';
    -print $object->code_client;
    -if ($object->check_codeclient() != 0)
    -	print ' <font class="error">(' . $langs->trans("WrongCustomerCode") . ')</font>';
    -print '</td>';
    -print '</tr>';
    +dol_fiche_end();
     
    -print '<tr>';
    -print '<td>';
    -print $form->editfieldkey("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta, $object, $user->rights->societe->creer);
    -print '</td><td colspan="3">';
    -print $form->editfieldval("CustomerAccountancyCode", 'customeraccountancycode', $object->code_compta, $object, $user->rights->societe->creer);
    -print '</td>';
    -print '</tr>';
    -
    -// Address
    -print '<tr><td valign="top">' . $langs->trans("Address") . '</td><td colspan="3">';
    -dol_print_address($object->address, 'gmap', 'thirdparty', $object->id);
    -print '</td></tr>';
    -
    -// Zip / Town
    -print '<tr><td class="nowrap">' . $langs->trans("Zip") . ' / ' . $langs->trans("Town") . '</td><td colspan="3">' . $object->zip . (($object->zip && $object->town) ? ' / ' : '') . $object->town . '</td>';
    -print '</tr>';
    -
    -// Country
    -print '<tr><td>' . $langs->trans("Country") . '</td><td colspan="3">';
    -// $img=picto_from_langcode($object->country_code);
    -$img = '';
    -if ($object->isInEEC())
    -	print $form->textwithpicto(($img ? $img . ' ' : '') . $object->country, $langs->trans("CountryIsInEEC"), 1, 0);
    -else
    -	print ($img ? $img . ' ' : '') . $object->country;
    -print '</td></tr>';
    -
    -print '</table>';
    +print '<br>';
     
     $sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, ";
     $sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, ";
    @@ -209,7 +169,7 @@ while ( $obj = $db->fetch_object($resql) ) {
     
     $sql .= $db->plimit($limit + 1, $offset);
     
    -dol_syslog("/accountancy/bookkeeping/thirdparty_lettrage.php", LOG_DEBUG);
    +dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG);
     $resql = $db->query($sql);
     if (! $resql) {
     	dol_print_error($db);
    @@ -218,7 +178,7 @@ if (! $resql) {
     
     $num = $db->num_rows($resql);
     
    -dol_syslog("/accountancy/bookkeeping/thirdparty_lettrage.php", LOG_DEBUG);
    +dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG);
     if ($resql) {
     	$i = 0;
     
    @@ -317,4 +277,3 @@ if ($resql) {
     // End of page
     llxFooter();
     $db->close();
    -
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    similarity index 82%
    rename from htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    rename to htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    index 905361b4c8e..b70d0a07242 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    @@ -111,7 +111,7 @@ if ($action == 'lettering') {
     
     if ($action == 'autolettrage') {
     
    -	$result = $BookKeeping->lettrageTiers($socid);
    +	$result = $BookKeeping->lettering_thirdparty($socid);
     
     	if ($result < 0) {
     		setEventMessages('', $BookKeeping->errors, 'errors');
    @@ -140,55 +140,13 @@ $head = societe_prepare_head($object);
     
     dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error');
     
    -dol_fiche_head($head, 'accounting_supplier', $langs->trans("ThirdParty"), 0, 'company');
    +dol_fiche_head($head, 'lettering_supplier', $langs->trans("ThirdParty"), 0, 'company');
     
    -print '<table width="100%" class="border">';
    -print '<tr><td width="30%">' . $langs->trans("ThirdPartyName") . '</td><td width="70%" colspan="3">';
    -$object->next_prev_filter = "te.fournisseur = 1";
    -print $form->showrefnav($object, 'socid', '', ($user->societe_id ? 0 : 1), 'rowid', 'nom', '', '');
    -print '</td></tr>';
    +$linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
     
    -if (! empty($conf->global->SOCIETE_USEPREFIX)) // Old not used prefix field
    -{
    -	print '<tr><td>' . $langs->trans('Prefix') . '</td><td colspan="3">' . $object->prefix_comm . '</td></tr>';
    -}
    +dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom');
     
    -print '<tr>';
    -print '<td class="nowrap">' . $langs->trans("SupplierCode") . '</td><td colspan="3">';
    -print $object->code_fournisseur;
    -if ($object->check_codefournisseur() != 0)
    -	print ' <font class="error">(' . $langs->trans("WrongSupplierCode") . ')</font>';
    -print '</td>';
    -print '</tr>';
    -
    -print '<tr>';
    -print '<td>';
    -print $form->editfieldkey("SupplierAccountancyCode", 'supplieraccountancycode', $object->code_compta_fournisseur, $object, $user->rights->societe->creer);
    -print '</td><td colspan="3">';
    -print $form->editfieldval("SupplierAccountancyCode", 'supplieraccountancycode', $object->code_compta_fournisseur, $object, $user->rights->societe->creer);
    -print '</td>';
    -print '</tr>';
    -
    -// Address
    -print '<tr><td valign="top">' . $langs->trans("Address") . '</td><td colspan="3">';
    -dol_print_address($object->address, 'gmap', 'thirdparty', $object->id);
    -print '</td></tr>';
    -
    -// Zip / Town
    -print '<tr><td class="nowrap">' . $langs->trans("Zip") . ' / ' . $langs->trans("Town") . '</td><td colspan="3">' . $object->zip . (($object->zip && $object->town) ? ' / ' : '') . $object->town . '</td>';
    -print '</tr>';
    -
    -// Country
    -print '<tr><td>' . $langs->trans("Country") . '</td><td colspan="3">';
    -// $img=picto_from_langcode($object->country_code);
    -$img = '';
    -if ($object->isInEEC())
    -	print $form->textwithpicto(($img ? $img . ' ' : '') . $object->country, $langs->trans("CountryIsInEEC"), 1, 0);
    -else
    -	print ($img ? $img . ' ' : '') . $object->country;
    -print '</td></tr>';
    -
    -print '</table>';
    +dol_fiche_end();
     
     $sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, ";
     $sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, ";
    diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php
    index 0ddbaeb5026..220ed24d5d6 100644
    --- a/htdocs/accountancy/class/lettering.class.php
    +++ b/htdocs/accountancy/class/lettering.class.php
    @@ -1,7 +1,7 @@
     <?php
    -/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013      Alexandre Spangaro   <alexandre.spangaro@gmail.com>
    +/* Copyright (C) 2004-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2013       Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -18,9 +18,9 @@
      */
     
     /**
    - * \file accountancy/class/bookkeeping.class.php
    - * \ingroup Advanced accountancy
    - * \brief 	File of class for lettering
    + * \file        accountancy/class/bookkeeping.class.php
    + * \ingroup     Advanced accountancy
    + * \brief       File of class for lettering
      */
     include_once DOL_DOCUMENT_ROOT . "/accountancy/class/bookkeeping.class.php";
     include_once DOL_DOCUMENT_ROOT . "/societe/class/societe.class.php";
    @@ -32,12 +32,12 @@ include_once DOL_DOCUMENT_ROOT . "/core/lib/date.lib.php";
     class lettering extends BookKeeping
     {
     	/**
    -	 * lettrageTiers
    +	 * lettering_thirdparty
     	 *
     	 * @param int $socid Thirdparty id
     	 * @return int 1 OK, <0 error
     	 */
    -	public function lettrageTiers($socid)
    +	public function lettering_thirdparty($socid)
     	{
     		global $conf;
     
    diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php
    index 0e2401434d7..46e3922a0d0 100644
    --- a/htdocs/core/lib/company.lib.php
    +++ b/htdocs/core/lib/company.lib.php
    @@ -6,11 +6,11 @@
      * Copyright (C) 2013-2014  Florian Henry           <florian.henry@open-concept.pro>
      * Copyright (C) 2013-2014  Juanjo Menent           <jmenent@2byte.es>
      * Copyright (C) 2013       Christophe Battarel     <contact@altairis.fr>
    - * Copyright (C) 2013       Alexandre Spangaro      <aspangaro.dolibarr@gmail.com>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
      * Copyright (C) 2015-2018  Frédéric France         <frederic.france@netlogic.fr>
      * Copyright (C) 2015       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) 2017       Rui Strecht			    <rui.strecht@aliartalentos.com>
    - * Copyright (C) 2018       Ferran Marcet		    <fmarcet@2byte.es>
    + * Copyright (C) 2017       Rui Strecht             <rui.strecht@aliartalentos.com>
    + * Copyright (C) 2018       Ferran Marcet           <fmarcet@2byte.es>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -154,18 +154,18 @@ function societe_prepare_head(Societe $object)
     		// Tab to accountancy
     		if (! empty($conf->accounting->enabled) && $object->client>0)
     		{
    -			$head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettrage.php?socid='.$object->id;
    -			$head[$h][1] = $langs->trans("TabAccountingCustomer");
    -			$head[$h][2] = 'accounting';
    +			$head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettering_customer.php?socid='.$object->id;
    +			$head[$h][1] = $langs->trans("TabLetteringCustomer");
    +			$head[$h][2] = 'lettering_customer';
     			$h++;
     		}
     
     		// Tab to accountancy
     		if (! empty($conf->accounting->enabled) && $object->fournisseur>0)
     		{
    -			$head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettrage_supplier.php?socid='.$object->id;
    -			$head[$h][1] = $langs->trans("TabAccountingSupplier");
    -			$head[$h][2] = 'accounting_supplier';
    +			$head[$h][0] = DOL_URL_ROOT.'/accountancy/bookkeeping/thirdparty_lettering_supplier.php?socid='.$object->id;
    +			$head[$h][1] = $langs->trans("TabLetteringSupplier");
    +			$head[$h][2] = 'lettering_supplier';
     			$h++;
     		}
     	}
    diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang
    index 0e59bf9a5a3..e6215269512 100644
    --- a/htdocs/langs/en_US/accountancy.lang
    +++ b/htdocs/langs/en_US/accountancy.lang
    @@ -160,6 +160,7 @@ Docref=Reference
     LabelAccount=Label account
     LabelOperation=Label operation
     Sens=Sens
    +LetteringCode=Lettering code
     Codejournal=Journal
     NumPiece=Piece number
     TransactionNumShort=Num. transaction
    diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
    index fb2f2a8e9fb..03d65917a97 100644
    --- a/htdocs/langs/en_US/main.lang
    +++ b/htdocs/langs/en_US/main.lang
    @@ -870,6 +870,8 @@ NewLeadOrProject=New lead or project
     Rights=Permissions
     LineNb=Line no.
     IncotermLabel=Incoterms
    +TabLetteringCustomer=Customer lettering
    +TabLetteringSupplier=Supplier lettering
     # Week day
     Monday=Monday
     Tuesday=Tuesday
    
    From cf1819ea0e05c7151953d6bdac87709f325f5be3 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Tue, 16 Oct 2018 22:27:34 +0200
    Subject: [PATCH 294/433] Update html.formmail.class.php
    
    ---
     htdocs/core/class/html.formmail.class.php | 16 +++++++++++++++-
     1 file changed, 15 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php
    index f9e5c111878..68da2dce777 100644
    --- a/htdocs/core/class/html.formmail.class.php
    +++ b/htdocs/core/class/html.formmail.class.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2010-2011 Juanjo Menent	    <jmenent@2byte.es>
      * Copyright (C) 2015-2017 Marcos García        <marcosgdf@gmail.com>
      * Copyright (C) 2015-2017 Nicolas ZABOURI      <info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -44,15 +45,28 @@ class FormMail extends Form
     
     	public $fromname;
     	public $frommail;
    +
         /**
          * @var string user, company, robot
          */
         public $fromtype;
    +
         /**
          * @var int ID
          */
         public $fromid;
    -	public $replytoname;
    +
    +    /**
    +     * @var string thirdparty etc
    +     */
    +    public $totype;
    +
    +    /**
    +     * @var int ID
    +     */
    +    public $toid;
    +
    +    public $replytoname;
     	public $replytomail;
     	public $toname;
     	public $tomail;
    
    From 2e77b9fed9ef745a24d133d346478bfcc86aacd2 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Tue, 16 Oct 2018 22:42:18 +0200
    Subject: [PATCH 295/433] fix phpunit
    
    ---
     htdocs/compta/paiement/class/paiement.class.php | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
    index cc60c2cba8e..50f7bc2c4e6 100644
    --- a/htdocs/compta/paiement/class/paiement.class.php
    +++ b/htdocs/compta/paiement/class/paiement.class.php
    @@ -76,8 +76,8 @@ class Paiement extends CommonObject
     	//paiement de llx_c_paiement
     	public $num_paiement;	// Numero du CHQ, VIR, etc...
     	public $num_payment;	// Numero du CHQ, VIR, etc...
    -  public $payment_id;	// Id of external modepayment
    -  public $payment_site;	// name of external modepayment
    +    public $payment_id;	// Id of external modepayment
    +    public $payment_site;	// name of external modepayment
     	public $bank_account;	// Id compte bancaire du paiement
     	public $bank_line;     // Id de la ligne d'ecriture bancaire
     	// fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...)
    @@ -233,11 +233,11 @@ class Paiement extends CommonObject
     			$mtotal = $totalamount;
     		}
     		$note = ($this->note_public?$this->note_public:$this->note);
    -    $payment_id = $this->payment_id ? $this->payment_id : null;
    -    $payment_site = $this->payment_site ? $this->payment_site : null;
    +        $payment_id = $this->payment_id ? $this->payment_id : null;
    +        $payment_site = $this->payment_site ? $this->payment_site : null;
     
     		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat)";
    -		$sql.= " VALUES (".$conf->entity.", '".$this->ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($note)."', '".$this->payment_id."', '".$this->payment_site."', ".$user->id.")";
    +		$sql.= " VALUES (".$conf->entity.", '".$this->ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($note)."', '".$this->db->escape($payment_id)."', '".$this->db->escape($payment_site)."', ".$user->id.")";
     
     		dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
     		$resql = $this->db->query($sql);
    
    From fa78ab7c66336ce6283d3274685d68a3ddb61978 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Tue, 16 Oct 2018 23:20:13 +0200
    Subject: [PATCH 296/433] do not trim int
    
    ---
     htdocs/contrat/class/contrat.class.php | 15 ++++++++-------
     1 file changed, 8 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php
    index 398da806c2d..7e0c2d13ca5 100644
    --- a/htdocs/contrat/class/contrat.class.php
    +++ b/htdocs/contrat/class/contrat.class.php
    @@ -10,6 +10,7 @@
      * Copyright (C) 2014-2015	Marcos García			<marcosgdf@gmail.com>
      * Copyright (C) 2015-2017	Ferran Marcet			<fmarcet@2byte.es>
      * Copyright (C) 2018   	Nicolas ZABOURI			<info@inovea-conseil.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -2887,9 +2888,9 @@ class ContratLigne extends CommonObjectLine
     		$error=0;
     
     		// Clean parameters
    -		$this->fk_contrat=trim($this->fk_contrat);
    -		$this->fk_product=trim($this->fk_product);
    -		$this->statut=(int) $this->statut;
    +		$this->fk_contrat = (int) $this->fk_contrat;
    +		$this->fk_product = (int) $this->fk_product;
    +		$this->statut = (int) $this->statut;
     		$this->label=trim($this->label);
     		$this->description=trim($this->description);
     		$this->vat_src_code=trim($this->vat_src_code);
    @@ -2899,7 +2900,7 @@ class ContratLigne extends CommonObjectLine
     		$this->qty=trim($this->qty);
     		$this->remise_percent=trim($this->remise_percent);
     		$this->remise=trim($this->remise);
    -		$this->fk_remise_except=trim($this->fk_remise_except);
    +		$this->fk_remise_except = (int) $this->fk_remise_except;
     		$this->subprice=price2num($this->subprice);
     		$this->price_ht=price2num($this->price_ht);
     		$this->total_ht=trim($this->total_ht);
    @@ -2908,9 +2909,9 @@ class ContratLigne extends CommonObjectLine
     		$this->total_localtax2=trim($this->total_localtax2);
     		$this->total_ttc=trim($this->total_ttc);
     		$this->info_bits=trim($this->info_bits);
    -		$this->fk_user_author=trim($this->fk_user_author);
    -		$this->fk_user_ouverture=trim($this->fk_user_ouverture);
    -		$this->fk_user_cloture=trim($this->fk_user_cloture);
    +		$this->fk_user_author = (int) $this->fk_user_author;
    +		$this->fk_user_ouverture = (int) $this->fk_user_ouverture;
    +		$this->fk_user_cloture = (int) $this->fk_user_cloture;
     		$this->commentaire=trim($this->commentaire);
     		//if (empty($this->subprice)) $this->subprice = 0;
     		if (empty($this->price_ht)) $this->price_ht = 0;
    
    From 27b7cf8beaa34985efc3c193504a9d9c0a16a3d0 Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Tue, 16 Oct 2018 23:31:19 +0200
    Subject: [PATCH 297/433] Fix uniformization dates of order in API
    
    ---
     htdocs/commande/class/commande.class.php | 10 ++++++++--
     1 file changed, 8 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
    index c588830d83d..7f2a8c98dbe 100644
    --- a/htdocs/commande/class/commande.class.php
    +++ b/htdocs/commande/class/commande.class.php
    @@ -155,7 +155,10 @@ class Commande extends CommonOrder
     	public $demand_reason_id;   // Source reason. Why we receive order (after a phone campaign, ...)
     	public $demand_reason_code;
     	public $date;				// Date commande
    -
    +  public $date_creation;				// Date commande
    +  public $date_validation;				// Date commande
    +  public $date_modification;				// Date commande
    +  
     	/**
     	 * @deprecated
     	 * @see date
    @@ -1620,7 +1623,7 @@ class Commande extends CommonOrder
     		$sql = 'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_statut';
     		$sql.= ', c.amount_ht, c.total_ht, c.total_ttc, c.tva as total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason';
     		$sql.= ', c.fk_account';
    -		$sql.= ', c.date_commande';
    +		$sql.= ', c.date_commande, c.date_valid, c.tms';
     		$sql.= ', c.date_livraison';
     		$sql.= ', c.fk_shipping_method';
     		$sql.= ', c.fk_warehouse';
    @@ -1673,6 +1676,9 @@ class Commande extends CommonOrder
     				$this->total_ttc			= $obj->total_ttc;
     				$this->date					= $this->db->jdate($obj->date_commande);
     				$this->date_commande		= $this->db->jdate($obj->date_commande);
    +        $this->date_creation		= $this->db->jdate($obj->date_creation);
    +        $this->date_validation		= $this->db->jdate($obj->date_valid);
    +        $this->date_modification		= $this->db->jdate($obj->tms);
     				$this->remise				= $obj->remise;
     				$this->remise_percent		= $obj->remise_percent;
     				$this->remise_absolue		= $obj->remise_absolue;
    
    From 70b6c502dab209a0db427df3e0132e7d1f975a3f Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Tue, 16 Oct 2018 23:36:00 +0200
    Subject: [PATCH 298/433] Update menubase.class.php
    
    ---
     htdocs/core/class/menubase.class.php | 20 ++++++++++++--------
     1 file changed, 12 insertions(+), 8 deletions(-)
    
    diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php
    index 0daf4fe56da..17ada096fd1 100644
    --- a/htdocs/core/class/menubase.class.php
    +++ b/htdocs/core/class/menubase.class.php
    @@ -1,6 +1,7 @@
     <?php
     /* Copyright (C) 2007-2009	Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2009-2012	Regis Houssin		<regis.houssin@capnetworks.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -59,15 +60,18 @@ class Menubase
         public $fk_menu;
     
         /**
    -     * @var int ID
    +     * @var string fk_mainmenu
          */
         public $fk_mainmenu;
     
         /**
    -     * @var int ID
    +     * @var string fk_leftmenu
          */
         public $fk_leftmenu;
     
    +    /**
    +     * @var int position
    +     */
         public $position;
         public $url;
         public $target;
    @@ -111,10 +115,10 @@ class Menubase
             $this->type=trim($this->type);
             $this->mainmenu=trim($this->mainmenu);
             $this->leftmenu=trim($this->leftmenu);
    -        $this->fk_menu=trim($this->fk_menu);          // If -1, fk_mainmenu and fk_leftmenu must be defined
    +        $this->fk_menu = (int) $this->fk_menu;          // If -1, fk_mainmenu and fk_leftmenu must be defined
             $this->fk_mainmenu=trim($this->fk_mainmenu);
             $this->fk_leftmenu=trim($this->fk_leftmenu);
    -        $this->position=trim($this->position);
    +        $this->position = (int) $this->position;
             $this->url=trim($this->url);
             $this->target=trim($this->target);
             $this->titre=trim($this->titre);
    @@ -155,7 +159,7 @@ class Menubase
             $sql = "SELECT count(*)";
             $sql.= " FROM ".MAIN_DB_PREFIX."menu";
             $sql.= " WHERE menu_handler = '".$this->db->escape($this->menu_handler)."'";
    -        $sql.= " AND fk_menu = ".((int) $this->db->escape($this->fk_menu));
    +        $sql.= " AND fk_menu = ".((int) $this->fk_menu);
             $sql.= " AND position = ".((int) $this->position);
             $sql.= " AND url = '".$this->db->escape($this->url)."'";
             $sql.= " AND entity = ".$conf->entity;
    @@ -252,10 +256,10 @@ class Menubase
             $this->type=trim($this->type);
             $this->mainmenu=trim($this->mainmenu);
             $this->leftmenu=trim($this->leftmenu);
    -        $this->fk_menu=trim($this->fk_menu);
    +        $this->fk_menu = (int) $this->fk_menu;
             $this->fk_mainmenu=trim($this->fk_mainmenu);
             $this->fk_leftmenu=trim($this->fk_leftmenu);
    -        $this->position=trim($this->position);
    +        $this->position = (int) $this->position;
             $this->url=trim($this->url);
             $this->target=trim($this->target);
             $this->titre=trim($this->titre);
    @@ -274,7 +278,7 @@ class Menubase
             $sql.= " type='".$this->db->escape($this->type)."',";
             $sql.= " mainmenu='".$this->db->escape($this->mainmenu)."',";
             $sql.= " leftmenu='".$this->db->escape($this->leftmenu)."',";
    -        $sql.= " fk_menu='".$this->db->escape($this->fk_menu)."',";
    +        $sql.= " fk_menu=".$this->fk_menu.",";
             $sql.= " fk_mainmenu=".($this->fk_mainmenu?"'".$this->db->escape($this->fk_mainmenu)."'":"null").",";
             $sql.= " fk_leftmenu=".($this->fk_leftmenu?"'".$this->db->escape($this->fk_leftmenu)."'":"null").",";
             $sql.= " position=".($this->position > 0 ? $this->position : 0).",";
    
    From 3fdf3c95b449c8ef89454709089fc07dd387affb Mon Sep 17 00:00:00 2001
    From: ptibogxiv <ptibogxiv@msn.com>
    Date: Wed, 17 Oct 2018 00:04:44 +0200
    Subject: [PATCH 299/433] FIX harmony in date name with API
    
    ---
     htdocs/compta/facture/class/facture.class.php | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
    index e225d1468c4..d614447b189 100644
    --- a/htdocs/compta/facture/class/facture.class.php
    +++ b/htdocs/compta/facture/class/facture.class.php
    @@ -112,6 +112,7 @@ class Facture extends CommonInvoice
     	public $date;              // Date invoice
     	public $date_creation;		// Creation date
     	public $date_validation;	// Validation date
    +  public $date_modification;	// Validation date
     	public $datem;
     	public $ref_client;
     	public $ref_int;
    @@ -1361,6 +1362,7 @@ class Facture extends CommonInvoice
     				$this->date_pointoftax		= $this->db->jdate($obj->date_pointoftax);
     				$this->date_creation		= $this->db->jdate($obj->datec);
     				$this->date_validation		= $this->db->jdate($obj->datev);
    +        $this->date_modification		= $this->db->jdate($obj->datem);
     				$this->datem				= $this->db->jdate($obj->datem);
     				$this->remise_percent		= $obj->remise_percent;
     				$this->remise_absolue		= $obj->remise_absolue;
    
    From 7c35eae2026ac0eb96e1ed6f11acf71cf2981936 Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Wed, 17 Oct 2018 00:06:24 +0200
    Subject: [PATCH 300/433] Update commande.class.php
    
    ---
     htdocs/commande/class/commande.class.php | 12 ++++++------
     1 file changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
    index 7f2a8c98dbe..4f5051f3411 100644
    --- a/htdocs/commande/class/commande.class.php
    +++ b/htdocs/commande/class/commande.class.php
    @@ -155,9 +155,9 @@ class Commande extends CommonOrder
     	public $demand_reason_id;   // Source reason. Why we receive order (after a phone campaign, ...)
     	public $demand_reason_code;
     	public $date;				// Date commande
    -  public $date_creation;				// Date commande
    -  public $date_validation;				// Date commande
    -  public $date_modification;				// Date commande
    +	public $date_creation;				// Date commande
    +	public $date_validation;				// Date commande
    +	public $date_modification;				// Date commande
       
     	/**
     	 * @deprecated
    @@ -1676,9 +1676,9 @@ class Commande extends CommonOrder
     				$this->total_ttc			= $obj->total_ttc;
     				$this->date					= $this->db->jdate($obj->date_commande);
     				$this->date_commande		= $this->db->jdate($obj->date_commande);
    -        $this->date_creation		= $this->db->jdate($obj->date_creation);
    -        $this->date_validation		= $this->db->jdate($obj->date_valid);
    -        $this->date_modification		= $this->db->jdate($obj->tms);
    +				$this->date_creation		= $this->db->jdate($obj->date_creation);
    +				$this->date_validation		= $this->db->jdate($obj->date_valid);
    +				$this->date_modification		= $this->db->jdate($obj->tms);
     				$this->remise				= $obj->remise;
     				$this->remise_percent		= $obj->remise_percent;
     				$this->remise_absolue		= $obj->remise_absolue;
    
    From a77458cb36703ef4c7bb21993981a324c4dba6d7 Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Wed, 17 Oct 2018 00:07:21 +0200
    Subject: [PATCH 301/433] Update facture.class.php
    
    ---
     htdocs/compta/facture/class/facture.class.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
    index d614447b189..3f36cb72830 100644
    --- a/htdocs/compta/facture/class/facture.class.php
    +++ b/htdocs/compta/facture/class/facture.class.php
    @@ -112,7 +112,7 @@ class Facture extends CommonInvoice
     	public $date;              // Date invoice
     	public $date_creation;		// Creation date
     	public $date_validation;	// Validation date
    -  public $date_modification;	// Validation date
    +	public $date_modification;	// Validation date
     	public $datem;
     	public $ref_client;
     	public $ref_int;
    @@ -1362,7 +1362,7 @@ class Facture extends CommonInvoice
     				$this->date_pointoftax		= $this->db->jdate($obj->date_pointoftax);
     				$this->date_creation		= $this->db->jdate($obj->datec);
     				$this->date_validation		= $this->db->jdate($obj->datev);
    -        $this->date_modification		= $this->db->jdate($obj->datem);
    +				$this->date_modification		= $this->db->jdate($obj->datem);
     				$this->datem				= $this->db->jdate($obj->datem);
     				$this->remise_percent		= $obj->remise_percent;
     				$this->remise_absolue		= $obj->remise_absolue;
    
    From 3ef32a24a43d4790cbefa7ee0c056888c2e6df1f Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 17 Oct 2018 00:34:39 +0200
    Subject: [PATCH 302/433] Look and feel
    
    ---
     htdocs/user/agenda_extsites.php | 10 ++++++++--
     htdocs/user/perms.php           |  4 +++-
     2 files changed, 11 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/user/agenda_extsites.php b/htdocs/user/agenda_extsites.php
    index 7280fcc5c2a..2eb2ede000b 100644
    --- a/htdocs/user/agenda_extsites.php
    +++ b/htdocs/user/agenda_extsites.php
    @@ -162,12 +162,17 @@ if ($user->rights->user->user->lire || $user->admin) {
     
     dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
     
    -print $langs->trans("AgendaExtSitesDesc")."<br>\n";
    +
    +print '<div class="underbanner clearboth"></div>';
    +
    +print '<br>';
    +print '<span class="opacitymedium">'.$langs->trans("AgendaExtSitesDesc")."</span><br>\n";
     print "<br>\n";
     
     $selectedvalue=$conf->global->AGENDA_DISABLE_EXT;
     if ($selectedvalue==1) $selectedvalue=0; else $selectedvalue=1;
     
    +
     print '<div class="div-table-responsive">';
     print "<table class=\"noborder\" width=\"100%\">";
     
    @@ -210,12 +215,13 @@ while ($i <= $MAXAGENDA)
     print '</table>';
     print '</div>';
     
    -dol_fiche_end();
     
     print '<div class="center">';
     print "<input type=\"submit\" id=\"save\" name=\"save\" class=\"button hideifnotset\" value=\"".$langs->trans("Save")."\">";
     print "</div>";
     
    +dol_fiche_end();
    +
     print "</form>\n";
     
     // End of page
    diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php
    index c51ad67760c..8b7599f3707 100644
    --- a/htdocs/user/perms.php
    +++ b/htdocs/user/perms.php
    @@ -245,7 +245,7 @@ if ($user->rights->user->user->lire || $user->admin) {
     dol_banner_tab($object,'id',$linkback,$user->rights->user->user->lire || $user->admin);
     
     
    -//print '<div class="underbanner clearboth"></div>';
    +print '<div class="underbanner clearboth"></div>';
     
     if ($user->admin) print info_admin($langs->trans("WarningOnlyPermissionOfActivatedModules"));
     // Show warning about external users
    @@ -257,6 +257,7 @@ if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'e
     
     
     print "\n";
    +print '<div class="div-table-responsive">';
     print '<table width="100%" class="noborder">';
     print '<tr class="liste_titre">';
     print '<td>'.$langs->trans("Module").'</td>';
    @@ -392,6 +393,7 @@ if ($result)
     }
     else dol_print_error($db);
     print '</table>';
    +print '</div>';
     
     $parameters=array();
     $reshook=$hookmanager->executeHooks('insertExtraFooter',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
    
    From f2d0004a3e542afb3f520dccc9b0bf7eb9515821 Mon Sep 17 00:00:00 2001
    From: ptibogxiv <support@ptibogxiv.net>
    Date: Wed, 17 Oct 2018 00:36:40 +0200
    Subject: [PATCH 303/433] ADD civility list in API
    
    ---
     htdocs/api/class/api_setup.class.php | 60 ++++++++++++++++++++++++++++
     1 file changed, 60 insertions(+)
    
    diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php
    index 3ec618dc92a..304abf46432 100644
    --- a/htdocs/api/class/api_setup.class.php
    +++ b/htdocs/api/class/api_setup.class.php
    @@ -380,6 +380,66 @@ class Setup extends DolibarrApi
             return $list;
         }
     
    +    /**
    +     * Get the list of civility.
    +     *
    +     * @param string    $sortfield  Sort field
    +     * @param string    $sortorder  Sort order
    +     * @param int       $limit      Number of items per page
    +     * @param int       $page       Page number (starting from zero)
    +     * @param string    $module     To filter on module events
    +     * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    +     * @return List of events types
    +     *
    +     * @url     GET dictionary/civility
    +     *
    +     * @throws RestException
    +     */
    +    function getListOfCivility($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $sqlfilters = '')
    +    {
    +        $list = array();
    +
    +        $sql = "SELECT rowid, code, label, module";
    +        $sql.= " FROM ".MAIN_DB_PREFIX."c_civility as t";
    +        $sql.= " WHERE t.active = 1";
    +        if ($module)    $sql.=" AND t.module LIKE '%" . $this->db->escape($module) . "%'";
    +        // Add sql filters
    +        if ($sqlfilters)
    +        {
    +            if (! DolibarrApi::_checkFilters($sqlfilters))
    +            {
    +                throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
    +            }
    +	        $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
    +            $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
    +        }
    +
    +
    +        $sql.= $this->db->order($sortfield, $sortorder);
    +
    +        if ($limit) {
    +            if ($page < 0) {
    +                $page = 0;
    +            }
    +            $offset = $limit * $page;
    +
    +            $sql .= $this->db->plimit($limit, $offset);
    +        }
    +
    +        $result = $this->db->query($sql);
    +
    +        if ($result) {
    +            $num = $this->db->num_rows($result);
    +            $min = min($num, ($limit <= 0 ? $num : $limit));
    +            for ($i = 0; $i < $min; $i++) {
    +                $list[] = $this->db->fetch_object($result);
    +            }
    +        } else {
    +            throw new RestException(503, 'Error when retrieving list of civility : '.$this->db->lasterror());
    +        }
    +
    +        return $list;
    +    }
     
         /**
          * Get the list of extra fields.
    
    From a466104b810db2caae6055dc034701bbbafcb66f Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Wed, 17 Oct 2018 07:20:04 +0200
    Subject: [PATCH 304/433] Fix FEC on transaction card
    
    Fix for FEC compliance
    - Remove useless column label_compte
    - label_compte is generated with label of accounting account number
    - Insert also the label of the journal
    ---
     htdocs/accountancy/bookkeeping/card.php | 61 ++++++++++++++-----------
     1 file changed, 35 insertions(+), 26 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php
    index a8ff1e13338..09a3b7ef8f5 100644
    --- a/htdocs/accountancy/bookkeeping/card.php
    +++ b/htdocs/accountancy/bookkeeping/card.php
    @@ -1,8 +1,8 @@
     <?php
    -/* Copyright (C) 2013-2017 Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013-2017 Florian Henry        <florian.henry@open-concept.pro>
    - * Copyright (C) 2013-2018 Alexandre Spangaro   <aspangaro@zendsi.com>
    - * Copyright (C) 2017      Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2013-2017  Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013-2017  Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2017       Laurent Destailleur     <eldy@users.sourceforge.net>
      * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
     require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
     require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.facture.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php';
    +require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php';
     
     // Load translation files required by the page
     $langs->loadLangs(array("accountancy", "bills", "compta"));
    @@ -49,12 +50,21 @@ if ($user->societe_id > 0) {
     
     $mesg = '';
     
    -$account_number = GETPOST('account_number','alphanohtml');
    +$accountingaccount = new AccountingAccount($db);
    +$accountingjournal = new AccountingJournal($db);
    +
    +$accountingaccount_number = GETPOST('accountingaccount_number','alphanohtml');
    +$accountingaccount->fetch(null, $accountingaccount_number, true);
    +$accountingaccount_label = $accountingaccount->label;
    +
    +$journal_code = GETPOST('code_journal','alpha');
    +$accountingjournal->fetch(null, $journal_code);
    +$journal_label = $accountingjournal->label;
    +
     $subledger_account = GETPOST('subledger_account','alphanohtml');
     if ($subledger_account == - 1) {
     	$subledger_account = null;
     }
    -$label_compte = GETPOST('label_compte','alphanohtml');
     $label_operation= GETPOST('label_operation','alphanohtml');
     $debit = price2num(GETPOST('debit','alpha'));
     $credit = price2num(GETPOST('credit','alpha'));
    @@ -80,7 +90,7 @@ if ($action == "confirm_update") {
     		setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors');
     		$action='update';
     	}
    -	if (empty($account_number) || $account_number == '-1')
    +	if (empty($accountingaccount_number) || $accountingaccount_number == '-1')
     	{
     		$error++;
     		setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors');
    @@ -96,9 +106,9 @@ if ($action == "confirm_update") {
     			$error++;
     			setEventMessages($object->error, $object->errors, 'errors');
     		} else {
    -			$object->numero_compte = $account_number;
    +			$object->numero_compte = $accountingaccount_number;
     			$object->subledger_account = $subledger_account;
    -			$object->label_compte = $label_compte;
    +			$object->label_compte = $accountingaccount_label;
     			$object->label_operation= $label_operation;
     			$object->debit = $debit;
     			$object->credit = $credit;
    @@ -139,7 +149,7 @@ else if ($action == "add") {
     		setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors');
     		$action='';
     	}
    -	if (empty($account_number) || $account_number == '-1')
    +	if (empty($accountingaccount_number) || $accountingaccount_number == '-1')
     	{
     		$error++;
     		setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors');
    @@ -149,9 +159,9 @@ else if ($action == "add") {
     	if (! $error) {
     		$object = new BookKeeping($db);
     
    -		$object->numero_compte = $account_number;
    +		$object->numero_compte = $accountingaccount_number;
     		$object->subledger_account = $subledger_account;
    -		$object->label_compte = $label_compte;
    +		$object->label_compte = $accountingaccount_label;
     		$object->label_operation= $label_operation;
     		$object->debit = $debit;
     		$object->credit = $credit;
    @@ -159,7 +169,8 @@ else if ($action == "add") {
     		$object->doc_type = GETPOST('doc_type','alpha');
     		$object->piece_num = $piece_num;
     		$object->doc_ref = GETPOST('doc_ref','alpha');
    -		$object->code_journal = GETPOST('code_journal','alpha');
    +		$object->code_journal = $journal_code;
    +		$object->journal_label = $journal_label;
     		$object->fk_doc = GETPOST('fk_doc','alpha');
     		$object->fk_docdet = GETPOST('fk_docdet','alpha');
     
    @@ -212,7 +223,7 @@ else if ($action == "confirm_create") {
     
     	$object = new BookKeeping($db);
     
    -	if (! GETPOST('code_journal','alpha') || GETPOST('code_journal','alpha') == '-1') {
    +	if (! $journal_code || $journal_code == '-1') {
     		setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Journal")), null, 'errors');
     		$action='create';
     		$error++;
    @@ -232,7 +243,8 @@ else if ($action == "confirm_create") {
     		$object->doc_type = GETPOST('doc_type','alpha');
     		$object->piece_num = GETPOST('next_num_mvt','alpha');
     		$object->doc_ref = GETPOST('doc_ref','alpha');
    -		$object->code_journal = GETPOST('code_journal','alpha');
    +		$object->code_journal = $journal_code;
    +		$object->journal_label = $journal_label;
     		$object->fk_doc = 0;
     		$object->fk_docdet = 0;
     		$object->montant = 0;
    @@ -267,8 +279,8 @@ if ($action == 'setdate') {
     }
     
     if ($action == 'setjournal') {
    -	$journaldoc = trim(GETPOST('code_journal','alpha'));
    -	$result = $object->updateByMvt($piece_num, 'code_journal', $journaldoc, $mode);
    +	$result = $object->updateByMvt($piece_num, 'code_journal', $journal_code, $mode);
    +	$result = $object->updateByMvt($piece_num, 'journal_label', $journal_label, $mode);
     	if ($result < 0) {
     		setEventMessages($object->error, $object->errors, 'errors');
     	} else {
    @@ -312,7 +324,6 @@ if ($action == 'valid') {
     
     $html = new Form($db);
     $formaccounting = new FormAccounting($db);
    -$accountjournal = new AccountingJournal($db);
     
     llxHeader('', $langs->trans("CreateMvts"));
     
    @@ -357,7 +368,7 @@ if ($action == 'create')
     
     	print '<tr>';
     	print '<td class="fieldrequired">' . $langs->trans("Codejournal") . '</td>';
    -	print '<td>' . $formaccounting->select_journal(GETPOST('code_journal', 'alpha'),'code_journal',0,1,array(),1,1) . '</td>';
    +	print '<td>' . $formaccounting->select_journal($journal_code,'code_journal',0,0,1,1) . '</td>';
     	print '</tr>';
     
     	print '<tr>';
    @@ -460,7 +471,7 @@ if ($action == 'create')
     			print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
     			print '</form>';
     		} else {
    -		print $object->code_journal ;
    +			print $object->code_journal ;
     		}
     		print '</td>';
     		print '</tr>';
    @@ -590,7 +601,6 @@ if ($action == 'create')
     
     				print_liste_field_titre("AccountAccountingShort");
     				print_liste_field_titre("SubledgerAccount");
    -				print_liste_field_titre("LabelAccount");
     				print_liste_field_titre("LabelOperation");
     				print_liste_field_titre("Debit", "", "", "", "", 'align="right"');
     				print_liste_field_titre("Credit", "", "", "", "", 'align="right"');
    @@ -605,7 +615,7 @@ if ($action == 'create')
     
     					if ($action == 'update' && $line->id == $id) {
     						print '<td>';
    -						print $formaccounting->select_account($line->numero_compte, 'account_number', 1, array (), 1, 1, '');
    +						print $formaccounting->select_account($line->numero_compte, 'accountingaccount_number', 1, array (), 1, 1, '');
     						print '</td>';
     						print '<td>';
     						// TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because it does not
    @@ -628,9 +638,9 @@ if ($action == 'create')
     						print '<input type="submit" class="button" name="update" value="' . $langs->trans("Update") . '">';
     						print '</td>';
     					} else {
    -						print '<td>' . length_accountg($line->numero_compte) . '</td>';
    +						$accountingaccount->fetch(null, $line->numero_compte, true);
    +						print '<td>' . $accountingaccount->getNomUrl(0,1,1,'',0) . '</td>';
     						print '<td>' . length_accounta($line->subledger_account) . '</td>';
    -						print '<td>' . $line->label_compte . '</td>';
     						print '<td>' . $line->label_operation. '</td>';
     						print '<td align="right">' . price($line->debit) . '</td>';
     						print '<td align="right">' . price($line->credit) . '</td>';
    @@ -663,7 +673,7 @@ if ($action == 'create')
     				if ($action == "" || $action == 'add') {
     					print '<tr class="oddeven">';
     					print '<td>';
    -					print $formaccounting->select_account($account_number, 'account_number', 1, array (), 1, 1, '');
    +					print $formaccounting->select_account($accountingaccount_number, 'accountingaccount_number', 1, array (), 1, 1, '');
     					print '</td>';
     					print '<td>';
     					// TODO For the moment we keep a fre input text instead of a combo. The select_auxaccount has problem because it does not
    @@ -677,7 +687,6 @@ if ($action == 'create')
     						print '<input type="text" name="subledger_account" value="">';
     					}
     					print '</td>';
    -					print '<td><input type="text" class="minwidth100" name="label_compte" value=""/></td>';
     					print '<td><input type="text" class="minwidth200" name="label_operation" value=""/></td>';
     					print '<td align="right"><input type="text" size="6" class="right" name="debit" value=""/></td>';
     					print '<td align="right"><input type="text" size="6" class="right" name="credit" value=""/></td>';
    
    From 7d8ff0429251f4860ca70c8aa5226e8266a4e0e2 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 17 Oct 2018 08:15:12 +0200
    Subject: [PATCH 305/433] Update paiement.class.php
    
    ---
     htdocs/compta/paiement/class/paiement.class.php | 8 +++-----
     1 file changed, 3 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
    index 50f7bc2c4e6..4fdc4a0ae63 100644
    --- a/htdocs/compta/paiement/class/paiement.class.php
    +++ b/htdocs/compta/paiement/class/paiement.class.php
    @@ -138,8 +138,8 @@ class Paiement extends CommonObject
     				$this->type_libelle   = $obj->type_libelle;
     				$this->type_code      = $obj->type_code;
     				$this->statut         = $obj->statut;
    -        $this->payment_id     = $obj->ext_payment_id;
    -        $this->payment_site   = $obj->ext_payment_site;
    +                $this->payment_id     = $obj->ext_payment_id;
    +                $this->payment_site   = $obj->ext_payment_site;
     
     				$this->bank_account   = $obj->fk_account; // deprecated
     				$this->fk_account     = $obj->fk_account;
    @@ -233,11 +233,9 @@ class Paiement extends CommonObject
     			$mtotal = $totalamount;
     		}
     		$note = ($this->note_public?$this->note_public:$this->note);
    -        $payment_id = $this->payment_id ? $this->payment_id : null;
    -        $payment_site = $this->payment_site ? $this->payment_site : null;
     
     		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat)";
    -		$sql.= " VALUES (".$conf->entity.", '".$this->ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($note)."', '".$this->db->escape($payment_id)."', '".$this->db->escape($payment_site)."', ".$user->id.")";
    +		$sql.= " VALUES (".$conf->entity.", '".$this->ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($note)."', ".($this->payment_id?"'".$this->db->escape($this->payment_id)."'":"null").", ".($this->payment_site?"'".$this->db->escape($this->payment_site)."'":"null").", ".$user->id.")";
     
     		dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
     		$resql = $this->db->query($sql);
    
    From b462e7b2170e7de3114a4e12548f1f89ae17c2ca Mon Sep 17 00:00:00 2001
    From: Ferran Marcet <fmarcet@2byte.es>
    Date: Wed, 17 Oct 2018 10:01:02 +0200
    Subject: [PATCH 306/433] FIX When delete a product, llx_product_association
     rows are not deleted
    
    ---
     htdocs/product/class/product.class.php | 15 ++++++++++++++-
     1 file changed, 14 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index f33029d368a..56227bc5266 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -12,7 +12,7 @@
      * Copyright (C) 2014		Henry Florian			<florian.henry@open-concept.pro>
      * Copyright (C) 2014-2016	Philippe Grand			<philippe.grand@atoo-net.com>
      * Copyright (C) 2014		Ion agorria			    <ion@agorria.com>
    - * Copyright (C) 2016-2017	Ferran Marcet			<fmarcet@2byte.es>
    + * Copyright (C) 2016-2018	Ferran Marcet			<fmarcet@2byte.es>
      * Copyright (C) 2017		Gustavo Novaro
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -1114,6 +1114,19 @@ class Product extends CommonObject
     				}
     			}
     
    +			// Delete from product_association
    +			if (!$error){
    +				$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_association";
    +				$sql.= " WHERE fk_product_pere = ".$this->rowid." OR fk_product_fils = ".$this->rowid;
    +				dol_syslog(get_class($this).'::delete', LOG_DEBUG);
    +				$result = $this->db->query($sql);
    +				if (! $result)
    +				{
    +					$error++;
    +					$this->errors[] = $this->db->lasterror();
    +				}
    +			}
    +
     			// Delete product
     			if (! $error)
     			{
    
    From bdae4e1c4dae0369ef3d0051cf5e8c53572bf7c3 Mon Sep 17 00:00:00 2001
    From: Ferran Marcet <fmarcet@2byte.es>
    Date: Wed, 17 Oct 2018 10:04:42 +0200
    Subject: [PATCH 307/433] FIX When delete a product, llx_product_association
     rows are not deleted
    
    ---
     htdocs/product/class/product.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 56227bc5266..9a52722a3c9 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -1117,7 +1117,7 @@ class Product extends CommonObject
     			// Delete from product_association
     			if (!$error){
     				$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_association";
    -				$sql.= " WHERE fk_product_pere = ".$this->rowid." OR fk_product_fils = ".$this->rowid;
    +				$sql.= " WHERE fk_product_pere = ".$this->id." OR fk_product_fils = ".$this->id;
     				dol_syslog(get_class($this).'::delete', LOG_DEBUG);
     				$result = $this->db->query($sql);
     				if (! $result)
    
    From ffde3534419f28f37f57028405074b7b3a7fb5c2 Mon Sep 17 00:00:00 2001
    From: Ferran Marcet <fmarcet@2byte.es>
    Date: Wed, 17 Oct 2018 10:06:06 +0200
    Subject: [PATCH 308/433] FIX When delete a product, llx_product_association
     rows are not deleted
    
    ---
     htdocs/product/class/product.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 9a52722a3c9..ce3658c9a72 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -1117,7 +1117,7 @@ class Product extends CommonObject
     			// Delete from product_association
     			if (!$error){
     				$sql = "DELETE FROM ".MAIN_DB_PREFIX."product_association";
    -				$sql.= " WHERE fk_product_pere = ".$this->id." OR fk_product_fils = ".$this->id;
    +				$sql.= " WHERE fk_product_pere = ".$id." OR fk_product_fils = ".$id;
     				dol_syslog(get_class($this).'::delete', LOG_DEBUG);
     				$result = $this->db->query($sql);
     				if (! $result)
    
    From a66256a799468bd5813838ffcb498934070b5020 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 17 Oct 2018 13:22:52 +0200
    Subject: [PATCH 309/433] FIX Hover on the filemanager
    
    ---
     htdocs/core/class/html.formfile.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
    index 4a59e28f044..d47b846ba02 100644
    --- a/htdocs/core/class/html.formfile.class.php
    +++ b/htdocs/core/class/html.formfile.class.php
    @@ -1162,7 +1162,7 @@ class FormFile
     					print '<!-- Line list_of_documents '.$key.' relativepath = '.$relativepath.' -->'."\n";
     					// Do we have entry into database ?
     					print '<!-- In database: position='.$filearray[$key]['position'].' -->'."\n";
    -					print '<tr id="row-'.($filearray[$key]['rowid']>0?$filearray[$key]['rowid']:'-AFTER'.$lastrowid.'POS'.($i+1)).'">';
    +					print '<tr class="oddeven" id="row-'.($filearray[$key]['rowid']>0?$filearray[$key]['rowid']:'AFTER'.$lastrowid.'POS'.($i+1)).'">';
     
     					// File name
     					print '<td class="minwith200">';
    
    From aea7299970f6bd48b101474074868f8f9c611e45 Mon Sep 17 00:00:00 2001
    From: gauthier <gauthier.verdol@atm-consulting.fr>
    Date: Wed, 17 Oct 2018 15:49:08 +0200
    Subject: [PATCH 310/433] FIX : use discount with multicurrency
    
    ---
     htdocs/compta/facture/card.php                | 6 ++++++
     htdocs/compta/facture/class/facture.class.php | 6 +++---
     htdocs/core/class/discount.class.php          | 4 +++-
     htdocs/societe/class/societe.class.php        | 6 +++---
     4 files changed, 15 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
    index 1d22d21d574..c92a182124e 100644
    --- a/htdocs/compta/facture/card.php
    +++ b/htdocs/compta/facture/card.php
    @@ -693,6 +693,9 @@ if (empty($reshook))
     					$amount_ht[$line->tva_tx] += $line->total_ht;
     					$amount_tva[$line->tva_tx] += $line->total_tva;
     					$amount_ttc[$line->tva_tx] += $line->total_ttc;
    +					$multicurrency_amount_ht[$line->tva_tx] += $line->multicurrency_total_ht;
    +					$multicurrency_amount_tva[$line->tva_tx] += $line->multicurrency_total_tva;
    +					$multicurrency_amount_ttc[$line->tva_tx] += $line->multicurrency_total_ttc;
     					$i ++;
     				}
     			}
    @@ -748,6 +751,9 @@ if (empty($reshook))
     					$discount->amount_ht = abs($amount_ht[$tva_tx]);
     					$discount->amount_tva = abs($amount_tva[$tva_tx]);
     					$discount->amount_ttc = abs($amount_ttc[$tva_tx]);
    +					$discount->multicurrency_amount_ht = abs($multicurrency_amount_ht[$tva_tx]);
    +					$discount->multicurrency_amount_tva = abs($multicurrency_amount_tva[$tva_tx]);
    +					$discount->multicurrency_amount_ttc = abs($multicurrency_amount_ttc[$tva_tx]);
     					$discount->tva_tx = abs($tva_tx);
     
     					$result = $discount->create($user);
    diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
    index 9bf6d4b876c..f0601ba37af 100644
    --- a/htdocs/compta/facture/class/facture.class.php
    +++ b/htdocs/compta/facture/class/facture.class.php
    @@ -1700,9 +1700,9 @@ class Facture extends CommonInvoice
     			$facligne->total_ttc = -$remise->amount_ttc;
     
     			$facligne->multicurrency_subprice = -$remise->multicurrency_subprice;
    -			$facligne->multicurrency_total_ht = -$remise->multicurrency_total_ht;
    -			$facligne->multicurrency_total_tva = -$remise->multicurrency_total_tva;
    -			$facligne->multicurrency_total_ttc = -$remise->multicurrency_total_ttc;
    +			$facligne->multicurrency_total_ht = -$remise->multicurrency_amount_ht;
    +			$facligne->multicurrency_total_tva = -$remise->multicurrency_amount_tva;
    +			$facligne->multicurrency_total_ttc = -$remise->multicurrency_amount_ttc;
     
     			$lineid=$facligne->insert();
     			if ($lineid > 0)
    diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php
    index 37dedea8b6b..e1796c38421 100644
    --- a/htdocs/core/class/discount.class.php
    +++ b/htdocs/core/class/discount.class.php
    @@ -103,7 +103,7 @@ class DiscountAbsolute
                     $this->amount_tva = $obj->amount_tva;
                     $this->amount_ttc = $obj->amount_ttc;
     
    -                $this->multicurrency_amount_ht = $obj->multicurrency_amount_ht;
    +                $this->multicurrency_amount_ht = $this->multicurrency_subprice = $obj->multicurrency_amount_ht;
                     $this->multicurrency_amount_tva = $obj->multicurrency_amount_tva;
                     $this->multicurrency_amount_ttc = $obj->multicurrency_amount_ttc;
     
    @@ -161,10 +161,12 @@ class DiscountAbsolute
             $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_except";
             $sql.= " (entity, datec, fk_soc, fk_user, description,";
             $sql.= " amount_ht, amount_tva, amount_ttc, tva_tx,";
    +        $sql.= " multicurrency_amount_ht, multicurrency_amount_tva, multicurrency_amount_ttc,";
             $sql.= " fk_facture_source";
             $sql.= ")";
             $sql.= " VALUES (".$conf->entity.", '".$this->db->idate($this->datec!=''?$this->datec:dol_now())."', ".$this->fk_soc.", ".$user->id.", '".$this->db->escape($this->description)."',";
             $sql.= " ".$this->amount_ht.", ".$this->amount_tva.", ".$this->amount_ttc.", ".$this->tva_tx.",";
    +        $sql.= " ".$this->multicurrency_amount_ht.", ".$this->multicurrency_amount_tva.", ".$this->multicurrency_amount_ttc.", ";
             $sql.= " ".($this->fk_facture_source ? "'".$this->db->escape($this->fk_facture_source)."'":"null");
             $sql.= ")";
     
    diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
    index 843803abca8..2a488aacf44 100644
    --- a/htdocs/societe/class/societe.class.php
    +++ b/htdocs/societe/class/societe.class.php
    @@ -1680,9 +1680,9 @@ class Societe extends CommonObject
     
     			$discount = new DiscountAbsolute($this->db);
     			$discount->fk_soc=$this->id;
    -			$discount->amount_ht=price2num($remise,'MT');
    -			$discount->amount_tva=price2num($remise*$tva_tx/100,'MT');
    -			$discount->amount_ttc=price2num($discount->amount_ht+$discount->amount_tva,'MT');
    +			$discount->amount_ht=$discount->multicurrency_amount_ht=price2num($remise,'MT');
    +			$discount->amount_tva=$discount->multicurrency_amount_tva=price2num($remise*$tva_tx/100,'MT');
    +			$discount->amount_ttc=$discount->multicurrency_amount_ttc=price2num($discount->amount_ht+$discount->amount_tva,'MT');
     			$discount->tva_tx=price2num($tva_tx,'MT');
     			$discount->description=$desc;
     			$result=$discount->create($user);
    
    From d86c44e641b336a46a6b673298db44704a019090 Mon Sep 17 00:00:00 2001
    From: atm-greg <gregory.blemand@atm-consulting.fr>
    Date: Wed, 17 Oct 2018 15:55:46 +0200
    Subject: [PATCH 311/433] Add conf to disable a thirdparty type
    
    ---
     htdocs/langs/en_US/admin.lang    |  1 +
     htdocs/societe/admin/societe.php | 34 ++++++++++++++++++++++++++++++++
     2 files changed, 35 insertions(+)
    
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index 4630757dbad..4054ca8c254 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -1821,3 +1821,4 @@ DisabledResourceLinkUser=Disable feature to link a resource to users
     DisabledResourceLinkContact=Disable feature to link a resource to contacts
     ConfirmUnactivation=Confirm module reset
     OnMobileOnly=On small screen (smartphone) only
    +DisableProspectCustomerType=Disable the "Prospect/customer" thirdparty type
    diff --git a/htdocs/societe/admin/societe.php b/htdocs/societe/admin/societe.php
    index 3a7b26505c7..49a9538e225 100644
    --- a/htdocs/societe/admin/societe.php
    +++ b/htdocs/societe/admin/societe.php
    @@ -211,6 +211,21 @@ if ($action=="setaskforshippingmet") {
     	}
     }
     
    +//Activate "Disable prospect/customer type"
    +if ($action=="setdisableprospectcustomer") {
    +    $setdisableprospectcustomer = GETPOST('value','int');
    +    $res = dolibarr_set_const($db, "SOCIETE_DISABLE_PROSPECTSCUSTOMERS", $setdisableprospectcustomer,'yesno',0,'',$conf->entity);
    +    if (! $res > 0) $error++;
    +    if (! $error)
    +    {
    +        setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
    +    }
    +    else
    +    {
    +        setEventMessages($langs->trans("Error"), null, 'errors');
    +    }
    +}
    +
     //Activate ProfId unique
     if ($action == 'setprofid')
     {
    @@ -821,6 +836,25 @@ else
     print '</a></td>';
     print '</tr>';
     
    +// Disable Prospect/Customer thirdparty type
    +print '<tr class="oddeven">';
    +print '<td width="80%">'.$langs->trans("DisableProspectCustomerType").'</td>';
    +print '<td>&nbsp</td>';
    +print '<td align="center">';
    +if (!empty($conf->global->SOCIETE_DISABLE_PROSPECTSCUSTOMERS))
    +{
    +    print '<a href="'.$_SERVER['PHP_SELF'].'?action=setdisableprospectcustomer&value=0">';
    +    print img_picto($langs->trans("Activated"),'switch_on');
    +    
    +}
    +else
    +{
    +    print '<a href="'.$_SERVER['PHP_SELF'].'?action=setdisableprospectcustomer&value=1">';
    +    print img_picto($langs->trans("Disabled"),'switch_off');
    +}
    +print '</a></td>';
    +print '</tr>';
    +
     /*print '<tr class="oddeven">';
     print '<td width="80%">'.$langs->trans("OnSearchAndListGoOnCustomerOrSupplierCard").'</td>';
     print '<td>&nbsp</td>';
    
    From 456bdb5b8c6020480899165f4cbb34ee8ce40fd5 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 17 Oct 2018 20:04:48 +0200
    Subject: [PATCH 312/433] do not trim int
    
    ---
     htdocs/ticket/class/ticketlogs.class.php | 33 ++++++++++++------------
     1 file changed, 17 insertions(+), 16 deletions(-)
    
    diff --git a/htdocs/ticket/class/ticketlogs.class.php b/htdocs/ticket/class/ticketlogs.class.php
    index 79a4c95efed..68ce6481b31 100644
    --- a/htdocs/ticket/class/ticketlogs.class.php
    +++ b/htdocs/ticket/class/ticketlogs.class.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) - 2013-2016    Jean-François FERRY    <hello@librethic.io>
    +/* Copyright (C) 2013-2016  Jean-François FERRY     <hello@librethic.io>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -63,12 +64,12 @@ class Ticketlogs// extends CommonObject
     	public $id;
     
     	/**
    -     * @var int ID
    +     * @var string trackid
          */
         public $fk_track_id;
     
         /**
    -     * @var int ID
    +     * @var int user create ID
          */
         public $fk_user_create;
     
    @@ -104,7 +105,7 @@ class Ticketlogs// extends CommonObject
             }
     
             if (isset($this->fk_user_create)) {
    -            $this->fk_user_create = trim($this->fk_user_create);
    +            $this->fk_user_create = (int) $this->fk_user_create;
             }
     
             if (isset($this->message)) {
    @@ -143,7 +144,7 @@ class Ticketlogs// extends CommonObject
             if (!$error) {
                 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "ticket_logs");
     
    -            if (!$notrigger) {
    +            //if (!$notrigger) {
                     // Uncomment this and change MYOBJECT to your own tag if you
                     // want this action calls a trigger.
     
    @@ -153,7 +154,7 @@ class Ticketlogs// extends CommonObject
                     //$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf);
                     //if ($result < 0) { $error++; $this->errors=$interface->errors; }
                     //// End call triggers
    -            }
    +            //}
             }
     
             // Commit or rollback
    @@ -232,7 +233,7 @@ class Ticketlogs// extends CommonObject
             }
     
             if (isset($this->fk_user_create)) {
    -            $this->fk_user_create = trim($this->fk_user_create);
    +            $this->fk_user_create = (int) $this->fk_user_create;
             }
     
             if (isset($this->message)) {
    @@ -261,8 +262,8 @@ class Ticketlogs// extends CommonObject
                 $this->errors[] = "Error " . $this->db->lasterror();
             }
     
    -        if (!$error) {
    -            if (!$notrigger) {
    +        //if (!$error) {
    +            //if (!$notrigger) {
                     // Uncomment this and change MYOBJECT to your own tag if you
                     // want this action calls a trigger.
     
    @@ -272,8 +273,8 @@ class Ticketlogs// extends CommonObject
                     //$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf);
                     //if ($result < 0) { $error++; $this->errors=$interface->errors; }
                     //// End call triggers
    -            }
    -        }
    +            //}
    +        //}
     
             // Commit or rollback
             if ($error) {
    @@ -303,8 +304,8 @@ class Ticketlogs// extends CommonObject
     
             $this->db->begin();
     
    -        if (!$error) {
    -            if (!$notrigger) {
    +        //if (!$error) {
    +            //if (!$notrigger) {
                     // Uncomment this and change MYOBJECT to your own tag if you
                     // want this action calls a trigger.
     
    @@ -314,8 +315,8 @@ class Ticketlogs// extends CommonObject
                     //$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
                     //if ($result < 0) { $error++; $this->errors=$interface->errors; }
                     //// End call triggers
    -            }
    -        }
    +            //}
    +        //}
     
             if (!$error) {
                 $sql = "DELETE FROM " . MAIN_DB_PREFIX . "ticket_logs";
    @@ -354,7 +355,7 @@ class Ticketlogs// extends CommonObject
             $this->id = 0;
     
             $this->fk_track_id = '';
    -        $this->fk_user_create = '';
    +        $this->fk_user_create = 1;
             $this->datec = '';
             $this->message = '';
         }
    
    From 47048baa36fbf642a23cb5c4c63cbcdf3da657ce Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 17 Oct 2018 20:14:01 +0200
    Subject: [PATCH 313/433] do not trim int
    
    ---
     htdocs/projet/class/task.class.php | 11 ++++++-----
     1 file changed, 6 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php
    index 84829bf85cb..a4ef7965851 100644
    --- a/htdocs/projet/class/task.class.php
    +++ b/htdocs/projet/class/task.class.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2008-2014	Laurent Destailleur	<eldy@users.sourceforge.net>
      * Copyright (C) 2010-2012	Regis Houssin		<regis.houssin@capnetworks.com>
      * Copyright (C) 2014       Marcos García       <marcosgdf@gmail.com>
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -340,7 +341,7 @@ class Task extends CommonObject
     		// Clean parameters
     		if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project);
     		if (isset($this->ref)) $this->ref=trim($this->ref);
    -		if (isset($this->fk_task_parent)) $this->fk_task_parent=trim($this->fk_task_parent);
    +		if (isset($this->fk_task_parent)) $this->fk_task_parent = (int) $this->fk_task_parent;
     		if (isset($this->label)) $this->label=trim($this->label);
     		if (isset($this->description)) $this->description=trim($this->description);
     		if (isset($this->duration_effective)) $this->duration_effective=trim($this->duration_effective);
    @@ -705,12 +706,12 @@ class Task extends CommonObject
     
     		$this->fk_projet='';
     		$this->ref='TK01';
    -		$this->fk_task_parent='';
    +		$this->fk_task_parent=null;
     		$this->label='Specimen task TK01';
     		$this->duration_effective='';
    -		$this->fk_user_creat='';
    +		$this->fk_user_creat=null;
     		$this->progress='25';
    -		$this->fk_statut='';
    +		$this->fk_statut=null;
     		$this->note='This is a specimen task not';
     	}
     
    @@ -1999,4 +2000,4 @@ class Task extends CommonObject
     
     		return ($datetouse > 0 && ($datetouse < ($now - $conf->projet->task->warning_delay)));
     	}
    -}
    \ No newline at end of file
    +}
    
    From 393303fe31d816cf8c0f4e8d0b79a08fa9d97b73 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 17 Oct 2018 20:17:43 +0200
    Subject: [PATCH 314/433] do not trim int
    
    ---
     .../stock/class/productstockentrepot.class.php       | 12 ++++++------
     1 file changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/htdocs/product/stock/class/productstockentrepot.class.php b/htdocs/product/stock/class/productstockentrepot.class.php
    index 6b12af88c7a..740afcb5f04 100644
    --- a/htdocs/product/stock/class/productstockentrepot.class.php
    +++ b/htdocs/product/stock/class/productstockentrepot.class.php
    @@ -93,8 +93,8 @@ class ProductStockEntrepot extends CommonObject
     
     		// Clean parameters
     
    -		if (isset($this->fk_product)) $this->fk_product = trim($this->fk_product);
    -		if (isset($this->fk_entrepot)) $this->fk_entrepot = trim($this->fk_entrepot);
    +		if (isset($this->fk_product)) $this->fk_product = (int) $this->fk_product;
    +		if (isset($this->fk_entrepot)) $this->fk_entrepot = (int) $this->fk_entrepot;
     		if (isset($this->seuil_stock_alerte)) $this->seuil_stock_alerte = trim($this->seuil_stock_alerte);
     		if (isset($this->desiredstock)) $this->desiredstock = trim($this->desiredstock);
     		if (isset($this->import_key)) $this->import_key = trim($this->import_key);
    @@ -317,8 +317,8 @@ class ProductStockEntrepot extends CommonObject
     
     		// Clean parameters
     
    -		if (isset($this->fk_product)) $this->fk_product = trim($this->fk_product);
    -		if (isset($this->fk_entrepot)) $this->fk_entrepot = trim($this->fk_entrepot);
    +		if (isset($this->fk_product)) $this->fk_product = (int) $this->fk_product;
    +		if (isset($this->fk_entrepot)) $this->fk_entrepot = (int) $this->fk_entrepot;
     		if (isset($this->seuil_stock_alerte)) $this->seuil_stock_alerte = trim($this->seuil_stock_alerte);
     		if (isset($this->desiredstock)) $this->desiredstock = trim($this->desiredstock);
     		if (isset($this->import_key)) $this->import_key = trim($this->import_key);
    @@ -575,8 +575,8 @@ class ProductStockEntrepot extends CommonObject
     		$this->id = 0;
     
     		$this->tms = '';
    -		$this->fk_product = '';
    -		$this->fk_entrepot = '';
    +		$this->fk_product = null;
    +		$this->fk_entrepot = null;
     		$this->seuil_stock_alerte = '';
     		$this->desiredstock = '';
     		$this->import_key = '';
    
    From ebc5cb5a96d2e99de95202a6cadb8ed5561e5495 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 17 Oct 2018 20:24:43 +0200
    Subject: [PATCH 315/433] do not trim int
    
    ---
     .../product/stock/class/productlot.class.php  | 37 +++++++++----------
     1 file changed, 17 insertions(+), 20 deletions(-)
    
    diff --git a/htdocs/product/stock/class/productlot.class.php b/htdocs/product/stock/class/productlot.class.php
    index 1530e068856..d61630eb88e 100644
    --- a/htdocs/product/stock/class/productlot.class.php
    +++ b/htdocs/product/stock/class/productlot.class.php
    @@ -3,7 +3,7 @@
      * Copyright (C) 2014       Juanjo Menent       <jmenent@2byte.es>
      * Copyright (C) 2015       Florian Henry       <florian.henry@open-concept.pro>
      * Copyright (C) 2015       Raphaël Doursenaud  <rdoursenaud@gpcsolutions.fr>
    - * Copyright (C) ---Put here your own copyright and developer email---
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -115,19 +115,19 @@ class Productlot extends CommonObject
     		// Clean parameters
     
     		if (isset($this->entity)) {
    -			 $this->entity = trim($this->entity);
    +			 $this->entity = (int) $this->entity;
     		}
     		if (isset($this->fk_product)) {
    -			 $this->fk_product = trim($this->fk_product);
    +			 $this->fk_product = (int) $this->fk_product;
     		}
     		if (isset($this->batch)) {
     			 $this->batch = trim($this->batch);
     		}
     		if (isset($this->fk_user_creat)) {
    -			 $this->fk_user_creat = trim($this->fk_user_creat);
    +			 $this->fk_user_creat = (int) $this->fk_user_creat;
     		}
     		if (isset($this->fk_user_modif)) {
    -			 $this->fk_user_modif = trim($this->fk_user_modif);
    +			 $this->fk_user_modif = (int) $this->fk_user_modif;
     		}
     		if (isset($this->import_key)) {
     			 $this->import_key = trim($this->import_key);
    @@ -296,19 +296,19 @@ class Productlot extends CommonObject
     		// Clean parameters
     
     		if (isset($this->entity)) {
    -			 $this->entity = trim($this->entity);
    +			 $this->entity = (int) $this->entity;
     		}
     		if (isset($this->fk_product)) {
    -			 $this->fk_product = trim($this->fk_product);
    +			 $this->fk_product = (int) $this->fk_product;
     		}
     		if (isset($this->batch)) {
     			 $this->batch = trim($this->batch);
     		}
     		if (isset($this->fk_user_creat)) {
    -			 $this->fk_user_creat = trim($this->fk_user_creat);
    +			 $this->fk_user_creat = (int) $this->fk_user_creat;
     		}
     		if (isset($this->fk_user_modif)) {
    -			 $this->fk_user_modif = trim($this->fk_user_modif);
    +			 $this->fk_user_modif = (int) $this->fk_user_modif;
     		}
     		if (isset($this->import_key)) {
     			 $this->import_key = trim($this->import_key);
    @@ -358,9 +358,6 @@ class Productlot extends CommonObject
     		}
     
     		if (!$error && !$notrigger) {
    -			// Uncomment this and change MYOBJECT to your own tag if you
    -			// want this action calls a trigger.
    -
     			// Call triggers
     			$result=$this->call_trigger('PRODUCTLOT_MODIFY',$user);
     			if ($result < 0) { $error++; }
    @@ -395,8 +392,8 @@ class Productlot extends CommonObject
     
     		$this->db->begin();
     
    -		if (!$error) {
    -			if (!$notrigger) {
    +		//if (!$error) {
    +			//if (!$notrigger) {
     				// Uncomment this and change MYOBJECT to your own tag if you
     				// want this action calls a trigger.
     
    @@ -404,8 +401,8 @@ class Productlot extends CommonObject
     				//$result=$this->call_trigger('MYOBJECT_DELETE',$user);
     				//if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail}
     				//// End call triggers
    -			}
    -		}
    +			//}
    +		//}
     
     		if (!$error) {
     			$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . $this->table_element;
    @@ -587,15 +584,15 @@ class Productlot extends CommonObject
     	{
     		$this->id = 0;
     
    -		$this->entity = '';
    -		$this->fk_product = '';
    +		$this->entity = null;
    +		$this->fk_product = null;
     		$this->batch = '';
     		$this->eatby = '';
     		$this->sellby = '';
     		$this->datec = '';
     		$this->tms = '';
    -		$this->fk_user_creat = '';
    -		$this->fk_user_modif = '';
    +		$this->fk_user_creat = null;
    +		$this->fk_user_modif = null;
     		$this->import_key = '';
     	}
     }
    
    From db732ddeddcfd3c6ae4d6ea56f5790eeb690d42e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 17 Oct 2018 20:36:45 +0200
    Subject: [PATCH 316/433] code comment
    
    ---
     htdocs/categories/class/categorie.class.php | 9 +++++----
     1 file changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php
    index 15cb254ed7d..a9432234793 100644
    --- a/htdocs/categories/class/categorie.class.php
    +++ b/htdocs/categories/class/categorie.class.php
    @@ -10,6 +10,7 @@
      * Copyright (C) 2015       Marcos García           <marcosgdf@gmail.com>
      * Copyright (C) 2015       Raphaël Doursenaud      <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2016       Charlie Benke           <charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -805,7 +806,7 @@ class Categorie extends CommonObject
     	 * @param	string	$sortorder	Sort order
     	 * @param	int		$limit		Limit for list
     	 * @param	int		$page		Page number
    -	 * @return	array				Array of categories
    +	 * @return	array|int			Array of categories, 0 if no cat, -1 on error
     	 */
     	function getListForItem($id, $type='customer', $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
     	{
    @@ -974,7 +975,7 @@ class Categorie extends CommonObject
     	 * @param   string 	$type        	Type of categories ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...).
     	 * @param   int    	$markafterid 	Removed all categories including the leaf $markafterid in category tree.
     	 *
    -	 * @return  array               	Array of categories. this->cats and this->motherof are set.
    +	 * @return  array|int               Array of categories. this->cats and this->motherof are set, -1 on error
     	 */
     	function get_full_arbo($type, $markafterid=0)
     	{
    @@ -1126,7 +1127,7 @@ class Categorie extends CommonObject
     	 *
     	 *	@param	int			$type		Type of category (0, 1, ...)
     	 *	@param	boolean		$parent		Just parent categories if true
    -	 *	@return	array					Table of Object Category
    +	 *	@return	array|int				Table of Object Category, -1 on error
     	 */
     	function get_all_categories($type=null, $parent=false)
     	{
    @@ -1441,7 +1442,7 @@ class Categorie extends CommonObject
      	 * 	@param		string		$type		Type of category ('member', 'customer', 'supplier', 'product', 'contact'). Old mode (0, 1, 2, ...) is deprecated.
     	 * 	@param		boolean		$exact		Exact string search (true/false)
     	 * 	@param		boolean		$case		Case sensitive (true/false)
    -	 * 	@return		array					Array of category id
    +	 * 	@return		array|int				Array of category id, -1 if error
     	 */
     	function rechercher($id, $nom, $type, $exact = false, $case = false)
     	{
    
    From 52840478c02599701eb4b8b92ea85a4aaf693510 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 17 Oct 2018 21:11:07 +0200
    Subject: [PATCH 317/433] Clean code
    
    ---
     htdocs/core/class/CMailFile.class.php | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
    index 7562cd609c2..ef8d07dfb45 100644
    --- a/htdocs/core/class/CMailFile.class.php
    +++ b/htdocs/core/class/CMailFile.class.php
    @@ -569,7 +569,8 @@ class CMailFile
     				$keyforstarttls  ='MAIN_MAIL_EMAIL_STARTTLS_EMAILING';
     			}
     
    -			if(!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) {
    +			if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO))
    +			{
     				$this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO;
     				$this->addr_cc = '';
     				$this->addr_bcc = '';
    
    From 3f136ee58d57c005de34c9781526f2433d2f10e5 Mon Sep 17 00:00:00 2001
    From: Scott Albertson <ascottalbertson@gmail.com>
    Date: Wed, 17 Oct 2018 12:28:05 -0700
    Subject: [PATCH 318/433] Add "Reviewed by Hound" badge
    
    ---
     README.md | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/README.md b/README.md
    index 776e2b02432..c38d0ca7dd1 100644
    --- a/README.md
    +++ b/README.md
    @@ -1,6 +1,7 @@
     # DOLIBARR ERP & CRM
     
     ![Downloads per day](https://img.shields.io/sourceforge/dm/dolibarr.svg)
    +[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
     
     |6|7|8|develop|
     |----------|----------|----------|----------|
    
    From 63f47047259a10386376d378d54ae8cf9f35aec7 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 18 Oct 2018 01:05:10 +0200
    Subject: [PATCH 319/433] Fix translation
    
    ---
     htdocs/langs/en_US/admin.lang | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index 4630757dbad..1fc67ae2ba6 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -620,7 +620,7 @@ Module50000Name=PayBox
     Module50000Desc=Offer customers a PayBox online payment page (credit/debit cards). This can be used to allow your customers to make free payments or for a payment on a particular Dolibarr object (invoice, order, ...)
     Module50100Name=Point of sales
     Module50100Desc=Point of sales module (POS).
    -Module50150Name=Point of salesaa
    +Module50150Name=Point of sales
     Module50150Desc=Point of sales module (Touch screen POS).
     Module50200Name=Paypal
     Module50200Desc=Offer customers a PayPal online payment page (PayPal account or credit/debit cards). This can be used to allow your customers to make free payments or for a payment on a particular Dolibarr object (invoice, order, ...)
    @@ -925,7 +925,7 @@ BackToModuleList=Back to modules list
     BackToDictionaryList=Back to list of Dictionaries
     TypeOfRevenueStamp=Type of tax stamp
     VATManagement=VAT Management
    -VATIsUsedDesc=By default when creating prospects, invoices, orders etc. the VAT rate follows the active standard rule:<br>If the seller is not subject to VAT, then VAT defaults to 0. End of rule.<br><p>If the (seller's country = buyer's country), then the VAT by default equals the VAT of the product in the seller's country. End of rule.</p><p>If the seller and buyer are both in the European Community and goods are transport-related products (haulage, shipping, airline), the default VAT is 0. This rule is dependant on the seller's country - please consult with your accountant. The VAT should be paid by the buyer to their customs office in their country and not to the seller. End of rule.</p><p>If the seller and buyer are both in the European Community and the buyer is not a company (with a registered intra-Community VAT number) then the VAT by defaults to the VAT of the seller's country. End of rule.</p><p>If the seller and buyer are both in the European Community and the buyer is a company (with a registered intra-Community VAT number), then the VAT is 0 by default. End of rule.</p><p>In any other case the proposed default is VAT=0. End of rule.</p>
    +VATIsUsedDesc=By default when creating prospects, invoices, orders etc. the VAT rate follows the active standard rule:<br>If the seller is not subject to VAT, then VAT defaults to 0. End of rule.<br>If the (seller's country = buyer's country), then the VAT by default equals the VAT of the product in the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and goods are transport-related products (haulage, shipping, airline), the default VAT is 0. This rule is dependant on the seller's country - please consult with your accountant. The VAT should be paid by the buyer to their customs office in their country and not to the seller. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is not a company (with a registered intra-Community VAT number) then the VAT by defaults to the VAT of the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is a company (with a registered intra-Community VAT number), then the VAT is 0 by default. End of rule.<br>In any other case the proposed default is VAT=0. End of rule.</p>
     VATIsNotUsedDesc=By default the proposed VAT is 0 which can be used for cases like associations, individuals or small companies.
     VATIsUsedExampleFR=In France, it means companies or organizations having a real fiscal system (Simplified real or normal real).  A system in which VAT is declared.
     VATIsNotUsedExampleFR=In France, it means associations that are non VAT declared or companies, organizations or liberal professions that have chosen the micro enterprise fiscal system (VAT in franchise) and paid a franchise VAT without any VAT declaration.  This choice will display the reference "Non applicable VAT - art-293B of CGI" on invoices.
    
    From b2a7845c8abbfe36daa92a35cf33af3784b803f1 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 18 Oct 2018 01:28:14 +0200
    Subject: [PATCH 320/433] Fix trans
    
    ---
     htdocs/langs/en_US/admin.lang | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index 1fc67ae2ba6..2afe1a77c32 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -925,7 +925,7 @@ BackToModuleList=Back to modules list
     BackToDictionaryList=Back to list of Dictionaries
     TypeOfRevenueStamp=Type of tax stamp
     VATManagement=VAT Management
    -VATIsUsedDesc=By default when creating prospects, invoices, orders etc. the VAT rate follows the active standard rule:<br>If the seller is not subject to VAT, then VAT defaults to 0. End of rule.<br>If the (seller's country = buyer's country), then the VAT by default equals the VAT of the product in the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and goods are transport-related products (haulage, shipping, airline), the default VAT is 0. This rule is dependant on the seller's country - please consult with your accountant. The VAT should be paid by the buyer to their customs office in their country and not to the seller. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is not a company (with a registered intra-Community VAT number) then the VAT by defaults to the VAT of the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is a company (with a registered intra-Community VAT number), then the VAT is 0 by default. End of rule.<br>In any other case the proposed default is VAT=0. End of rule.</p>
    +VATIsUsedDesc=By default when creating prospects, invoices, orders etc. the VAT rate follows the active standard rule:<br>If the seller is not subject to VAT, then VAT defaults to 0. End of rule.<br>If the (seller's country = buyer's country), then the VAT by default equals the VAT of the product in the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and goods are transport-related products (haulage, shipping, airline), the default VAT is 0. This rule is dependant on the seller's country - please consult with your accountant. The VAT should be paid by the buyer to their customs office in their country and not to the seller. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is not a company (with a registered intra-Community VAT number) then the VAT by defaults to the VAT of the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is a company (with a registered intra-Community VAT number), then the VAT is 0 by default. End of rule.<br>In any other case the proposed default is VAT=0. End of rule.
     VATIsNotUsedDesc=By default the proposed VAT is 0 which can be used for cases like associations, individuals or small companies.
     VATIsUsedExampleFR=In France, it means companies or organizations having a real fiscal system (Simplified real or normal real).  A system in which VAT is declared.
     VATIsNotUsedExampleFR=In France, it means associations that are non VAT declared or companies, organizations or liberal professions that have chosen the micro enterprise fiscal system (VAT in franchise) and paid a franchise VAT without any VAT declaration.  This choice will display the reference "Non applicable VAT - art-293B of CGI" on invoices.
    
    From 548fafc6e9d52e05159cd1bc6383b097c88fa5eb Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 18 Oct 2018 01:32:06 +0200
    Subject: [PATCH 321/433] Fix trans
    
    ---
     htdocs/langs/en_US/admin.lang | 22 +++++++++++-----------
     1 file changed, 11 insertions(+), 11 deletions(-)
    
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index 2afe1a77c32..b173f7912dd 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -943,16 +943,16 @@ LocalTax2IsNotUsedDesc=Do not use other type of tax (other than VAT)
     LocalTax2Management=Third type of tax
     LocalTax2IsUsedExample=
     LocalTax2IsNotUsedExample=
    -LocalTax1ManagementES= RE Management
    -LocalTax1IsUsedDescES= The RE rate by default when creating prospects, invoices, orders etc. follow the active standard rule:<br>If the buyer is not subjected to RE, RE by default=0. End of rule.<br>If the buyer is subjected to RE then the RE by default. End of rule.<br>
    -LocalTax1IsNotUsedDescES= By default the proposed RE is 0. End of rule.
    -LocalTax1IsUsedExampleES= In Spain they are professionals subject to some specific sections of the Spanish IAE.
    -LocalTax1IsNotUsedExampleES= In Spain they are professional and societies and subject to certain sections of the Spanish IAE.
    -LocalTax2ManagementES= IRPF Management
    -LocalTax2IsUsedDescES= The RE rate by default when creating prospects, invoices, orders etc. follow the active standard rule:<br>If the seller is not subjected to IRPF, then IRPF by default=0. End of rule.<br>If the seller is subjected to IRPF then the IRPF by default. End of rule.<br>
    -LocalTax2IsNotUsedDescES= By default the proposed IRPF is 0. End of rule.
    -LocalTax2IsUsedExampleES= In Spain, freelancers and independent professionals who provide services and companies who have chosen the tax system of modules.
    -LocalTax2IsNotUsedExampleES= In Spain they are businesses not subject to tax system of modules.
    +LocalTax1ManagementES=RE Management
    +LocalTax1IsUsedDescES=The RE rate by default when creating prospects, invoices, orders etc. follow the active standard rule:<br>If the buyer is not subjected to RE, RE by default=0. End of rule.<br>If the buyer is subjected to RE then the RE by default. End of rule.<br>
    +LocalTax1IsNotUsedDescES=By default the proposed RE is 0. End of rule.
    +LocalTax1IsUsedExampleES=In Spain they are professionals subject to some specific sections of the Spanish IAE.
    +LocalTax1IsNotUsedExampleES=In Spain they are professional and societies and subject to certain sections of the Spanish IAE.
    +LocalTax2ManagementES=IRPF Management
    +LocalTax2IsUsedDescES=The IRPF rate by default when creating prospects, invoices, orders etc. follow the active standard rule:<br>If the seller is not subjected to IRPF, then IRPF by default=0. End of rule.<br>If the seller is subjected to IRPF then the IRPF by default. End of rule.<br>
    +LocalTax2IsNotUsedDescES=By default the proposed IRPF is 0. End of rule.
    +LocalTax2IsUsedExampleES=In Spain, freelancers and independent professionals who provide services and companies who have chosen the tax system of modules.
    +LocalTax2IsNotUsedExampleES=In Spain they are businesses not subject to tax system of modules.
     CalcLocaltax=Reports on local taxes
     CalcLocaltax1=Sales - Purchases
     CalcLocaltax1Desc=Local Taxes reports are calculated with the difference between localtaxes sales and localtaxes purchases
    @@ -1007,7 +1007,7 @@ MessageLogin=Login page message
     LoginPage=Login page
     BackgroundImageLogin=Background image
     PermanentLeftSearchForm=Permanent search form on left menu
    -DefaultLanguage=Default language to use (variant)
    +DefaultLanguage=Default language to use (language code)
     EnableMultilangInterface=Enable multilingual interface
     EnableShowLogo=Show logo on left menu
     CompanyInfo=Company/Organization
    
    From fd989230a4b439c90b3e5b88bf8d7cd5fda209f2 Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Thu, 18 Oct 2018 09:09:42 +0200
    Subject: [PATCH 322/433] New: works with variants: -Child label change if
     parent changes
    
    ---
     htdocs/variants/class/ProductCombination.class.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php
    index 8908bfa4d2d..77acc80483c 100644
    --- a/htdocs/variants/class/ProductCombination.class.php
    +++ b/htdocs/variants/class/ProductCombination.class.php
    @@ -330,6 +330,7 @@ class ProductCombination
     		$child->price_autogen = $parent->price_autogen;
     		$child->weight = $parent->weight + $this->variation_weight;
     		$child->weight_units = $parent->weight_units;
    +		$child->label = $parent->label;
     
     		if ($child->update($child->id, $user) > 0) {
     
    
    From 6c76f9517f259c14a4dc89121b846aabed2c2dbf Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Thu, 18 Oct 2018 10:26:21 +0200
    Subject: [PATCH 323/433] New: works with variants: -Child label with
     combination labels
    
    ---
     .../class/ProductCombination.class.php        | 38 ++++++++++++++++++-
     1 file changed, 37 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php
    index 77acc80483c..5385664abd4 100644
    --- a/htdocs/variants/class/ProductCombination.class.php
    +++ b/htdocs/variants/class/ProductCombination.class.php
    @@ -330,7 +330,8 @@ class ProductCombination
     		$child->price_autogen = $parent->price_autogen;
     		$child->weight = $parent->weight + $this->variation_weight;
     		$child->weight_units = $parent->weight_units;
    -		$child->label = $parent->label;
    +		$varlabel = $this->getLabelOfCombination($this->fk_product_child);
    +		$child->label = $parent->label.$varlabel;
     
     		if ($child->update($child->id, $user) > 0) {
     
    @@ -683,4 +684,39 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
     
     		return 1;
     	}
    +
    +	/**
    +	 * Return label for combinations
    +	 * @param 	int 	$prod_child		id of child
    +	 * @return 	string	combination label
    +	 */
    +	public function getLabelOfCombination($prod_child)
    +	{
    +		$label = '';
    +		$sql = 'SELECT pav.value AS label';
    +		$sql.= ' FROM llx_product_attribute_combination pac';
    +		$sql.= ' INNER JOIN llx_product_attribute_combination2val pac2v ON pac2v.fk_prod_combination=pac.rowid';
    +		$sql.= ' INNER JOIN llx_product_attribute_value pav ON pav.rowid=pac2v.fk_prod_attr_val';
    +		$sql.= ' WHERE pac.fk_product_child='.$prod_child;
    +
    +		$resql = $this->db->query($sql);
    +		if ($resql) {
    +			$num = $this->db->num_rows($resql);
    +
    +			$i = 0;
    +
    +			while ($i < $num)
    +			{
    +				$obj = $this->db->fetch_object($resql);
    +
    +				if ($obj->label)
    +				{
    +					$label.=' '.$obj->label;
    +				}
    +				$i++;
    +			}
    +
    +		}
    +		return $label;
    +	}
     }
    
    From c588f5e6c09ee98d586818dcdfe8f4bfae8599a6 Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Thu, 18 Oct 2018 10:55:27 +0200
    Subject: [PATCH 324/433] New: works with variants: -Child label with
     combination labels
    
    ---
     htdocs/variants/class/ProductCombination.class.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php
    index 5385664abd4..130b18dafc5 100644
    --- a/htdocs/variants/class/ProductCombination.class.php
    +++ b/htdocs/variants/class/ProductCombination.class.php
    @@ -694,9 +694,9 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
     	{
     		$label = '';
     		$sql = 'SELECT pav.value AS label';
    -		$sql.= ' FROM llx_product_attribute_combination pac';
    -		$sql.= ' INNER JOIN llx_product_attribute_combination2val pac2v ON pac2v.fk_prod_combination=pac.rowid';
    -		$sql.= ' INNER JOIN llx_product_attribute_value pav ON pav.rowid=pac2v.fk_prod_attr_val';
    +		$sql.= ' FROM '.MAIN_DB_PREFIX.'product_attribute_combination pac';
    +		$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product_attribute_combination2val pac2v ON pac2v.fk_prod_combination=pac.rowid';
    +		$sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'product_attribute_value pav ON pav.rowid=pac2v.fk_prod_attr_val';
     		$sql.= ' WHERE pac.fk_product_child='.$prod_child;
     
     		$resql = $this->db->query($sql);
    
    From 52ad5c5565a8b3eabb0e253d26fc2deec48a6dce Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Thu, 18 Oct 2018 12:21:39 +0200
    Subject: [PATCH 325/433] New: works with variants: -To edit child price and
     weight impacts better to see in tab the father price and weight
    
    ---
     htdocs/variants/combinations.php | 60 ++++++++++++++++++++++++++++++++
     1 file changed, 60 insertions(+)
    
    diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php
    index 848e5ee70fe..fb23921be25 100644
    --- a/htdocs/variants/combinations.php
    +++ b/htdocs/variants/combinations.php
    @@ -318,6 +318,66 @@ if (! empty($id) || ! empty($ref))
     
         dol_banner_tab($object, 'ref', $linkback, ($user->societe_id?0:1), 'ref', '', '', '', 0, '', '', 1);
     
    +	print '<div class="fichecenter">';
    +
    +	print '<div class="underbanner clearboth"></div>';
    +	print '<table class="border tableforfield" width="100%">';
    +
    +    // TVA
    +    print '<tr><td class="titlefield">' . $langs->trans("DefaultTaxRate") . '</td><td>';
    +
    +    $positiverates='';
    +    if (price2num($object->tva_tx))       $positiverates.=($positiverates?'/':'').price2num($object->tva_tx);
    +    if (price2num($object->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax1_tx);
    +    if (price2num($object->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($object->localtax2_tx);
    +    if (empty($positiverates)) $positiverates='0';
    +    echo vatrate($positiverates.($object->default_vat_code?' ('.$object->default_vat_code.')':''), '%', $object->tva_npr);
    +    /*
    +    if ($object->default_vat_code)
    +    {
    +        print vatrate($object->tva_tx, true) . ' ('.$object->default_vat_code.')';
    +    }
    +    else print vatrate($object->tva_tx, true, $object->tva_npr, true);*/
    +    print '</td></tr>';
    +
    +    // Price
    +    print '<tr><td>' . $langs->trans("SellingPrice") . '</td><td>';
    +    if ($object->price_base_type == 'TTC') {
    +        print price($object->price_ttc) . ' ' . $langs->trans($object->price_base_type);
    +    } else {
    +        print price($object->price) . ' ' . $langs->trans($object->price_base_type);
    +    }
    +    print '</td></tr>';
    +
    +    // Price minimum
    +    print '<tr><td>' . $langs->trans("MinPrice") . '</td><td>';
    +    if ($object->price_base_type == 'TTC') {
    +        print price($object->price_min_ttc) . ' ' . $langs->trans($object->price_base_type);
    +    } else {
    +        print price($object->price_min) . ' ' . $langs->trans($object->price_base_type);
    +    }
    +    print '</td></tr>';
    +
    +	// Weight
    +	print '<tr><td>'.$langs->trans("Weight").'</td><td>';
    +	if ($object->weight != '')
    +	{
    +		print $object->weight." ".measuring_units_string($object->weight_units,"weight");
    +	}
    +	else
    +	{
    +		print '&nbsp;';
    +	}
    +	print "</td></tr>\n";
    +
    +
    +
    +
    +	print "</table>\n";
    +
    +	print '</div>';
    +	print '<div style="clear:both"></div>';
    +
     	dol_fiche_end();
     
     
    
    From b396aaebc5d54fb95d1d2a1cf7c7394fe5f9e62a Mon Sep 17 00:00:00 2001
    From: andreubisquerra <jove@bisquerra.com>
    Date: Thu, 18 Oct 2018 16:31:37 +0200
    Subject: [PATCH 326/433] Fix delete without any selected line
    
    ---
     htdocs/takepos/invoice.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php
    index cdfe47a756f..c71f7f861a3 100644
    --- a/htdocs/takepos/invoice.php
    +++ b/htdocs/takepos/invoice.php
    @@ -115,7 +115,7 @@ if ($action=="deleteline"){
             $row = $db->fetch_array ($resql);
             $deletelineid=$row[0];
             $invoice->deleteline($deletelineid);
    -        $invoice->fetch($deletelineid);
    +        $invoice->fetch($placeid);
         }
     }
     
    
    From 7cafdc4d9a1610a1a52c831cf8be85e3a1008a9d Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 18 Oct 2018 16:56:43 +0200
    Subject: [PATCH 327/433] Fix phpcs
    
    ---
     htdocs/compta/paiement/class/paiement.class.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
    index cc60c2cba8e..a7e7c48a370 100644
    --- a/htdocs/compta/paiement/class/paiement.class.php
    +++ b/htdocs/compta/paiement/class/paiement.class.php
    @@ -233,11 +233,11 @@ class Paiement extends CommonObject
     			$mtotal = $totalamount;
     		}
     		$note = ($this->note_public?$this->note_public:$this->note);
    -    $payment_id = $this->payment_id ? $this->payment_id : null;
    -    $payment_site = $this->payment_site ? $this->payment_site : null;
    +		$payment_id = $this->payment_id ? $this->payment_id : null;
    +		$payment_site = $this->payment_site ? $this->payment_site : null;
     
     		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat)";
    -		$sql.= " VALUES (".$conf->entity.", '".$this->ref."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', '".$total."', '".$mtotal."', ".$this->paiementid.", '".$this->num_paiement."', '".$this->db->escape($note)."', '".$this->payment_id."', '".$this->payment_site."', ".$user->id.")";
    +		$sql.= " VALUES (".$conf->entity.", '".$this->db->escape($this->ref)."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".$total.", ".$mtotal.", ".$this->paiementid.", '".$this->db->escape($this->num_paiement)."', '".$this->db->escape($note)."', '".$this->db->escape($this->payment_id)."', '".$this->db->escape($this->payment_site)."', ".$user->id.")";
     
     		dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
     		$resql = $this->db->query($sql);
    
    From 05326e271da8f2f0b2008bdfdc9d90f2ca957f09 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 18 Oct 2018 17:15:26 +0200
    Subject: [PATCH 328/433] FIX Filter on invoice type
    
    ---
     htdocs/compta/facture/list.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
    index 78576e4c00d..35338722353 100644
    --- a/htdocs/compta/facture/list.php
    +++ b/htdocs/compta/facture/list.php
    @@ -422,7 +422,7 @@ if ($filtre)
     }
     if ($search_ref) $sql .= natural_search('f.facnumber', $search_ref);
     if ($search_refcustomer) $sql .= natural_search('f.ref_client', $search_refcustomer);
    -if ($search_type != '') $sql.=" AND f.type IN (".$db->escape($search_type).")";
    +if ($search_type != '' && $search_type != '-1') $sql.=" AND f.type IN (".$db->escape($search_type).")";
     if ($search_project) $sql .= natural_search('p.ref', $search_project);
     if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
     if ($search_town)  $sql.= natural_search('s.town', $search_town);
    
    From 66cb06eca9e876111cc27737e12cffc0a2fb93ae Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 18 Oct 2018 17:33:14 +0200
    Subject: [PATCH 329/433] NEW Top menu is always on screen with MD theme.
    
    ---
     htdocs/theme/md/style.css.php | 7 +++++++
     1 file changed, 7 insertions(+)
    
    diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
    index 3b67c895e0d..2ec97ec7a9d 100644
    --- a/htdocs/theme/md/style.css.php
    +++ b/htdocs/theme/md/style.css.php
    @@ -1205,6 +1205,13 @@ td.showDragHandle {
     .side-nav-vert {
     	margin-left: 228px;
     }
    +<?php if (empty($conf->global->THEME_DISABLE_STICKY_TOPMENU)) {  ?>
    +.side-nav-vert {
    +	position: sticky;
    +	top: 0px;
    +	z-index: 210;
    +}
    +<?php } ?>
     
     /* For smartphone (testmenuhider is on) */
     <?php if (in_array($conf->browser->layout, array('phone','tablet')) && ((GETPOST('testmenuhider') || ! empty($conf->global->MAIN_TESTMENUHIDER)) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))) { ?>
    
    From d4bc53660bf6daee7593d614a79576bfe0dfb568 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 18 Oct 2018 21:22:30 +0200
    Subject: [PATCH 330/433] Code comment and debug filemanager
    
    ---
     htdocs/core/ajax/ajaxdirpreview.php       | 24 ++++++-
     htdocs/core/ajax/ajaxdirtree.php          | 82 ++++++++++++++++++-----
     htdocs/core/tpl/filemanager.tpl.php       | 21 ++++--
     htdocs/ecm/tpl/enablefiletreeajax.tpl.php |  8 ++-
     4 files changed, 106 insertions(+), 29 deletions(-)
    
    diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php
    index 8d1c5cd712c..82f83595537 100644
    --- a/htdocs/core/ajax/ajaxdirpreview.php
    +++ b/htdocs/core/ajax/ajaxdirpreview.php
    @@ -82,9 +82,16 @@ else    // For no ajax call
                 dol_print_error($db,$ecmdir->error);
                 exit;
             }
    +
    +        $relativepath=$ecmdir->getRelativePath();	// Example   'mydir/'
         }
    -    $relativepath=$ecmdir->getRelativePath();
    -    $upload_dir = $rootdirfordoc.'/'.$relativepath;
    +	elseif (GETPOST('section_dir'))
    +	{
    +		$relativepath=GETPOST('section_dir');
    +	}
    +	//var_dump($section.'-'.GETPOST('section_dir').'-'.$relativepath);
    +
    +	$upload_dir = $rootdirfordoc.'/'.$relativepath;
     }
     
     if (empty($url))
    @@ -226,7 +233,18 @@ if ($type == 'directory')
         {
         	if ($module == 'medias')
         	{
    -    		$relativepath=GETPOST('file','alpha');
    +    		/*
    +    		   $_POST is array like
    +    		  'token' => string '062380e11b7dcd009d07318b57b71750' (length=32)
    +			  'action' => string 'file_manager' (length=12)
    +			  'website' => string 'template' (length=8)
    +			  'pageid' => string '124' (length=3)
    +			  'section_dir' => string 'mydir/' (length=3)
    +			  'section_id' => string '0' (length=1)
    +			  'max_file_size' => string '2097152' (length=7)
    +			  'sendit' => string 'Envoyer fichier' (length=15)
    +    		 */
    +    		$relativepath=GETPOST('file','alpha')?GETPOST('file','alpha'):GETPOST('section_dir','alpha');
         		if ($relativepath && $relativepath!= '/') $relativepath.='/';
         		$upload_dir = $dolibarr_main_data_root.'/'.$module.'/'.$relativepath;
         		if (GETPOSTISSET('website') || GETPOSTISSET('file_manager'))
    diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php
    index 4b588751829..a55df4a1038 100644
    --- a/htdocs/core/ajax/ajaxdirtree.php
    +++ b/htdocs/core/ajax/ajaxdirtree.php
    @@ -30,6 +30,7 @@ if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1');
     if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1');
     if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1');
     
    +
     if (! isset($mode) || $mode != 'noajax')    // For ajax call
     {
     	$res=@include '../../main.inc.php';
    @@ -39,16 +40,26 @@ if (! isset($mode) || $mode != 'noajax')    // For ajax call
     	include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
     	include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
     
    +	//if (GETPOST('preopened')) { $_GET['dir'] = $_POST['dir'] = '/bbb/'; }
    +
     	$openeddir = GETPOST('openeddir');
     	$modulepart= GETPOST('modulepart');
     	$selecteddir = jsUnEscape(GETPOST('dir'));        // relative path. We must decode using same encoding function used by javascript: escape()
    +
    +	$preopened = GETPOST('preopened');
    +
     	if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir);    // We removed last '/' except if it is '/'
     }
     else    // For no ajax call
     {
    +	//if (GETPOST('preopened')) { $_GET['dir'] = $_POST['dir'] = GETPOST('preopened'); }
    +
     	$openeddir = GETPOST('openeddir');
     	$modulepart= GETPOST('modulepart');
     	$selecteddir = GETPOST('dir');
    +
    +	$preopened = GETPOST('preopened');
    +
     	if ($selecteddir != '/') $selecteddir = preg_replace('/\/$/','',$selecteddir);    // We removed last '/' except if it is '/'
     	if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
     }
    @@ -58,8 +69,16 @@ $langs->load("ecm");
     
     // Define fullpathselecteddir.
     $fullpathselecteddir='<none>';
    -if ($modulepart == 'ecm') $fullpathselecteddir=$conf->ecm->dir_output.'/'.($selecteddir != '/' ? $selecteddir : '');
    -if ($modulepart == 'medias') $fullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($selecteddir != '/' ? $selecteddir : '');
    +if ($modulepart == 'ecm')
    +{
    +	$fullpathselecteddir=$conf->ecm->dir_output.'/'.($selecteddir != '/' ? $selecteddir : '');
    +	$fullpathopeneddir=$conf->ecm->dir_output.'/'.($openeddir != '/' ? $openeddir : '');
    +}
    +if ($modulepart == 'medias')
    +{
    +	$fullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($selecteddir != '/' ? $selecteddir : '');
    +	$fullpathopeneddir=$dolibarr_main_data_root.'/medias/'.($openeddir != '/' ? $openeddir : '');
    +}
     
     
     // Security:
    @@ -87,20 +106,20 @@ if ($modulepart == 'medias')
      * View
      */
     
    -if (! isset($mode) || $mode != 'noajax')
    +if (! isset($mode) || $mode != 'noajax')	// if ajax mode
     {
     	top_httphead();
     }
     
    -//print '<!-- selecteddir = '.$selecteddir.', openeddir = '.$openeddir.', modulepart='.$modulepart.' -->'."\n";
    +//print '<!-- selecteddir (relative dir we click on) = '.$selecteddir.', openeddir = '.$openeddir.', modulepart='.$modulepart.', preopened='.$preopened.' -->'."\n";
     $userstatic=new User($db);
     $form=new Form($db);
     $ecmdirstatic = new EcmDirectory($db);
     
    -// Load full tree from database. We will use it to define nbofsubdir and nboffilesinsubdir
    +// Load full tree of ECM module from database. We will use it to define nbofsubdir and nboffilesinsubdir
     if (empty($sqltree)) $sqltree=$ecmdirstatic->get_full_arbo(0);
     
    -// Try to find key into $sqltree
    +// Try to find selected dir id into $sqltree and save it into $current_ecmdir_id
     $current_ecmdir_id=-1;
     foreach($sqltree as $keycursor => $val)
     {
    @@ -113,6 +132,25 @@ foreach($sqltree as $keycursor => $val)
     
     if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))
     {
    +
    +/**
    + * treeOutputForAbsoluteDir
    + *
    + * @param array	  $sqltree					Sqltree
    + * @param string  $selecteddir				Selected dir
    + * @param string  $fullpathselecteddir		Full path of selected dir
    + * @param string  $modulepart				Modulepart
    + * @param string  $websitekey				Website key
    + * @param int     $pageid					Page id
    + * @return	void
    + */
    +function treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid)
    +{
    +	global $db, $langs, $form;
    +
    +	$ecmdirstatic = new EcmDirectory($db);
    +	$userstatic = new User($db);
    +
     	if (file_exists($fullpathselecteddir))
     	{
     		$files = @scandir($fullpathselecteddir);
    @@ -172,7 +210,7 @@ if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE
     	    		    		$nboffilesinsubdir=$langs->trans("Unknown");
     						}
     
    -			        	print '<li class="directory collapsed">';
    +			        	print '<li class="directory collapsed">';	// collapsed is opposite if expanded
     
     	    				print "<a class=\"fmdirlia jqft ecmjqft\" href=\"";
     	    				print "#";
    @@ -229,15 +267,30 @@ if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE
     	    				print "</tr></table>\n";
     	                    print '</div>';
     
    +	                    if (0)
    +	                    {
    +	                    	treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid);
    +	                    }
    +
     	                    //print '<div>&nbsp;</div>';
     	    				print "</li>\n";
     	    			}
     	    		}
     
    -	    		// Enable jquery handlers on new generated HTML objects (same code than into lib_footer.js.php)
    -	    		// Because the content is reloaded by ajax call, we must also reenable some jquery hooks
    -				print "\n<!-- JS CODE TO ENABLE Tooltips on all object with class classfortooltip (reload into ajaxdirtree) -->\n";
    -	    		print '<script type="text/javascript">
    +	    		echo "</ul>\n";
    +
    +	    	}
    +	    }
    +	    else print "PermissionDenied";
    +	}
    +}
    +
    +	treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid);
    +
    +	// Enable jquery handlers on new generated HTML objects (same code than into lib_footer.js.php)
    +	// Because the content is reloaded by ajax call, we must also reenable some jquery hooks
    +	print "\n<!-- JS CODE TO ENABLE Tooltips on all object with class classfortooltip (reload into ajaxdirtree) -->\n";
    +	print '<script type="text/javascript">
     	            	jQuery(document).ready(function () {
     	            		jQuery(".classfortooltip").tooltip({
     							show: { collision: "flipfit", effect:\'toggle\', delay:50 },
    @@ -250,13 +303,6 @@ if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE
     	            	});
     	            	</script>';
     
    -	    		echo "</ul>\n";
    -
    -	    	}
    -	    }
    -	    else print "PermissionDenied";
    -	}
    -
     	// This ajax service is called only when a directory $selecteddir is opened but not when closed.
     	//print '<script language="javascript">';
     	//print "loadandshowpreview('".dol_escape_js($selecteddir)."');";
    diff --git a/htdocs/core/tpl/filemanager.tpl.php b/htdocs/core/tpl/filemanager.tpl.php
    index 8ca6b6f215a..adc594e780f 100644
    --- a/htdocs/core/tpl/filemanager.tpl.php
    +++ b/htdocs/core/tpl/filemanager.tpl.php
    @@ -111,7 +111,7 @@ if ((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABL
     		<?php
     	}
     
    -	$sectiondir=GETPOST('file','alpha');
    +	$sectiondir=GETPOST('file','alpha')?GETPOST('file','alpha'):GETPOST('section_dir','alpha');
     	print '<!-- Start form to attach new file in filemanager.tpl.php sectionid='.$section.' sectiondir='.$sectiondir.' -->'."\n";
     	include_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
         $formfile=new FormFile($db);
    @@ -168,14 +168,14 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
     
         	print '<tr><td>';
     
    -    	// Show filemanager tree (will be filled by call of ajax /ecm/tpl/enablefiletreeajax.tpl.php that execute ajaxdirtree.php)
    +    	// Show filemanager tree (will be filled by a call of ajax /ecm/tpl/enablefiletreeajax.tpl.php, later, that executes ajaxdirtree.php)
     	    print '<div id="filetree" class="ecmfiletree"></div>';
     
     	    if ($action == 'deletefile') print $form->formconfirm('eeeee', $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 'deletefile');
     
     	    print '</td></tr>';
         }
    -    else
    +    else	// Show filtree when ajax is disabled (rare)
         {
             print '<tr><td style="padding-left: 20px">';
     
    @@ -186,6 +186,9 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
             // Show filemanager tree (will be filled by direct include of ajaxdirtree.php in mode noajax, this will return all dir - all levels - to show)
             print '<div id="filetree" class="ecmfiletree">';
     
    +        // Variables that may be defined:
    +        // $_GET['modulepart'], $_GET['openeddir'], $_GET['sortfield'], $_GET['sortorder']
    +        // $_POST['dir']
             $mode='noajax';
             if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
             include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirtree.php';
    @@ -211,7 +214,7 @@ if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg
     
     $mode='noajax';
     if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php';
    -include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php';
    +include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php';	// Show content of a directory on right side
     
     
     // End right panel
    @@ -224,7 +227,15 @@ include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php';
     <?php
     
     
    -if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) {
    +if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) // Show filtree when ajax is enabled
    +{
    +	//var_dump($modulepart);
    +	// Variables that may be defined:
    +	// $_GET['modulepart'], $_GET['openeddir'], $_GET['sortfield'], $_GET['sortorder']
    +	// $_POST['dir']
    +	// $_POST['section_dir'], $_POST['section_id'], $_POST['token'], $_POST['max_file_size'], $_POST['sendit']
    +	if (GETPOST('section_dir','alpha')) { $preopened=GETPOST('section_dir','alpha'); }
    +
     	include DOL_DOCUMENT_ROOT.'/ecm/tpl/enablefiletreeajax.tpl.php';
     }
     
    diff --git a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
    index b7c20e33d2d..c47ca3e40ba 100644
    --- a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
    +++ b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
    @@ -27,7 +27,7 @@ if (empty($conf) || ! is_object($conf))
     ?>
     
     <!-- BEGIN PHP TEMPLATE ecm/tpl/enablefiletreeajax.tpl.php -->
    -<!-- Doc of fileTree plugin at https://www.abeautifulsite.net/jquery-file-tree:  http://www.abeautifulsite.net/blog/2008/03/jquery-file-tree/ -->
    +<!-- Doc of fileTree plugin at https://www.abeautifulsite.net/jquery-file-tree -->
     
     <script type="text/javascript">
     
    @@ -35,7 +35,9 @@ if (empty($conf) || ! is_object($conf))
     if (empty($module)) $module='ecm';
     $paramwithoutsection=preg_replace('/&?section=(\d+)/', '', $param);
     
    -$openeddir='/';
    +$openeddir='/';		// The root directory shown
    +// $preopened		// The dir to have preopened
    +
     ?>
     
     $(document).ready(function() {
    @@ -43,7 +45,7 @@ $(document).ready(function() {
     	$('#filetree').fileTree({
     		root: '<?php print dol_escape_js($openeddir); ?>',
     		// Ajax called if we click to expand a dir (not a file). Parameter 'dir' is provided as a POST parameter by fileTree code to this following URL.
    -		script: '<?php echo DOL_URL_ROOT.'/core/ajax/ajaxdirtree.php?modulepart='.$module.'&openeddir='.urlencode($openeddir).(empty($paramwithoutsection)?'':$paramwithoutsection); ?>',
    +		script: '<?php echo DOL_URL_ROOT.'/core/ajax/ajaxdirtree.php?modulepart='.$module.(empty($preopened)?'':'&preopened='.urlencode($preopened)).'&openeddir='.urlencode($openeddir).(empty($paramwithoutsection)?'':$paramwithoutsection); ?>',
     		folderEvent: 'click',	// 'dblclick'
     		multiFolder: false  },
     		// Called if we click on a file (not a dir)
    
    From b0e24e2b8deefd8916a7bc194972a87f1cde23c5 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Thu, 18 Oct 2018 21:24:06 +0200
    Subject: [PATCH 331/433] use strict comparaison
    
    ---
     htdocs/core/login/functions_openid.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/core/login/functions_openid.php b/htdocs/core/login/functions_openid.php
    index 83543c43dd5..79cf1a09cb9 100644
    --- a/htdocs/core/login/functions_openid.php
    +++ b/htdocs/core/login/functions_openid.php
    @@ -70,7 +70,7 @@ function check_user_password_openid($usertotest,$passwordtotest,$entitytotest)
             $openid = new SimpleOpenID();
             $openid->SetIdentity($_GET['openid_identity']);
             $openid_validation_result = $openid->ValidateWithServer();
    -        if ($openid_validation_result == true)
    +        if ($openid_validation_result === true)
             {
                 // OK HERE KEY IS VALID
     
    @@ -90,7 +90,7 @@ function check_user_password_openid($usertotest,$passwordtotest,$entitytotest)
                     }
                 }
             }
    -        else if($openid->IsError() == true)
    +        else if($openid->IsError() === true)
             {
                 // ON THE WAY, WE GOT SOME ERROR
                 $error = $openid->GetError();
    
    From 6c85fbbc303d33c3fc19c18a56dc9864a983cc25 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= <frederic.france@free.fr>
    Date: Thu, 18 Oct 2018 21:47:10 +0200
    Subject: [PATCH 332/433] add log and comment
    
    ---
     .../core/class/commondocgenerator.class.php   |  5 +++
     .../doc/doc_generic_order_odt.modules.php     | 45 +++++++++++--------
     .../modules/commande/modules_commande.php     |  4 --
     3 files changed, 32 insertions(+), 22 deletions(-)
    
    diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php
    index f75ced719a1..9c23badcf02 100644
    --- a/htdocs/core/class/commondocgenerator.class.php
    +++ b/htdocs/core/class/commondocgenerator.class.php
    @@ -38,6 +38,11 @@ abstract class CommonDocGenerator
     	 */
     	public $error='';
     
    +    /**
    +     * @var string[]    Array of error strings
    +     */
    +    public $errors = array();
    +
     	/**
          * @var DoliDB Database handler.
          */
    diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
    index 3839edb85c1..dff597c5593 100644
    --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
    +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
    @@ -4,21 +4,22 @@
      * Copyright (C) 2014		Marcos García		<marcosgdf@gmail.com>
      * Copyright (C) 2016		Charlie Benke		<charlie@patas-monkey.com>
      * Copyright (C) 2018       Philippe Grand      <philippe.grand@atoo-net.com>
    -*
    -* This program is free software; you can redistribute it and/or modify
    -* it under the terms of the GNU General Public License as published by
    -* the Free Software Foundation; either version 3 of the License, or
    -* (at your option) any later version.
    -*
    -* This program is distributed in the hope that it will be useful,
    -* but WITHOUT ANY WARRANTY; without even the implied warranty of
    -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -* GNU General Public License for more details.
    -*
    -* You should have received a copy of the GNU General Public License
    -* along with this program. If not, see <http://www.gnu.org/licenses/>.
    -* or see http://www.gnu.org/
    -*/
    + * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; either version 3 of the License, or
    + * (at your option) any later version.
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    + * GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    + * or see http://www.gnu.org/
    + */
     
     /**
      *	\file       htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php
    @@ -46,7 +47,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     	public $emetteur;
     
     	/**
    -   * @var array() Minimum version of PHP required by module.
    +   * @var array Minimum version of PHP required by module.
     	 * e.g.: PHP ≥ 5.4 = array(5, 4)
        */
     	public $phpmin = array(5, 4);
    @@ -351,6 +352,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     				catch(Exception $e)
     				{
     					$this->error=$e->getMessage();
    +					dol_syslog($e->getMessage(), LOG_INFO);
     					return -1;
     				}
     				// After construction $odfHandler->contentXml contains content and
    @@ -366,6 +368,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     				}
     				catch(OdfException $e)
     				{
    +                    dol_syslog($e->getMessage(), LOG_INFO);
     				}
     
     				// Define substitution array
    @@ -402,6 +405,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     				// Replace tags of lines
    @@ -434,9 +438,11 @@ class doc_generic_order_odt extends ModelePDFCommandes
     								}
     								catch(OdfException $e)
     								{
    +                                    dol_syslog($e->getMessage(), LOG_INFO);
     								}
     								catch(SegmentException $e)
     								{
    +                                    dol_syslog($e->getMessage(), LOG_INFO);
     								}
     							}
     							$listlines->merge();
    @@ -460,6 +466,7 @@ class doc_generic_order_odt extends ModelePDFCommandes
     					}
     					catch(OdfException $e)
     					{
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     					}
     				}
     
    @@ -473,7 +480,8 @@ class doc_generic_order_odt extends ModelePDFCommandes
     					try {
     						$odfHandler->exportAsAttachedPDF($file);
     					}catch (Exception $e){
    -						$this->error=$e->getMessage();
    +                        $this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    @@ -481,7 +489,8 @@ class doc_generic_order_odt extends ModelePDFCommandes
     					try {
     					$odfHandler->saveToDisk($file);
     					}catch (Exception $e){
    -						$this->error=$e->getMessage();
    +                        $this->error=$e->getMessage();
    +                        dol_syslog($e->getMessage(), LOG_INFO);
     						return -1;
     					}
     				}
    diff --git a/htdocs/core/modules/commande/modules_commande.php b/htdocs/core/modules/commande/modules_commande.php
    index 1a4b732246d..7a1ffea8792 100644
    --- a/htdocs/core/modules/commande/modules_commande.php
    +++ b/htdocs/core/modules/commande/modules_commande.php
    @@ -39,10 +39,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
      */
     abstract class ModelePDFCommandes extends CommonDocGenerator
     {
    -	/**
    -	 * @var string Error code (or message)
    -	 */
    -	public $error='';
     
         // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
         /**
    
    From 32a3779d23630237c5d820f0ba0f8432b4328817 Mon Sep 17 00:00:00 2001
    From: Mavyre <bastien.vide@gmail.com>
    Date: Thu, 18 Oct 2018 22:08:23 +0200
    Subject: [PATCH 333/433] Fixed all ressources displaying
    
    ---
     htdocs/core/tpl/resource_add.tpl.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/tpl/resource_add.tpl.php b/htdocs/core/tpl/resource_add.tpl.php
    index 688d3aba221..f9daffe33ed 100644
    --- a/htdocs/core/tpl/resource_add.tpl.php
    +++ b/htdocs/core/tpl/resource_add.tpl.php
    @@ -28,7 +28,7 @@ $out .= '<input type="hidden" name="resource_type" value="'.(empty($resource_typ
     $out .= '<div class="tagtd">'.$langs->trans("SelectResource").'</div>';
     $out .= '<div class="tagtd">';
     $events=array();
    -$out .= $formresources->select_resource_list('','fk_resource','',1,1,0,$events,'',2);
    +$out .= $formresources->select_resource_list('','fk_resource','',1,1,0,$events,'',2,null);
     $out .= '</div>';
     
     $out .= '<div class="tagtd"><label>'.$langs->trans('Busy').'</label> '.$form->selectyesno('busy',(isset($_POST['busy'])?$_POST['busy']:1),1).'</div>';
    
    From 1714bce8a1fb67b1175e7ef52e45649bce5993a2 Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Fri, 19 Oct 2018 08:53:01 +0200
    Subject: [PATCH 334/433] New: works with variants: - Better function name
    
    ---
     htdocs/variants/class/ProductCombination.class.php | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php
    index 130b18dafc5..c2e378d045d 100644
    --- a/htdocs/variants/class/ProductCombination.class.php
    +++ b/htdocs/variants/class/ProductCombination.class.php
    @@ -330,7 +330,7 @@ class ProductCombination
     		$child->price_autogen = $parent->price_autogen;
     		$child->weight = $parent->weight + $this->variation_weight;
     		$child->weight_units = $parent->weight_units;
    -		$varlabel = $this->getLabelOfCombination($this->fk_product_child);
    +		$varlabel = $this->getCombinationLabel($this->fk_product_child);
     		$child->label = $parent->label.$varlabel;
     
     		if ($child->update($child->id, $user) > 0) {
    @@ -688,9 +688,9 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1";
     	/**
     	 * Return label for combinations
     	 * @param 	int 	$prod_child		id of child
    -	 * @return 	string	combination label
    +	 * @return 	string					combination label
     	 */
    -	public function getLabelOfCombination($prod_child)
    +	public function getCombinationLabel($prod_child)
     	{
     		$label = '';
     		$sql = 'SELECT pav.value AS label';
    
    From 985ab1efda3eda0f48508e8cd2093445d7b54192 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 10:59:34 +0200
    Subject: [PATCH 335/433] FIX delete of a file in file_manager return to same
     dir
    
    ---
     htdocs/core/actions_linkedfiles.inc.php | 23 +++++-----
     htdocs/ecm/index.php                    | 58 +++++++++++++------------
     htdocs/website/index.php                |  2 +-
     3 files changed, 45 insertions(+), 38 deletions(-)
    
    diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php
    index 297f7821599..9724465864b 100644
    --- a/htdocs/core/actions_linkedfiles.inc.php
    +++ b/htdocs/core/actions_linkedfiles.inc.php
    @@ -77,20 +77,23 @@ elseif (GETPOST('linkit','none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     // Delete file/link
     if ($action == 'confirm_deletefile' && $confirm == 'yes')
     {
    -        $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1);	// Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
    -        if (GETPOST('section', 'alpha')) $file = $upload_dir . "/" . $urlfile;	// For a delete of GED module urlfile contains full path from upload_dir
    -        else															// For documents pages, upload_dir contains already path to file from module dir, so we clean path into urlfile.
    +        $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1);				// Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
    +        if (GETPOST('section', 'alpha')) 	// For a delete from the ECM module, upload_dir is ECM root dir and urlfile contains relative path from upload_dir
    +        {
    +        	$file = $upload_dir . (preg_match('/\/$/', $upload_dir) ? '' : '/') . $urlfile;
    +        }
    +        else								// For a delete from the file manager into another module, or from documents pages, upload_dir contains already path to file from module dir, so we clean path into urlfile.
     		{
            		$urlfile=basename($urlfile);
    -			$file = $upload_dir . "/" . $urlfile;
    +       		$file = $upload_dir . (preg_match('/\/$/', $upload_dir) ? '' : '/') . $urlfile;
     			if (! empty($upload_dirold)) $fileold = $upload_dirold . "/" . $urlfile;
     		}
    -        $linkid = GETPOST('linkid', 'int');	// Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP).
    +        $linkid = GETPOST('linkid', 'int');
     
    -        if ($urlfile)
    +        if ($urlfile)		// delete of a file
             {
    -	        $dir = dirname($file).'/';     // Chemin du dossier contenant l'image d'origine
    -	        $dirthumb = $dir.'/thumbs/';   // Chemin du dossier contenant la vignette
    +	        $dir = dirname($file).'/';		// Chemin du dossier contenant l'image d'origine
    +	        $dirthumb = $dir.'/thumbs/';	// Chemin du dossier contenant la vignette (if file is an image)
     
     	        $ret = dol_delete_file($file, 0, 0, 0, (is_object($object)?$object:null));
                 if (! empty($fileold)) dol_delete_file($fileold, 0, 0, 0, (is_object($object)?$object:null));     // Delete file using old path
    @@ -114,7 +117,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes')
                 if ($ret) setEventMessages($langs->trans("FileWasRemoved", $urlfile), null, 'mesgs');
                 else setEventMessages($langs->trans("ErrorFailToDeleteFile", $urlfile), null, 'errors');
             }
    -        elseif ($linkid)
    +        elseif ($linkid)	// delete of external link
             {
                 require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
                 $link = new Link($db);
    @@ -143,7 +146,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes')
             	}
             	else
             	{
    -        		header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id.(!empty($withproject)?'&withproject=1':''));
    +        		header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.(GETPOST('section_dir','alpha')?'&section_dir='.urlencode(GETPOST('section_dir','alpha')):'').(!empty($withproject)?'&withproject=1':''));
             		exit;
             	}
             }
    diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php
    index ae11ebbd479..d2c2424099b 100644
    --- a/htdocs/ecm/index.php
    +++ b/htdocs/ecm/index.php
    @@ -77,6 +77,10 @@ $error=0;
      *	Actions
      */
     
    +// TODO Replace sendit and confirm_deletefile with
    +//$backtopage=$_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid;	// used after a confirm_deletefile into actions_linkedfiles.inc.php
    +//include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
    +
     // Upload file (code similar but different than actions_linkedfiles.inc.php)
     if (GETPOST("sendit",'none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     {
    @@ -113,6 +117,33 @@ if (GETPOST("sendit",'none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     	}
     }
     
    +// Remove file (code similar but different than actions_linkedfiles.inc.php)
    +if ($action == 'confirm_deletefile')
    +{
    +	if (GETPOST('confirm') == 'yes')
    +	{
    +		// GETPOST('urlfile','alpha') is full relative URL from ecm root dir. Contains path of all sections.
    +		//var_dump(GETPOST('urlfile'));exit;
    +
    +		$upload_dir = $conf->ecm->dir_output.($relativepath?'/'.$relativepath:'');
    +		$file = $upload_dir . "/" . GETPOST('urlfile','alpha');
    +
    +		$ret=dol_delete_file($file);	// This include also the delete from file index in database.
    +		if ($ret)
    +		{
    +			setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile','alpha')), null, 'mesgs');
    +			$result=$ecmdir->changeNbOfFiles('-');
    +		}
    +		else
    +		{
    +			setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile','alpha')), null, 'errors');
    +		}
    +
    +		clearstatcache();
    +	}
    +	$action='file_manager';
    +}
    +
     // Add directory
     if ($action == 'add' && $user->rights->ecm->setup)
     {
    @@ -135,33 +166,6 @@ if ($action == 'add' && $user->rights->ecm->setup)
     	clearstatcache();
     }
     
    -// Remove file (code similar but different than actions_linkedfiles.inc.php)
    -if ($action == 'confirm_deletefile')
    -{
    -    if (GETPOST('confirm') == 'yes')
    -    {
    -    	// GETPOST('urlfile','alpha') is full relative URL from ecm root dir. Contains path of all sections.
    -		//var_dump(GETPOST('urlfile'));exit;
    -
    -    	$upload_dir = $conf->ecm->dir_output.($relativepath?'/'.$relativepath:'');
    -    	$file = $upload_dir . "/" . GETPOST('urlfile','alpha');	// Do not use urldecode here ($_GET and $_POST are already decoded by PHP).
    -
    -    	$ret=dol_delete_file($file);	// This include also the delete from file index in database.
    -    	if ($ret)
    -    	{
    -    		setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile','alpha')), null, 'mesgs');
    -    		$result=$ecmdir->changeNbOfFiles('-');
    -    	}
    -    	else
    -    	{
    -    		setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile','alpha')), null, 'errors');
    -    	}
    -
    -    	clearstatcache();
    -    }
    -   	$action='file_manager';
    -}
    -
     // Remove directory
     if ($action == 'confirm_deletesection' && GETPOST('confirm') == 'yes')
     {
    diff --git a/htdocs/website/index.php b/htdocs/website/index.php
    index dc8209bcb01..f2bf4ad1888 100644
    --- a/htdocs/website/index.php
    +++ b/htdocs/website/index.php
    @@ -207,7 +207,7 @@ $htmlheadercontentdefault.='-->'."\n";
      * Actions
      */
     
    -$backtopage=$_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid;	// used after a confirm_deletefile into actions_linkedfiles.inc.php
    +$backtopage=$_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid.(GETPOST('section_dir','alpha')?'&section_dir='.urlencode(GETPOST('section_dir','alpha')):'');	// used after a confirm_deletefile into actions_linkedfiles.inc.php
     include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
     
     if ($action == 'renamefile') $action='file_manager';		// After actions_linkedfiles, if action were renamefile, we set it to 'file_manager'
    
    From 34118bcf200100a63e45853b8349d56d26f33eba Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Fri, 19 Oct 2018 12:02:14 +0200
    Subject: [PATCH 336/433] New: works with variants: - Multiprices compatibility
    
    ---
     .../class/ProductCombination.class.php        | 49 +++++++++++++------
     1 file changed, 35 insertions(+), 14 deletions(-)
    
    diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php
    index c2e378d045d..a0aed832eac 100644
    --- a/htdocs/variants/class/ProductCombination.class.php
    +++ b/htdocs/variants/class/ProductCombination.class.php
    @@ -340,14 +340,33 @@ class ProductCombination
     
     			// MultiPrix
     			if (! empty($conf->global->PRODUIT_MULTIPRICES)) {
    -				$new_type = $parent->multiprices_base_type[1];
    -				$new_min_price = $parent->multiprices_min[1];
    -				$new_psq = $parent->multiprices_recuperableonly[1];
    +				for ($i=1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++)
    +				{
    +					if ($parent->multiprices[$i] != '') {
    +						$new_type = $parent->multiprices_base_type[$i];
    +						$new_min_price = $parent->multiprices_min[$i];
    +						if ($parent->prices_by_qty_list[$i]) {
    +							$new_psq = 1;
    +						} else {
    +							$new_psq = 0;
    +						}
     
    -				if ($new_type == 'TTC') {
    -					$new_price = $parent->multiprices_ttc[1];
    -				} else {
    -					$new_price = $parent->multiprices[1];
    +						if ($new_type == 'TTC') {
    +							$new_price = $parent->multiprices_ttc[$i];
    +						} else {
    +							$new_price = $parent->multiprices[$i];
    +						}
    +
    +						if ($this->variation_price_percentage) {
    +							if ($new_price != 0) {
    +								$new_price *= 1 + ($this->variation_price / 100);
    +							}
    +						} else {
    +							$new_price += $this->variation_price;
    +						}
    +
    +						$child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, $i, $new_npr, $new_psq);
    +					}
     				}
     			} else {
     				$new_type = $parent->price_base_type;
    @@ -359,15 +378,17 @@ class ProductCombination
     				} else {
     					$new_price = $parent->price;
     				}
    -			}
     
    -			if ($this->variation_price_percentage) {
    -				$new_price *= 1 + ($this->variation_price/100);
    -			} else {
    -				$new_price += $this->variation_price;
    -			}
    +				if ($this->variation_price_percentage) {
    +					if ($new_price != 0) {
    +						$new_price *= 1 + ($this->variation_price / 100);
    +					}
    +				} else {
    +					$new_price += $this->variation_price;
    +				}
     
    -			$child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, 1, $new_npr, $new_psq);
    +				$child->updatePrice($new_price, $new_type, $user, $new_vat, $new_min_price, 1, $new_npr, $new_psq);
    +			}
     
     			$this->db->commit();
     
    
    From 696023c1aa2a83b86d7b0540bc8cdec3aa3378dc Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 12:47:59 +0200
    Subject: [PATCH 337/433] NEW Enhancement in the generic file manager
    
    ---
     htdocs/core/actions_linkedfiles.inc.php   |  29 +-
     htdocs/core/ajax/ajaxdirtree.php          | 332 ++++++++++++----------
     htdocs/core/class/html.formfile.class.php |  13 +-
     htdocs/core/tpl/filemanager.tpl.php       |   2 +-
     htdocs/ecm/index.php                      |   3 +-
     htdocs/ecm/tpl/enablefiletreeajax.tpl.php |   3 +-
     6 files changed, 203 insertions(+), 179 deletions(-)
    
    diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php
    index 9724465864b..58f96b7faf1 100644
    --- a/htdocs/core/actions_linkedfiles.inc.php
    +++ b/htdocs/core/actions_linkedfiles.inc.php
    @@ -50,13 +50,17 @@ if (GETPOST('sendit','alpha') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     
     		if (! $error)
     		{
    +			// Define if we have to generate thumbs or not
    +			$generatethumbs = 1;
    +			if (GETPOST('section_dir')) $generatethumbs=0;
    +
     			if (! empty($upload_dirold) && ! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
     			{
    -				$result = dol_add_file_process($upload_dirold, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'));
    +				$result = dol_add_file_process($upload_dirold, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'), null, '', $generatethumbs);
     			}
     			elseif (! empty($upload_dir))
     			{
    -				$result = dol_add_file_process($upload_dir, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'));
    +				$result = dol_add_file_process($upload_dir, 0, 1, 'userfile', GETPOST('savingdocmask', 'alpha'), null, '', $generatethumbs);
     			}
     		}
     	}
    @@ -69,7 +73,7 @@ elseif (GETPOST('linkit','none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
             if (substr($link, 0, 7) != 'http://' && substr($link, 0, 8) != 'https://' && substr($link, 0, 7) != 'file://') {
                 $link = 'http://' . $link;
             }
    -        dol_add_file_process($upload_dir, 0, 1, 'userfile', null, $link);
    +        dol_add_file_process($upload_dir, 0, 1, 'userfile', null, $link, '', 0);
         }
     }
     
    @@ -211,13 +215,20 @@ elseif ($action == 'renamefile' && GETPOST('renamefilesave','alpha'))
     	            		$result = dol_move($srcpath, $destpath);
     			            if ($result)
     			            {
    -			            	if ($object->id)
    -			            	{
    -			                	$object->addThumbs($destpath);
    -			            	}
    +			            	// Define if we have to generate thumbs or not
    +			            	$generatethumbs = 1;
    +			            	if (GETPOST('section_dir')) $generatethumbs=0;
     
    -			                // TODO Add revert function of addThumbs to remove for old name
    -			                //$object->delThumbs($srcpath);
    +			            	if ($generatethumbs)
    +			            	{
    +				            	if ($object->id)
    +				            	{
    +				                	$object->addThumbs($destpath);
    +				            	}
    +
    +				                // TODO Add revert function of addThumbs to remove thumbs with old name
    +				                //$object->delThumbs($srcpath);
    +			            	}
     
     			                setEventMessages($langs->trans("FileRenamed"), null);
     			            }
    diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php
    index a55df4a1038..fc01474a072 100644
    --- a/htdocs/core/ajax/ajaxdirtree.php
    +++ b/htdocs/core/ajax/ajaxdirtree.php
    @@ -72,12 +72,12 @@ $fullpathselecteddir='<none>';
     if ($modulepart == 'ecm')
     {
     	$fullpathselecteddir=$conf->ecm->dir_output.'/'.($selecteddir != '/' ? $selecteddir : '');
    -	$fullpathopeneddir=$conf->ecm->dir_output.'/'.($openeddir != '/' ? $openeddir : '');
    +	$fullpathpreopened=$conf->ecm->dir_output.'/'.($preopened != '/' ? $preopened : '');
     }
     if ($modulepart == 'medias')
     {
     	$fullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($selecteddir != '/' ? $selecteddir : '');
    -	$fullpathopeneddir=$dolibarr_main_data_root.'/medias/'.($openeddir != '/' ? $openeddir : '');
    +	$fullpathpreopened=$dolibarr_main_data_root.'/medias/'.($preopened != '/' ? $preopened : '');
     }
     
     
    @@ -132,161 +132,9 @@ foreach($sqltree as $keycursor => $val)
     
     if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))
     {
    +	treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid, $preopened, $fullpathpreopened);
     
    -/**
    - * treeOutputForAbsoluteDir
    - *
    - * @param array	  $sqltree					Sqltree
    - * @param string  $selecteddir				Selected dir
    - * @param string  $fullpathselecteddir		Full path of selected dir
    - * @param string  $modulepart				Modulepart
    - * @param string  $websitekey				Website key
    - * @param int     $pageid					Page id
    - * @return	void
    - */
    -function treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid)
    -{
    -	global $db, $langs, $form;
    -
    -	$ecmdirstatic = new EcmDirectory($db);
    -	$userstatic = new User($db);
    -
    -	if (file_exists($fullpathselecteddir))
    -	{
    -		$files = @scandir($fullpathselecteddir);
    -
    -		if ($files)
    -	    {
    -	    	natcasesort($files);
    -	    	if (count($files) > 2)    /* The 2 accounts for . and .. */
    -	    	{
    -	    		echo '<ul class="ecmjqft" style="display: none;">'."\n";
    -
    -	    		// All dirs
    -	    		foreach ($files as $file)    // $file can be '.', '..', or 'My dir' or 'My file'
    -	    		{
    -	    		    if ($file == 'temp') continue;
    -
    -	    	        $nbofsubdir=0;
    -	    	        $nboffilesinsubdir=0;
    -
    -	    	        $val=array();
    -
    -	    	        // Loop on all database entries (sqltree) to find the one matching the subdir found into dir to scan
    -			        foreach($sqltree as $key => $tmpval)
    -			        {
    -	    	            //print "-- key=".$key." - ".$tmpval['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file)."<br>\n";
    -			        	if ($tmpval['fullrelativename'] == (($selecteddir != '/'?$selecteddir.'/':'').$file))		// We found equivalent record into database
    -			            {
    -			                $val=$tmpval;
    -			                $resarray=tree_showpad($sqltree,$key,1);
    -
    -			                // Refresh cache for this subdir
    -			            	if (isset($val['cachenbofdoc']) && $val['cachenbofdoc'] < 0)	// Cache is not up to date, so we update it for this directory t
    -			            	{
    -			            		$result=$ecmdirstatic->fetch($val['id']);
    -			            		$ecmdirstatic->ref=$ecmdirstatic->label;
    -
    -			            		$result=$ecmdirstatic->refreshcachenboffile(0);
    -			            		$val['cachenbofdoc']=$result;
    -			            	}
    -
    -	                        $a=$resarray[0];
    -	                        $nbofsubdir=$resarray[1];
    -	                        $nboffilesinsubdir=$resarray[2];
    -	                        break;
    -			            }
    -			        }
    -
    -	    		    //print 'modulepart='.$modulepart.' fullpathselecteddir='.$fullpathselecteddir.' - val[fullrelativename] (in database)='.$val['fullrelativename'].' - val[id]='.$val['id'].' - is_dir='.dol_is_dir($fullpathselecteddir . $file).' - file='.$file."\n";
    -	    		    if ($file != '.' && $file != '..' && ((! empty($val['fullrelativename']) && $val['id'] >= 0) || dol_is_dir($fullpathselecteddir . (preg_match('/\/$/',$fullpathselecteddir)?'':'/') . $file)))
    -	    		    {
    -						if (empty($val['fullrelativename']))	// If we did not find entry into database, but found a directory (dol_is_dir was ok at previous test)
    -						{
    -	    		    		$val['fullrelativename']=(($selecteddir && $selecteddir != '/')?$selecteddir.'/':'').$file;
    -	    		    		$val['id']=0;
    -	    		    		$val['label']=$file;
    -	    		    		$val['description']='';
    -	    		    		$nboffilesinsubdir=$langs->trans("Unknown");
    -						}
    -
    -			        	print '<li class="directory collapsed">';	// collapsed is opposite if expanded
    -
    -	    				print "<a class=\"fmdirlia jqft ecmjqft\" href=\"";
    -	    				print "#";
    -	    				print "\" rel=\"" . dol_escape_htmltag($val['fullrelativename'].'/') . "\" id=\"fmdirlia_id_".$val['id']."\"";
    -						print " onClick=\"loadandshowpreview('".dol_escape_js($val['fullrelativename'])."',".$val['id'].")";
    -	    				print "\">";
    -	    				print dol_escape_htmltag($file);
    -	    				print "</a>";
    -
    -	    				print '<div class="ecmjqft">';
    -
    -	    				print '<table class="nobordernopadding"><tr>';
    -
    -	    				/*print '<td align="left">';
    -	    				print dol_escape_htmltag($file);
    -	    				print '</td>';*/
    -
    -	    				// Nb of docs
    -	    				print '<td align="right">';
    -	    				print (isset($val['cachenbofdoc']) && $val['cachenbofdoc']  >= 0)?$val['cachenbofdoc']:'&nbsp;';
    -	    				print '</td>';
    -	    				print '<td align="left">';
    -	    				if ($nbofsubdir > 0  && $nboffilesinsubdir > 0) print '<font color="#AAAAAA">+'.$nboffilesinsubdir.'</font> ';
    -	    				print '</td>';
    -
    -	    				// Edit link
    -	    				print '<td align="right" width="18"><a href="';
    -	    				print DOL_URL_ROOT.'/ecm/dir_card.php?module='.urlencode($modulepart).'&section='.$val['id'].'&relativedir='.urlencode($val['fullrelativename']);
    -	    				print '&backtopage='.urlencode($_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid);
    -	    				print '">'.img_edit($langs->trans("Edit").' - '.$langs->trans("View"), 0, 'class="valignmiddle opacitymedium"').'</a></td>';
    -
    -	    				// Add link
    -	    				//print '<td align="right"><a href="'.DOL_URL_ROOT.'/ecm/dir_add_card.php?action=create&amp;catParent='.$val['id'].'">'.img_edit_add().'</a></td>';
    -	    				//print '<td align="right" width="14">&nbsp;</td>';
    -
    -	    				// Info
    -	    				if ($modulepart == 'ecm')
    -	    				{
    -	    					print '<td align="right" width="18">';
    -		    				$userstatic->id=isset($val['fk_user_c'])?$val['fk_user_c']:0;
    -		    				$userstatic->lastname=isset($val['login_c'])?$val['login_c']:0;
    -		    				$htmltooltip='<b>'.$langs->trans("ECMSection").'</b>: '.$val['label'].'<br>';
    -		    				$htmltooltip='<b>'.$langs->trans("Type").'</b>: '.$langs->trans("ECMSectionManual").'<br>';
    -		    				$htmltooltip.='<b>'.$langs->trans("ECMCreationUser").'</b>: '.$userstatic->getNomUrl(1, '', false, 1).'<br>';
    -		    				$htmltooltip.='<b>'.$langs->trans("ECMCreationDate").'</b>: '.(isset($val['date_c'])?dol_print_date($val['date_c'],"dayhour"):$langs->trans("NeedRefresh")).'<br>';
    -		    				$htmltooltip.='<b>'.$langs->trans("Description").'</b>: '.$val['description'].'<br>';
    -		    				$htmltooltip.='<b>'.$langs->trans("ECMNbOfFilesInDir").'</b>: '.((isset($val['cachenbofdoc']) && $val['cachenbofdoc'] >= 0)?$val['cachenbofdoc']:$langs->trans("NeedRefresh")).'<br>';
    -		    				if ($nboffilesinsubdir > 0) $htmltooltip.='<b>'.$langs->trans("ECMNbOfFilesInSubDir").'</b>: '.$nboffilesinsubdir;
    -		    				else $htmltooltip.='<b>'.$langs->trans("ECMNbOfSubDir").'</b>: '.($nbofsubdir >= 0 ? $nbofsubdir : $langs->trans("NeedRefresh")).'<br>';
    -		    				print $form->textwithpicto('',$htmltooltip,1,"info");
    -		    				print "</td>";
    -	    				}
    -
    -	    				print "</tr></table>\n";
    -	                    print '</div>';
    -
    -	                    if (0)
    -	                    {
    -	                    	treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid);
    -	                    }
    -
    -	                    //print '<div>&nbsp;</div>';
    -	    				print "</li>\n";
    -	    			}
    -	    		}
    -
    -	    		echo "</ul>\n";
    -
    -	    	}
    -	    }
    -	    else print "PermissionDenied";
    -	}
    -}
    -
    -	treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid);
    -
    +	// TODO Find a solution to not output this code for each leaf we open
     	// Enable jquery handlers on new generated HTML objects (same code than into lib_footer.js.php)
     	// Because the content is reloaded by ajax call, we must also reenable some jquery hooks
     	print "\n<!-- JS CODE TO ENABLE Tooltips on all object with class classfortooltip (reload into ajaxdirtree) -->\n";
    @@ -472,3 +320,175 @@ if (empty($conf->use_javascript_ajax) || ! empty($conf->global->MAIN_ECM_DISABLE
     
     // Close db if mode is not noajax
     if ((! isset($mode) || $mode != 'noajax') && is_object($db)) $db->close();
    +
    +
    +
    +/**
    + * treeOutputForAbsoluteDir
    + *
    + * @param	array	$sqltree				Sqltree
    + * @param	string	$selecteddir			Selected dir
    + * @param	string	$fullpathselecteddir	Full path of selected dir
    + * @param	string	$modulepart				Modulepart
    + * @param	string	$websitekey				Website key
    + * @param	int		$pageid					Page id
    + * @param	string	$preopened				Current open dir
    + * @param	string	$fullpathpreopened		Full path of current open dir
    + * @param	int		$depth					Depth
    + * @return	void
    + */
    +function treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir, $modulepart, $websitekey, $pageid, $preopened, $fullpathpreopened, $depth=0)
    +{
    +	global $conf, $db, $langs, $form;
    +	global $dolibarr_main_data_root;
    +
    +	$ecmdirstatic = new EcmDirectory($db);
    +	$userstatic = new User($db);
    +
    +	if (file_exists($fullpathselecteddir))
    +	{
    +		$files = @scandir($fullpathselecteddir);
    +
    +		if ($files)
    +		{
    +			natcasesort($files);
    +			if (count($files) > 2)    /* The 2 accounts for . and .. */
    +			{
    +				echo '<ul class="ecmjqft" style="display: none;">'."\n";
    +
    +				// All dirs
    +				foreach ($files as $file)    // $file can be '.', '..', or 'My dir' or 'My file'
    +				{
    +					if ($file == 'temp') continue;
    +
    +					$nbofsubdir=0;
    +					$nboffilesinsubdir=0;
    +
    +					$val=array();
    +
    +					// Loop on all database entries (sqltree) to find the one matching the subdir found into dir to scan
    +					foreach($sqltree as $key => $tmpval)
    +					{
    +						//print "-- key=".$key." - ".$tmpval['fullrelativename']." vs ".(($selecteddir != '/'?$selecteddir.'/':'').$file)."<br>\n";
    +						if ($tmpval['fullrelativename'] == (($selecteddir != '/'?$selecteddir.'/':'').$file))		// We found equivalent record into database
    +						{
    +							$val=$tmpval;
    +							$resarray=tree_showpad($sqltree,$key,1);
    +
    +							// Refresh cache for this subdir
    +							if (isset($val['cachenbofdoc']) && $val['cachenbofdoc'] < 0)	// Cache is not up to date, so we update it for this directory t
    +							{
    +								$result=$ecmdirstatic->fetch($val['id']);
    +								$ecmdirstatic->ref=$ecmdirstatic->label;
    +
    +								$result=$ecmdirstatic->refreshcachenboffile(0);
    +								$val['cachenbofdoc']=$result;
    +							}
    +
    +							$a=$resarray[0];
    +							$nbofsubdir=$resarray[1];
    +							$nboffilesinsubdir=$resarray[2];
    +							break;
    +						}
    +					}
    +
    +					//print 'modulepart='.$modulepart.' fullpathselecteddir='.$fullpathselecteddir.' - val[fullrelativename] (in database)='.$val['fullrelativename'].' - val[id]='.$val['id'].' - is_dir='.dol_is_dir($fullpathselecteddir . $file).' - file='.$file."\n";
    +					if ($file != '.' && $file != '..' && ((! empty($val['fullrelativename']) && $val['id'] >= 0) || dol_is_dir($fullpathselecteddir . (preg_match('/\/$/',$fullpathselecteddir)?'':'/') . $file)))
    +					{
    +						if (empty($val['fullrelativename']))	// If we did not find entry into database, but found a directory (dol_is_dir was ok at previous test)
    +						{
    +							$val['fullrelativename']=(($selecteddir && $selecteddir != '/')?$selecteddir.'/':'').$file;
    +							$val['id']=0;
    +							$val['label']=$file;
    +							$val['description']='';
    +							$nboffilesinsubdir=$langs->trans("Unknown");
    +						}
    +
    +						$collapsedorexpanded='collapsed';
    +						if (preg_match('/^'.preg_quote($val['fullrelativename'].'/', '/').'/', $preopened)) $collapsedorexpanded='expanded';
    +						print '<li class="directory '.$collapsedorexpanded.'">';	// collapsed is opposite if expanded
    +
    +						print "<a class=\"fmdirlia jqft ecmjqft\" href=\"";
    +						print "#";
    +						print "\" rel=\"" . dol_escape_htmltag($val['fullrelativename'].'/') . "\" id=\"fmdirlia_id_".$val['id']."\"";
    +						print " onClick=\"loadandshowpreview('".dol_escape_js($val['fullrelativename'])."',".$val['id'].")";
    +						print "\">";
    +						print dol_escape_htmltag($file);
    +						print "</a>";
    +
    +						print '<div class="ecmjqft">';
    +
    +						print '<table class="nobordernopadding"><tr>';
    +
    +						/*print '<td align="left">';
    +						 print dol_escape_htmltag($file);
    +						 print '</td>';*/
    +
    +						// Nb of docs
    +						print '<td align="right">';
    +						print (isset($val['cachenbofdoc']) && $val['cachenbofdoc']  >= 0)?$val['cachenbofdoc']:'&nbsp;';
    +						print '</td>';
    +						print '<td align="left">';
    +						if ($nbofsubdir > 0  && $nboffilesinsubdir > 0) print '<font color="#AAAAAA">+'.$nboffilesinsubdir.'</font> ';
    +						print '</td>';
    +
    +						// Edit link
    +						print '<td align="right" width="18"><a href="';
    +						print DOL_URL_ROOT.'/ecm/dir_card.php?module='.urlencode($modulepart).'&section='.$val['id'].'&relativedir='.urlencode($val['fullrelativename']);
    +						print '&backtopage='.urlencode($_SERVER["PHP_SELF"].'?file_manager=1&website='.$websitekey.'&pageid='.$pageid);
    +						print '">'.img_edit($langs->trans("Edit").' - '.$langs->trans("View"), 0, 'class="valignmiddle opacitymedium"').'</a></td>';
    +
    +						// Add link
    +						//print '<td align="right"><a href="'.DOL_URL_ROOT.'/ecm/dir_add_card.php?action=create&amp;catParent='.$val['id'].'">'.img_edit_add().'</a></td>';
    +						//print '<td align="right" width="14">&nbsp;</td>';
    +
    +						// Info
    +						if ($modulepart == 'ecm')
    +						{
    +							print '<td align="right" width="18">';
    +							$userstatic->id=isset($val['fk_user_c'])?$val['fk_user_c']:0;
    +							$userstatic->lastname=isset($val['login_c'])?$val['login_c']:0;
    +							$htmltooltip='<b>'.$langs->trans("ECMSection").'</b>: '.$val['label'].'<br>';
    +							$htmltooltip='<b>'.$langs->trans("Type").'</b>: '.$langs->trans("ECMSectionManual").'<br>';
    +							$htmltooltip.='<b>'.$langs->trans("ECMCreationUser").'</b>: '.$userstatic->getNomUrl(1, '', false, 1).'<br>';
    +							$htmltooltip.='<b>'.$langs->trans("ECMCreationDate").'</b>: '.(isset($val['date_c'])?dol_print_date($val['date_c'],"dayhour"):$langs->trans("NeedRefresh")).'<br>';
    +							$htmltooltip.='<b>'.$langs->trans("Description").'</b>: '.$val['description'].'<br>';
    +							$htmltooltip.='<b>'.$langs->trans("ECMNbOfFilesInDir").'</b>: '.((isset($val['cachenbofdoc']) && $val['cachenbofdoc'] >= 0)?$val['cachenbofdoc']:$langs->trans("NeedRefresh")).'<br>';
    +							if ($nboffilesinsubdir > 0) $htmltooltip.='<b>'.$langs->trans("ECMNbOfFilesInSubDir").'</b>: '.$nboffilesinsubdir;
    +							else $htmltooltip.='<b>'.$langs->trans("ECMNbOfSubDir").'</b>: '.($nbofsubdir >= 0 ? $nbofsubdir : $langs->trans("NeedRefresh")).'<br>';
    +							print $form->textwithpicto('',$htmltooltip,1,"info");
    +							print "</td>";
    +						}
    +
    +						print "</tr></table>\n";
    +						print '</div>';
    +
    +						//print 'selecteddir='.$selecteddir.' preopened='.$preopened.' $val[\'fullrelativename\']='.$val['fullrelativename']."<br>\n";
    +						if (preg_match('/^'.preg_quote($val['fullrelativename'].'/', '/').'/', $preopened))
    +						{
    +							//print 'modulepart='.$modulepart.' fullpathselecteddir='.$fullpathselecteddir.' - val[fullrelativename] (in database)='.$val['fullrelativename'].' - val[id]='.$val['id'].' - is_dir='.dol_is_dir($fullpathselecteddir . $file).' - file='.$file."\n";
    +							$newselecteddir = $val['fullrelativename'];
    +							if ($modulepart == 'ecm')
    +							{
    +								$newfullpathselecteddir=$conf->ecm->dir_output.'/'.($val['fullrelativename'] != '/' ? $val['fullrelativename'] : '');
    +							}
    +							if ($modulepart == 'medias')
    +							{
    +								$newfullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($val['fullrelativename'] != '/' ? $val['fullrelativename'] : '');
    +							}
    +
    +							treeOutputForAbsoluteDir($sqltree, $newselecteddir, $newfullpathselecteddir, $modulepart, $websitekey, $pageid, $preopened, $fullpathpreopened, $depth+1);
    +						}
    +
    +						print "</li>\n";
    +					}
    +				}
    +
    +				echo "</ul>\n";
    +
    +			}
    +		}
    +		else print "PermissionDenied";
    +	}
    +}
    +
    diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
    index d47b846ba02..e4c5b9a84b5 100644
    --- a/htdocs/core/class/html.formfile.class.php
    +++ b/htdocs/core/class/html.formfile.class.php
    @@ -1139,7 +1139,6 @@ class FormFile
     				//var_dump($sortfield.' - '.$sortorder);
     				if ($sortfield && $sortorder)	// If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name)
     				{
    -					//var_dump($sortfield);
     					$filearray=dol_sort_array($filearray, $sortfield, $sortorder);
     				}
     			}
    @@ -1258,12 +1257,9 @@ class FormFile
     								if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1';
     
     								$fulllink=$urlwithroot.'/document.php'.($paramlink?'?'.$paramlink:'');
    -								//if (! empty($object->ref))       $fulllink.='&hashn='.$object->ref;		// Hash of file path
    -								//elseif (! empty($object->label)) $fulllink.='&hashc='.$object->label;		// Hash of file content
     
     								print img_picto($langs->trans("FileSharedViaALink"),'object_globe.png').' ';
     								print '<input type="text" class="quatrevingtpercent" id="downloadlink" name="downloadexternallink" value="'.dol_escape_htmltag($fulllink).'">';
    -								//print ' <a href="'.$fulllink.'">'.$langs->trans("Download").'</a>';	// No target here
     							}
     							else
     							{
    @@ -1299,17 +1295,12 @@ class FormFile
     
     							if ($permtoeditline)
     							{
    -								print '<a href="'.(($useinecm == 1)?'#':($url.'?action=editfile&urlfile='.urlencode($filepath).$param)).'" class="editfilelink" rel="'.$filepath.'">'.img_edit('default',0,'class="paddingrightonly"').'</a>';
    +								$paramsectiondir=(in_array($modulepart, array('medias','ecm'))?'&section_dir='.urlencode($relativepath):'');
    +								print '<a href="'.(($useinecm == 1)?'#':($url.'?action=editfile&urlfile='.urlencode($filepath).$paramsectiondir.$param)).'" class="editfilelink" rel="'.$filepath.'">'.img_edit('default',0,'class="paddingrightonly"').'</a>';
     							}
     						}
     						if ($permonobject)
     						{
    -							/*
    -    						if ($file['level1name'] <> $object->id)
    -    							$filepath=$file['level1name'].'/'.$file['name'];
    -    						else
    -    							$filepath=$file['name'];
    -    						*/
     							$useajax=1;
     							if (! empty($conf->dol_use_jmobile)) $useajax=0;
     							if (empty($conf->use_javascript_ajax)) $useajax=0;
    diff --git a/htdocs/core/tpl/filemanager.tpl.php b/htdocs/core/tpl/filemanager.tpl.php
    index adc594e780f..5ee19aa25a8 100644
    --- a/htdocs/core/tpl/filemanager.tpl.php
    +++ b/htdocs/core/tpl/filemanager.tpl.php
    @@ -28,7 +28,7 @@ if (empty($conf) || ! is_object($conf))
     ?>
     
     <!-- BEGIN PHP TEMPLATE core/tpl/filemanager.tpl.php -->
    -<!-- Doc of fileTree plugin at http://www.abeautifulsite.net/blog/2008/03/jquery-file-tree/ -->
    +<!-- Doc of fileTree plugin at https://www.abeautifulsite.net/jquery-file-tree -->
     
     <?php
     
    diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php
    index d2c2424099b..faac5eba10d 100644
    --- a/htdocs/ecm/index.php
    +++ b/htdocs/ecm/index.php
    @@ -109,7 +109,8 @@ if (GETPOST("sendit",'none') && ! empty($conf->global->MAIN_UPLOAD_DOC))
     
     	if (! $error)
     	{
    -	    $res = dol_add_file_process($upload_dir, 0, 1, 'userfile', '', '', '', 0);
    +		$generatethumbs = 0;
    +		$res = dol_add_file_process($upload_dir, 0, 1, 'userfile', '', null, '', $generatethumbs);
     	    if ($res > 0)
     	    {
     	       $result=$ecmdir->changeNbOfFiles('+');
    diff --git a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
    index c47ca3e40ba..5fe466803fb 100644
    --- a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
    +++ b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2012	Regis Houssin	<regis.houssin@capnetworks.com>
    +/* Copyright (C) 2012	Regis Houssin			<regis.houssin@capnetworks.com>
    + * Copyright (C) 2018	Laurent Destailleur 	<eldy@users.sourceforge.net>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    
    From 4bdde9ad56108ff5ef57cb3074dffc6247394676 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 12:51:14 +0200
    Subject: [PATCH 338/433] Update ticketlogs.class.php
    
    ---
     htdocs/ticket/class/ticketlogs.class.php | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/ticket/class/ticketlogs.class.php b/htdocs/ticket/class/ticketlogs.class.php
    index 68ce6481b31..66cecd6eb5e 100644
    --- a/htdocs/ticket/class/ticketlogs.class.php
    +++ b/htdocs/ticket/class/ticketlogs.class.php
    @@ -352,10 +352,12 @@ class Ticketlogs// extends CommonObject
          */
         public function initAsSpecimen()
         {
    +	global $user;
    +	    
             $this->id = 0;
     
             $this->fk_track_id = '';
    -        $this->fk_user_create = 1;
    +        $this->fk_user_create = $user->id;
             $this->datec = '';
             $this->message = '';
         }
    
    From b6e333876ed5fd371e8e51aae8a52585d1bd506c Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 12:56:21 +0200
    Subject: [PATCH 339/433] FIX #9813
    
    ---
     htdocs/societe/class/societe.class.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
    index 0f1e8b3ef15..5ec8198b123 100644
    --- a/htdocs/societe/class/societe.class.php
    +++ b/htdocs/societe/class/societe.class.php
    @@ -3344,6 +3344,7 @@ class Societe extends CommonObject
     		$this->town=empty($conf->global->MAIN_INFO_SOCIETE_TOWN)?'':$conf->global->MAIN_INFO_SOCIETE_TOWN;
     		$this->state_id=empty($conf->global->MAIN_INFO_SOCIETE_STATE)?'':$conf->global->MAIN_INFO_SOCIETE_STATE;
     		$this->region_code=empty($conf->global->MAIN_INFO_SOCIETE_REGION)?'':$conf->global->MAIN_INFO_SOCIETE_REGION;
    +		$this->object=empty($conf->global->MAIN_INFO_SOCIETE_OBJECT)?'':$conf->global->MAIN_INFO_SOCIETE_OBJECT;
     
     		$this->note_private=empty($conf->global->MAIN_INFO_SOCIETE_NOTE)?'':$conf->global->MAIN_INFO_SOCIETE_NOTE;
     
    
    From 762d82f2fef1573ff405f10ad55b92dde237f534 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 13:38:05 +0200
    Subject: [PATCH 340/433] Move declaration into common
    
    ---
     htdocs/compta/facture/class/facture.class.php          | 3 ---
     htdocs/core/class/commonobject.class.php               | 6 ++++++
     htdocs/modulebuilder/template/class/myobject.class.php | 2 +-
     3 files changed, 7 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
    index 3f36cb72830..8861deb058f 100644
    --- a/htdocs/compta/facture/class/facture.class.php
    +++ b/htdocs/compta/facture/class/facture.class.php
    @@ -110,9 +110,6 @@ class Facture extends CommonInvoice
     	public $fk_user_valid;
     
     	public $date;              // Date invoice
    -	public $date_creation;		// Creation date
    -	public $date_validation;	// Validation date
    -	public $date_modification;	// Validation date
     	public $datem;
     	public $ref_client;
     	public $ref_int;
    diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
    index 76e2b1a093a..b0a469b6cae 100644
    --- a/htdocs/core/class/commonobject.class.php
    +++ b/htdocs/core/class/commonobject.class.php
    @@ -399,6 +399,12 @@ abstract class CommonObject
     	public $firstname;
     	public $civility_id;
     
    +	// Dates
    +	public $date_creation;			// Date creation
    +	public $date_validation;		// Date validation
    +	public $date_modification;		// Date last change (tms field)
    +
    +
     
     	// No constructor as it is an abstract class
     
    diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php
    index e6631e0dfc8..9f180343f5b 100644
    --- a/htdocs/modulebuilder/template/class/myobject.class.php
    +++ b/htdocs/modulebuilder/template/class/myobject.class.php
    @@ -93,7 +93,7 @@ class MyObject extends CommonObject
     		'note_private'  =>array('type'=>'html',			'label'=>'NotePrivate',		 'enabled'=>1, 'visible'=>0,  'position'=>62),
     		'date_creation' =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>500),
     	    'tms'           =>array('type'=>'timestamp',    'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>501),
    -		//'date_valid'    =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'position'=>502),
    +		//'date_validation'    =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'position'=>502),
     		'fk_user_creat' =>array('type'=>'integer',      'label'=>'UserAuthor',       'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>510, 'foreignkey'=>'llx_user.rowid'),
     		'fk_user_modif' =>array('type'=>'integer',      'label'=>'UserModif',        'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511),
     		//'fk_user_valid' =>array('type'=>'integer',      'label'=>'UserValidation',        'enabled'=>1, 'visible'=>-1, 'position'=>512),
    
    From 5f309bf155887f48cd3a6a6e3ab5ed56eb83e84f Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 13:38:23 +0200
    Subject: [PATCH 341/433] Update commande.class.php
    
    ---
     htdocs/commande/class/commande.class.php | 3 ---
     1 file changed, 3 deletions(-)
    
    diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php
    index 4f5051f3411..1925b71992e 100644
    --- a/htdocs/commande/class/commande.class.php
    +++ b/htdocs/commande/class/commande.class.php
    @@ -155,9 +155,6 @@ class Commande extends CommonOrder
     	public $demand_reason_id;   // Source reason. Why we receive order (after a phone campaign, ...)
     	public $demand_reason_code;
     	public $date;				// Date commande
    -	public $date_creation;				// Date commande
    -	public $date_validation;				// Date commande
    -	public $date_modification;				// Date commande
       
     	/**
     	 * @deprecated
    
    From c1d25569659de4cc2790304207b4f698e9250e48 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 13:47:18 +0200
    Subject: [PATCH 342/433] Update admin.lang
    
    ---
     htdocs/langs/en_US/admin.lang | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index 4054ca8c254..3acc7c3c046 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -1821,4 +1821,4 @@ DisabledResourceLinkUser=Disable feature to link a resource to users
     DisabledResourceLinkContact=Disable feature to link a resource to contacts
     ConfirmUnactivation=Confirm module reset
     OnMobileOnly=On small screen (smartphone) only
    -DisableProspectCustomerType=Disable the "Prospect/customer" thirdparty type
    +DisableProspectCustomerType=Disable the "Prospect + Customer" third party type (so third party must be Prospect or Customer but can't be both)
    
    From 47abbd3eb2865907d098e97ac1d68adc707d49a6 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 14:23:36 +0200
    Subject: [PATCH 343/433] Fix bad merge
    
    ---
     htdocs/core/actions_massactions.inc.php | 10 ----------
     1 file changed, 10 deletions(-)
    
    diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
    index cb77489d397..696e1135ca9 100644
    --- a/htdocs/core/actions_massactions.inc.php
    +++ b/htdocs/core/actions_massactions.inc.php
    @@ -1017,16 +1017,6 @@ if (! $error && ($massaction == 'delete' || ($action == 'delete' && $confirm ==
     				}
     			}
     
    -			if (in_array($objecttmp->element, array('societe','member'))) $result = $objecttmp->delete($objecttmp->id, $user, 1);
    -			else $result = $objecttmp->delete($user);
    -			if ($result <= 0)
    -			{
    -				setEventMessages($objecttmp->error, $objecttmp->errors, 'errors');
    -				$error++;
    -				break;
    -			}
    -			else $nbok++;
    -
     			if (in_array($objecttmp->element, array('societe','member'))) $result = $objecttmp->delete($objecttmp->id, $user, 1);
     			else $result = $objecttmp->delete($user);
     
    
    From 57ad200ae50f28f95cf9e615543e6ada7e20c570 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 14:43:10 +0200
    Subject: [PATCH 344/433] Fix regression in creating discount
    
    ---
     htdocs/core/class/discount.class.php | 9 +++++++++
     1 file changed, 9 insertions(+)
    
    diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php
    index e1796c38421..b174848cadf 100644
    --- a/htdocs/core/class/discount.class.php
    +++ b/htdocs/core/class/discount.class.php
    @@ -147,8 +147,17 @@ class DiscountAbsolute
             $this->amount_ht=price2num($this->amount_ht);
             $this->amount_tva=price2num($this->amount_tva);
             $this->amount_ttc=price2num($this->amount_ttc);
    +
             $this->tva_tx=price2num($this->tva_tx);
     
    +        $this->multicurrency_amount_ht=price2num($this->multicurrency_amount_ht);
    +        $this->multicurrency_amount_tva=price2num($this->multicurrency_amount_tva);
    +        $this->multicurrency_amount_ttc=price2num($this->multicurrency_amount_ttc);
    +
    +        if (empty($this->multicurrency_amount_ht)) $this->multicurrency_amount_ht=0;
    +        if (empty($this->multicurrency_amount_tva)) $this->multicurrency_amount_tva=0;
    +        if (empty($this->multicurrency_amount_ttc)) $this->multicurrency_amount_ttc=0;
    +
             // Check parameters
             if (empty($this->description))
             {
    
    From b32ffdbbb940095af1152a4d8b6d1ff2d48f5d01 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 14:59:00 +0200
    Subject: [PATCH 345/433] Clean code
    
    ---
     .../compta/paiement/cheque/class/remisecheque.class.php  | 9 +++++----
     1 file changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/compta/paiement/cheque/class/remisecheque.class.php b/htdocs/compta/paiement/cheque/class/remisecheque.class.php
    index ade6895ac41..64d0f8601fa 100644
    --- a/htdocs/compta/paiement/cheque/class/remisecheque.class.php
    +++ b/htdocs/compta/paiement/cheque/class/remisecheque.class.php
    @@ -152,6 +152,8 @@ class RemiseCheque extends CommonObject
     
     		$now=dol_now();
     
    +		dol_syslog("RemiseCheque::Create start", LOG_DEBUG);
    +
     		$this->db->begin();
     
     		$sql = "INSERT INTO ".MAIN_DB_PREFIX."bordereau_cheque (";
    @@ -178,7 +180,6 @@ class RemiseCheque extends CommonObject
     		$sql.= ", ''";
     		$sql.= ")";
     
    -		dol_syslog("RemiseCheque::Create", LOG_DEBUG);
     		$resql = $this->db->query($sql);
     		if ( $resql )
     		{
    @@ -195,7 +196,6 @@ class RemiseCheque extends CommonObject
     				$sql.= " SET ref='(PROV".$this->id.")'";
     				$sql.= " WHERE rowid=".$this->id."";
     
    -				dol_syslog("RemiseCheque::Create", LOG_DEBUG);
     				$resql = $this->db->query($sql);
     				if (! $resql)
     				{
    @@ -242,13 +242,12 @@ class RemiseCheque extends CommonObject
     						if($linetoremise==$lineid) $checkremise=true;
     					}
     
    -					if($checkremise==true)
    +					if ($checkremise)
     					{
     						$sql = "UPDATE ".MAIN_DB_PREFIX."bank";
     						$sql.= " SET fk_bordereau = ".$this->id;
     						$sql.= " WHERE rowid = ".$lineid;
     
    -						dol_syslog("RemiseCheque::Create", LOG_DEBUG);
     						$resql = $this->db->query($sql);
     						if (!$resql)
     						{
    @@ -284,11 +283,13 @@ class RemiseCheque extends CommonObject
             if (! $this->errno)
             {
                 $this->db->commit();
    +            dol_syslog("RemiseCheque::Create end", LOG_DEBUG);
                 return $this->id;
             }
             else
             {
                 $this->db->rollback();
    +            dol_syslog("RemiseCheque::Create end", LOG_DEBUG);
                 return $this->errno;
             }
     	}
    
    From 897a2b09a789901791b146636fa1055ba44be476 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 15:02:54 +0200
    Subject: [PATCH 346/433] Removed scrutinizer warning
    
    ---
     htdocs/core/class/CMailFile.class.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
    index ef8d07dfb45..b3027b90885 100644
    --- a/htdocs/core/class/CMailFile.class.php
    +++ b/htdocs/core/class/CMailFile.class.php
    @@ -1350,10 +1350,10 @@ class CMailFile
     		// Build the list of image extensions
     		$extensions = array_keys($this->image_types);
     
    -
    +		$matches = array();
     		preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches);  // If "xxx.ext" or 'xxx.ext' found
     
    -		if ($matches)
    +		if (! empty($matches))
     		{
     			$i=0;
     			foreach ($matches[1] as $full)
    
    From 4571210bcf348df55d3ba985d39ffce28a9c07ca Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Fri, 19 Oct 2018 15:45:56 +0200
    Subject: [PATCH 347/433] Fix remove deprecated field
    
    ---
     htdocs/accountancy/bookkeeping/card.php | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php
    index 09a3b7ef8f5..567fccaeab1 100644
    --- a/htdocs/accountancy/bookkeeping/card.php
    +++ b/htdocs/accountancy/bookkeeping/card.php
    @@ -629,7 +629,6 @@ if ($action == 'create')
     							print '<input type="text" name="subledger_account" value="'.$line->subledger_account.'">';
     						}
     						print '</td>';
    -						print '<td><input type="text" class="minwidth100" name="label_compte" value="' . $line->label_compte . '"/></td>';
     						print '<td><input type="text" class="minwidth200" name="label_operation" value="' . $line->label_operation. '"/></td>';
     						print '<td align="right"><input type="text" size="6" class="right" name="debit" value="' . price($line->debit) . '"/></td>';
     						print '<td align="right"><input type="text" size="6" class="right" name="credit" value="' . price($line->credit) . '"/></td>';
    
    From c811d5a371d73ffafed21f9214d803a010ffad29 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= <frederic.france@free.fr>
    Date: Fri, 19 Oct 2018 18:20:06 +0200
    Subject: [PATCH 348/433] fix new pdf
    
    ---
     .../core/class/commondocgenerator.class.php   |  85 +++--
     .../commande/doc/pdf_eratosthene.modules.php  | 162 +++++----
     .../facture/doc/pdf_sponge.modules.php        | 317 +++++++++---------
     .../modules/propale/doc/pdf_cyan.modules.php  | 202 ++++++-----
     4 files changed, 379 insertions(+), 387 deletions(-)
    
    diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php
    index c24059ecc05..e25b1525f1a 100644
    --- a/htdocs/core/class/commondocgenerator.class.php
    +++ b/htdocs/core/class/commondocgenerator.class.php
    @@ -1,10 +1,11 @@
     <?php
    -/* Copyright (C) 2003-2005	Rodolphe Quiedeville	<rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2010	Laurent Destailleur	<eldy@users.sourceforge.net>
    - * Copyright (C) 2004		Eric Seigne		<eric.seigne@ryxeo.com>
    - * Copyright (C) 2005-2012	Regis Houssin		<regis.houssin@capnetworks.com>
    - * Copyright (C) 2015       	Marcos García           <marcosgdf@gmail.com>
    - * Copyright (C) 2016       	Charlie Benke           <charlie@patas-monkey.com>
    +/* Copyright (C) 2003-2005	Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2010	Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2004		Eric Seigne             <eric.seigne@ryxeo.com>
    + * Copyright (C) 2005-2012	Regis Houssin           <regis.houssin@capnetworks.com>
    + * Copyright (C) 2015       Marcos García           <marcosgdf@gmail.com>
    + * Copyright (C) 2016       Charlie Benke           <charlie@patas-monkey.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -823,8 +824,8 @@ abstract class CommonDocGenerator
             if (empty($hidebottom)) $pdf->line($x+$l, $y+$h, $x, $y+$h);
             $pdf->line($x, $y+$h, $x, $y);
         }
    -    
    -    
    +
    +
         /**
          *   	uasort callback function to Sort colums fields
          *
    @@ -832,17 +833,16 @@ abstract class CommonDocGenerator
          *   	@param	array			$b    			PDF lines array fields configs
          *      @return	int								Return compare result
          */
    -    function columnSort($a, $b) {
    -        
    +    function columnSort($a, $b)
    +    {
             if(empty($a['rank'])){ $a['rank'] = 0; }
             if(empty($b['rank'])){ $b['rank'] = 0; }
             if ($a['rank'] == $b['rank']) {
                 return 0;
             }
             return ($a['rank'] > $b['rank']) ? -1 : 1;
    -        
         }
    -    
    +
         /**
          *   	Prepare Array Column Field
          *
    @@ -853,34 +853,34 @@ abstract class CommonDocGenerator
          *      @param		int			$hideref			Do not show ref
          *      @return	null
          */
    -    function prepareArrayColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    -        
    +    function prepareArrayColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +    {
             global $conf;
    -        
    +
             $this->defineColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    -        
    -        
    +
    +
             // Sorting
             uasort ( $this->cols, array( $this, 'columnSort' ) );
    -        
    +
             // Positionning
             $curX = $this->page_largeur-$this->marge_droite; // start from right
    -        
    +
             // Array witdh
             $arrayWidth = $this->page_largeur-$this->marge_droite-$this->marge_gauche;
    -        
    +
             // Count flexible column
             $totalDefinedColWidth = 0;
             $countFlexCol = 0;
             foreach ($this->cols as $colKey =>& $colDef)
             {
                 if(!$this->getColumnStatus($colKey)) continue; // continue if desable
    -            
    +
                 if(!empty($colDef['scale'])){
                     // In case of column widht is defined by percentage
                     $colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100 );
                 }
    -            
    +
                 if(empty($colDef['width'])){
                     $countFlexCol++;
                 }
    @@ -888,7 +888,7 @@ abstract class CommonDocGenerator
                     $totalDefinedColWidth += $colDef['width'];
                 }
             }
    -        
    +
             foreach ($this->cols as $colKey =>& $colDef)
             {
                 // setting empty conf with default
    @@ -898,7 +898,7 @@ abstract class CommonDocGenerator
                 else{
                     $colDef['title'] = $this->defaultTitlesFieldsStyle;
                 }
    -            
    +
                 // setting empty conf with default
                 if(!empty($colDef['content'])){
                     $colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']);
    @@ -906,14 +906,14 @@ abstract class CommonDocGenerator
                 else{
                     $colDef['content'] = $this->defaultContentsFieldsStyle;
                 }
    -            
    +
                 if($this->getColumnStatus($colKey))
                 {
                     // In case of flexible column
                     if(empty($colDef['width'])){
                         $colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol;
                     }
    -                
    +
                     // Set positions
                     $lastX = $curX;
                     $curX = $lastX - $colDef['width'];
    @@ -922,7 +922,7 @@ abstract class CommonDocGenerator
                 }
             }
         }
    -    
    +
         /**
          *   	get column content width from column key
          *
    @@ -934,8 +934,8 @@ abstract class CommonDocGenerator
             $colDef = $this->cols[$colKey];
             return  $colDef['width'] - $colDef['content']['padding'][3] - $colDef['content']['padding'][1];
         }
    -    
    -    
    +
    +
         /**
          *   	get column content X (abscissa) left position from column key
          *
    @@ -947,7 +947,7 @@ abstract class CommonDocGenerator
             $colDef = $this->cols[$colKey];
             return  $colDef['xStartPos'] + $colDef['content']['padding'][3];
         }
    -    
    +
         /**
          *   	get column position rank from column key
          *
    @@ -959,7 +959,7 @@ abstract class CommonDocGenerator
             if(!isset($this->cols[$colKey]['rank'])) return -1;
             return  $this->cols[$colKey]['rank'];
         }
    -    
    +
         /**
          *   	get column position rank from column key
          *
    @@ -973,21 +973,21 @@ abstract class CommonDocGenerator
         {
             // prepare wanted rank
             $rank = -1;
    -        
    +
             // try to get rank from target column
             if(!empty($targetCol)){
                 $rank = $this->getColumnRank($targetCol);
                 if($rank>=0 && $insertAfterTarget){ $rank++; }
             }
    -        
    +
             // get rank from new column definition
             if($rank<0 && !empty($defArray['rank'])){
                 $rank = $defArray['rank'];
             }
    -        
    +
             // error: no rank
             if($rank<0){ return -1; }
    -        
    +
             foreach ($this->cols as $colKey =>& $colDef)
             {
                 if( $rank <= $colDef['rank'])
    @@ -995,14 +995,14 @@ abstract class CommonDocGenerator
                     $colDef['rank'] = $colDef['rank'] + 1;
                 }
             }
    -        
    +
             $defArray['rank'] = $rank;
             $this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys
    -        
    +
             return $rank;
         }
    -    
    -    
    +
    +
         /**
          *   	print standard column content
          *
    @@ -1015,7 +1015,7 @@ abstract class CommonDocGenerator
         function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '')
         {
             global $hookmanager;
    -        
    +
             $parameters=array(
                 'object' => $object,
                 'curY' =>& $curY,
    @@ -1031,10 +1031,9 @@ abstract class CommonDocGenerator
                 $colDef = $this->cols[$colKey];
                 $pdf->MultiCell( $this->getColumnContentWidth($colKey),2, $columnText,'',$colDef['content']['align']);
             }
    -        
         }
    -    
    -    
    +
    +
         /**
          *   	get column status from column key
          *
    diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    index 039f29fa379..1bd98f846cf 100644
    --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    @@ -7,6 +7,7 @@
      * Copyright (C) 2012       Cedric Salvador     <csalvador@gpcsolutions.fr>
      * Copyright (C) 2015       Marcos García       <marcosgdf@gmail.com>
      * Copyright (C) 2017       Ferran Marcet       <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -67,7 +68,7 @@ class pdf_eratosthene extends ModelePDFCommandes
         public $type;
     
     	/**
    -     * @var array() Minimum version of PHP required by module.
    +     * @var array Minimum version of PHP required by module.
     	 * e.g.: PHP ≥ 5.3 = array(5, 3)
          */
     	public $phpmin = array(5, 2);
    @@ -136,7 +137,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     
     		// Define position of columns
     		$this->posxdesc=$this->marge_gauche+1;
    -		
    +
     
     		$this->tva=array();
     		$this->localtax1=array();
    @@ -145,7 +146,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     		$this->atleastonediscount=0;
     	}
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Function to build pdf onto disk
          *
          *  @param		Object		$object				Object to generate
    @@ -156,8 +158,9 @@ class pdf_eratosthene extends ModelePDFCommandes
          *  @param		int			$hideref			Do not show ref
          *  @return     int             			    1=OK, 0=KO
     	 */
    -	function write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
    +	public function write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
     	{
    +        // phpcs:enable
     		global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblignes;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
    @@ -252,7 +255,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     				        break;
     				    }
     				}
    -				
    +
     				if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS))
     				{
     					$this->posxpicture+=($this->postotalht - $this->posxdiscount);
    @@ -316,25 +319,25 @@ class pdf_eratosthene extends ModelePDFCommandes
     				{
     				    $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
     				    $pageposbeforenote = $pagenb;
    -				    
    +
     				    $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
     				    complete_substitutions_array($substitutionarray, $outputlangs, $object);
     				    $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
    -				    
    +
     					$tab_top -= 2;
    -				    
    +
     				    $pdf->startTransaction();
    -				    
    +
     				    $pdf->SetFont('','', $default_font_size - 1);
     				    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     				    // Description
     				    $pageposafternote=$pdf->getPage();
     				    $posyafter = $pdf->GetY();
    -				    
    +
     				    if($pageposafternote>$pageposbeforenote )
     				    {
     				        $pdf->rollbackTransaction(true);
    -				        
    +
     				        // prepar pages to receive notes
     				        while ($pagenb < $pageposafternote) {
     				            $pdf->AddPage();
    @@ -346,16 +349,16 @@ class pdf_eratosthene extends ModelePDFCommandes
     				            // The only function to edit the bottom margin of current page to set it.
     				            $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     				        }
    -				        
    +
     				        // back to start
     				        $pdf->setPage($pageposbeforenote);
     				        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     				        $pdf->SetFont('','', $default_font_size - 1);
     				        $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     				        $pageposafternote=$pdf->getPage();
    -				        
    +
     				        $posyafter = $pdf->GetY();
    -				        
    +
     				        if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
     				        {
     				            $pdf->AddPage('','',true);
    @@ -367,14 +370,14 @@ class pdf_eratosthene extends ModelePDFCommandes
     				            $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     				            //$posyafter = $tab_top_newpage;
     				        }
    -				        
    -				        
    +
    +
     				        // apply note frame to previus pages
     				        $i = $pageposbeforenote;
     				        while ($i < $pageposafternote) {
     				            $pdf->setPage($i);
    -				            
    -				            
    +
    +
     				            $pdf->SetDrawColor(128,128,128);
     				            // Draw note frame
     				            if($i>$pageposbeforenote){
    @@ -385,21 +388,21 @@ class pdf_eratosthene extends ModelePDFCommandes
     				                $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
     				                $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
     				            }
    -				            
    +
     				            // Add footer
     				            $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
     				            $this->_pagefoot($pdf,$object,$outputlangs,1);
    -				            
    +
     				            $i++;
     				        }
    -				        
    +
     				        // apply note frame to last page
     				        $pdf->setPage($pageposafternote);
     				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     				        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     				        $height_note=$posyafter-$tab_top_newpage;
     				        $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
    -				        
    +
     				    }
     				    else // No pagebreak
     				    {
    @@ -407,8 +410,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     				        $posyafter = $pdf->GetY();
     				        $height_note=$posyafter-$tab_top;
     				        $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
    -				        
    -				        
    +
    +
     				        if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
     				        {
     				            // not enough space, need to add page
    @@ -418,12 +421,12 @@ class pdf_eratosthene extends ModelePDFCommandes
     				            $pdf->setPage($pageposafternote);
     				            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     				            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    -				            
    +
     				            $posyafter = $tab_top_newpage;
     				        }
    -				        
    +
     				    }
    -				    
    +
     				    $tab_height = $tab_height - $height_note;
     				    $tab_top = $posyafter +6;
     				}
    @@ -435,10 +438,10 @@ class pdf_eratosthene extends ModelePDFCommandes
     				$iniY = $tab_top + 7;
     				$curY = $tab_top + 7;
     				$nexY = $tab_top + 7;
    -				
    +
     				// Use new auto collum system
     				$this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    -				
    +
     				// Loop on each lines
     				$pageposbeforeprintlines=$pdf->getPage();
     				$pagenb = $pageposbeforeprintlines;
    @@ -456,7 +459,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					$curX = $this->posxdesc-1;
     
     					$showpricebeforepagebreak=1;
    -					
    +
     					if($this->getColumnStatus('desc'))
     					{
         					$pdf->startTransaction();
    @@ -493,7 +496,7 @@ class pdf_eratosthene extends ModelePDFCommandes
         					}
         					$posYAfterDescription=$pdf->GetY();
     					}
    -					
    +
     					$nexY = $pdf->GetY();
     					$pageposafter=$pdf->getPage();
     
    @@ -515,7 +518,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Unit price before discount
     					if ($this->getColumnStatus('subprice'))
     					{
    @@ -523,7 +526,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Quantity
     					// Enough for 6 chars
     					if ($this->getColumnStatus('qty'))
    @@ -532,8 +535,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    -					
    +
    +
     					// Unit
     					if ($this->getColumnStatus('unit'))
     					{
    @@ -541,7 +544,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Discount on line
     					if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
     					{
    @@ -549,7 +552,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Total HT line
     					if ($this->getColumnStatus('totalexcltax'))
     					{
    @@ -557,8 +560,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    -					
    +
    +
     					$parameters=array(
     					    'object' => $object,
     					    'i' => $i,
    @@ -569,7 +572,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    'hidedetails' => $hidedetails
     					);
     					$reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this);    // Note that $object may have been modified by hook
    -					
    +
     
     					// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
     					if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva;
    @@ -664,16 +667,16 @@ class pdf_eratosthene extends ModelePDFCommandes
     				$bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
     
     				// Affiche zone infos
    -				$posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
    +				$posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
     
     				// Affiche zone totaux
    -				$posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
    +				$posy=$this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
     
     				// Affiche zone versements
     				/*
     				if ($deja_regle)
     				{
    -					$posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs);
    +					$posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
     				}
     				*/
     
    @@ -720,9 +723,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *	@param	Translate	$outputlangs	Object langs for output
     	 *	@return int							<0 if KO, >0 if OK
     	 */
    -	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
    +	private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
     	{
    -
     	}
     
     
    @@ -735,7 +737,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *   @param		Translate	$outputlangs	Langs object
     	 *   @return	void
     	 */
    -	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
    +	private function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
     	{
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -922,7 +924,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *	@param	Translate	$outputlangs	Objet langs
     	 *	@return int							Position pour suite
     	 */
    -	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
    +	private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
     	    global $conf,$mysoc;
     
    @@ -1185,7 +1187,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *   @param		string		$currency		Currency code
     	 *   @return	void
     	 */
    -	function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
    +	private function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop=0, $hidebottom=0, $currency='')
     	{
     		global $conf;
     
    @@ -1220,29 +1222,27 @@ class pdf_eratosthene extends ModelePDFCommandes
     		foreach ($this->cols as $colKey => $colDef)
     		{
     		    if(!$this->getColumnStatus($colKey)) continue;
    -		    
    +
     		    // get title label
     		    $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
    -		    
    +
     		    // Add column separator
     		    if(!empty($colDef['border-left'])){
     		        $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
     		    }
    -		    
    +
     		    if (empty($hidetop))
     		    {
     		      $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
    -		    
    +
     		      $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
     		      $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
     		    }
     		}
    -		
    +
     		if (empty($hidetop)){
     			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
     		}
    -
    -		
     	}
     
     	/**
    @@ -1255,7 +1255,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *  @param	string		$titlekey		Translation key to show as title of document
     	 *  @return	void
     	 */
    -	function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey="PdfOrderTitle")
    +	private function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $titlekey="PdfOrderTitle")
     	{
     		global $conf,$langs,$hookmanager;
     
    @@ -1463,15 +1463,15 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *      @param	int			$hidefreetext		1=Hide free text
     	 *      @return	int								Return height of bottom margin including footer text
     	 */
    -	function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
    +	private function _pagefoot(&$pdf,$object,$outputlangs,$hidefreetext=0)
     	{
     		global $conf;
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'ORDER_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -	
     
    -	
    +
    +
     	/**
     	 *   	Define Array Column Field
     	 *
    @@ -1482,22 +1482,22 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *      @param	int			   $hideref			Do not show ref
     	 *      @return	null
     	 */
    -	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    -	    
    +    public function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +    {
     	    global $conf, $hookmanager;
    -	    
    +
     	    // Default field style for content
     	    $this->defaultContentsFieldsStyle = array(
     	        'align' => 'R', // R,C,L
     	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    // Default field style for content
     	    $this->defaultTitlesFieldsStyle = array(
     	        'align' => 'C', // R,C,L
     	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    /*
     	     * For exemple
     	     $this->cols['theColKey'] = array(
    @@ -1515,7 +1515,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	     ),
     	     );
     	     */
    -	    
    +
     	    $rank=0; // do not use negative rank
     	    $this->cols['desc'] = array(
     	        'rank' => $rank,
    @@ -1532,7 +1532,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	            'align' => 'L',
     	        ),
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['photo'] = array(
     	        'rank' => $rank,
    @@ -1547,13 +1547,13 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => false, // remove left line separator
     	    );
    -	    
    +
     	    if (! empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE))
     	    {
     	        $this->cols['photo']['status'] = true;
     	    }
    -	    
    -	    
    +
    +
     	    $rank = $rank + 10;
     	    $this->cols['vat'] = array(
     	        'rank' => $rank,
    @@ -1564,12 +1564,12 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
     	    {
     	        $this->cols['vat']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['subprice'] = array(
     	        'rank' => $rank,
    @@ -1580,7 +1580,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['qty'] = array(
     	        'rank' => $rank,
    @@ -1591,7 +1591,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['progress'] = array(
     	        'rank' => $rank,
    @@ -1602,12 +1602,12 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => false, // add left line separator
     	    );
    -	    
    +
     	    if($this->situationinvoice)
     	    {
     	        $this->cols['progress']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['unit'] = array(
     	        'rank' => $rank,
    @@ -1621,7 +1621,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	    if($conf->global->PRODUCT_USE_UNITS){
     	        $this->cols['unit']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['discount'] = array(
     	        'rank' => $rank,
    @@ -1635,7 +1635,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	    if ($this->atleastonediscount){
     	        $this->cols['discount']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['totalexcltax'] = array(
     	        'rank' => $rank,
    @@ -1646,8 +1646,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    -	    
    +
    +
     	    $parameters=array(
     	        'object' => $object,
     	        'outputlangs' => $outputlangs,
    @@ -1655,7 +1655,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        'hidedesc' => $hidedesc,
     	        'hideref' => $hideref
     	    );
    -	    
    +
     	    $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this);    // Note that $object may have been modified by hook
     	    if ($reshook < 0)
     	    {
    @@ -1669,7 +1669,5 @@ class pdf_eratosthene extends ModelePDFCommandes
     	    {
     	        $this->cols = $hookmanager->resArray;
     	    }
    -	    
     	}
    -	
     }
    diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    index 74f4bf34acf..dc5fbc315cd 100644
    --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    @@ -8,6 +8,7 @@
      * Copyright (C) 2012-2014	Raphaël Doursenaud	<rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2015		Marcos García		<marcosgdf@gmail.com>
      * Copyright (C) 2017		Ferran Marcet		<fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -68,7 +69,7 @@ class pdf_sponge extends ModelePDFFactures
         public $type;
     
     	/**
    -     * @var array() Minimum version of PHP required by module.
    +     * @var array Minimum version of PHP required by module.
     	 * e.g.: PHP ≥ 5.3 = array(5, 3)
          */
     	public $phpmin = array(5, 2);
    @@ -108,7 +109,7 @@ class pdf_sponge extends ModelePDFFactures
     	function __construct($db)
     	{
     		global $conf,$langs,$mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "bills"));
     
    @@ -147,8 +148,8 @@ class pdf_sponge extends ModelePDFFactures
     
     		// Define position of columns
     		$this->posxdesc=$this->marge_gauche+1; // used for notes ans other stuff
    -		
    -		//  Use new system for position of columns, view  $this->defineColumnField() 
    +
    +		//  Use new system for position of columns, view  $this->defineColumnField()
     
     		$this->tva=array();
     		$this->localtax1=array();
    @@ -159,7 +160,8 @@ class pdf_sponge extends ModelePDFFactures
     	}
     
     
    -	/**
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    /**
          *  Function to build pdf onto disk
          *
          *  @param		Object		$object				Object to generate
    @@ -170,30 +172,31 @@ class pdf_sponge extends ModelePDFFactures
          *  @param		int			$hideref			Do not show ref
          *  @return     int         	    			1=OK, 0=KO
     	 */
    -	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
    +	public function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     	    global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
    -	    
    +
     	    if (! is_object($outputlangs)) $outputlangs=$langs;
     	    // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     	    if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -	    
    +
     	    // Translations
     	    $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
    -	    
    +
     	    $nblignes = count($object->lines);
    -	    
    +
     	    // Loop on each lines to detect if there is at least one image to show
     	    $realpatharray=array();
     	    $this->atleastonephoto = false;
     	    if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE))
     	    {
     	        $objphoto = new Product($this->db);
    -	        
    +
     	        for ($i = 0 ; $i < $nblignes ; $i++)
     	        {
     	            if (empty($object->lines[$i]->fk_product)) continue;
    -	            
    +
     	            $objphoto->fetch($object->lines[$i]->fk_product);
     	            //var_dump($objphoto->ref);exit;
     	            if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
    @@ -206,14 +209,14 @@ class pdf_sponge extends ModelePDFFactures
     	                $pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/';				// default
     	                $pdir[1] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/";	// alternative
     	            }
    -	            
    +
     	            $arephoto = false;
     	            foreach ($pdir as $midir)
     	            {
     	                if (! $arephoto)
     	                {
     	                    $dir = $conf->product->dir_output.'/'.$midir;
    -	                    
    +
     	                    foreach ($objphoto->liste_photos($dir,1) as $key => $obj)
     	                    {
     	                        if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES))		// If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
    @@ -231,28 +234,28 @@ class pdf_sponge extends ModelePDFFactures
     	                        {
     	                            $filename=$obj['photo'];
     	                        }
    -	                        
    +
     	                        $realpath = $dir.$filename;
     	                        $arephoto = true;
     	                        $this->atleastonephoto = true;
     	                    }
     	                }
     	            }
    -	            
    +
     	            if ($realpath && $arephoto) $realpatharray[$i]=$realpath;
     	        }
     	    }
    -	    
    +
     	    //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
    -	    
    +
     	    if ($conf->facture->dir_output)
     	    {
     	        $object->fetch_thirdparty();
    -	        
    +
     	        $deja_regle = $object->getSommePaiement(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
     	        $amount_credit_notes_included = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
     	        $amount_deposits_included = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
    -	        
    +
     	        // Definition of $dir and $file
     	        if ($object->specimen)
     	        {
    @@ -273,7 +276,7 @@ class pdf_sponge extends ModelePDFFactures
     	                return 0;
     	            }
     	        }
    -	        
    +
     	        if (file_exists($dir))
     	        {
     	            // Add pdfgeneration hook
    @@ -286,47 +289,47 @@ class pdf_sponge extends ModelePDFFactures
     	            $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
     	            global $action;
     	            $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
    -	            
    +
     	            // Set nblignes with the new facture lines content after hook
     	            $nblignes = count($object->lines);
     	            $nbpayments = count($object->getListOfPayments());
    -	            
    +
     	            // Create pdf instance
     	            $pdf=pdf_getInstance($this->format);
     	            $default_font_size = pdf_getPDFFontSize($outputlangs);	// Must be after pdf_getInstance
     	            $pdf->SetAutoPageBreak(1,0);
    -	            
    +
     	            $heightforinfotot = 50+(4*$nbpayments);	// Height reserved to output the info and total part and payment part
     	            $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5);	// Height reserved to output the free text on last page
     	            $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22);	// Height reserved to output the footer (value include bottom margin)
    -	            
    +
     	            if (class_exists('TCPDF'))
     	            {
     	                $pdf->setPrintHeader(false);
     	                $pdf->setPrintFooter(false);
     	            }
     	            $pdf->SetFont(pdf_getPDFFont($outputlangs));
    -	            
    +
     	            // Set path to the background PDF File
                     if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
     	            {
     	                $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
     	                $tplidx = $pdf->importPage(1);
     	            }
    -	            
    +
     	            $pdf->Open();
     	            $pagenb=0;
     	            $pdf->SetDrawColor(128,128,128);
    -	            
    +
     	            $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
     	            $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle"));
     	            $pdf->SetCreator("Dolibarr ".DOL_VERSION);
     	            $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
     	            $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
     	            if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
    -	            
    +
     	            $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
    -	            
    +
     	            // Does we have at least one line with discount $this->atleastonediscount
     	            foreach ($object->lines as $line) {
     	               if ($line->remise_percent){
    @@ -334,30 +337,30 @@ class pdf_sponge extends ModelePDFFactures
     	                    break;
     	               }
     	            }
    -	            
    -	           
    +
    +
     	            // Situation invoice handling
     	            if ($object->situation_cycle_ref)
     	            {
     	                $this->situationinvoice = true;
     	            }
    -	            
    +
     	            // New page
     	            $pdf->AddPage();
     	            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     	            $pagenb++;
    -	            
    +
     	            $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
     	            $pdf->SetFont('','', $default_font_size - 1);
     	            $pdf->MultiCell(0, 3, '');		// Set interline to 3
     	            $pdf->SetTextColor(0,0,0);
    -	            
    +
     	            $tab_top = 90+$top_shift;
     	            $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
     	            $tab_height = 130-$top_shift;
     	            $tab_height_newpage = 150;
     	            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift;
    -	            
    +
     	            // Incoterm
     	            $height_incoterms = 0;
     	            if ($conf->incoterm->enabled)
    @@ -366,21 +369,21 @@ class pdf_sponge extends ModelePDFFactures
     	                if ($desc_incoterms)
     	                {
     						$tab_top -= 2;
    -	                    
    +
     	                    $pdf->SetFont('','', $default_font_size - 1);
     	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                    $height_incoterms=$nexY-$tab_top;
    -	                    
    +
     	                    // Rect prend une longueur en 3eme param
     	                    $pdf->SetDrawColor(192,192,192);
     	                    $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
    -	                    
    +
     	                    $tab_top = $nexY+6;
     	                    $height_incoterms += 4;
     	                }
     	            }
    -	            
    +
     	            // Affiche notes
     	            $notetoshow=empty($object->note_public)?'':$object->note_public;
     	            if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
    @@ -394,7 +397,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
     	                }
     	            }
    -	            
    +
     	            $pagenb = $pdf->getPage();
     	            if ($notetoshow)
     	            {
    @@ -402,24 +405,24 @@ class pdf_sponge extends ModelePDFFactures
     
     	                $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
     	                $pageposbeforenote = $pagenb;
    -	                
    +
     	                $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
     	                complete_substitutions_array($substitutionarray, $outputlangs, $object);
     	                $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
    -	                
    -	                
    +
    +
     	                $pdf->startTransaction();
    -	                
    +
     	                $pdf->SetFont('','', $default_font_size - 1);
     	                $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     	                // Description
     	                $pageposafternote=$pdf->getPage();
     	                $posyafter = $pdf->GetY();
    -	                
    +
     	                if($pageposafternote>$pageposbeforenote )
     	                {
     	                    $pdf->rollbackTransaction(true);
    -	                    
    +
     	                    // prepar pages to receive notes
     	                    while ($pagenb < $pageposafternote) {
     	                        $pdf->AddPage();
    @@ -431,16 +434,16 @@ class pdf_sponge extends ModelePDFFactures
     	                        // The only function to edit the bottom margin of current page to set it.
     	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     	                    }
    -	                    
    +
     	                    // back to start
     	                    $pdf->setPage($pageposbeforenote);
     	                    $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     	                    $pdf->SetFont('','', $default_font_size - 1);
     	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     	                    $pageposafternote=$pdf->getPage();
    -	                    
    +
     	                    $posyafter = $pdf->GetY();
    -	                    
    +
     	                    if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
     	                    {
     	                        $pdf->AddPage('','',true);
    @@ -452,14 +455,14 @@ class pdf_sponge extends ModelePDFFactures
     	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     	                        //$posyafter = $tab_top_newpage;
     	                    }
    -	                    
    -	                    
    +
    +
     	                    // apply note frame to previus pages
     	                    $i = $pageposbeforenote;
     	                    while ($i < $pageposafternote) {
     	                        $pdf->setPage($i);
    -	                        
    -	                        
    +
    +
     	                        $pdf->SetDrawColor(128,128,128);
     	                        // Draw note frame
     	                        if($i>$pageposbeforenote){
    @@ -470,21 +473,21 @@ class pdf_sponge extends ModelePDFFactures
     	                            $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
     	                            $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
     	                        }
    -	                        
    +
     	                        // Add footer
     	                        $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
     	                        $this->_pagefoot($pdf,$object,$outputlangs,1);
    -	                        
    +
     	                        $i++;
     	                    }
    -	                    
    +
     	                    // apply note frame to last page
     	                    $pdf->setPage($pageposafternote);
     	                    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     	                    if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     	                    $height_note=$posyafter-$tab_top_newpage;
     	                    $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
    -	                    
    +
     	                }
     	                else // No pagebreak
     	                {
    @@ -492,8 +495,8 @@ class pdf_sponge extends ModelePDFFactures
     	                    $posyafter = $pdf->GetY();
     	                    $height_note=$posyafter-$tab_top;
     	                    $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
    -	                    
    -	                    
    +
    +
     	                    if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
     	                    {
     	                        // not enough space, need to add page
    @@ -503,12 +506,12 @@ class pdf_sponge extends ModelePDFFactures
     	                        $pdf->setPage($pageposafternote);
     	                        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     	                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    -	                        
    +
     	                        $posyafter = $tab_top_newpage;
     	                    }
    -	                    
    +
     	                }
    -	                
    +
     	                $tab_height = $tab_height - $height_note;
     	                $tab_top = $posyafter +6;
     	            }
    @@ -516,36 +519,36 @@ class pdf_sponge extends ModelePDFFactures
     	            {
     	                $height_note=0;
     	            }
    -	            
    +
     	            $iniY = $tab_top + 7;
     	            $curY = $tab_top + 7;
     	            $nexY = $tab_top + 7;
    -	            
    +
     	            // Use new auto collum system
     	            $this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    -	            
    +
     	            // Loop on each lines
     	            $pageposbeforeprintlines=$pdf->getPage();
     	            $pagenb = $pageposbeforeprintlines;
     	            for ($i = 0; $i < $nblignes; $i++)
     	            {
    -	                
    +
     	                $curY = $nexY;
     	                $pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
     	                $pdf->SetTextColor(0,0,0);
    -	                
    +
     	                // Define size of image if we need it
     	                $imglinesize=array();
     	                if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]);
    -	                
    +
     	                $pdf->setTopMargin($tab_top_newpage);
     	                $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
     	                $pageposbefore=$pdf->getPage();
    -	                
    +
     	                $showpricebeforepagebreak=1;
     	                $posYAfterImage=0;
     	                $posYAfterDescription=0;
    -	                
    +
     	                if($this->getColumnStatus('photo'))
     	                {
         	                // We start with Photo of product line
    @@ -554,11 +557,11 @@ class pdf_sponge extends ModelePDFFactures
         	                    $pdf->AddPage('','',true);
         	                    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
         	                    $pdf->setPage($pageposbefore+1);
    -    	                    
    +
         	                    $curY = $tab_top_newpage;
         	                    $showpricebeforepagebreak=0;
         	                }
    -    	                
    +
         	                if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
         	                {
         	                    $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300);	// Use 300 dpi
    @@ -566,7 +569,7 @@ class pdf_sponge extends ModelePDFFactures
         	                    $posYAfterImage=$curY+$imglinesize['height'];
         	                }
     	                }
    -	                
    +
     	                // Description of product line
     	                if ($this->getColumnStatus('desc'))
     	                {
    @@ -604,20 +607,20 @@ class pdf_sponge extends ModelePDFFactures
         	                }
         	                $posYAfterDescription=$pdf->GetY();
     	                }
    -	                
    +
     	                $nexY = $pdf->GetY();
     	                $pageposafter=$pdf->getPage();
     	                $pdf->setPage($pageposbefore);
     	                $pdf->setTopMargin($this->marge_haute);
     	                $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    -	                
    +
     	                // We suppose that a too long description or photo were moved completely on next page
     	                if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
    -	                    $pdf->setPage($pageposafter); $curY = $tab_top_newpage; 
    +	                    $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
     	                }
    -	                
    +
     	                $pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
    -	                
    +
     	                // VAT Rate
     	                if ($this->getColumnStatus('vat'))
     	                {
    @@ -625,7 +628,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Unit price before discount
     	                if ($this->getColumnStatus('subprice'))
     	                {
    @@ -633,7 +636,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Quantity
     	                // Enough for 6 chars
     	                if ($this->getColumnStatus('qty'))
    @@ -642,7 +645,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Situation progress
     	                if ($this->getColumnStatus('progress'))
     	                {
    @@ -650,7 +653,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'progress', $progress);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Unit
     	                if ($this->getColumnStatus('unit'))
     	                {
    @@ -658,7 +661,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Discount on line
     	                if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
     	                {
    @@ -666,7 +669,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Total HT line
     	                if ($this->getColumnStatus('totalexcltax'))
     	                {
    @@ -674,8 +677,8 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    -	                
    +
    +
     	                $parameters=array(
     	                    'object' => $object,
     	                    'i' => $i,
    @@ -686,9 +689,9 @@ class pdf_sponge extends ModelePDFFactures
     	                    'hidedetails' => $hidedetails
     	                );
     	                $reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this);    // Note that $object may have been modified by hook
    -	                
    -	                
    -	                
    +
    +
    +
     	                $sign=1;
     	                if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
     	                // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
    @@ -701,20 +704,20 @@ class pdf_sponge extends ModelePDFFactures
     	                    if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne= $sign * $object->lines[$i]->multicurrency_total_tva;
     	                    else $tvaligne= $sign * $object->lines[$i]->total_tva;
     	                }
    -	                
    +
     	                $localtax1ligne=$object->lines[$i]->total_localtax1;
     	                $localtax2ligne=$object->lines[$i]->total_localtax2;
     	                $localtax1_rate=$object->lines[$i]->localtax1_tx;
     	                $localtax2_rate=$object->lines[$i]->localtax2_tx;
     	                $localtax1_type=$object->lines[$i]->localtax1_type;
     	                $localtax2_type=$object->lines[$i]->localtax2_type;
    -	                
    +
     	                if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
     	                if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
     	                if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
    -	                
    +
     	                $vatrate=(string) $object->lines[$i]->tva_tx;
    -	                
    +
     	                // Retrieve type from database for backward compatibility with old records
     	                if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
     	                    && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
    @@ -723,19 +726,19 @@ class pdf_sponge extends ModelePDFFactures
     	                    $localtax1_type = $localtaxtmp_array[0];
     	                    $localtax2_type = $localtaxtmp_array[2];
     	                }
    -	                
    +
     	                // retrieve global local tax
     	                if ($localtax1_type && $localtax1ligne != 0)
     	                    $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
     	                    if ($localtax2_type && $localtax2ligne != 0)
     	                        $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
    -	                        
    +
     	                        if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
     	                        if (! isset($this->tva[$vatrate])) 				$this->tva[$vatrate]=0;
     	                        $this->tva[$vatrate] += $tvaligne;
    -	                        
    +
     	                        $nexY = max($nexY,$posYAfterImage);
    -	                        
    +
     	                        // Add line
     	                        if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
     	                        {
    @@ -745,9 +748,9 @@ class pdf_sponge extends ModelePDFFactures
     	                            $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
     	                            $pdf->SetLineStyle(array('dash'=>0));
     	                        }
    -	                        
    +
     	                        $nexY+=2;    // Passe espace entre les lignes
    -	                        
    +
     	                        // Detect if some page were added automatically and output _tableau for past pages
     	                        while ($pagenb < $pageposafter)
     	                        {
    @@ -766,7 +769,7 @@ class pdf_sponge extends ModelePDFFactures
     	                            $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
     	                            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     	                        }
    -	                        
    +
     	                        if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
     	                        {
     	                            if ($pagenb == $pageposafter)
    @@ -784,9 +787,9 @@ class pdf_sponge extends ModelePDFFactures
     	                            $pagenb++;
     	                            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     	                        }
    -	                  
    +
     	            }
    -	            
    +
     	            // Show square
     	            if ($pagenb == $pageposbeforeprintlines)
     	            {
    @@ -798,38 +801,38 @@ class pdf_sponge extends ModelePDFFactures
     	                $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
     	                $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
     	            }
    -	            
    +
     	            // Affiche zone infos
    -	            $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
    -	            
    +	            $posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
    +
     	            // Affiche zone totaux
    -	            $posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
    -	            
    +	            $posy=$this->drawTotalTable($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
    +
     	            // 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->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
     	            }
    -	            
    +
     	            // Pied de page
     	            $this->_pagefoot($pdf,$object,$outputlangs);
     	            if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages();
    -	            
    +
     	            $pdf->Close();
    -	            
    +
     	            $pdf->Output($file,'F');
    -	            
    +
     	            // Add pdfgeneration hook
     	            $hookmanager->initHooks(array('pdfgeneration'));
     	            $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
     	            global $action;
     	            $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    -	            
    +
     	            if (! empty($conf->global->MAIN_UMASK))
     	                @chmod($file, octdec($conf->global->MAIN_UMASK));
    -	                
    +
     	                $this->result = array('fullpath'=>$file);
    -	                
    +
     	                return 1;   // No error
     	        }
     	        else
    @@ -855,7 +858,7 @@ class pdf_sponge extends ModelePDFFactures
          *  @param  Translate	$outputlangs    Object langs for output
          *  @return int             			<0 if KO, >0 if OK
     	 */
    -	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
    +	function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
     	{
     		global $conf;
     
    @@ -982,7 +985,6 @@ class pdf_sponge extends ModelePDFFactures
     			$this->error=$this->db->lasterror();
     			return -1;
     		}
    -
     	}
     
     
    @@ -995,7 +997,7 @@ class pdf_sponge extends ModelePDFFactures
     	 *   @param		Translate	$outputlangs	Langs object
     	 *   @return	void
     	 */
    -	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
    +	private function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
     	{
     		global $conf;
     
    @@ -1153,7 +1155,7 @@ class pdf_sponge extends ModelePDFFactures
     	 *	@param	Translate	$outputlangs	Objet langs
     	 *	@return int							Position pour suite
     	 */
    -	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
    +	private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
     		global $conf,$mysoc;
     
    @@ -1511,29 +1513,27 @@ class pdf_sponge extends ModelePDFFactures
     		foreach ($this->cols as $colKey => $colDef)
     		{
     		    if(!$this->getColumnStatus($colKey)) continue;
    -		    
    +
     		    // get title label
     		    $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
    -		    
    +
     		    // Add column separator
     		    if(!empty($colDef['border-left'])){
     		        $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
     		    }
    -		    
    +
     		    if (empty($hidetop))
     		    {
     		      $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
    -		    
    +
     		      $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
     		      $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
     		    }
     		}
    -		
    +
     		if (empty($hidetop)){
     			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
     		}
    -
    -		
     	}
     
     	/**
    @@ -1548,7 +1548,7 @@ class pdf_sponge extends ModelePDFFactures
     	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
     	{
     		global $conf, $langs;
    -		
    +
     		// Translations
     		$outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
     
    @@ -1822,9 +1822,9 @@ class pdf_sponge extends ModelePDFFactures
     		return pdf_pagefoot($pdf,$outputlangs,'INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
     
    -	
    -	
    -	
    +
    +
    +
     	/**
     	 *   	Define Array Column Field
     	 *
    @@ -1835,22 +1835,22 @@ class pdf_sponge extends ModelePDFFactures
          *      @param	int			   $hideref			Do not show ref
     	 *      @return	null
     	 */
    -	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    -	    
    +    function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +    {
     	    global $conf, $hookmanager;
    -	    
    +
     	    // Default field style for content
     	    $this->defaultContentsFieldsStyle = array(
     	        'align' => 'R', // R,C,L
     	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    // Default field style for content
     	    $this->defaultTitlesFieldsStyle = array(
    -	        'align' => 'C', // R,C,L 
    +	        'align' => 'C', // R,C,L
     	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    /*
     	     * For exemple
     	    $this->cols['theColKey'] = array(
    @@ -1859,19 +1859,19 @@ class pdf_sponge extends ModelePDFFactures
     	        'title' => array(
     	            'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
     	            'label' => ' ', // the final label : used fore final generated text
    -	            'align' => 'L', // text alignement :  R,C,L 
    +	            'align' => 'L', // text alignement :  R,C,L
     	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	        ),
     	        'content' => array(
    -	            'align' => 'L', // text alignement :  R,C,L 
    +	            'align' => 'L', // text alignement :  R,C,L
     	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	        ),
     	    );
     	    */
    -	    
    +
     	    $rank=0; // do not use negative rank
     	    $this->cols['desc'] = array(
    -	        'rank' => $rank, 
    +	        'rank' => $rank,
     	        'width' => false, // only for desc
     	        'status' => true,
     	        'title' => array(
    @@ -1885,7 +1885,7 @@ class pdf_sponge extends ModelePDFFactures
     	            'align' => 'L',
     	        ),
     	    );
    -	    
    +
     	    // PHOTO
             $rank = $rank + 10;
             $this->cols['photo'] = array(
    @@ -1894,20 +1894,20 @@ class pdf_sponge extends ModelePDFFactures
                 'status' => false,
                 'title' => array(
                     'textkey' => 'Photo',
    -                'label' => ' ' 
    +                'label' => ' '
                 ),
                 'content' => array(
                     'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
                 ),
                 'border-left' => false, // remove left line separator
             );
    -	        
    +
     	    if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto))
     	    {
     	        $this->cols['photo']['status'] = true;
     	    }
    -	    
    -	    
    +
    +
     	    $rank = $rank + 10;
     	    $this->cols['vat'] = array(
     	        'rank' => $rank,
    @@ -1918,12 +1918,12 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
     	    {
     	        $this->cols['vat']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['subprice'] = array(
     	        'rank' => $rank,
    @@ -1934,7 +1934,7 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['qty'] = array(
     	        'rank' => $rank,
    @@ -1945,7 +1945,7 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['progress'] = array(
     	        'rank' => $rank,
    @@ -1956,12 +1956,12 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    if($this->situationinvoice)
     	    {
     	        $this->cols['progress']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['unit'] = array(
     	        'rank' => $rank,
    @@ -1975,7 +1975,7 @@ class pdf_sponge extends ModelePDFFactures
     	    if($conf->global->PRODUCT_USE_UNITS){
     	        $this->cols['unit']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['discount'] = array(
     	        'rank' => $rank,
    @@ -1989,7 +1989,7 @@ class pdf_sponge extends ModelePDFFactures
     	    if ($this->atleastonediscount){
     	        $this->cols['discount']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['totalexcltax'] = array(
     	        'rank' => $rank,
    @@ -2000,8 +2000,8 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    -	    
    +
    +
     	    $parameters=array(
     	        'object' => $object,
     	        'outputlangs' => $outputlangs,
    @@ -2009,7 +2009,7 @@ class pdf_sponge extends ModelePDFFactures
     	        'hidedesc' => $hidedesc,
     	        'hideref' => $hideref
     	    );
    -	    
    +
     	    $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this);    // Note that $object may have been modified by hook
     	    if ($reshook < 0)
     	    {
    @@ -2023,8 +2023,5 @@ class pdf_sponge extends ModelePDFFactures
     	    {
     	        $this->cols = $hookmanager->resArray;
     	    }
    -	    
     	}
    -	
    -	
     }
    diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    index c9bce8b07a4..be7aea54464 100644
    --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    @@ -7,6 +7,7 @@
      * Copyright (C) 2012      Cedric Salvador      <csalvador@gpcsolutions.fr>
      * Copyright (C) 2015      Marcos García        <marcosgdf@gmail.com>
      * Copyright (C) 2017      Ferran Marcet        <fmarcet@2byte.es>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -40,24 +41,24 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
      */
     class pdf_cyan extends ModelePDFPropales
     {
    -	var $db;
    -	var $name;
    -	var $description;
    -	var $update_main_doc_field;	// Save the name of generated file as the main doc when generating a doc with this template
    -	var $type;
    +	public $db;
    +	public $name;
    +	public $description;
    +	public $update_main_doc_field;	// Save the name of generated file as the main doc when generating a doc with this template
    +	public $type;
     
    -	var $phpmin = array(4,3,0); // Minimum version of PHP required by module
    -	var $version = 'development';
    +	public $phpmin = array(4,3,0); // Minimum version of PHP required by module
    +	public $version = 'development';
     
    -	var $page_largeur;
    -	var $page_hauteur;
    -	var $format;
    -	var $marge_gauche;
    -	var	$marge_droite;
    -	var	$marge_haute;
    -	var	$marge_basse;
    +	public $page_largeur;
    +	public $page_hauteur;
    +	public $format;
    +	public $marge_gauche;
    +	public	$marge_droite;
    +	public	$marge_haute;
    +	public	$marge_basse;
     
    -	var $emetteur;	// Objet societe qui emet
    +	public $emetteur;	// Objet societe qui emet
     
     
     	/**
    @@ -65,10 +66,10 @@ class pdf_cyan extends ModelePDFPropales
     	 *
     	 *  @param		DoliDB		$db      Database handler
     	 */
    -	function __construct($db)
    +	public function __construct($db)
     	{
     		global $conf,$langs,$mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "bills"));
     
    @@ -107,8 +108,8 @@ class pdf_cyan extends ModelePDFPropales
     
     		// Define position of columns
     		$this->posxdesc=$this->marge_gauche+1;
    -		
    -		
    +
    +
     
     		$this->tva=array();
     		$this->localtax1=array();
    @@ -117,6 +118,7 @@ class pdf_cyan extends ModelePDFPropales
     		$this->atleastonediscount=0;
     	}
     
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	/**
          *  Function to build pdf onto disk
          *
    @@ -128,8 +130,9 @@ class pdf_cyan extends ModelePDFPropales
          *  @param		int			$hideref			Do not show ref
          *  @return     int             				1=OK, 0=KO
     	 */
    -	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
    +	public function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +        // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
    @@ -286,8 +289,8 @@ class pdf_cyan extends ModelePDFPropales
     				        break;
     				    }
     				}
    -				
    -				
    +
    +
     
     				// New page
     				$pdf->AddPage();
    @@ -308,7 +311,7 @@ class pdf_cyan extends ModelePDFPropales
     
     	            $tab_top = 90+$top_shift;
     				$tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
    -				
    +
     
     				// Incoterm
     				$height_incoterms = 0;
    @@ -353,7 +356,7 @@ class pdf_cyan extends ModelePDFPropales
     				    if ($tmpuser->email) $notetoshow.=',  Mail: '.$tmpuser->email;
     				    if ($tmpuser->office_phone) $notetoshow.=', Tel: '.$tmpuser->office_phone;
     				}
    -				
    +
     				$pagenb = $pdf->getPage();
     				if ($notetoshow)
     				{
    @@ -361,24 +364,24 @@ class pdf_cyan extends ModelePDFPropales
     
     				    $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
     				    $pageposbeforenote = $pagenb;
    -				    
    +
     					$substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
     					complete_substitutions_array($substitutionarray, $outputlangs, $object);
     					$notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
     
     
     					$pdf->startTransaction();
    -					
    +
     					$pdf->SetFont('','', $default_font_size - 1);
     					$pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     					// Description
     					$pageposafternote=$pdf->getPage();
     					$posyafter = $pdf->GetY();
    -					
    +
     					if($pageposafternote>$pageposbeforenote )
     					{
     					    $pdf->rollbackTransaction(true);
    -					    
    +
     					    // prepar pages to receive notes
     					    while ($pagenb < $pageposafternote) {
     					        $pdf->AddPage();
    @@ -390,16 +393,16 @@ class pdf_cyan extends ModelePDFPropales
     					        // The only function to edit the bottom margin of current page to set it.
     					        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     					    }
    -					    
    +
     					    // back to start
     					    $pdf->setPage($pageposbeforenote);
     					    $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     					    $pdf->SetFont('','', $default_font_size - 1);
     					    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     					    $pageposafternote=$pdf->getPage();
    -					    
    +
     					    $posyafter = $pdf->GetY();
    -					    
    +
     					    if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
     					    {
     					        $pdf->AddPage('','',true);
    @@ -411,14 +414,14 @@ class pdf_cyan extends ModelePDFPropales
     					        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     					        //$posyafter = $tab_top_newpage;
     					    }
    -					    
    -					    
    +
    +
     					    // apply note frame to previus pages
     					    $i = $pageposbeforenote;
     					    while ($i < $pageposafternote) {
     					        $pdf->setPage($i);
    -					        
    -					        
    +
    +
     					        $pdf->SetDrawColor(128,128,128);
     					        // Draw note frame
     					        if($i>$pageposbeforenote){
    @@ -429,21 +432,21 @@ class pdf_cyan extends ModelePDFPropales
     					            $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
     					            $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
     					        }
    -					        
    +
     					        // Add footer
     					        $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
     					        $this->_pagefoot($pdf,$object,$outputlangs,1);
    -					        
    +
     					        $i++;
     					    }
    -					    
    +
     					    // apply note frame to last page
     					    $pdf->setPage($pageposafternote);
     					    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     					    if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     					    $height_note=$posyafter-$tab_top_newpage;
     					    $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
    -					    
    +
     					}
     					else // No pagebreak
     					{
    @@ -451,8 +454,8 @@ class pdf_cyan extends ModelePDFPropales
     					    $posyafter = $pdf->GetY();
     					    $height_note=$posyafter-$tab_top;
     					    $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
    -					    
    -					    
    +
    +
     					    if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
     					    {
     					        // not enough space, need to add page
    @@ -462,12 +465,12 @@ class pdf_cyan extends ModelePDFPropales
     					        $pdf->setPage($pageposafternote);
     					        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     					        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    -					        
    +
     					        $posyafter = $tab_top_newpage;
     					    }
    -					    
    +
     					}
    -					
    +
     					$tab_height = $tab_height - $height_note;
     					$tab_top = $posyafter +6;
     				}
    @@ -479,10 +482,10 @@ class pdf_cyan extends ModelePDFPropales
     				$iniY = $tab_top + 7;
     				$curY = $tab_top + 7;
     				$nexY = $tab_top + 7;
    -				
    +
     				// Use new auto collum system
     				$this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    -				
    +
     				// Loop on each lines
     				$pageposbeforeprintlines=$pdf->getPage();
     				$pagenb = $pageposbeforeprintlines;
    @@ -513,12 +516,12 @@ class pdf_cyan extends ModelePDFPropales
         						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
         						//if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
         						$pdf->setPage($pageposbefore+1);
    -    
    +
         						$curY = $tab_top_newpage;
         						$showpricebeforepagebreak=0;
         					}
    -    
    -    					
    +
    +
         					if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
         					{
         						$pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300);	// Use 300 dpi
    @@ -526,7 +529,7 @@ class pdf_cyan extends ModelePDFPropales
         						$posYAfterImage=$curY+$imglinesize['height'];
         					}
     					}
    -					
    +
     					// Description of product line
     					if($this->getColumnStatus('desc'))
     					{
    @@ -540,7 +543,7 @@ class pdf_cyan extends ModelePDFPropales
         						//print $pageposafter.'-'.$pageposbefore;exit;
         						$pdf->setPageOrientation('', 1, $heightforfooter);	// The only function to edit the bottom margin of current page to set it.
         						pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
    -    
    +
         						$pageposafter=$pdf->getPage();
         						$posyafter=$pdf->GetY();
         						//var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
    @@ -596,7 +599,7 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Quantity
     					// Enough for 6 chars
     					if ($this->getColumnStatus('qty'))
    @@ -605,8 +608,8 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    -					
    +
    +
     					// Unit
     					if ($this->getColumnStatus('unit'))
     					{
    @@ -614,7 +617,7 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Discount on line
     					if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
     					{
    @@ -622,7 +625,7 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Total HT line
     					if ($this->getColumnStatus('totalexcltax'))
     					{
    @@ -630,8 +633,8 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    -					
    +
    +
     					$parameters=array(
     					    'object' => $object,
     					    'i' => $i,
    @@ -642,8 +645,8 @@ class pdf_cyan extends ModelePDFPropales
     					    'hidedetails' => $hidedetails
     					);
     					$reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this);    // Note that $object may have been modified by hook
    -					
    -					
    +
    +
     
     					// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
     					if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva;
    @@ -745,23 +748,23 @@ class pdf_cyan extends ModelePDFPropales
     				}
     
     				// Affiche zone infos
    -				$posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
    +				$posy=$this->drawInfoTable($pdf, $object, $bottomlasttab, $outputlangs);
     
     				// Affiche zone totaux
    -				$posy=$this->_tableau_tot($pdf, $object, 0, $bottomlasttab, $outputlangs);
    +				$posy=$this->drawTotalTable($pdf, $object, 0, $bottomlasttab, $outputlangs);
     
     				// Affiche zone versements
     				/*
     				if ($deja_regle || $amount_credit_notes_included || $amount_deposits_included)
     				{
    -					$posy=$this->_tableau_versements($pdf, $object, $posy, $outputlangs);
    +					$posy=$this->drawPaymentsTable($pdf, $object, $posy, $outputlangs);
     				}
     				*/
     
     				// Customer signature area
     				if (empty($conf->global->PROPAL_DISABLE_SIGNATURE))
     				{
    -				    $posy=$this->_signature_area($pdf, $object, $posy, $outputlangs);
    +				    $posy=$this->drawSignatureArea($pdf, $object, $posy, $outputlangs);
     				}
     
     				// Pied de page
    @@ -872,7 +875,7 @@ class pdf_cyan extends ModelePDFPropales
     		}
     	}
     
    -	/**
    +    /**
     	 *  Show payments table
     	 *
          *  @param	TCPDF		$pdf           Object PDF
    @@ -881,9 +884,8 @@ class pdf_cyan extends ModelePDFPropales
          *  @param  Translate	$outputlangs    Object langs for output
          *  @return int             			<0 if KO, >0 if OK
     	 */
    -	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
    +	private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
     	{
    -
     	}
     
     
    @@ -896,7 +898,7 @@ class pdf_cyan extends ModelePDFPropales
     	 *   @param		Translate	$outputlangs	Langs object
     	 *   @return	void
     	 */
    -	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
    +	function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
     	{
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1076,7 +1078,7 @@ class pdf_cyan extends ModelePDFPropales
     	 *	@param	Translate	$outputlangs	Objet langs
     	 *	@return int							Position pour suite
     	 */
    -	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
    +	private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
     		global $conf,$mysoc;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1389,29 +1391,27 @@ class pdf_cyan extends ModelePDFPropales
     		foreach ($this->cols as $colKey => $colDef)
     		{
     		    if(!$this->getColumnStatus($colKey)) continue;
    -		    
    +
     		    // get title label
     		    $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
    -		    
    +
     		    // Add column separator
     		    if(!empty($colDef['border-left'])){
     		        $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
     		    }
    -		    
    +
     		    if (empty($hidetop))
     		    {
     		      $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
    -		    
    +
     		      $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
     		      $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
     		    }
     		}
    -		
    +
     		if (empty($hidetop)){
     			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
     		}
    -
    -		
     	}
     
     	/**
    @@ -1661,7 +1661,7 @@ class pdf_cyan extends ModelePDFPropales
     	 *	@param	Translate	$outputlangs	Objet langs
     	 *	@return int							Position pour suite
     	 */
    -	function _signature_area(&$pdf, $object, $posy, $outputlangs)
    +	private function drawSignatureArea(&$pdf, $object, $posy, $outputlangs)
     	{
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1686,8 +1686,8 @@ class pdf_cyan extends ModelePDFPropales
     
     		return ($tab_hl*7);
     	}
    -	
    -	
    +
    +
     	/**
     	 *   	Define Array Column Field
     	 *
    @@ -1698,22 +1698,22 @@ class pdf_cyan extends ModelePDFPropales
     	 *      @param	int			   $hideref			Do not show ref
     	 *      @return	null
     	 */
    -	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    -	    
    +    function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +    {
     	    global $conf, $hookmanager;
    -	    
    +
     	    // Default field style for content
     	    $this->defaultContentsFieldsStyle = array(
     	        'align' => 'R', // R,C,L
     	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    // Default field style for content
     	    $this->defaultTitlesFieldsStyle = array(
     	        'align' => 'C', // R,C,L
     	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    /*
     	     * For exemple
     	     $this->cols['theColKey'] = array(
    @@ -1731,7 +1731,7 @@ class pdf_cyan extends ModelePDFPropales
     	     ),
     	     );
     	     */
    -	    
    +
     	    $rank=0; // do not use negative rank
     	    $this->cols['desc'] = array(
     	        'rank' => $rank,
    @@ -1748,7 +1748,7 @@ class pdf_cyan extends ModelePDFPropales
     	            'align' => 'L',
     	        ),
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['photo'] = array(
     	        'rank' => $rank,
    @@ -1763,13 +1763,13 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => false, // remove left line separator
     	    );
    -	    
    +
     	    if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE) && !empty($this->atleastonephoto))
     	    {
     	        $this->cols['photo']['status'] = true;
     	    }
    -	    
    -	    
    +
    +
     	    $rank = $rank + 10;
     	    $this->cols['vat'] = array(
     	        'rank' => $rank,
    @@ -1780,12 +1780,12 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
     	    {
     	        $this->cols['vat']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['subprice'] = array(
     	        'rank' => $rank,
    @@ -1796,7 +1796,7 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['qty'] = array(
     	        'rank' => $rank,
    @@ -1807,7 +1807,7 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['progress'] = array(
     	        'rank' => $rank,
    @@ -1818,12 +1818,12 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => false, // add left line separator
     	    );
    -	    
    +
     	    if($this->situationinvoice)
     	    {
     	        $this->cols['progress']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['unit'] = array(
     	        'rank' => $rank,
    @@ -1837,7 +1837,7 @@ class pdf_cyan extends ModelePDFPropales
     	    if($conf->global->PRODUCT_USE_UNITS){
     	        $this->cols['unit']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['discount'] = array(
     	        'rank' => $rank,
    @@ -1851,7 +1851,7 @@ class pdf_cyan extends ModelePDFPropales
     	    if ($this->atleastonediscount){
     	        $this->cols['discount']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['totalexcltax'] = array(
     	        'rank' => $rank,
    @@ -1862,8 +1862,8 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    -	    
    +
    +
     	    $parameters=array(
     	        'object' => $object,
     	        'outputlangs' => $outputlangs,
    @@ -1871,7 +1871,7 @@ class pdf_cyan extends ModelePDFPropales
     	        'hidedesc' => $hidedesc,
     	        'hideref' => $hideref
     	    );
    -	    
    +
     	    $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this);    // Note that $object may have been modified by hook
     	    if ($reshook < 0)
     	    {
    @@ -1885,7 +1885,5 @@ class pdf_cyan extends ModelePDFPropales
     	    {
     	        $this->cols = $hookmanager->resArray;
     	    }
    -	    
     	}
    -	
     }
    
    From 042118fe38f76f7eb624488249d907c1e9542dd0 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= <frederic.france@free.fr>
    Date: Fri, 19 Oct 2018 18:35:16 +0200
    Subject: [PATCH 349/433] fix it
    
    ---
     htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php | 2 +-
     htdocs/core/modules/facture/doc/pdf_sponge.modules.php       | 2 +-
     htdocs/core/modules/propale/doc/pdf_cyan.modules.php         | 2 +-
     3 files changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    index 1bd98f846cf..adcdda6f209 100644
    --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    @@ -146,7 +146,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     		$this->atleastonediscount=0;
     	}
     
    -    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
         /**
          *  Function to build pdf onto disk
          *
    diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    index dc5fbc315cd..a910c7e0984 100644
    --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    @@ -160,7 +160,7 @@ class pdf_sponge extends ModelePDFFactures
     	}
     
     
    -    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
         /**
          *  Function to build pdf onto disk
          *
    diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    index be7aea54464..f6b4c43b3e8 100644
    --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    @@ -118,7 +118,7 @@ class pdf_cyan extends ModelePDFPropales
     		$this->atleastonediscount=0;
     	}
     
    -    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
     	/**
          *  Function to build pdf onto disk
          *
    
    From f322c73dd7cd009158c2d3f3f1dacd74c3a54bd7 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Fri, 19 Oct 2018 22:52:18 +0200
    Subject: [PATCH 350/433] Update ajax.lib.php
    
    ---
     htdocs/core/lib/ajax.lib.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php
    index 1fc5e23ebb4..1e6330ba35a 100644
    --- a/htdocs/core/lib/ajax.lib.php
    +++ b/htdocs/core/lib/ajax.lib.php
    @@ -547,7 +547,7 @@ function ajax_constantonoff($code, $input=array(), $entity=null, $revertonoff=0,
      *  @param  string  $text_on    Text if on
      *  @param  string  $text_off   Text if off
      *  @param  array   $input      Array of type->list of CSS element to switch. Example: array('disabled'=>array(0=>'cssid'))
    - *  @return void
    + *  @return string              html for button on/off
      */
     function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input=array())
     {
    
    From 5cbcef44652a2e7ef086fe54be2f97cc30dc3692 Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Sat, 20 Oct 2018 08:26:30 +0200
    Subject: [PATCH 351/433] Debug Lettering
    
    ---
     .../thirdparty_lettering_customer.php         | 65 ++++++-------
     .../thirdparty_lettering_supplier.php         | 95 ++++++++-----------
     .../accountancy/class/bookkeeping.class.php   | 14 +--
     htdocs/langs/en_US/accountancy.lang           |  1 +
     4 files changed, 78 insertions(+), 97 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    index fa41b404f03..24532b86e35 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    @@ -23,10 +23,9 @@
     /**
      * \file        accountancy/bookkeeping/thirdparty_lettering_customer.php
      * \ingroup     Advanced accountancy
    - * \brief       Onglet de gestion de parametrages des ventilations
    + * \brief       Tab to manage customer lettering
      */
     require '../../main.inc.php';
    -
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
    @@ -34,7 +33,7 @@ require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
     
     // Load translation files required by the page
    -$langs->loadLangs(array("compta"));
    +$langs->loadLangs(array("compta","accountancy"));
     
     $action = GETPOST('action', 'aZ09');
     $massaction = GETPOST('massaction', 'alpha');
    @@ -79,6 +78,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
     $socid = GETPOST("socid", 'int');
     // if ($user->societe_id) $socid=$user->societe_id;
     
    +$lettering = new lettering($db);
     $object = new Societe($db);
     $object->id = $socid;
     $result = $object->fetch($socid);
    @@ -87,39 +87,40 @@ if ($result < 0)
     	setEventMessages($object->error, $object->errors, 'errors');
     }
     
    -$form = new Form($db);
    -$BookKeeping = new lettering($db);
    -$formaccounting = new FormAccounting($db);
    -
     /*
      * Action
      */
     
     if ($action == 'lettering') {
     
    -	$result = $BookKeeping->updateLettrage($toselect);
    +	$result = $lettering->updateLettrage($toselect);
     
     	if ($result < 0) {
    -		setEventMessages('', $BookKeeping->errors, 'errors');
    +		setEventMessages('', $lettering->errors, 'errors');
     		$error ++;
     	}
     }
     
     if ($action == 'autolettrage') {
     
    -	$result = $BookKeeping->lettering_thirdparty($socid);
    +	$result = $lettering->lettering_thirdparty($socid);
     
     	if ($result < 0) {
    -		setEventMessages('', $BookKeeping->errors, 'errors');
    +		setEventMessages('', $lettering->errors, 'errors');
     		$error ++;
     	}
     }
     
    -llxHeader('', 'Compta - Grand Livre');
    -
     /*
    - * Affichage onglets
    + * View
      */
    +$form = new Form($db);
    +$formaccounting = new FormAccounting($db);
    +
    +$title=$object->name." - ".$langs->trans('TabLetteringCustomer');
    +$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
    +llxHeader('',$title,$help_url);
    +
     $head = societe_prepare_head($object);
     
     dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error');
    @@ -192,21 +193,19 @@ if ($resql) {
     	print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Labelcompte", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder);
    +	print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "bk.montant", "", $param, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Sens", $_SERVER["PHP_SELF"], "bk.sens", "", $param, "", $sortfield, $sortorder);
    +	print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
     	print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder);
    -	print_liste_field_titre("Solde", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
    -	print '<td></td>';
    +	print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder);
     	print "</tr>\n";
     
     	print '<tr class="liste_titre">';
     	print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
     	print '<td><input type="text" name="search_year" value="' . $search_year . '"></td>';
     	print '<td><input type="text" name="search_doc_refe" value="' . $search_doc_ref . '"></td>';
    -	print '<td colspan="7">&nbsp;</td>';
    +	print '<td colspan="5">&nbsp;</td>';
     	print '<td align="right">';
     	$searchpicto = $form->showFilterButtons();
     	print $searchpicto;
    @@ -236,38 +235,36 @@ if ($resql) {
     		print '<td>' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
     		print '<td>' . $obj->doc_ref . '</td>';
     		print '<td>' . $obj->label_compte . '</td>';
    -		print '<td>' . price($obj->debit) . '</td>';
    -		print '<td>' . price($obj->credit) . '</td>';
    -		print '<td>' . price($obj->montant) . '</td>';
    -		print '<td>' . $obj->sens . '</td>';
    -		print '<td>' . $obj->code_journal . '</td>';
    -		print '<td>' . round($solde, 2) . '</td>';
    +		print '<td align="right">' . price($obj->debit) . '</td>';
    +		print '<td align="right">' . price($obj->credit) . '</td>';
    +		print '<td align="right">' . price(round($solde, 2)) . '</td>';
    +		print '<td align="center">' . $obj->code_journal . '</td>';
     
     		if (empty($obj->lettering_code)) {
     			print '<td class="nowrap" align="center"><input type="checkbox" class="flat checkforselect" name="toselect[]" id="toselect[]" value="' . $obj->rowid . '" /></td>';
     		} else
    -			print '<td>' . $obj->lettering_code . '</td>';
    +			print '<td align="center">' . $obj->lettering_code . '</td>';
     
     		print "</tr>\n";
     	}
     
     	print '<tr class="oddeven">';
    -	print '<td colspan="4">Mouvement totaux</td>' . "\n";
    -	print '<td><strong>' . price($debit) . '</strong></td>';
    -	print '<td><strong>' . price($credit) . '</strong></td>';
    +	print '<td colspan="4">'.$langs->trans("Total").':</td>' . "\n";
    +	print '<td align="right"><strong>' . price($debit) . '</strong></td>';
    +	print '<td align="right"><strong>' . price($credit) . '</strong></td>';
     	print '<td colspan="5"></td>';
     	print "</tr>\n";
     
     	print '<tr class="oddeven">';
    -	print '<td colspan="9">Solde Comptable</td>' . "\n";
    -	print '<td><strong>' . price($credit - $debit) . '</strong></td>';
    -	print '<td colspan="5"></td>';
    +	print '<td colspan="6">'.$langs->trans("Balancing").':</td>' . "\n";
    +	print '<td align="right"><strong>' . price($credit - $debit) . '</strong></td>';
    +	print '<td colspan="3"></td>';
     	print "</tr>\n";
     
     	print "</table>";
     
     	print '<input class="butAction" type="submit" value="lettering" name="lettering" id="lettering">';
    -	print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '&action=autolettrage">' . $langs->trans('AccountancyAutoLettering') . '</a>';
    +	//print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?socid=' . $object->id . '&action=autolettering">' . $langs->trans('AccountancyAutoLettering') . '</a>';
     	print "</form>";
     	$db->free($resql);
     } else {
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    index b70d0a07242..6fdc5a26452 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    @@ -1,9 +1,9 @@
     <?php
    -/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2005      Laurent Destailleur  <eldy@users.sourceforge.net>
    - * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013      Florian Henry	    <florian.henry@open-concept.pro>
    - * Copyright (C) 2013      Alexandre Spangaro   <alexandre.spangaro@gmail.com>
    +/* Copyright (C) 2004-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2005       Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2013       Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013       Florian Henry           <florian.henry@open-concept.pro>
    + * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -21,14 +21,11 @@
      */
     
     /**
    - * \file accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    - * \ingroup Advanced accountancy
    - * \brief Tab to setup lettering
    + * \file        accountancy/bookkeeping/thirdparty_lettering_supplier.php
    + * \ingroup     Advanced accountancy
    + * \brief       Tab to setup lettering
      */
    -
    -// Dolibarr environment
     require '../../main.inc.php';
    -
     require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
     require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
    @@ -36,7 +33,7 @@ require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
     require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
     
     // Load translation files required by the page
    -$langs->loadLangs(array("compta"));
    +$langs->loadLangs(array("compta","accountancy"));
     
     $action = GETPOST('action', 'aZ09');
     $massaction = GETPOST('massaction', 'alpha');
    @@ -83,6 +80,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
     $socid = GETPOST("socid", 'int');
     // if ($user->societe_id) $socid=$user->societe_id;
     
    +$lettering = new lettering($db);
     $object = new Societe($db);
     $object->id = $socid;
     $result = $object->fetch($socid);
    @@ -91,51 +89,39 @@ if ($result<0)
     	setEventMessages($object->error, $object->errors, 'errors');
     }
     
    -$form = new Form($db);
    -$BookKeeping = new lettering($db);
    -$formaccounting = new FormAccounting($db);
    -
     /*
      * Action
      */
     if ($action == 'lettering') {
     
    -	$result = $BookKeeping->updateLettrage($toselect);
    +	$result = $lettering->updateLettrage($toselect);
     
    -	// var_dump($result);
     	if ($result < 0) {
    -		setEventMessages('', $BookKeeping->errors, 'errors');
    +		setEventMessages('', $lettering->errors, 'errors');
     		$error ++;
     	}
     }
     
     if ($action == 'autolettrage') {
     
    -	$result = $BookKeeping->lettering_thirdparty($socid);
    +	$result = $lettering->lettering_thirdparty($socid);
     
     	if ($result < 0) {
    -		setEventMessages('', $BookKeeping->errors, 'errors');
    +		setEventMessages('', $lettering->errors, 'errors');
     		$error ++;
     	}
     }
     
    -$title = 'AccountancyLettrage';
    -
    -llxHeader('', $title);
    -
    -
    -$param='';
    -if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.$contextpage;
    -if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit;
    -if (!empty($search_year)) $param.='&search_year='.$search_year;
    -if (!empty($socid)) $param.='&socid='.$socid;
    -if (!empty($search_doc_type)) $param.='&search_doc_type='.$search_doc_type;
    -if (!empty($search_doc_ref)) $param.='&search_doc_ref='.$search_doc_ref;
    -
    -
     /*
    - * Display tabs
    + * View
      */
    +$form = new Form($db);
    +$formaccounting = new FormAccounting($db);
    +
    +$title=$object->name." - ".$langs->trans('TabLetteringSupplier');
    +$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas';
    +llxHeader('',$title,$help_url);
    +
     $head = societe_prepare_head($object);
     
     dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error');
    @@ -210,21 +196,19 @@ if ($resql) {
     	print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Docref", $_SERVER["PHP_SELF"], "bk.doc_ref","",$param,"",$sortfield,$sortorder);
    -	print_liste_field_titre("Labelcompte", $_SERVER["PHP_SELF"], "bk.label_compte","",$param,"",$sortfield,$sortorder);
    +	print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit","",$param,"",$sortfield,$sortorder);
    -	print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "bk.montant","",$param,"",$sortfield,$sortorder);
    -	print_liste_field_titre("Sens", $_SERVER["PHP_SELF"], "bk.sens","",$param,"",$sortfield,$sortorder);
    +	print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder);
     	print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal","",$param,"",$sortfield,$sortorder);
    -	print_liste_field_titre("Solde", $_SERVER["PHP_SELF"], "","",$param,"",$sortfield,$sortorder);
    -	print '<td></td>';
    +	print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder);
     	print "</tr>\n";
     
     	print '<tr class="liste_titre">';
     	print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
     	print '<td><input type="text" name="search_year" value="' . $search_year . '"></td>';
     	print '<td><input type="text" name="search_doc_refe" value="' . $search_doc_ref . '"></td>';
    -	print '<td colspan="7">&nbsp;</td>';
    +	print '<td colspan="6">&nbsp;</td>';
     	print '<td align="right">';
     	$searchpicto=$form->showFilterButtons();
     	print $searchpicto;
    @@ -254,39 +238,36 @@ if ($resql) {
     		print '<td>' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
     		print '<td>' . $obj->doc_ref . '</td>';
     		print '<td>' . $obj->label_compte . '</td>';
    -		print '<td>' . price($obj->debit) . '</td>';
    -		print '<td>' . price($obj->credit) . '</td>';
    -		print '<td>' . price($obj->montant) . '</td>';
    -		print '<td>' . $obj->sens . '</td>';
    -		print '<td>' . $obj->code_journal . '</td>';
    -		print '<td>' . round($solde, 2) . '</td>';
    +		print '<td align="right">' . price($obj->debit) . '</td>';
    +		print '<td align="right">' . price($obj->credit) . '</td>';
    +		print '<td align="right">' . price(round($solde, 2)) . '</td>';
    +		print '<td align="center">' . $obj->code_journal . '</td>';
     
     		if (empty($obj->lettering_code)) {
     			print '<td class="nowrap" align="center"><input type="checkbox" class="flat checkforselect" name="toselect[]" id="toselect[]" value="' . $obj->rowid . '" /></td>';
     		} else
    -			print '<td>' . $obj->lettering_code . '</td>';
    +			print '<td align="center">' . $obj->lettering_code . '</td>';
     
     		print "</tr>\n";
     	}
     
     	print '<tr class="oddeven">';
    -
    -	print '<td colspan="4">Mouvement totaux</td>' . "\n";
    -	print '<td><strong>' . price($debit) . '</strong></td>';
    -	print '<td><strong>' . price($credit) . '</strong></td>';
    +	print '<td colspan="4">'.$langs->trans("Total").':</td>' . "\n";
    +	print '<td align="right"><strong>' . price($debit) . '</strong></td>';
    +	print '<td align="right"><strong>' . price($credit) . '</strong></td>';
     	print '<td colspan="5"></td>';
     	print "</tr>\n";
     
     	print '<tr class="oddeven">';
    -	print '<td colspan="9">Solde Comptable</td>' . "\n";
    -	print '<td><strong>' . price($credit - $debit) . '</strong></td>';
    -	print '<td colspan="5"></td>';
    +	print '<td colspan="6">'.$langs->trans("Balancing").':</td>' . "\n";
    +	print '<td align="right"><strong>' . price($credit - $debit) . '</strong></td>';
    +	print '<td colspan="3"></td>';
     	print "</tr>\n";
     
     	print "</table>";
     
     	print '<input class="butAction" type="submit" value="lettering" name="lettering" id="lettering">';
    -	print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '&action=autolettrage">'.$langs->trans('AccountancyAutoLettering').'</a>';
    +	//print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '&action=autolettrage">'.$langs->trans('AccountancyAutoLettering').'</a>';
     	print "</form>";
     	$db->free($resql);
     } else {
    diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
    index 87d561b6add..6bbc4cce743 100644
    --- a/htdocs/accountancy/class/bookkeeping.class.php
    +++ b/htdocs/accountancy/class/bookkeeping.class.php
    @@ -1,7 +1,7 @@
     <?php
    -/* Copyright (C) 2014-2017  Olivier Geffroy		<jeff@jeffinfo.com>
    - * Copyright (C) 2015-2017  Alexandre Spangaro	<aspangaro@zendsi.com>
    - * Copyright (C) 2015-2017  Florian Henry		<florian.henry@open-concept.pro>
    +/* Copyright (C) 2014-2017  Olivier Geffroy     <jeff@jeffinfo.com>
    + * Copyright (C) 2015-2017  Alexandre Spangaro  <aspangaro@zendsi.com>
    + * Copyright (C) 2015-2017  Florian Henry       <florian.henry@open-concept.pro>
      * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
    @@ -19,9 +19,9 @@
      */
     
     /**
    - *	\file		htdocs/accountancy/class/bookkeeping.class.php
    - *	\ingroup	Advanced accountancy
    - *	\brief		File of class to manage Ledger (General Ledger and Subledger)
    + * \file        htdocs/accountancy/class/bookkeeping.class.php
    + * \ingroup     Advanced accountancy
    + * \brief       File of class to manage Ledger (General Ledger and Subledger)
      */
     
     // Class
    @@ -862,6 +862,7 @@ class BookKeeping extends CommonObject
     		$sql .= " t.label_operation,";
     		$sql .= " t.debit,";
     		$sql .= " t.credit,";
    +		$sql .= " t.lettering_code,";
     		$sql .= " t.montant,";
     		$sql .= " t.sens,";
     		$sql .= " t.fk_user_author,";
    @@ -934,6 +935,7 @@ class BookKeeping extends CommonObject
     				$line->credit = $obj->credit;
     				$line->montant = $obj->montant;
     				$line->sens = $obj->sens;
    +				$line->lettering_code = $obj->lettering_code;
     				$line->fk_user_author = $obj->fk_user_author;
     				$line->import_key = $obj->import_key;
     				$line->code_journal = $obj->code_journal;
    diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang
    index e6215269512..e2f6083e6a6 100644
    --- a/htdocs/langs/en_US/accountancy.lang
    +++ b/htdocs/langs/en_US/accountancy.lang
    @@ -226,6 +226,7 @@ AutomaticBindingDone=Automatic binding done
     
     ErrorAccountancyCodeIsAlreadyUse=Error, you cannot delete this accounting account because it is used
     MvtNotCorrectlyBalanced=Movement not correctly balanced. Debit = %s | Credit = %s
    +Balancing=Balancing
     FicheVentilation=Binding card
     GeneralLedgerIsWritten=Transactions are written in the Ledger
     GeneralLedgerSomeRecordWasNotRecorded=Some of the transactions could not be journalized. If there is no other error message, this is probably because they were already journalized.
    
    From 921757c4a3069c879464595608f4067dd0531e82 Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Sat, 20 Oct 2018 10:57:59 +0200
    Subject: [PATCH 352/433] Fix travis
    
    ---
     .../accountancy/bookkeeping/thirdparty_lettering_customer.php | 2 +-
     .../accountancy/bookkeeping/thirdparty_lettering_supplier.php | 4 ++--
     htdocs/accountancy/class/lettering.class.php                  | 4 ++--
     3 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    index 24532b86e35..08994e3853d 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    @@ -103,7 +103,7 @@ if ($action == 'lettering') {
     
     if ($action == 'autolettrage') {
     
    -	$result = $lettering->lettering_thirdparty($socid);
    +	$result = $lettering->letteringThirdparty($socid);
     
     	if ($result < 0) {
     		setEventMessages('', $lettering->errors, 'errors');
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    index 6fdc5a26452..0da446301c6 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    @@ -104,7 +104,7 @@ if ($action == 'lettering') {
     
     if ($action == 'autolettrage') {
     
    -	$result = $lettering->lettering_thirdparty($socid);
    +	$result = $lettering->letteringThirdparty($socid);
     
     	if ($result < 0) {
     		setEventMessages('', $lettering->errors, 'errors');
    @@ -266,7 +266,7 @@ if ($resql) {
     
     	print "</table>";
     
    -	print '<input class="butAction" type="submit" value="lettering" name="lettering" id="lettering">';
    +	print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '&action=lettering">'.$langs->trans('AccountancyLettering').'</a>';
     	//print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '&action=autolettrage">'.$langs->trans('AccountancyAutoLettering').'</a>';
     	print "</form>";
     	$db->free($resql);
    diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php
    index 220ed24d5d6..488941cbc02 100644
    --- a/htdocs/accountancy/class/lettering.class.php
    +++ b/htdocs/accountancy/class/lettering.class.php
    @@ -32,12 +32,12 @@ include_once DOL_DOCUMENT_ROOT . "/core/lib/date.lib.php";
     class lettering extends BookKeeping
     {
     	/**
    -	 * lettering_thirdparty
    +	 * letteringThirdparty
     	 *
     	 * @param int $socid Thirdparty id
     	 * @return int 1 OK, <0 error
     	 */
    -	public function lettering_thirdparty($socid)
    +	public function letteringThirdparty($socid)
     	{
     		global $conf;
     
    
    From a7de7013a11157ce646b03d2f3152460deb017f1 Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Sat, 20 Oct 2018 11:20:53 +0200
    Subject: [PATCH 353/433] Update code
    
    ---
     .../thirdparty_lettering_customer.php         | 21 ++++++++---------
     .../thirdparty_lettering_supplier.php         | 23 ++++++++-----------
     htdocs/accountancy/class/lettering.class.php  |  2 +-
     3 files changed, 20 insertions(+), 26 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    index 08994e3853d..0cab173823c 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    @@ -60,11 +60,10 @@ $search_year = GETPOST("search_year", 'int');
     $search_doc_type = GETPOST("search_doc_type", 'alpha');
     $search_doc_ref = GETPOST("search_doc_ref", 'alpha');
     
    -$lettering = GETPOST('lettering');
    +$lettering = GETPOST('lettering', 'alpha');
     if (! empty($lettering)) {
     	$action = $lettering;
     }
    -$toselect = GETPOST('toselect', 'array');
     
     // Did we click on purge search criteria ?
     // All tests are required to be compatible with all browsers
    @@ -93,7 +92,7 @@ if ($result < 0)
     
     if ($action == 'lettering') {
     
    -	$result = $lettering->updateLettrage($toselect);
    +	$result = $lettering->updateLettering($toselect);
     
     	if ($result < 0) {
     		setEventMessages('', $lettering->errors, 'errors');
    @@ -216,12 +215,8 @@ if ($resql) {
     	$tmp = '';
     	while ( $obj = $db->fetch_object($resql) ) {
     
    -		if ($tmp != $obj->lettering_code || empty($tmp))
    -			$tmp = $obj->lettering_code;
    -
    -		if ($tmp != $obj->lettering_code || empty($obj->lettering_code))
    -
    -		$solde += ($obj->credit - $obj->debit);
    +		if ($tmp != $obj->lettering_code || empty($tmp))						$tmp = $obj->lettering_code;
    +		/*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/	$solde += ($obj->credit - $obj->debit);
     
     		print '<tr class="oddeven">';
     
    @@ -229,8 +224,9 @@ if ($resql) {
     			print '<td><a href="' . dol_buildpath('/accountancy/bookkeeping/card.php', 1) . '?piece_num=' . $obj->piece_num . '">';
     			print img_edit();
     			print '</a>&nbsp;' . $obj->doc_type . '</td>' . "\n";
    -		} else
    +		} else {
     			print '<td>' . $obj->doc_type . '</td>' . "\n";
    +		}
     
     		print '<td>' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
     		print '<td>' . $obj->doc_ref . '</td>';
    @@ -249,14 +245,15 @@ if ($resql) {
     	}
     
     	print '<tr class="oddeven">';
    -	print '<td colspan="4">'.$langs->trans("Total").':</td>' . "\n";
    +	print '<td align="right" colspan="4">'.$langs->trans("Total").':</td>' . "\n";
     	print '<td align="right"><strong>' . price($debit) . '</strong></td>';
     	print '<td align="right"><strong>' . price($credit) . '</strong></td>';
     	print '<td colspan="5"></td>';
     	print "</tr>\n";
     
     	print '<tr class="oddeven">';
    -	print '<td colspan="6">'.$langs->trans("Balancing").':</td>' . "\n";
    +	print '<td align="right" colspan="4">'.$langs->trans("Balancing").':</td>' . "\n";
    +	print '<td colspan="2">&nbsp;</td>';
     	print '<td align="right"><strong>' . price($credit - $debit) . '</strong></td>';
     	print '<td colspan="3"></td>';
     	print "</tr>\n";
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    index 0da446301c6..659643260f9 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    @@ -60,11 +60,10 @@ $search_year = GETPOST("search_year",'int');
     $search_doc_type = GETPOST("search_doc_type",'alpha');
     $search_doc_ref = GETPOST("search_doc_ref",'alpha');
     
    -$lettering = GETPOST('lettering');
    +$lettering = GETPOST('lettering', 'alpha');
     if (!empty($lettering)) {
     	$action=$lettering;
     }
    -$toselect = GETPOST('toselect','array');
     
     // Did we click on purge search criteria ?
     // All tests are required to be compatible with all browsers
    @@ -94,7 +93,7 @@ if ($result<0)
      */
     if ($action == 'lettering') {
     
    -	$result = $lettering->updateLettrage($toselect);
    +	$result = $lettering->updateLettering($toselect);
     
     	if ($result < 0) {
     		setEventMessages('', $lettering->errors, 'errors');
    @@ -219,12 +218,8 @@ if ($resql) {
     	$tmp = '';
     	while ($obj = $db->fetch_object($resql)) {
     
    -		if ($tmp != $obj->lettering_code || empty($tmp))
    -			$tmp = $obj->lettering_code;
    -
    -			if ($tmp != $obj->lettering_code || empty($obj->lettering_code))
    -
    -		$solde += ($obj->credit - $obj->debit);
    +		if ($tmp != $obj->lettering_code || empty($tmp))						$tmp = $obj->lettering_code;
    +		/*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/	$solde += ($obj->credit - $obj->debit);
     
     		print '<tr class="oddeven">';
     
    @@ -232,8 +227,9 @@ if ($resql) {
     			print '<td><a href="' . dol_buildpath('/accountancy/bookkeeping/card.php', 1) . '?piece_num=' . $obj->piece_num . '">';
     			print img_edit();
     			print '</a>&nbsp;' . $obj->doc_type . '</td>' . "\n";
    -		} else
    +		} else {
     			print '<td>' . $obj->doc_type . '</td>' . "\n";
    +		}
     
     		print '<td>' . dol_print_date($db->jdate($obj->doc_date), 'day') . '</td>';
     		print '<td>' . $obj->doc_ref . '</td>';
    @@ -252,21 +248,22 @@ if ($resql) {
     	}
     
     	print '<tr class="oddeven">';
    -	print '<td colspan="4">'.$langs->trans("Total").':</td>' . "\n";
    +	print '<td align="right" colspan="4">'.$langs->trans("Total").':</td>' . "\n";
     	print '<td align="right"><strong>' . price($debit) . '</strong></td>';
     	print '<td align="right"><strong>' . price($credit) . '</strong></td>';
     	print '<td colspan="5"></td>';
     	print "</tr>\n";
     
     	print '<tr class="oddeven">';
    -	print '<td colspan="6">'.$langs->trans("Balancing").':</td>' . "\n";
    +	print '<td align="right" colspan="4">'.$langs->trans("Balancing").':</td>' . "\n";
    +	print '<td colspan="2">&nbsp;</td>';
     	print '<td align="right"><strong>' . price($credit - $debit) . '</strong></td>';
     	print '<td colspan="3"></td>';
     	print "</tr>\n";
     
     	print "</table>";
     
    -	print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '&action=lettering">'.$langs->trans('AccountancyLettering').'</a>';
    +	print '<input class="butAction" type="submit" value="' . $langs->trans('AccountancyLettering') . '" name="lettering" id="lettering">';
     	//print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?socid=' . $object->id . '&action=autolettrage">'.$langs->trans('AccountancyAutoLettering').'</a>';
     	print "</form>";
     	$db->free($resql);
    diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php
    index 488941cbc02..b6eeba24c01 100644
    --- a/htdocs/accountancy/class/lettering.class.php
    +++ b/htdocs/accountancy/class/lettering.class.php
    @@ -229,7 +229,7 @@ class lettering extends BookKeeping
     	 * @param boolean $notrigger no trigger
      	 * @return number
     	 */
    -	public function updateLettrage($ids = array(), $notrigger = false)
    +	public function updateLettering($ids = array(), $notrigger = false)
     	{
     		$error = 0;
     		$lettre = 'AAA';
    
    From 550dc622ca411bc3190a2d08c194640e2836e62d Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sat, 20 Oct 2018 13:40:40 +0200
    Subject: [PATCH 354/433] code comment
    
    ---
     .../class/accountingaccount.class.php         | 46 +++++++++++++------
     1 file changed, 32 insertions(+), 14 deletions(-)
    
    diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php
    index 9030e65b049..85f9ee39c61 100644
    --- a/htdocs/accountancy/class/accountingaccount.class.php
    +++ b/htdocs/accountancy/class/accountingaccount.class.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2013-2014  Florian Henry        <florian.henry@open-concept.pro>
      * Copyright (C) 2014       Juanjo Menent        <jmenent@2byte.es>
      * Copyright (C) 2015       Ari Elbaz (elarifr)  <github@accedinfo.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -30,6 +31,9 @@
      */
     class AccountingAccount extends CommonObject
     {
    +	/**
    +	 * @var string Name of element
    +	 */
     	public $element='accounting_account';
     
     	/**
    @@ -59,16 +63,6 @@ class AccountingAccount extends CommonObject
     	 */
     	public $db;
     
    -	/**
    -	 * @var string Error code (or message)
    -	 */
    -	public $error='';
    -
    -	/**
    -	 * @var string[] Error codes (or messages)
    -	 */
    -	public $errors = array();
    -
     	/**
     	 * @var int ID
     	 */
    @@ -79,17 +73,39 @@ class AccountingAccount extends CommonObject
     	 */
     	public $rowid;
     
    -	public $datec; // Creation date
    +	/**
    +     * @var string Creation date
    +     */
    +	public $datec;
     
     	/**
    -     * @var int ID
    +     * @var string pcg version
          */
     	public $fk_pcg_version;
     
    +    /**
    +     * @var string pcg type
    +     */
     	public $pcg_type;
    +
    +    /**
    +     * @var string pcg subtype
    +     */
     	public $pcg_subtype;
    +
    +    /**
    +     * @var string account number
    +     */
     	public $account_number;
    +
    +    /**
    +     * @var int ID parent account
    +     */
     	public $account_parent;
    +
    +    /**
    +     * @var int ID category account
    +     */
     	public $account_category;
     
     	/**
    @@ -112,8 +128,10 @@ class AccountingAccount extends CommonObject
          */
         public $fk_user_modif;
     
    -    public $active;       // duplicate with status
    -
    +	/**
    +	 * @var int active (duplicate with status)
    +	 */
    +    public $active;
     
     	/**
     	 * Constructor
    
    From 4d72cafa52a31e504219197c848053f6118ddb22 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sat, 20 Oct 2018 13:47:51 +0200
    Subject: [PATCH 355/433] code comment
    
    ---
     htdocs/api/class/api_setup.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php
    index 304abf46432..60a51074d58 100644
    --- a/htdocs/api/class/api_setup.class.php
    +++ b/htdocs/api/class/api_setup.class.php
    @@ -122,7 +122,7 @@ class Setup extends DolibarrApi
          * @param string    $filter     To filter the countries by name
          * @param string    $lang       Code of the language the label of the countries must be translated to
          * @param string    $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)"
    -     * @return List of countries
    +     * @return array                List of countries
          *
          * @url     GET dictionary/countries
          *
    
    From fab10acc15f3f8e4350b71e1763786da21d42d6e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sat, 20 Oct 2018 16:23:43 +0200
    Subject: [PATCH 356/433] change class name from lettering to Lettering
    
    ---
     htdocs/accountancy/class/lettering.class.php | 19 ++++++++++---------
     1 file changed, 10 insertions(+), 9 deletions(-)
    
    diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php
    index 70d7a88c55b..d37b29961f2 100644
    --- a/htdocs/accountancy/class/lettering.class.php
    +++ b/htdocs/accountancy/class/lettering.class.php
    @@ -1,7 +1,8 @@
     <?php
    -/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
    - * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
    - * Copyright (C) 2013      Alexandre Spangaro   <alexandre.spangaro@gmail.com>
    +/* Copyright (C) 2004-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2013       Olivier Geffroy         <jeff@jeffinfo.com>
    + * Copyright (C) 2013       Alexandre Spangaro      <alexandre.spangaro@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -18,8 +19,8 @@
      */
     
     /**
    - * \file      accountancy/class/bookkeeping.class.php
    - * \ingroup   Accounting Expert
    + * \file      htdocs/accountancy/class/lettering.class.php
    + * \ingroup   accountancy
      * \brief     Fichier de la classe des comptes comptable
      */
     
    @@ -29,9 +30,9 @@ include_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
     
     
     /**
    - * Class lettering
    + * Class Lettering
      */
    -class lettering extends BookKeeping
    +class Lettering extends BookKeeping
     {
         /**
          * lettrageTiers
    @@ -48,10 +49,10 @@ class lettering extends BookKeeping
     		$object->fetch($socid);
     
     
    -		if( $object->code_compta == '411CUSTCODE')
    +		if ($object->code_compta == '411CUSTCODE')
     			$object->code_compta = '';
     
    -		if( $object->code_compta_fournisseur == '401SUPPCODE')
    +		if ($object->code_compta_fournisseur == '401SUPPCODE')
     			$object->code_compta_fournisseur = '';
     
     
    
    From d3022413ef2aa26c00d60a011a2b843b0324425e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sat, 20 Oct 2018 16:25:57 +0200
    Subject: [PATCH 357/433] Update thirdparty_lettrage.php
    
    ---
     htdocs/accountancy/bookkeeping/thirdparty_lettrage.php | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettrage.php b/htdocs/accountancy/bookkeeping/thirdparty_lettrage.php
    index 9ffffb4d1ed..8717f7b46a1 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettrage.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettrage.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
      * Copyright (C) 2013      Florian Henry	      <florian.henry@open-concept.pro>
      * Copyright (C) 2013      Alexandre Spangaro   <alexandre.spangaro@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -63,7 +64,7 @@ $object->fetch($socid);
     
     
     $form = new Form($db);
    -$BookKeeping = new lettering($db);
    +$BookKeeping = new Lettering($db);
     $formaccounting = new FormAccounting($db);
     
     
    
    From 02954931d8c6b6e8525a8d4285c46f23ba901828 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sat, 20 Oct 2018 16:27:15 +0200
    Subject: [PATCH 358/433] Update thirdparty_lettrage_supplier.php
    
    ---
     .../bookkeeping/thirdparty_lettrage_supplier.php           | 7 ++++---
     1 file changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    index 05315fe13ad..8fa6cd4a3d5 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2013      Olivier Geffroy      <jeff@jeffinfo.com>
      * Copyright (C) 2013      Florian Henry	      <florian.henry@open-concept.pro>
      * Copyright (C) 2013      Alexandre Spangaro   <alexandre.spangaro@gmail.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -21,8 +22,8 @@
      */
     
     /**
    - * \file    accounting/bookkeeping/thirdparty_lettrage.php
    - * \ingroup Accounting Expert
    + * \file    htdocs/accountancy/bookkeeping/thirdparty_lettrage_supplier.php
    + * \ingroup accountancy
      * \brief   Onglet de gestion de parametrages des ventilations
      */
     
    @@ -65,7 +66,7 @@ $object->id = $socid;
     $object->fetch($socid);
     
     $form = new Form($db);
    -$BookKeeping = new lettering($db);
    +$BookKeeping = new Lettering($db);
     $formaccounting = new FormAccounting($db);
     
     
    
    From fbc5ce623e02868e677d5c19804bcaa92183dec7 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= <frederic.france@free.fr>
    Date: Sat, 20 Oct 2018 17:17:21 +0200
    Subject: [PATCH 359/433] payments
    
    ---
     .../compta/paiement/class/paiement.class.php  | 88 +++++++++++++++----
     htdocs/public/payment/paymentok.php           | 14 +--
     2 files changed, 78 insertions(+), 24 deletions(-)
    
    diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php
    index fd64155f3d9..18dabbcf980 100644
    --- a/htdocs/compta/paiement/class/paiement.class.php
    +++ b/htdocs/compta/paiement/class/paiement.class.php
    @@ -1,13 +1,14 @@
     <?php
    -/* Copyright (C) 2002-2004 Rodolphe Quiedeville  <rodolphe@quiedeville.org>
    - * Copyright (C) 2004-2010 Laurent Destailleur   <eldy@users.sourceforge.net>
    - * Copyright (C)      2005 Marc Barilley / Ocebo <marc@ocebo.com>
    +/* Copyright (C) 2002-2004  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
    + * Copyright (C) 2004-2010  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2005       Marc Barilley / Ocebo   <marc@ocebo.com>
      * Copyright (C) 2012      Cédric Salvador       <csalvador@gpcsolutions.fr>
      * Copyright (C) 2014      Raphaël Doursenaud    <rdoursenaud@gpcsolutions.fr>
      * Copyright (C) 2014      Marcos García 		 <marcosgdf@gmail.com>
      * Copyright (C) 2015      Juanjo Menent		 <jmenent@2byte.es>
      * Copyright (C) 2018      Ferran Marcet		 <fmarcet@2byte.es>
      * Copyright (C) 2018      Thibault FOUCART		 <support@ptibogxiv.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -73,16 +74,69 @@ class Paiement extends CommonObject
     	public $author;
     	public $paiementid;	// Type de paiement. Stocke dans fk_paiement
     	// de llx_paiement qui est lie aux types de
    -	//paiement de llx_c_paiement
    -	public $num_paiement;	// Numero du CHQ, VIR, etc...
    -	public $num_payment;	// Numero du CHQ, VIR, etc...
    -    public $payment_id;	// Id of external modepayment
    -    public $payment_site;	// name of external modepayment
    -	public $bank_account;	// Id compte bancaire du paiement
    -	public $bank_line;     // Id de la ligne d'ecriture bancaire
    +    //paiement de llx_c_paiement
    +
    +    /**
    +     * @var string type libelle
    +     */
    +    public $type_libelle;
    +
    +    /**
    +     * @var string type code
    +     */
    +    public $type_code;
    +
    +    /**
    +     * @var string Numero du CHQ, VIR, etc...
    +     * @deprecated
    +     * @see num_payment
    +     */
    +    public $numero;
    +
    +    /**
    +     * @var string Numero du CHQ, VIR, etc...
    +     * @deprecated
    +     * @see num_payment
    +     */
    +    public $num_paiement;
    +
    +    /**
    +     * @var string Numero du CHQ, VIR, etc...
    +     */
    +    public $num_payment;
    +
    +    /**
    +     * @var string Id of external payment mode
    +     */
    +    public $ext_payment_id;
    +
    +    /**
    +     * @var string Name of external payment mode
    +     */
    +    public $ext_payment_site;
    +
    +    /**
    +     * @var int bank account id of payment
    +     * @deprecated
    +     */
    +    public $bank_account;
    +
    +    /**
    +     * @var int bank account id of payment
    +     */
    +    public $fk_account;
    +
    +    /**
    +     * @var int id of payment line in bank account
    +     */
    +    public $bank_line;
    +
     	// fk_paiement dans llx_paiement est l'id du type de paiement (7 pour CHQ, ...)
    -	// fk_paiement dans llx_paiement_facture est le rowid du paiement
    -    public $fk_paiement;    // Type of paiment
    +    // fk_paiement dans llx_paiement_facture est le rowid du paiement
    +    /**
    +     * @var int payment id
    +     */
    +    public $fk_paiement;    // Type of payment
     
     
     	/**
    @@ -90,7 +144,7 @@ class Paiement extends CommonObject
     	 *
     	 *  @param		DoliDB		$db      Database handler
     	 */
    -	function __construct($db)
    +	public function __construct($db)
     	{
     		$this->db = $db;
     	}
    @@ -103,7 +157,7 @@ class Paiement extends CommonObject
     	 *    @param	int		$fk_bank	Id of bank line associated to payment
     	 *    @return   int		            <0 if KO, 0 if not found, >0 if OK
     	 */
    -	function fetch($id, $ref='', $fk_bank='')
    +	public function fetch($id, $ref='', $fk_bank='')
     	{
     		$sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.ext_payment_id, p.ext_payment_site, p.fk_bank,';
     		$sql.= ' c.code as type_code, c.libelle as type_libelle,';
    @@ -138,8 +192,8 @@ class Paiement extends CommonObject
     				$this->type_libelle   = $obj->type_libelle;
     				$this->type_code      = $obj->type_code;
     				$this->statut         = $obj->statut;
    -                $this->payment_id     = $obj->ext_payment_id;
    -                $this->payment_site   = $obj->ext_payment_site;
    +                $this->ext_payment_id = $obj->ext_payment_id;
    +                $this->ext_payment_site = $obj->ext_payment_site;
     
     				$this->bank_account   = $obj->fk_account; // deprecated
     				$this->fk_account     = $obj->fk_account;
    @@ -235,7 +289,7 @@ class Paiement extends CommonObject
     		$note = ($this->note_public?$this->note_public:$this->note);
     
     		$sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat)";
    -		$sql.= " VALUES (".$conf->entity.", '".$this->db->escape($this->ref)."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".$total.", ".$mtotal.", ".$this->paiementid.", '".$this->db->escape($this->num_paiement)."', '".$this->db->escape($note)."', ".($this->payment_id?"'".$this->db->escape($this->payment_id)."'":"null").", ".($this->payment_site?"'".$this->db->escape($this->payment_site)."'":"null").", ".$user->id.")";
    +		$sql.= " VALUES (".$conf->entity.", '".$this->db->escape($this->ref)."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".$total.", ".$mtotal.", ".$this->paiementid.", '".$this->db->escape($this->num_paiement)."', '".$this->db->escape($note)."', ".($this->ext_payment_id?"'".$this->db->escape($this->ext_payment_id)."'":"null").", ".($this->ext_payment_site?"'".$this->db->escape($this->ext_payment_site)."'":"null").", ".$user->id.")";
     
     		dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG);
     		$resql = $this->db->query($sql);
    diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php
    index 15e77502625..36723658946 100644
    --- a/htdocs/public/payment/paymentok.php
    +++ b/htdocs/public/payment/paymentok.php
    @@ -630,9 +630,9 @@ if ($ispaymentok)
     				$paiement->paiementid   = $paymentTypeId;
     				$paiement->num_paiement = '';
     				$paiement->note_public  = 'Online payment '.dol_print_date($now, 'standard').' from '.$ipaddress;
    -				$paiement->payment_id = $TRANSACTIONID;
    -				$paiement->payment_site = $paymentmethod;
    -        
    +				$paiement->ext_payment_id = $TRANSACTIONID;
    +				$paiement->ext_payment_site = $paymentmethod;
    +
     				if (! $error)
     				{
     					$paiement_id = $paiement->create($user, 1);    // This include closing invoices and regenerating documents
    @@ -653,8 +653,8 @@ if ($ispaymentok)
     				{
     					$bankaccountid = 0;
     					if ($paymentmethod == 'paybox') $bankaccountid = $conf->global->PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS;
    -					if ($paymentmethod == 'paypal') $bankaccountid = $conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS;
    -					if ($paymentmethod == 'stripe') $bankaccountid = $conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS;
    +					elseif ($paymentmethod == 'paypal') $bankaccountid = $conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS;
    +					elseif ($paymentmethod == 'stripe') $bankaccountid = $conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS;
     
     					if ($bankaccountid > 0)
     					{
    @@ -873,8 +873,8 @@ else
         if (! empty($conf->global->PAYMENTONLINE_SENDEMAIL)) $sendemail=$conf->global->PAYMENTONLINE_SENDEMAIL;
         // TODO Remove local option to keep only the generic one ?
         if ($paymentmethod == 'paypal' && ! empty($conf->global->PAYPAL_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->PAYPAL_PAYONLINE_SENDEMAIL;
    -    if ($paymentmethod == 'paybox' && ! empty($conf->global->PAYBOX_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->PAYBOX_PAYONLINE_SENDEMAIL;
    -    if ($paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->STRIPE_PAYONLINE_SENDEMAIL;
    +    elseif ($paymentmethod == 'paybox' && ! empty($conf->global->PAYBOX_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->PAYBOX_PAYONLINE_SENDEMAIL;
    +    elseif ($paymentmethod == 'stripe' && ! empty($conf->global->STRIPE_PAYONLINE_SENDEMAIL)) $sendemail=$conf->global->STRIPE_PAYONLINE_SENDEMAIL;
     
         // Send an email
         if ($sendemail)
    
    From 5f6cbda5a6489e7a41c4062ee1f4807184f56dba Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sat, 20 Oct 2018 22:34:00 +0200
    Subject: [PATCH 360/433] Update facture.class.php
    
    ---
     htdocs/compta/facture/class/facture.class.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php
    index fcbee2da90e..20983ebd3c9 100644
    --- a/htdocs/compta/facture/class/facture.class.php
    +++ b/htdocs/compta/facture/class/facture.class.php
    @@ -990,6 +990,7 @@ class Facture extends CommonInvoice
     		$this->user_valid         = '';
     		$this->fk_facture_source  = 0;
     		$this->date_creation      = '';
    +		$this->date_modification = '';
     		$this->date_validation    = '';
     		$this->ref_client         = '';
     		$this->close_code         = '';
    
    From 80bd93d600b3cc0847afbb416483054e121bf75f Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sat, 20 Oct 2018 22:36:12 +0200
    Subject: [PATCH 361/433] Update .travis.yml
    
    ---
     .travis.yml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/.travis.yml b/.travis.yml
    index 4b17ebaf0c8..9c001a480d9 100644
    --- a/.travis.yml
    +++ b/.travis.yml
    @@ -298,7 +298,7 @@ script:
       set -e
       # Exclusions are defined in the ruleset.xml file
       #phpcs -s -n -p -d memory_limit=-1 --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 .
    -  phpcs -s -p -d memory_limit=-1 --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .
    +  #phpcs -s -p -d memory_limit=-1 --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .
       set +e
       echo
     
    
    From f9a3dec26d2efa920840d7096a185f647938e0f0 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sat, 20 Oct 2018 22:48:46 +0200
    Subject: [PATCH 362/433] Update FactureTest.php
    
    ---
     .travis.yml                  | 4 ++--
     test/phpunit/FactureTest.php | 5 +++--
     2 files changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/.travis.yml b/.travis.yml
    index 9c001a480d9..96a238e6ad4 100644
    --- a/.travis.yml
    +++ b/.travis.yml
    @@ -2,7 +2,7 @@
     # from Dolibarr GitHub repository.
     # For syntax, see http://about.travis-ci.org/docs/user/languages/php/
     
    -# We use dist: trusty to have php 5.4+ available 
    +# We use dist: trusty to have php 5.4+ available
     dist: trusty
     sudo: required
     
    @@ -298,7 +298,7 @@ script:
       set -e
       # Exclusions are defined in the ruleset.xml file
       #phpcs -s -n -p -d memory_limit=-1 --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 .
    -  #phpcs -s -p -d memory_limit=-1 --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .
    +  phpcs -s -p -d memory_limit=-1 --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .
       set +e
       echo
     
    diff --git a/test/phpunit/FactureTest.php b/test/phpunit/FactureTest.php
    index d04844783c5..a1dd46de978 100644
    --- a/test/phpunit/FactureTest.php
    +++ b/test/phpunit/FactureTest.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2010 Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2010 Laurent Destailleur   <eldy@users.sourceforge.net>
    + * Copyright (C) 2018 Frédéric France       <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -228,7 +229,7 @@ class FactureTest extends PHPUnit_Framework_TestCase
     			$newlocalobject,
     			true,
     			array(
    -				'newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem',
    +				'newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem','date_modification',
     				'ref','statut','paye','specimen','facnumber','actiontypecode','actionmsg2','actionmsg','mode_reglement','cond_reglement',
     				'cond_reglement_doc','situation_cycle_ref','situation_counter','situation_final','multicurrency_total_ht','multicurrency_total_tva',
     				'multicurrency_total_ttc','fk_multicurrency','multicurrency_code','multicurrency_tx'
    
    From d10dfd51cb68bd4f16bd750d06d37409ce9f501b Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= <frederic.france@free.fr>
    Date: Sat, 20 Oct 2018 23:14:04 +0200
    Subject: [PATCH 363/433] fix
    
    ---
     test/phpunit/FactureTest.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/test/phpunit/FactureTest.php b/test/phpunit/FactureTest.php
    index d04844783c5..09ea42dd2b6 100644
    --- a/test/phpunit/FactureTest.php
    +++ b/test/phpunit/FactureTest.php
    @@ -228,7 +228,7 @@ class FactureTest extends PHPUnit_Framework_TestCase
     			$newlocalobject,
     			true,
     			array(
    -				'newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem',
    +				'newref','oldref','id','lines','client','thirdparty','brouillon','user_author','date_creation','date_validation','datem','date_modification',
     				'ref','statut','paye','specimen','facnumber','actiontypecode','actionmsg2','actionmsg','mode_reglement','cond_reglement',
     				'cond_reglement_doc','situation_cycle_ref','situation_counter','situation_final','multicurrency_total_ht','multicurrency_total_tva',
     				'multicurrency_total_ttc','fk_multicurrency','multicurrency_code','multicurrency_tx'
    
    From cce2e2414f00b6c912c116e8bdafeaae5b198c8d Mon Sep 17 00:00:00 2001
    From: ias-ceo <hytham.soliman@ias-systems.com>
    Date: Sun, 21 Oct 2018 07:41:40 +0300
    Subject: [PATCH 364/433] missing simicolon
    
    ---
     htdocs/theme/eldy/style.css.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php
    index bb43aa0af55..d9ad2a590ac 100644
    --- a/htdocs/theme/eldy/style.css.php
    +++ b/htdocs/theme/eldy/style.css.php
    @@ -3271,7 +3271,7 @@ ul.noborder li:nth-child(even):not(.liste_titre) {
     .boxstats130 {
         width: 158px;
         height: 48px;
    -    padding: 3px
    +    padding: 3px;
     }
     .boxstats {
         padding: 3px;
    
    From c4029f5e5fc5d596e2d26d63f0756b2d8be1c168 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sun, 21 Oct 2018 09:23:33 +0200
    Subject: [PATCH 365/433] Update style.css.php
    
    ---
     htdocs/theme/md/style.css.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
    index fe947935ec5..c6560bef8e5 100644
    --- a/htdocs/theme/md/style.css.php
    +++ b/htdocs/theme/md/style.css.php
    @@ -2918,7 +2918,7 @@ div .tdtop {
     .boxstats130 {
         width: 135px;
         height: 48px;
    -    padding: 3px
    +    padding: 3px;
     }
     @media only screen and (max-width: 767px)
     {
    
    From 28c86a613d755b72bcecd9588431761a1e491727 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sun, 21 Oct 2018 09:39:07 +0200
    Subject: [PATCH 366/433] Update style.css.php
    
    ---
     htdocs/theme/md/style.css.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
    index c6560bef8e5..618a9de6d7f 100644
    --- a/htdocs/theme/md/style.css.php
    +++ b/htdocs/theme/md/style.css.php
    @@ -3018,7 +3018,7 @@ tr.box_titre {
         white-space: nowrap;
     }
     
    -tr.box_titre td.boxclose {
    +tr.box_titre, td.boxclose {
     	width: 30px;
     }
     img.boxhandle, img.boxclose {
    
    From 83e29511071b4bbb9d31ab6ceadba7750a757622 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sun, 21 Oct 2018 09:59:14 +0200
    Subject: [PATCH 367/433] Update style.css.php
    
    ---
     htdocs/theme/md/style.css.php | 16 ++++++++--------
     1 file changed, 8 insertions(+), 8 deletions(-)
    
    diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
    index 618a9de6d7f..84384a9130e 100644
    --- a/htdocs/theme/md/style.css.php
    +++ b/htdocs/theme/md/style.css.php
    @@ -1262,7 +1262,7 @@ div#tmenu_tooltip {
     <?php } else { ?>
     	background: rgb(<?php echo $colorbackhmenu1 ?>);
     	/*
    -	background-image: linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
    +	background-image: linear-gradient(to top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
     	background-image: -o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
     	background-image: -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
     	background-image: -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(128,128,128,.3) 100%);
    @@ -1343,7 +1343,7 @@ ul.tmenu {	/* t r b l */
     ul.tmenu li {
     	background: rgb(<?php echo $colorbackhmenu1 ?>);
     	/*
    -	background-image: linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
    +	background-image: linear-gradient(to top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
     	background-image: -o-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
     	background-image: -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
     	background-image: -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%);
    @@ -1374,7 +1374,7 @@ li.tmenusel, li.tmenu:hover {
         background-image: -moz-linear-gradient(bottom, rgba(0,0,0,0.5) 0%, rgba(250,250,250,0) 100%) !important;
         background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.3) 0%, rgba(250,250,250,0) 100%) !important;
         background-image: -ms-linear-gradient(bottom, rgba(250,250,250,0.3) 0%, rgba(0,0,0,0.3) 100%) !important;
    -    background-image: linear-gradient(bottom, rgba(250,250,250,0.3) 0%, rgba(0,0,0,0.3) 100%) !important;
    +    background-image: linear-gradient(to bottom, rgba(250,250,250,0.3) 0%, rgba(0,0,0,0.3) 100%) !important;
     	background: rgb(<?php echo $colorbackhmenu1 ?>);
     */
     	/* background: url(<?php echo dol_buildpath($path.'/theme/'.$theme.'/img/nav-overlay3.png',1); ?>) 50% 0 repeat-x !important; Nicer but problem when menu wrap on 2 lines */
    @@ -1964,7 +1964,7 @@ td.ecmroot {
         background-image: -moz-linear-gradient(bottom, rgba(200,200,200,0.1) 0%, rgba(255,255,255,0.3) 120%) !important;
         background-image: -webkit-linear-gradient(bottom, rgba(200,200,200,0.1) 0%, rgba(255,255,255,0.3) 120%) !important;
         background-image: -ms-linear-gradient(bottom, rgba(200,200,200,0.1) 0%, rgba(255,255,255,0.3) 120%) !important;
    -    background-image: linear-gradient(bottom, rgba(200,200,200,0.1) 0%, rgba(255,255,255,0.3) 120%) !important;
    +    background-image: linear-gradient(to bottom, rgba(200,200,200,0.1) 0%, rgba(255,255,255,0.3) 120%) !important;
     
         background: #FFF;
         background-repeat: repeat-x !important;
    @@ -2613,7 +2613,7 @@ div.pagination li.paginationafterarrows {
     
     /* Prepare to remove class pair - impair
     .noborder > tbody > tr:nth-child(even) td {
    -	background: linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
    +	background: linear-gradient(to bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
     	background: -o-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
     	background: -moz-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
     	background: -webkit-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
    @@ -2626,7 +2626,7 @@ div.pagination li.paginationafterarrows {
     }
     
     .noborder > tbody > tr:nth-child(odd) td {
    -	background: linear-gradient(bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
    +	background: linear-gradient(to bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
     	background: -o-linear-gradient(bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
     	background: -moz-linear-gradient(bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
     	background: -webkit-linear-gradient(bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
    @@ -2867,7 +2867,7 @@ div .tdtop {
     /* Prepare to remove class pair - impair */
     
     .noborder > tbody > tr:nth-child(even):not(.liste_titre), .liste > tbody > tr:nth-child(even):not(.liste_titre) {
    -	background: linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
    +	background: linear-gradient(to bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
     	background: -o-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
     	background: -moz-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
     	background: -webkit-linear-gradient(bottom, rgb(<?php echo $colorbacklineimpair1; ?>) 85%, rgb(<?php echo $colorbacklineimpair2; ?>) 100%);
    @@ -2878,7 +2878,7 @@ div .tdtop {
     }
     
     .noborder > tbody > tr:nth-child(odd):not(.liste_titre), .liste > tbody > tr:nth-child(odd):not(.liste_titre) {
    -	background: linear-gradient(bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
    +	background: linear-gradient(to bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
     	background: -o-linear-gradient(bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
     	background: -moz-linear-gradient(bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
     	background: -webkit-linear-gradient(bottom, rgb(<?php echo $colorbacklinepair1; ?>) 85%, rgb(<?php echo $colorbacklinepair2; ?>) 100%);
    
    From f169ec9259a5876452195b89a9787a6f80e7c4dd Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sun, 21 Oct 2018 10:37:49 +0200
    Subject: [PATCH 368/433] Update ajaxdirtree.php
    
    ---
     htdocs/core/ajax/ajaxdirtree.php | 9 +++++----
     1 file changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php
    index fc01474a072..0f3ac26693a 100644
    --- a/htdocs/core/ajax/ajaxdirtree.php
    +++ b/htdocs/core/ajax/ajaxdirtree.php
    @@ -1,5 +1,6 @@
     <?php
    -/* Copyright (C) 2007-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
    +/* Copyright (C) 2007-2018  Laurent Destailleur     <eldy@users.sourceforge.net>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -74,7 +75,7 @@ if ($modulepart == 'ecm')
     	$fullpathselecteddir=$conf->ecm->dir_output.'/'.($selecteddir != '/' ? $selecteddir : '');
     	$fullpathpreopened=$conf->ecm->dir_output.'/'.($preopened != '/' ? $preopened : '');
     }
    -if ($modulepart == 'medias')
    +elseif ($modulepart == 'medias')
     {
     	$fullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($selecteddir != '/' ? $selecteddir : '');
     	$fullpathpreopened=$dolibarr_main_data_root.'/medias/'.($preopened != '/' ? $preopened : '');
    @@ -96,7 +97,7 @@ if ($modulepart == 'ecm')
     {
     	if (! $user->rights->ecm->read) accessforbidden();
     }
    -if ($modulepart == 'medias')
    +elseif ($modulepart == 'medias')
     {
     	// Always allowed
     }
    @@ -349,7 +350,7 @@ function treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir,
     	{
     		$files = @scandir($fullpathselecteddir);
     
    -		if ($files)
    +		if (! empty($files))
     		{
     			natcasesort($files);
     			if (count($files) > 2)    /* The 2 accounts for . and .. */
    
    From d38c68e54f586478dc7cf8f93d2b13d698e93ceb Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 21 Oct 2018 11:10:04 +0200
    Subject: [PATCH 369/433] Remove unexpected char
    
    ---
     htdocs/core/tpl/onlinepaymentlinks.tpl.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/tpl/onlinepaymentlinks.tpl.php b/htdocs/core/tpl/onlinepaymentlinks.tpl.php
    index a5c5ce7cf11..37639a5f8e6 100644
    --- a/htdocs/core/tpl/onlinepaymentlinks.tpl.php
    +++ b/htdocs/core/tpl/onlinepaymentlinks.tpl.php
    @@ -1,4 +1,4 @@
    -<<?php
    +<?php
     /* Copyright (C) 2017 Laurent Destailleur <eldy@destailleur.fr>
      *
      * This program is free software; you can redistribute it and/or modify
    
    From cd9431809b720ab83ca1548ffdf27cfdd8e2e8fb Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 21 Oct 2018 11:44:21 +0200
    Subject: [PATCH 370/433] Fix: do not loose country_code after update
    
    ---
     htdocs/societe/class/societe.class.php | 24 ++++++++++++++++++++----
     1 file changed, 20 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php
    index 078b0d85fe8..c91593b079f 100644
    --- a/htdocs/societe/class/societe.class.php
    +++ b/htdocs/societe/class/societe.class.php
    @@ -1071,10 +1071,26 @@ class Societe extends CommonObject
     			$resql=$this->db->query($sql);
     			if ($resql)
     			{
    -				unset($this->country_code);		// We clean this because it may have been changed after an update of country_id
    -				unset($this->country);
    -				unset($this->state_code);
    -				unset($this->state);
    +				if (is_object($this->oldcopy))	// If we have information on old values
    +				{
    +					if ($this->oldcopy->country_id != $this->country_id)
    +					{
    +						unset($this->country_code);
    +						unset($this->country);
    +					}
    +					if ($this->oldcopy->state_id != $this->state_id)
    +					{
    +						unset($this->state_code);
    +						unset($this->state);
    +					}
    +				}
    +				else
    +				{
    +					unset($this->country_code);	// We clean this, in the doubt, because it may have been changed after an update of country_id
    +					unset($this->country);
    +					unset($this->state_code);
    +					unset($this->state);
    +				}
     
     				$nbrowsaffected = $this->db->affected_rows($resql);
     
    
    From fa99ea1f0fceb704dfb7226776846834ed5e3a50 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 21 Oct 2018 11:55:25 +0200
    Subject: [PATCH 371/433] Fix thirdparty popup
    
    ---
     htdocs/core/boxes/box_contracts.php | 12 ++++++++++--
     1 file changed, 10 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/core/boxes/box_contracts.php b/htdocs/core/boxes/box_contracts.php
    index 6f9a62e1063..7592f882b59 100644
    --- a/htdocs/core/boxes/box_contracts.php
    +++ b/htdocs/core/boxes/box_contracts.php
    @@ -40,7 +40,7 @@ class box_contracts extends ModeleBoxes
          * @var DoliDB Database handler.
          */
         public $db;
    -    
    +
         var $param;
     
         var $info_box_head = array();
    @@ -83,7 +83,7 @@ class box_contracts extends ModeleBoxes
             	$contractstatic=new Contrat($db);
             	$thirdpartytmp=new Societe($db);
     
    -    	    $sql = "SELECT s.nom as name, s.rowid as socid,";
    +    	    $sql = "SELECT s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
         		$sql.= " c.rowid, c.ref, c.statut as fk_statut, c.date_contrat, c.datec, c.fin_validite, c.date_cloture";
         		$sql.= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as c";
         		if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
    @@ -108,6 +108,7 @@ class box_contracts extends ModeleBoxes
                     while ($line < $num)
                     {
         				$objp = $db->fetch_object($resql);
    +
         				$datec=$db->jdate($objp->datec);
         				$dateterm=$db->jdate($objp->fin_validite);
         				$dateclose=$db->jdate($objp->date_cloture);
    @@ -120,6 +121,13 @@ class box_contracts extends ModeleBoxes
     
         				$thirdpartytmp->name = $objp->name;
         				$thirdpartytmp->id = $objp->socid;
    +    				$thirdpartytmp->email = $objp->email;
    +    				$thirdpartytmp->client = $objp->client;
    +    				$thirdpartytmp->fournisseur = $objp->fournisseur;
    +    				$thirdpartytmp->code_client = $objp->code_client;
    +    				$thirdpartytmp->code_fournisseur = $objp->code_fournisseur;
    +    				$thirdpartytmp->code_compta = $objp->code_compta;
    +    				$thirdpartytmp->code_compta_fournisseur = $objp->code_compta_fournisseur;
     
         				// fin_validite is no more on contract but on services
         				// if ($objp->fk_statut == 1 && $dateterm < ($now - $conf->contrat->cloture->warning_delay)) { $late = img_warning($langs->trans("Late")); }
    
    From f6b3bc3bdb4009fe6d902bbe9177f34ec54ad30e Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 21 Oct 2018 12:03:22 +0200
    Subject: [PATCH 372/433] Fix thirdparty popup
    
    ---
     htdocs/core/boxes/box_services_contracts.php | 11 +++++++++--
     htdocs/core/boxes/box_services_expired.php   | 13 ++++++++++---
     2 files changed, 19 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php
    index 41d287d0c37..d07ce87dd47 100644
    --- a/htdocs/core/boxes/box_services_contracts.php
    +++ b/htdocs/core/boxes/box_services_contracts.php
    @@ -41,7 +41,7 @@ class box_services_contracts extends ModeleBoxes
          * @var DoliDB Database handler.
          */
         public $db;
    -    
    +
     	var $param;
     
     	var $info_box_head = array();
    @@ -88,7 +88,7 @@ class box_services_contracts extends ModeleBoxes
     		    $thirdpartytmp = new Societe($db);
     		    $productstatic = new Product($db);
     
    -			$sql = "SELECT s.nom as name, s.rowid as socid,";
    +			$sql = "SELECT s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
     			$sql.= " c.rowid, c.ref, c.statut as contract_status,";
     			$sql.= " cd.rowid as cdid, cd.label, cd.description, cd.tms as datem, cd.statut, cd.product_type as type,";
     			$sql.= " p.rowid as product_id, p.ref as product_ref, p.label as plabel, p.fk_product_type as ptype, p.entity";
    @@ -130,6 +130,13 @@ class box_services_contracts extends ModeleBoxes
     
     					$thirdpartytmp->name = $objp->name;
     					$thirdpartytmp->id = $objp->socid;
    +					$thirdpartytmp->email = $objp->email;
    +					$thirdpartytmp->client = $objp->client;
    +					$thirdpartytmp->fournisseur = $objp->fournisseur;
    +					$thirdpartytmp->code_client = $objp->code_client;
    +					$thirdpartytmp->code_fournisseur = $objp->code_fournisseur;
    +					$thirdpartytmp->code_compta = $objp->code_compta;
    +					$thirdpartytmp->code_compta_fournisseur = $objp->code_compta_fournisseur;
     
     					// Multilangs
     					if (! empty($conf->global->MAIN_MULTILANGS) && $objp->product_id > 0) // if option multilang is on
    diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php
    index afc087ad715..c23e9940377 100644
    --- a/htdocs/core/boxes/box_services_expired.php
    +++ b/htdocs/core/boxes/box_services_expired.php
    @@ -39,7 +39,7 @@ class box_services_expired extends ModeleBoxes
          * @var DoliDB Database handler.
          */
         public $db;
    -    
    +
         var $param;
     
         var $info_box_head = array();
    @@ -84,7 +84,7 @@ class box_services_expired extends ModeleBoxes
         	    // Select contracts with at least one expired service
     			$sql = "SELECT ";
         		$sql.= " c.rowid, c.ref, c.statut as fk_statut, c.date_contrat, c.ref_customer, c.ref_supplier,";
    -			$sql.= " s.nom as name, s.rowid as socid,";
    +			$sql.= " s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
     			$sql.= " MIN(cd.date_fin_validite) as date_line, COUNT(cd.rowid) as nb_services";
         		$sql.= " FROM ".MAIN_DB_PREFIX."contrat as c, ".MAIN_DB_PREFIX."societe s, ".MAIN_DB_PREFIX."contratdet as cd";
                 if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
    @@ -113,8 +113,15 @@ class box_services_expired extends ModeleBoxes
     
         				$objp = $db->fetch_object($resql);
     
    -    				$thirdpartytmp->id = $objp->socid;
         				$thirdpartytmp->name = $objp->name;
    +    				$thirdpartytmp->id = $objp->socid;
    +    				$thirdpartytmp->email = $objp->email;
    +    				$thirdpartytmp->client = $objp->client;
    +    				$thirdpartytmp->fournisseur = $objp->fournisseur;
    +    				$thirdpartytmp->code_client = $objp->code_client;
    +    				$thirdpartytmp->code_fournisseur = $objp->code_fournisseur;
    +    				$thirdpartytmp->code_compta = $objp->code_compta;
    +    				$thirdpartytmp->code_compta_fournisseur = $objp->code_compta_fournisseur;
     
         				$contract->id = $objp->rowid;
         				$contract->ref = $objp->ref;
    
    From 868caa49916ba1efca2a48a5ecb12febae991215 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 21 Oct 2018 12:05:31 +0200
    Subject: [PATCH 373/433] Missing ref_customer in popup
    
    ---
     htdocs/core/boxes/box_services_contracts.php | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php
    index d07ce87dd47..7c73bbbe328 100644
    --- a/htdocs/core/boxes/box_services_contracts.php
    +++ b/htdocs/core/boxes/box_services_contracts.php
    @@ -89,7 +89,7 @@ class box_services_contracts extends ModeleBoxes
     		    $productstatic = new Product($db);
     
     			$sql = "SELECT s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,";
    -			$sql.= " c.rowid, c.ref, c.statut as contract_status,";
    +			$sql.= " c.rowid, c.ref, c.statut as contract_status, c.ref_customer, c.ref_supplier,";
     			$sql.= " cd.rowid as cdid, cd.label, cd.description, cd.tms as datem, cd.statut, cd.product_type as type,";
     			$sql.= " p.rowid as product_id, p.ref as product_ref, p.label as plabel, p.fk_product_type as ptype, p.entity";
     			$sql.= " FROM (".MAIN_DB_PREFIX."societe as s";
    @@ -127,6 +127,8 @@ class box_services_contracts extends ModeleBoxes
                         $contractstatic->statut=$objp->contract_status;
     					$contractstatic->id=$objp->rowid;
     					$contractstatic->ref=$objp->ref;
    +					$contractstatic->ref_customer=$objp->ref_customer;
    +					$contractstatic->ref_supplier=$objp->ref_supplier;
     
     					$thirdpartytmp->name = $objp->name;
     					$thirdpartytmp->id = $objp->socid;
    
    From 4e6b21881fd8f9b9487681ae1454127286c68f36 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 21 Oct 2018 12:14:20 +0200
    Subject: [PATCH 374/433] Fix bug reported by scrutinizer
    
    ---
     htdocs/core/ajax/ajaxdirtree.php     | 5 +++--
     htdocs/core/class/menubase.class.php | 2 +-
     2 files changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php
    index fc01474a072..173d8520423 100644
    --- a/htdocs/core/ajax/ajaxdirtree.php
    +++ b/htdocs/core/ajax/ajaxdirtree.php
    @@ -468,16 +468,17 @@ function treeOutputForAbsoluteDir($sqltree, $selecteddir, $fullpathselecteddir,
     						{
     							//print 'modulepart='.$modulepart.' fullpathselecteddir='.$fullpathselecteddir.' - val[fullrelativename] (in database)='.$val['fullrelativename'].' - val[id]='.$val['id'].' - is_dir='.dol_is_dir($fullpathselecteddir . $file).' - file='.$file."\n";
     							$newselecteddir = $val['fullrelativename'];
    +							$newfullpathselecteddir='';
     							if ($modulepart == 'ecm')
     							{
     								$newfullpathselecteddir=$conf->ecm->dir_output.'/'.($val['fullrelativename'] != '/' ? $val['fullrelativename'] : '');
     							}
    -							if ($modulepart == 'medias')
    +							elseif ($modulepart == 'medias')
     							{
     								$newfullpathselecteddir=$dolibarr_main_data_root.'/medias/'.($val['fullrelativename'] != '/' ? $val['fullrelativename'] : '');
     							}
     
    -							treeOutputForAbsoluteDir($sqltree, $newselecteddir, $newfullpathselecteddir, $modulepart, $websitekey, $pageid, $preopened, $fullpathpreopened, $depth+1);
    +							if ($newfullpathselecteddir) treeOutputForAbsoluteDir($sqltree, $newselecteddir, $newfullpathselecteddir, $modulepart, $websitekey, $pageid, $preopened, $fullpathpreopened, $depth+1);
     						}
     
     						print "</li>\n";
    diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php
    index 17ada096fd1..1ca10d9dd9b 100644
    --- a/htdocs/core/class/menubase.class.php
    +++ b/htdocs/core/class/menubase.class.php
    @@ -126,7 +126,7 @@ class Menubase
             $this->perms=trim($this->perms);
             $this->enabled=trim($this->enabled);
             $this->user=trim($this->user);
    -        $this->position=trim($this->position);
    +        if (empty($this->position)) $this->position=0;
             if (! $this->level) $this->level=0;
     
             // Check parameters
    
    From 2816bdf74705b49cf72d74ed2c368fa9bef17df0 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Sun, 21 Oct 2018 16:22:56 +0200
    Subject: [PATCH 375/433] FIX Date into filename of FEC file.
    
    ---
     htdocs/accountancy/bookkeeping/list.php       |  6 ++--
     .../class/accountancyexport.class.php         | 34 +++----------------
     .../accountancy/class/bookkeeping.class.php   |  3 +-
     htdocs/accountancy/tpl/export_journal.tpl.php | 21 +++++++++++-
     4 files changed, 29 insertions(+), 35 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php
    index 132aa4e0afa..e87c9b22aee 100644
    --- a/htdocs/accountancy/bookkeeping/list.php
    +++ b/htdocs/accountancy/bookkeeping/list.php
    @@ -337,7 +337,7 @@ if ($action == 'delmouvconfirm') {
     	}
     }
     
    -// Export into a file with format defined into setup
    +// Export into a file with format defined into setup (FEC, CSV, ...)
     if ($action == 'export_file') {
     
     	$result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter);
    @@ -350,7 +350,9 @@ if ($action == 'export_file') {
     	{
     		$accountancyexport = new AccountancyExport($db);
     		$accountancyexport->export($object->lines);
    -		if (!empty($accountancyexport->errors)) {
    +
    +		if (!empty($accountancyexport->errors))
    +		{
     			setEventMessages('', $accountancyexport->errors, 'errors');
     		}
     		exit;
    diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php
    index 13fec3cf388..7b832976e89 100644
    --- a/htdocs/accountancy/class/accountancyexport.class.php
    +++ b/htdocs/accountancy/class/accountancyexport.class.php
    @@ -206,7 +206,7 @@ class AccountancyExport
     
     
     	/**
    -	 * Function who chose which export to use with the default config
    +	 * Function who chose which export to use with the default config, and make the export into a file
     	 *
     	 * @param array		$TData 		data
     	 * @return void
    @@ -214,16 +214,16 @@ class AccountancyExport
     	public function export(&$TData)
     	{
     		global $conf, $langs;
    +		global $search_date_end;	// Used into /accountancy/tpl/export_journal.tpl.php
     
    -
    +		// Define name of file to save
     		$filename = 'general_ledger-'.$this->getFormatCode($conf->global->ACCOUNTING_EXPORT_MODELCSV);
    +
     		include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php';
     
     
     		switch ($conf->global->ACCOUNTING_EXPORT_MODELCSV) {
     			case self::$EXPORT_TYPE_NORMAL :
    -				/*$this->exportNormal($TData);
    -				break;*/
     			case self::$EXPORT_TYPE_CONFIGURABLE :
     				$this->exportConfigurable($TData);
     				break;
    @@ -261,32 +261,6 @@ class AccountancyExport
     		}
     	}
     
    -	/**
    -	 * Export format : Normal
    -	 *
    -	 * @param array $objectLines data
    -	 *
    -	 * @return void
    -	 */
    -	/* Use $EXPORT_TYPE_CONFIGURABLE instead
    -	public function exportNormal($objectLines)
    -	{
    -		global $conf;
    -
    -		foreach ( $objectLines as $line ) {
    -			// Std export
    -			$date = dol_print_date($line->doc_date, $conf->global->ACCOUNTING_EXPORT_DATE);
    -			print $date . $this->separator;
    -			print $line->doc_ref . $this->separator;
    -			print length_accountg($line->numero_compte) . $this->separator;
    -			print length_accounta($line->subledger_account) . $this->separator;
    -			print price($line->debit) . $this->separator;
    -			print price($line->credit) . $this->separator;
    -			print $line->code_journal . $this->separator;
    -			print $this->end_line;
    -		}
    -	}
    -	*/
     
     	/**
     	 * Export format : CEGID
    diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
    index 87d561b6add..0550fb5a438 100644
    --- a/htdocs/accountancy/class/bookkeeping.class.php
    +++ b/htdocs/accountancy/class/bookkeeping.class.php
    @@ -1001,8 +1001,7 @@ class BookKeeping extends CommonObject
     				}
     			}
     		}
    -		$sql.= ' WHERE 1 = 1';
    -		$sql .= " AND entity IN (" . getEntity('accountancy') . ")";
    +		$sql.= ' WHERE entity IN (' . getEntity('accountancy') . ')';
     		if (count($sqlwhere) > 0) {
     			$sql .= ' AND ' . implode(' ' . $filtermode . ' ', $sqlwhere);
     		}
    diff --git a/htdocs/accountancy/tpl/export_journal.tpl.php b/htdocs/accountancy/tpl/export_journal.tpl.php
    index 1d7e7fd6f54..d0d902770c0 100644
    --- a/htdocs/accountancy/tpl/export_journal.tpl.php
    +++ b/htdocs/accountancy/tpl/export_journal.tpl.php
    @@ -37,7 +37,26 @@ header('Content-Type: text/csv');
     
     if ($conf->global->ACCOUNTING_EXPORT_MODELCSV == "11") // Specific filename for FEC model export
     {
    -	$completefilename = $siren . "FEC" . $search_date_end . $endaccountingperiod . "." . $format;
    +
    +	// FEC format is defined here: https://www.legifrance.gouv.fr/affichCodeArticle.do?idArticle=LEGIARTI000027804775&cidTexte=LEGITEXT000006069583&dateTexte=20130802&oldAction=rechCodeArticle
    +	if (empty($search_date_end))
    +	{
    +		// TODO Get the max date into bookeeping table
    +		$search_date_end = dol_now();
    +	}
    +	$datetouseforfilename = $search_date_end;
    +	$tmparray=dol_getdate($datetouseforfilename);
    +	$fiscalmonth=empty($conf->global->SOCIETE_FISCAL_MONTH_START)?1:$conf->global->SOCIETE_FISCAL_MONTH_START;
    +	// Define end of month to use
    +	if ($tmparray['mon'] <= $fiscalmonth) $tmparray['mon']=$fiscalmonth;
    +	else {
    +		$tmparray['mon']  = $fiscalmonth;
    +		$tmparray['year']++;
    +	}
    +
    +	$endaccountingperiod = dol_print_date(dol_get_last_day($tmparray['year'], $tmparray['mon']), 'dayxcard');
    +
    +	$completefilename = $siren . "FEC" . $endaccountingperiod . "." . $format;
     }
     else
     {
    
    From 263b53bf63347a4a99956c361672145462f1cc7c Mon Sep 17 00:00:00 2001
    From: aplose <oandrade@aplose.fr>
    Date: Sun, 21 Oct 2018 18:28:05 +0200
    Subject: [PATCH 376/433] Paybox Update : include Paybox HMAC key in process in
     order to keep the module working with Paybox.
    
    ---
     htdocs/paybox/admin/paybox.php   |  9 ++++++
     htdocs/paybox/lib/paybox.lib.php | 47 ++++++++++++++++++++++++--------
     2 files changed, 45 insertions(+), 11 deletions(-)
    
    diff --git a/htdocs/paybox/admin/paybox.php b/htdocs/paybox/admin/paybox.php
    index 79a6a62ad2a..e4ae5a9eb66 100644
    --- a/htdocs/paybox/admin/paybox.php
    +++ b/htdocs/paybox/admin/paybox.php
    @@ -71,6 +71,9 @@ if ($action == 'setvalue' && $user->admin)
     	if (! $result > 0) $error++;
     	$result=dolibarr_set_const($db, "PAYMENT_SECURITY_TOKEN_UNIQUE",GETPOST('PAYMENT_SECURITY_TOKEN_UNIQUE','alpha'),'chaine',0,'',$conf->entity);
     	if (! $result > 0) $error++;
    +        $result=dolibarr_set_const($db, "PAYBOX_HMAC_KEY", dol_encode(GETPOST('PAYBOX_HMAC_KEY','alpha')),'chaine',0,'',$conf->entity);
    +	if (! $result > 0) $error++;
    +        
     
         if (! $error)
       	{
    @@ -145,6 +148,12 @@ print '<input size="32" type="text" name="PAYBOX_PBX_IDENTIFIANT" value="'.$conf
     print '<br>'.$langs->trans("Example").': 2 ('.$langs->trans("Test").')';
     print '</td></tr>';
     
    +print '<tr class="oddeven"><td>';
    +print '<span class="fieldrequired">'.$langs->trans("PAYBOX_HMAC_KEY").'</span></td><td>';
    +print '<input size="100" type="text" name="PAYBOX_HMAC_KEY" value="'.dol_decode($conf->global->PAYBOX_HMAC_KEY).'">';
    +print '<br>'.$langs->trans("Example").': 2 ('.$langs->trans("Test").')';
    +print '</td></tr>';
    +
     print '<tr class="liste_titre">';
     print '<td>'.$langs->trans("UsageParameter").'</td>';
     print '<td>'.$langs->trans("Value").'</td>';
    diff --git a/htdocs/paybox/lib/paybox.lib.php b/htdocs/paybox/lib/paybox.lib.php
    index a4106488f53..a904c372099 100644
    --- a/htdocs/paybox/lib/paybox.lib.php
    +++ b/htdocs/paybox/lib/paybox.lib.php
    @@ -92,16 +92,41 @@ function print_paybox_redirect($PRICE,$CURRENCY,$EMAIL,$urlok,$urlko,$TAG)
         $IBS_REFUSE=$urlko;
         $IBS_BKGD="#FFFFFF";
         $IBS_WAIT="2000";
    -	$IBS_LANG="GBR"; 	// By default GBR=english (FRA, GBR, ESP, ITA et DEU...)
    -	if (preg_match('/^FR/i',$langs->defaultlang)) $IBS_LANG="FRA";
    -	if (preg_match('/^ES/i',$langs->defaultlang)) $IBS_LANG="ESP";
    -	if (preg_match('/^IT/i',$langs->defaultlang)) $IBS_LANG="ITA";
    -	if (preg_match('/^DE/i',$langs->defaultlang)) $IBS_LANG="DEU";
    -	if (preg_match('/^NL/i',$langs->defaultlang)) $IBS_LANG="NLD";
    -	if (preg_match('/^SE/i',$langs->defaultlang)) $IBS_LANG="SWE";
    -	$IBS_OUTPUT='E';
    -	$PBX_SOURCE='HTML';
    -	$PBX_TYPEPAIEMENT='CARTE';
    +    $IBS_LANG="GBR"; 	// By default GBR=english (FRA, GBR, ESP, ITA et DEU...)
    +    if (preg_match('/^FR/i',$langs->defaultlang)) $IBS_LANG="FRA";
    +    if (preg_match('/^ES/i',$langs->defaultlang)) $IBS_LANG="ESP";
    +    if (preg_match('/^IT/i',$langs->defaultlang)) $IBS_LANG="ITA";
    +    if (preg_match('/^DE/i',$langs->defaultlang)) $IBS_LANG="DEU";
    +    if (preg_match('/^NL/i',$langs->defaultlang)) $IBS_LANG="NLD";
    +    if (preg_match('/^SE/i',$langs->defaultlang)) $IBS_LANG="SWE";
    +    $IBS_OUTPUT='E';
    +    $PBX_SOURCE='HTML';
    +    $PBX_TYPEPAIEMENT='CARTE';
    +    
    +    $msg = "PBX_IDENTIFIANT=".$PBX_IDENTIFIANT.
    +           "&PBX_MODE=".$IBS_MODE.
    +           "&PBX_SITE=".$IBS_SITE.
    +           "&PBX_RANG=".$IBS_RANG.
    +           "&PBX_TOTAL=".$IBS_TOTAL.
    +           "&PBX_DEVISE=".$IBS_DEVISE.
    +           "&PBX_CMD=".$IBS_CMD.
    +           "&PBX_PORTEUR=".$IBS_PORTEUR.
    +           "&PBX_RETOUR=".$IBS_RETOUR.
    +           "&PBX_EFFECTUE=".$IBS_EFFECTUE.
    +           "&PBX_ANNULE=".$IBS_ANNULE.
    +           "&PBX_REFUSE=".$IBS_REFUSE.
    +           "&PBX_TXT=".$IBS_TXT.
    +           "&PBX_BKGD=".$IBS_BKGD.
    +           "&PBX_WAIT=".$IBS_WAIT.
    +           "&PBX_LANGUE=".$IBS_LANG.
    +           "&PBX_OUTPUT=".$IBS_OUTPUT.
    +           "&PBX_SOURCE=".$PBX_SOURCE.
    +           "&PBX_TYPEPAIEMENT=".$PBX_TYPEPAIEMENT;
    +    
    +    $binKey = pack("H*", dol_decode($conf->global->PAYBOX_HMAC_KEY));
    +            
    +    $hmac = strtoupper(hash_hmac('sha512', $msg, $binKey));
    +           
     
         dol_syslog("Soumission Paybox", LOG_DEBUG);
         dol_syslog("IBS_MODE: $IBS_MODE", LOG_DEBUG);
    @@ -157,7 +182,7 @@ function print_paybox_redirect($PRICE,$CURRENCY,$EMAIL,$urlok,$urlko,$TAG)
         print '<input type="hidden" name="PBX_OUTPUT" value="'.$IBS_OUTPUT.'">'."\n";
         print '<input type="hidden" name="PBX_SOURCE" value="'.$PBX_SOURCE.'">'."\n";
         print '<input type="hidden" name="PBX_TYPEPAIEMENT" value="'.$PBX_TYPEPAIEMENT.'">'."\n";
    -
    +    print '<input type="hidden" name="PBX_HMAC" value="'.$hmac.'">'."\n";
         print '</form>'."\n";
     
     
    
    From 0171301543a810dbb4071524e198914971eb2d9b Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Sun, 21 Oct 2018 19:19:35 +0200
    Subject: [PATCH 377/433] code comment categories class
    
    ---
     htdocs/categories/class/categorie.class.php | 24 ++++++++++++++++-----
     1 file changed, 19 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php
    index a9432234793..a7ddab761e0 100644
    --- a/htdocs/categories/class/categorie.class.php
    +++ b/htdocs/categories/class/categorie.class.php
    @@ -76,6 +76,10 @@ class Categorie extends CommonObject
     		'user'         => 7,
     		'bank_line'    => 8,
     	);
    +
    +    /**
    +	 * @var array Code mapping from ID
    +	 */
     	public static $MAP_ID_TO_CODE = array(
     		0 => 'product',
     		1 => 'supplier',
    @@ -104,7 +108,8 @@ class Categorie extends CommonObject
             'bank_account' => 'account',
             'project'  => 'project',
     	);
    -	/**
    +
    +    /**
     	 * @var array Category tables mapping from type string
     	 *
     	 * @note Move to const array when PHP 5.6 will be our minimum target
    @@ -120,7 +125,8 @@ class Categorie extends CommonObject
             'bank_account'=> 'account',
             'project'  => 'project',
     	);
    -	/**
    +
    +    /**
     	 * @var array Object class mapping from type string
     	 *
     	 * @note Move to const array when PHP 5.6 will be our minimum target
    @@ -136,7 +142,8 @@ class Categorie extends CommonObject
     		'bank_account'  => 'Account',
             'project'  => 'Project',
     	);
    -	/**
    +
    +    /**
     	 * @var array Object table mapping from type string
     	 *
     	 * @note Move to const array when PHP 5.6 will be our minimum target
    @@ -199,7 +206,14 @@ class Categorie extends CommonObject
     	 */
     	public $type;
     
    -	public $cats = array();			// Categories table in memory
    +	/**
    +	 * @var array Categories table in memory
    +	 */
    +	public $cats = array();
    +
    +    /**
    +	 * @var array Mother of table
    +	 */
     	public $motherof = array();
     
     	/**
    @@ -1360,7 +1374,7 @@ class Categorie extends CommonObject
     	 * @param   string|int	$type   Type of category ('customer', 'supplier', 'contact', 'product', 'member') or (0, 1, 2, ...)
     	 * @param   string 		$mode   'id'=Get array of category ids, 'object'=Get array of fetched category instances, 'label'=Get array of category
     	 *                      	    labels, 'id'= Get array of category IDs
    -	 * @return  mixed           	Array of category objects or < 0 if KO
    +	 * @return  array|int           Array of category objects or < 0 if KO
     	 */
     	function containing($id, $type, $mode='object')
     	{
    
    From 59307165ce766e814fd4c0a3462b1e1369c6db8b Mon Sep 17 00:00:00 2001
    From: De Coninck Laurent <laurent@adlogix.eu>
    Date: Sun, 21 Oct 2018 19:45:33 +0200
    Subject: [PATCH 378/433] fix the pdf merge
    
    fix the pdf merge.
    
    [See: #9824]
    ---
     htdocs/includes/tcpdi/tcpdi_parser.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/includes/tcpdi/tcpdi_parser.php b/htdocs/includes/tcpdi/tcpdi_parser.php
    index 038994568ac..cdeaf4f94e6 100644
    --- a/htdocs/includes/tcpdi/tcpdi_parser.php
    +++ b/htdocs/includes/tcpdi/tcpdi_parser.php
    @@ -484,7 +484,7 @@ class tcpdi_parser {
     			$v = $sarr[$key];
     			if (($key == '/Type') AND ($v[0] == PDF_TYPE_TOKEN AND ($v[1] == 'XRef'))) {
     				$valid_crs = true;
    -			} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1] >= 2))) {
    +			} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1]) >= 2)) {
     				// first object number in the subsection
     				$index_first = intval($v[1][0][1]);
     				// number of entries in the subsection
    
    From beb906b5f18fea0707d019a24dd185040c48248e Mon Sep 17 00:00:00 2001
    From: fappels <francis.appels@yahoo.com>
    Date: Sun, 21 Oct 2018 22:52:53 +0200
    Subject: [PATCH 379/433] Deprecate class property before removing it.
    
    ---
     htdocs/expedition/class/expeditionbatch.class.php | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/expedition/class/expeditionbatch.class.php b/htdocs/expedition/class/expeditionbatch.class.php
    index 227566d8382..3df77b509e7 100644
    --- a/htdocs/expedition/class/expeditionbatch.class.php
    +++ b/htdocs/expedition/class/expeditionbatch.class.php
    @@ -35,6 +35,7 @@ class ExpeditionLineBatch extends CommonObject
     	var $eatby;
     	var $batch;
     	var $qty;
    +	var $dluo_qty; // deprecated, use qty
     	var $entrepot_id;
     	var $fk_origin_stock;
     	var $fk_expeditiondet;
    @@ -118,7 +119,7 @@ class ExpeditionLineBatch extends CommonObject
     		$sql.= " ".(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':("'".$this->db->idate($this->sellby))."'").",";
     		$sql.= " ".(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':("'".$this->db->idate($this->eatby))."'").",";
     		$sql.= " ".(! isset($this->batch)?'NULL':("'".$this->db->escape($this->batch)."'")).",";
    -		$sql.= " ".(! isset($this->qty)?'NULL':$this->qty).",";
    +		$sql.= " ".(! isset($this->qty)?(! isset($this->dluo_qty)?'NULL':$this->dluo_qty):$this->qty).","; // dluo_qty deprecated, use qty
     		$sql.= " ".(! isset($this->fk_origin_stock)?'NULL':$this->fk_origin_stock);
     		$sql.= ")";
     
    @@ -218,6 +219,7 @@ class ExpeditionLineBatch extends CommonObject
     				$tmp->id = $obj->rowid;
     				$tmp->fk_origin_stock = $obj->fk_origin_stock;
     				$tmp->fk_expeditiondet = $obj->fk_expeditiondet;
    +				$tmp->dluo_qty = $obj->qty; // dluo_qty deprecated, use qty
     				$tmp->qty = $obj->qty;
     
     				$ret[]=$tmp;
    
    From 930dce76112d31e9a18c70bd451d6691059e532d Mon Sep 17 00:00:00 2001
    From: Alexandre SPANGARO <alexandre.spangaro@gmail.com>
    Date: Mon, 22 Oct 2018 06:39:23 +0200
    Subject: [PATCH 380/433] change class name from lettering to Lettering
    
    ---
     .../bookkeeping/thirdparty_lettering_customer.php        | 7 ++++---
     .../bookkeeping/thirdparty_lettering_supplier.php        | 7 ++++---
     htdocs/accountancy/class/lettering.class.php             | 9 +++++----
     3 files changed, 13 insertions(+), 10 deletions(-)
    
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    index 0cab173823c..b71ce5860f0 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2013       Olivier Geffroy         <jeff@jeffinfo.com>
      * Copyright (C) 2013       Florian Henry           <florian.henry@open-concept.pro>
      * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -21,8 +22,8 @@
      */
     
     /**
    - * \file        accountancy/bookkeeping/thirdparty_lettering_customer.php
    - * \ingroup     Advanced accountancy
    + * \file        htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
    + * \ingroup     accountancy
      * \brief       Tab to manage customer lettering
      */
     require '../../main.inc.php';
    @@ -77,7 +78,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
     $socid = GETPOST("socid", 'int');
     // if ($user->societe_id) $socid=$user->societe_id;
     
    -$lettering = new lettering($db);
    +$lettering = new Lettering($db);
     $object = new Societe($db);
     $object->id = $socid;
     $result = $object->fetch($socid);
    diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    index 659643260f9..eaeefcca8a8 100644
    --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    +++ b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    @@ -4,6 +4,7 @@
      * Copyright (C) 2013       Olivier Geffroy         <jeff@jeffinfo.com>
      * Copyright (C) 2013       Florian Henry           <florian.henry@open-concept.pro>
      * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -21,8 +22,8 @@
      */
     
     /**
    - * \file        accountancy/bookkeeping/thirdparty_lettering_supplier.php
    - * \ingroup     Advanced accountancy
    + * \file        htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
    + * \ingroup     accountancy
      * \brief       Tab to setup lettering
      */
     require '../../main.inc.php';
    @@ -79,7 +80,7 @@ if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x',
     $socid = GETPOST("socid", 'int');
     // if ($user->societe_id) $socid=$user->societe_id;
     
    -$lettering = new lettering($db);
    +$lettering = new Lettering($db);
     $object = new Societe($db);
     $object->id = $socid;
     $result = $object->fetch($socid);
    diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php
    index b6eeba24c01..db943029acc 100644
    --- a/htdocs/accountancy/class/lettering.class.php
    +++ b/htdocs/accountancy/class/lettering.class.php
    @@ -2,6 +2,7 @@
     /* Copyright (C) 2004-2005  Rodolphe Quiedeville    <rodolphe@quiedeville.org>
      * Copyright (C) 2013       Olivier Geffroy         <jeff@jeffinfo.com>
      * Copyright (C) 2013-2018  Alexandre Spangaro      <aspangaro@zendsi.com>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -18,8 +19,8 @@
      */
     
     /**
    - * \file        accountancy/class/bookkeeping.class.php
    - * \ingroup     Advanced accountancy
    + * \file        htdocs/accountancy/class/lettering.class.php
    + * \ingroup     accountancy
      * \brief       File of class for lettering
      */
     include_once DOL_DOCUMENT_ROOT . "/accountancy/class/bookkeeping.class.php";
    @@ -27,9 +28,9 @@ include_once DOL_DOCUMENT_ROOT . "/societe/class/societe.class.php";
     include_once DOL_DOCUMENT_ROOT . "/core/lib/date.lib.php";
     
     /**
    - * Class lettering
    + * Class Lettering
      */
    -class lettering extends BookKeeping
    +class Lettering extends BookKeeping
     {
     	/**
     	 * letteringThirdparty
    
    From cf28e4e44210f11c0db950c0355a4da8f3099e8d Mon Sep 17 00:00:00 2001
    From: ATM-Nicolas <nicolas.prevost@atm-consulting.fr>
    Date: Mon, 22 Oct 2018 15:19:33 +0200
    Subject: [PATCH 381/433] FIX : Variable name
    
    ---
     htdocs/core/class/html.formprojet.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php
    index 524bd82ddd1..616355eab28 100644
    --- a/htdocs/core/class/html.formprojet.class.php
    +++ b/htdocs/core/class/html.formprojet.class.php
    @@ -225,7 +225,7 @@ class FormProjets
     						}
     						else if ($obj->fk_statut == 2)
     						{
    -							if ($discard_close == 2) $disabled=1;
    +							if ($discard_closed == 2) $disabled=1;
     							$labeltoshow.=' - '.$langs->trans("Closed");
     						}
     						else if ( empty($conf->global->PROJECT_ALLOW_TO_LINK_FROM_OTHER_COMPANY) &&  $socid > 0 && (! empty($obj->fk_soc) && $obj->fk_soc != $socid))
    
    From bf46a35a31b357c08a1aa43cd64fc9ed660c0200 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 22 Oct 2018 19:05:04 +0200
    Subject: [PATCH 382/433] Fix size of key for extrafield of type select
    
    ---
     htdocs/core/class/extrafields.class.php | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php
    index ae859181f67..1840f62ca5d 100644
    --- a/htdocs/core/class/extrafields.class.php
    +++ b/htdocs/core/class/extrafields.class.php
    @@ -239,8 +239,8 @@ class ExtraFields
     				$typedb='varchar';
     				$lengthdb='255';
     			} elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox') ||($type=='chkbxlst')){
    -				$typedb='text';
    -				$lengthdb='';
    +				$typedb='varchar';
    +				$lengthdb='255';
     			} elseif ($type=='link') {
     				$typedb='int';
     				$lengthdb='11';
    @@ -542,8 +542,8 @@ class ExtraFields
     				$typedb='varchar';
     				$lengthdb='255';
     			} elseif (($type=='select') || ($type=='sellist') || ($type=='radio') || ($type=='checkbox') || ($type=='chkbxlst')) {
    -				$typedb='text';
    -				$lengthdb='';
    +				$typedb='varchar';
    +				$lengthdb='255';
     			} elseif ($type == 'html') {
     				$typedb='text';
     			} elseif ($type=='link') {
    
    From f65df9e541db21f6b1f221cf33c7cac8d0319b30 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Mon, 22 Oct 2018 20:06:03 +0200
    Subject: [PATCH 383/433] NEW Add option PDF_DISABLE_MYCOMPANY_LOGO to disable
     logo on PDF
    
    ---
     .../commande/doc/pdf_einstein.modules.php     |  31 +-
     .../commande/doc/pdf_eratosthene.modules.php  | 165 ++++-----
     .../modules/facture/doc/pdf_crabe.modules.php |  31 +-
     .../facture/doc/pdf_sponge.modules.php        | 327 +++++++++---------
     .../modules/propale/doc/pdf_azur.modules.php  |  31 +-
     .../modules/propale/doc/pdf_cyan.modules.php  | 177 +++++-----
     6 files changed, 390 insertions(+), 372 deletions(-)
    
    diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    index 273027f3b99..ad77e9bea32 100644
    --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php
    @@ -1261,27 +1261,30 @@ class pdf_einstein extends ModelePDFCommandes
     		$pdf->SetXY($this->marge_gauche,$posy);
     
     		// Logo
    -		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    -		if ($this->emetteur->logo)
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
     		{
    -			if (is_readable($logo))
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
     			{
    -			    $height=pdf_getHeightForLogo($logo);
    -			    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +				    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B', $default_font_size -2);
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
     			}
     			else
     			{
    -				$pdf->SetTextColor(200,0,0);
    -				$pdf->SetFont('','B', $default_font_size -2);
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     			}
     		}
    -		else
    -		{
    -			$text=$this->emetteur->name;
    -			$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    -		}
     
     		$pdf->SetFont('','B', $default_font_size + 3);
     		$pdf->SetXY($posx,$posy);
    diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    index 039f29fa379..89297d1bdc6 100644
    --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    @@ -136,7 +136,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     
     		// Define position of columns
     		$this->posxdesc=$this->marge_gauche+1;
    -		
    +
     
     		$this->tva=array();
     		$this->localtax1=array();
    @@ -252,7 +252,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     				        break;
     				    }
     				}
    -				
    +
     				if (empty($this->atleastonediscount) && empty($conf->global->PRODUCT_USE_UNITS))
     				{
     					$this->posxpicture+=($this->postotalht - $this->posxdiscount);
    @@ -316,25 +316,25 @@ class pdf_eratosthene extends ModelePDFCommandes
     				{
     				    $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
     				    $pageposbeforenote = $pagenb;
    -				    
    +
     				    $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
     				    complete_substitutions_array($substitutionarray, $outputlangs, $object);
     				    $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
    -				    
    +
     					$tab_top -= 2;
    -				    
    +
     				    $pdf->startTransaction();
    -				    
    +
     				    $pdf->SetFont('','', $default_font_size - 1);
     				    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     				    // Description
     				    $pageposafternote=$pdf->getPage();
     				    $posyafter = $pdf->GetY();
    -				    
    +
     				    if($pageposafternote>$pageposbeforenote )
     				    {
     				        $pdf->rollbackTransaction(true);
    -				        
    +
     				        // prepar pages to receive notes
     				        while ($pagenb < $pageposafternote) {
     				            $pdf->AddPage();
    @@ -346,16 +346,16 @@ class pdf_eratosthene extends ModelePDFCommandes
     				            // The only function to edit the bottom margin of current page to set it.
     				            $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     				        }
    -				        
    +
     				        // back to start
     				        $pdf->setPage($pageposbeforenote);
     				        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     				        $pdf->SetFont('','', $default_font_size - 1);
     				        $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     				        $pageposafternote=$pdf->getPage();
    -				        
    +
     				        $posyafter = $pdf->GetY();
    -				        
    +
     				        if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
     				        {
     				            $pdf->AddPage('','',true);
    @@ -367,14 +367,14 @@ class pdf_eratosthene extends ModelePDFCommandes
     				            $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     				            //$posyafter = $tab_top_newpage;
     				        }
    -				        
    -				        
    +
    +
     				        // apply note frame to previus pages
     				        $i = $pageposbeforenote;
     				        while ($i < $pageposafternote) {
     				            $pdf->setPage($i);
    -				            
    -				            
    +
    +
     				            $pdf->SetDrawColor(128,128,128);
     				            // Draw note frame
     				            if($i>$pageposbeforenote){
    @@ -385,21 +385,21 @@ class pdf_eratosthene extends ModelePDFCommandes
     				                $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
     				                $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
     				            }
    -				            
    +
     				            // Add footer
     				            $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
     				            $this->_pagefoot($pdf,$object,$outputlangs,1);
    -				            
    +
     				            $i++;
     				        }
    -				        
    +
     				        // apply note frame to last page
     				        $pdf->setPage($pageposafternote);
     				        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     				        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     				        $height_note=$posyafter-$tab_top_newpage;
     				        $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
    -				        
    +
     				    }
     				    else // No pagebreak
     				    {
    @@ -407,8 +407,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     				        $posyafter = $pdf->GetY();
     				        $height_note=$posyafter-$tab_top;
     				        $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
    -				        
    -				        
    +
    +
     				        if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
     				        {
     				            // not enough space, need to add page
    @@ -418,12 +418,12 @@ class pdf_eratosthene extends ModelePDFCommandes
     				            $pdf->setPage($pageposafternote);
     				            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     				            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    -				            
    +
     				            $posyafter = $tab_top_newpage;
     				        }
    -				        
    +
     				    }
    -				    
    +
     				    $tab_height = $tab_height - $height_note;
     				    $tab_top = $posyafter +6;
     				}
    @@ -435,10 +435,10 @@ class pdf_eratosthene extends ModelePDFCommandes
     				$iniY = $tab_top + 7;
     				$curY = $tab_top + 7;
     				$nexY = $tab_top + 7;
    -				
    +
     				// Use new auto collum system
     				$this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    -				
    +
     				// Loop on each lines
     				$pageposbeforeprintlines=$pdf->getPage();
     				$pagenb = $pageposbeforeprintlines;
    @@ -456,7 +456,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					$curX = $this->posxdesc-1;
     
     					$showpricebeforepagebreak=1;
    -					
    +
     					if($this->getColumnStatus('desc'))
     					{
         					$pdf->startTransaction();
    @@ -493,7 +493,7 @@ class pdf_eratosthene extends ModelePDFCommandes
         					}
         					$posYAfterDescription=$pdf->GetY();
     					}
    -					
    +
     					$nexY = $pdf->GetY();
     					$pageposafter=$pdf->getPage();
     
    @@ -515,7 +515,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Unit price before discount
     					if ($this->getColumnStatus('subprice'))
     					{
    @@ -523,7 +523,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Quantity
     					// Enough for 6 chars
     					if ($this->getColumnStatus('qty'))
    @@ -532,8 +532,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    -					
    +
    +
     					// Unit
     					if ($this->getColumnStatus('unit'))
     					{
    @@ -541,7 +541,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Discount on line
     					if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
     					{
    @@ -549,7 +549,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Total HT line
     					if ($this->getColumnStatus('totalexcltax'))
     					{
    @@ -557,8 +557,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    -					
    +
    +
     					$parameters=array(
     					    'object' => $object,
     					    'i' => $i,
    @@ -569,7 +569,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     					    'hidedetails' => $hidedetails
     					);
     					$reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this);    // Note that $object may have been modified by hook
    -					
    +
     
     					// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
     					if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva;
    @@ -1220,29 +1220,29 @@ class pdf_eratosthene extends ModelePDFCommandes
     		foreach ($this->cols as $colKey => $colDef)
     		{
     		    if(!$this->getColumnStatus($colKey)) continue;
    -		    
    +
     		    // get title label
     		    $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
    -		    
    +
     		    // Add column separator
     		    if(!empty($colDef['border-left'])){
     		        $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
     		    }
    -		    
    +
     		    if (empty($hidetop))
     		    {
     		      $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
    -		    
    +
     		      $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
     		      $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
     		    }
     		}
    -		
    +
     		if (empty($hidetop)){
     			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
     		}
     
    -		
    +
     	}
     
     	/**
    @@ -1281,27 +1281,30 @@ class pdf_eratosthene extends ModelePDFCommandes
     		$pdf->SetXY($this->marge_gauche,$posy);
     
     		// Logo
    -		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    -		if ($this->emetteur->logo)
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
     		{
    -			if (is_readable($logo))
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
     			{
    -			    $height=pdf_getHeightForLogo($logo);
    -			    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +				    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B', $default_font_size -2);
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
     			}
     			else
     			{
    -				$pdf->SetTextColor(200,0,0);
    -				$pdf->SetFont('','B', $default_font_size -2);
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     			}
     		}
    -		else
    -		{
    -			$text=$this->emetteur->name;
    -			$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    -		}
     
     		$pdf->SetFont('','B', $default_font_size + 3);
     		$pdf->SetXY($posx,$posy);
    @@ -1469,9 +1472,9 @@ class pdf_eratosthene extends ModelePDFCommandes
     		$showdetails=$conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS;
     		return pdf_pagefoot($pdf,$outputlangs,'ORDER_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
    -	
     
    -	
    +
    +
     	/**
     	 *   	Define Array Column Field
     	 *
    @@ -1483,21 +1486,21 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *      @return	null
     	 */
     	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    -	    
    +
     	    global $conf, $hookmanager;
    -	    
    +
     	    // Default field style for content
     	    $this->defaultContentsFieldsStyle = array(
     	        'align' => 'R', // R,C,L
     	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    // Default field style for content
     	    $this->defaultTitlesFieldsStyle = array(
     	        'align' => 'C', // R,C,L
     	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    /*
     	     * For exemple
     	     $this->cols['theColKey'] = array(
    @@ -1515,7 +1518,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	     ),
     	     );
     	     */
    -	    
    +
     	    $rank=0; // do not use negative rank
     	    $this->cols['desc'] = array(
     	        'rank' => $rank,
    @@ -1532,7 +1535,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	            'align' => 'L',
     	        ),
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['photo'] = array(
     	        'rank' => $rank,
    @@ -1547,13 +1550,13 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => false, // remove left line separator
     	    );
    -	    
    +
     	    if (! empty($conf->global->MAIN_GENERATE_ORDERS_WITH_PICTURE))
     	    {
     	        $this->cols['photo']['status'] = true;
     	    }
    -	    
    -	    
    +
    +
     	    $rank = $rank + 10;
     	    $this->cols['vat'] = array(
     	        'rank' => $rank,
    @@ -1564,12 +1567,12 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
     	    {
     	        $this->cols['vat']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['subprice'] = array(
     	        'rank' => $rank,
    @@ -1580,7 +1583,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['qty'] = array(
     	        'rank' => $rank,
    @@ -1591,7 +1594,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['progress'] = array(
     	        'rank' => $rank,
    @@ -1602,12 +1605,12 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => false, // add left line separator
     	    );
    -	    
    +
     	    if($this->situationinvoice)
     	    {
     	        $this->cols['progress']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['unit'] = array(
     	        'rank' => $rank,
    @@ -1621,7 +1624,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	    if($conf->global->PRODUCT_USE_UNITS){
     	        $this->cols['unit']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['discount'] = array(
     	        'rank' => $rank,
    @@ -1635,7 +1638,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	    if ($this->atleastonediscount){
     	        $this->cols['discount']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['totalexcltax'] = array(
     	        'rank' => $rank,
    @@ -1646,8 +1649,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    -	    
    +
    +
     	    $parameters=array(
     	        'object' => $object,
     	        'outputlangs' => $outputlangs,
    @@ -1655,7 +1658,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	        'hidedesc' => $hidedesc,
     	        'hideref' => $hideref
     	    );
    -	    
    +
     	    $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this);    // Note that $object may have been modified by hook
     	    if ($reshook < 0)
     	    {
    @@ -1669,7 +1672,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	    {
     	        $this->cols = $hookmanager->resArray;
     	    }
    -	    
    +
     	}
    -	
    +
     }
    diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
    index af770999fda..c4d69424cb2 100644
    --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
    +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
    @@ -1598,27 +1598,30 @@ class pdf_crabe extends ModelePDFFactures
     		$pdf->SetXY($this->marge_gauche,$posy);
     
     		// Logo
    -		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    -		if ($this->emetteur->logo)
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
     		{
    -			if (is_readable($logo))
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
     			{
    -			    $height=pdf_getHeightForLogo($logo);
    -				$pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +					$pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B',$default_font_size - 2);
    +					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
     			}
     			else
     			{
    -				$pdf->SetTextColor(200,0,0);
    -				$pdf->SetFont('','B',$default_font_size - 2);
    -				$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    -				$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     			}
     		}
    -		else
    -		{
    -			$text=$this->emetteur->name;
    -			$pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    -		}
     
     		$pdf->SetFont('','B', $default_font_size + 3);
     		$pdf->SetXY($posx,$posy);
    diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    index 74f4bf34acf..ca27bd09aff 100644
    --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    @@ -108,7 +108,7 @@ class pdf_sponge extends ModelePDFFactures
     	function __construct($db)
     	{
     		global $conf,$langs,$mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "bills"));
     
    @@ -147,8 +147,8 @@ class pdf_sponge extends ModelePDFFactures
     
     		// Define position of columns
     		$this->posxdesc=$this->marge_gauche+1; // used for notes ans other stuff
    -		
    -		//  Use new system for position of columns, view  $this->defineColumnField() 
    +
    +		//  Use new system for position of columns, view  $this->defineColumnField()
     
     		$this->tva=array();
     		$this->localtax1=array();
    @@ -173,27 +173,27 @@ class pdf_sponge extends ModelePDFFactures
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
     	    global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
    -	    
    +
     	    if (! is_object($outputlangs)) $outputlangs=$langs;
     	    // For backward compatibility with FPDF, force output charset to ISO, because FPDF expect text to be encoded in ISO
     	    if (! empty($conf->global->MAIN_USE_FPDF)) $outputlangs->charset_output='ISO-8859-1';
    -	    
    +
     	    // Translations
     	    $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies"));
    -	    
    +
     	    $nblignes = count($object->lines);
    -	    
    +
     	    // Loop on each lines to detect if there is at least one image to show
     	    $realpatharray=array();
     	    $this->atleastonephoto = false;
     	    if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE))
     	    {
     	        $objphoto = new Product($this->db);
    -	        
    +
     	        for ($i = 0 ; $i < $nblignes ; $i++)
     	        {
     	            if (empty($object->lines[$i]->fk_product)) continue;
    -	            
    +
     	            $objphoto->fetch($object->lines[$i]->fk_product);
     	            //var_dump($objphoto->ref);exit;
     	            if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO))
    @@ -206,14 +206,14 @@ class pdf_sponge extends ModelePDFFactures
     	                $pdir[0] = get_exdir(0,0,0,0,$objphoto,'product') . dol_sanitizeFileName($objphoto->ref).'/';				// default
     	                $pdir[1] = get_exdir($objphoto->id,2,0,0,$objphoto,'product') . $objphoto->id ."/photos/";	// alternative
     	            }
    -	            
    +
     	            $arephoto = false;
     	            foreach ($pdir as $midir)
     	            {
     	                if (! $arephoto)
     	                {
     	                    $dir = $conf->product->dir_output.'/'.$midir;
    -	                    
    +
     	                    foreach ($objphoto->liste_photos($dir,1) as $key => $obj)
     	                    {
     	                        if (empty($conf->global->CAT_HIGH_QUALITY_IMAGES))		// If CAT_HIGH_QUALITY_IMAGES not defined, we use thumb if defined and then original photo
    @@ -231,28 +231,28 @@ class pdf_sponge extends ModelePDFFactures
     	                        {
     	                            $filename=$obj['photo'];
     	                        }
    -	                        
    +
     	                        $realpath = $dir.$filename;
     	                        $arephoto = true;
     	                        $this->atleastonephoto = true;
     	                    }
     	                }
     	            }
    -	            
    +
     	            if ($realpath && $arephoto) $realpatharray[$i]=$realpath;
     	        }
     	    }
    -	    
    +
     	    //if (count($realpatharray) == 0) $this->posxpicture=$this->posxtva;
    -	    
    +
     	    if ($conf->facture->dir_output)
     	    {
     	        $object->fetch_thirdparty();
    -	        
    +
     	        $deja_regle = $object->getSommePaiement(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
     	        $amount_credit_notes_included = $object->getSumCreditNotesUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
     	        $amount_deposits_included = $object->getSumDepositsUsed(($conf->multicurrency->enabled && $object->multicurrency_tx != 1) ? 1 : 0);
    -	        
    +
     	        // Definition of $dir and $file
     	        if ($object->specimen)
     	        {
    @@ -273,7 +273,7 @@ class pdf_sponge extends ModelePDFFactures
     	                return 0;
     	            }
     	        }
    -	        
    +
     	        if (file_exists($dir))
     	        {
     	            // Add pdfgeneration hook
    @@ -286,47 +286,47 @@ class pdf_sponge extends ModelePDFFactures
     	            $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
     	            global $action;
     	            $reshook=$hookmanager->executeHooks('beforePDFCreation',$parameters,$object,$action);    // Note that $action and $object may have been modified by some hooks
    -	            
    +
     	            // Set nblignes with the new facture lines content after hook
     	            $nblignes = count($object->lines);
     	            $nbpayments = count($object->getListOfPayments());
    -	            
    +
     	            // Create pdf instance
     	            $pdf=pdf_getInstance($this->format);
     	            $default_font_size = pdf_getPDFFontSize($outputlangs);	// Must be after pdf_getInstance
     	            $pdf->SetAutoPageBreak(1,0);
    -	            
    +
     	            $heightforinfotot = 50+(4*$nbpayments);	// Height reserved to output the info and total part and payment part
     	            $heightforfreetext= (isset($conf->global->MAIN_PDF_FREETEXT_HEIGHT)?$conf->global->MAIN_PDF_FREETEXT_HEIGHT:5);	// Height reserved to output the free text on last page
     	            $heightforfooter = $this->marge_basse + (empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS)?12:22);	// Height reserved to output the footer (value include bottom margin)
    -	            
    +
     	            if (class_exists('TCPDF'))
     	            {
     	                $pdf->setPrintHeader(false);
     	                $pdf->setPrintFooter(false);
     	            }
     	            $pdf->SetFont(pdf_getPDFFont($outputlangs));
    -	            
    +
     	            // Set path to the background PDF File
                     if (! empty($conf->global->MAIN_ADD_PDF_BACKGROUND))
     	            {
     	                $pagecount = $pdf->setSourceFile($conf->mycompany->dir_output.'/'.$conf->global->MAIN_ADD_PDF_BACKGROUND);
     	                $tplidx = $pdf->importPage(1);
     	            }
    -	            
    +
     	            $pdf->Open();
     	            $pagenb=0;
     	            $pdf->SetDrawColor(128,128,128);
    -	            
    +
     	            $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref));
     	            $pdf->SetSubject($outputlangs->transnoentities("PdfInvoiceTitle"));
     	            $pdf->SetCreator("Dolibarr ".DOL_VERSION);
     	            $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs)));
     	            $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("PdfInvoiceTitle")." ".$outputlangs->convToOutputCharset($object->thirdparty->name));
     	            if (! empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false);
    -	            
    +
     	            $pdf->SetMargins($this->marge_gauche, $this->marge_haute, $this->marge_droite);   // Left, Top, Right
    -	            
    +
     	            // Does we have at least one line with discount $this->atleastonediscount
     	            foreach ($object->lines as $line) {
     	               if ($line->remise_percent){
    @@ -334,30 +334,30 @@ class pdf_sponge extends ModelePDFFactures
     	                    break;
     	               }
     	            }
    -	            
    -	           
    +
    +
     	            // Situation invoice handling
     	            if ($object->situation_cycle_ref)
     	            {
     	                $this->situationinvoice = true;
     	            }
    -	            
    +
     	            // New page
     	            $pdf->AddPage();
     	            if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     	            $pagenb++;
    -	            
    +
     	            $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs);
     	            $pdf->SetFont('','', $default_font_size - 1);
     	            $pdf->MultiCell(0, 3, '');		// Set interline to 3
     	            $pdf->SetTextColor(0,0,0);
    -	            
    +
     	            $tab_top = 90+$top_shift;
     	            $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
     	            $tab_height = 130-$top_shift;
     	            $tab_height_newpage = 150;
     	            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift;
    -	            
    +
     	            // Incoterm
     	            $height_incoterms = 0;
     	            if ($conf->incoterm->enabled)
    @@ -366,21 +366,21 @@ class pdf_sponge extends ModelePDFFactures
     	                if ($desc_incoterms)
     	                {
     						$tab_top -= 2;
    -	                    
    +
     	                    $pdf->SetFont('','', $default_font_size - 1);
     	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top-1, dol_htmlentitiesbr($desc_incoterms), 0, 1);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                    $height_incoterms=$nexY-$tab_top;
    -	                    
    +
     	                    // Rect prend une longueur en 3eme param
     	                    $pdf->SetDrawColor(192,192,192);
     	                    $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_incoterms+1);
    -	                    
    +
     	                    $tab_top = $nexY+6;
     	                    $height_incoterms += 4;
     	                }
     	            }
    -	            
    +
     	            // Affiche notes
     	            $notetoshow=empty($object->note_public)?'':$object->note_public;
     	            if (! empty($conf->global->MAIN_ADD_SALE_REP_SIGNATURE_IN_NOTE))
    @@ -394,7 +394,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    if (! empty($salerepobj->signature)) $notetoshow=dol_concatdesc($notetoshow, $salerepobj->signature);
     	                }
     	            }
    -	            
    +
     	            $pagenb = $pdf->getPage();
     	            if ($notetoshow)
     	            {
    @@ -402,24 +402,24 @@ class pdf_sponge extends ModelePDFFactures
     
     	                $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
     	                $pageposbeforenote = $pagenb;
    -	                
    +
     	                $substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
     	                complete_substitutions_array($substitutionarray, $outputlangs, $object);
     	                $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
    -	                
    -	                
    +
    +
     	                $pdf->startTransaction();
    -	                
    +
     	                $pdf->SetFont('','', $default_font_size - 1);
     	                $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     	                // Description
     	                $pageposafternote=$pdf->getPage();
     	                $posyafter = $pdf->GetY();
    -	                
    +
     	                if($pageposafternote>$pageposbeforenote )
     	                {
     	                    $pdf->rollbackTransaction(true);
    -	                    
    +
     	                    // prepar pages to receive notes
     	                    while ($pagenb < $pageposafternote) {
     	                        $pdf->AddPage();
    @@ -431,16 +431,16 @@ class pdf_sponge extends ModelePDFFactures
     	                        // The only function to edit the bottom margin of current page to set it.
     	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     	                    }
    -	                    
    +
     	                    // back to start
     	                    $pdf->setPage($pageposbeforenote);
     	                    $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     	                    $pdf->SetFont('','', $default_font_size - 1);
     	                    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     	                    $pageposafternote=$pdf->getPage();
    -	                    
    +
     	                    $posyafter = $pdf->GetY();
    -	                    
    +
     	                    if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
     	                    {
     	                        $pdf->AddPage('','',true);
    @@ -452,14 +452,14 @@ class pdf_sponge extends ModelePDFFactures
     	                        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     	                        //$posyafter = $tab_top_newpage;
     	                    }
    -	                    
    -	                    
    +
    +
     	                    // apply note frame to previus pages
     	                    $i = $pageposbeforenote;
     	                    while ($i < $pageposafternote) {
     	                        $pdf->setPage($i);
    -	                        
    -	                        
    +
    +
     	                        $pdf->SetDrawColor(128,128,128);
     	                        // Draw note frame
     	                        if($i>$pageposbeforenote){
    @@ -470,21 +470,21 @@ class pdf_sponge extends ModelePDFFactures
     	                            $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
     	                            $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
     	                        }
    -	                        
    +
     	                        // Add footer
     	                        $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
     	                        $this->_pagefoot($pdf,$object,$outputlangs,1);
    -	                        
    +
     	                        $i++;
     	                    }
    -	                    
    +
     	                    // apply note frame to last page
     	                    $pdf->setPage($pageposafternote);
     	                    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     	                    if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     	                    $height_note=$posyafter-$tab_top_newpage;
     	                    $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
    -	                    
    +
     	                }
     	                else // No pagebreak
     	                {
    @@ -492,8 +492,8 @@ class pdf_sponge extends ModelePDFFactures
     	                    $posyafter = $pdf->GetY();
     	                    $height_note=$posyafter-$tab_top;
     	                    $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
    -	                    
    -	                    
    +
    +
     	                    if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
     	                    {
     	                        // not enough space, need to add page
    @@ -503,12 +503,12 @@ class pdf_sponge extends ModelePDFFactures
     	                        $pdf->setPage($pageposafternote);
     	                        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     	                        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    -	                        
    +
     	                        $posyafter = $tab_top_newpage;
     	                    }
    -	                    
    +
     	                }
    -	                
    +
     	                $tab_height = $tab_height - $height_note;
     	                $tab_top = $posyafter +6;
     	            }
    @@ -516,36 +516,36 @@ class pdf_sponge extends ModelePDFFactures
     	            {
     	                $height_note=0;
     	            }
    -	            
    +
     	            $iniY = $tab_top + 7;
     	            $curY = $tab_top + 7;
     	            $nexY = $tab_top + 7;
    -	            
    +
     	            // Use new auto collum system
     	            $this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    -	            
    +
     	            // Loop on each lines
     	            $pageposbeforeprintlines=$pdf->getPage();
     	            $pagenb = $pageposbeforeprintlines;
     	            for ($i = 0; $i < $nblignes; $i++)
     	            {
    -	                
    +
     	                $curY = $nexY;
     	                $pdf->SetFont('','', $default_font_size - 1);   // Into loop to work with multipage
     	                $pdf->SetTextColor(0,0,0);
    -	                
    +
     	                // Define size of image if we need it
     	                $imglinesize=array();
     	                if (! empty($realpatharray[$i])) $imglinesize=pdf_getSizeForImage($realpatharray[$i]);
    -	                
    +
     	                $pdf->setTopMargin($tab_top_newpage);
     	                $pdf->setPageOrientation('', 1, $heightforfooter+$heightforfreetext+$heightforinfotot);	// The only function to edit the bottom margin of current page to set it.
     	                $pageposbefore=$pdf->getPage();
    -	                
    +
     	                $showpricebeforepagebreak=1;
     	                $posYAfterImage=0;
     	                $posYAfterDescription=0;
    -	                
    +
     	                if($this->getColumnStatus('photo'))
     	                {
         	                // We start with Photo of product line
    @@ -554,11 +554,11 @@ class pdf_sponge extends ModelePDFFactures
         	                    $pdf->AddPage('','',true);
         	                    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
         	                    $pdf->setPage($pageposbefore+1);
    -    	                    
    +
         	                    $curY = $tab_top_newpage;
         	                    $showpricebeforepagebreak=0;
         	                }
    -    	                
    +
         	                if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
         	                {
         	                    $pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300);	// Use 300 dpi
    @@ -566,7 +566,7 @@ class pdf_sponge extends ModelePDFFactures
         	                    $posYAfterImage=$curY+$imglinesize['height'];
         	                }
     	                }
    -	                
    +
     	                // Description of product line
     	                if ($this->getColumnStatus('desc'))
     	                {
    @@ -604,20 +604,20 @@ class pdf_sponge extends ModelePDFFactures
         	                }
         	                $posYAfterDescription=$pdf->GetY();
     	                }
    -	                
    +
     	                $nexY = $pdf->GetY();
     	                $pageposafter=$pdf->getPage();
     	                $pdf->setPage($pageposbefore);
     	                $pdf->setTopMargin($this->marge_haute);
     	                $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
    -	                
    +
     	                // We suppose that a too long description or photo were moved completely on next page
     	                if ($pageposafter > $pageposbefore && empty($showpricebeforepagebreak)) {
    -	                    $pdf->setPage($pageposafter); $curY = $tab_top_newpage; 
    +	                    $pdf->setPage($pageposafter); $curY = $tab_top_newpage;
     	                }
    -	                
    +
     	                $pdf->SetFont('','', $default_font_size - 1);   // On repositionne la police par defaut
    -	                
    +
     	                // VAT Rate
     	                if ($this->getColumnStatus('vat'))
     	                {
    @@ -625,7 +625,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'vat', $vat_rate);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Unit price before discount
     	                if ($this->getColumnStatus('subprice'))
     	                {
    @@ -633,7 +633,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Quantity
     	                // Enough for 6 chars
     	                if ($this->getColumnStatus('qty'))
    @@ -642,7 +642,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Situation progress
     	                if ($this->getColumnStatus('progress'))
     	                {
    @@ -650,7 +650,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'progress', $progress);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Unit
     	                if ($this->getColumnStatus('unit'))
     	                {
    @@ -658,7 +658,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Discount on line
     	                if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
     	                {
    @@ -666,7 +666,7 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    +
     	                // Total HT line
     	                if ($this->getColumnStatus('totalexcltax'))
     	                {
    @@ -674,8 +674,8 @@ class pdf_sponge extends ModelePDFFactures
     	                    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
     	                    $nexY = max($pdf->GetY(),$nexY);
     	                }
    -	                
    -	                
    +
    +
     	                $parameters=array(
     	                    'object' => $object,
     	                    'i' => $i,
    @@ -686,9 +686,9 @@ class pdf_sponge extends ModelePDFFactures
     	                    'hidedetails' => $hidedetails
     	                );
     	                $reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this);    // Note that $object may have been modified by hook
    -	                
    -	                
    -	                
    +
    +
    +
     	                $sign=1;
     	                if (isset($object->type) && $object->type == 2 && ! empty($conf->global->INVOICE_POSITIVE_CREDIT_NOTE)) $sign=-1;
     	                // Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
    @@ -701,20 +701,20 @@ class pdf_sponge extends ModelePDFFactures
     	                    if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne= $sign * $object->lines[$i]->multicurrency_total_tva;
     	                    else $tvaligne= $sign * $object->lines[$i]->total_tva;
     	                }
    -	                
    +
     	                $localtax1ligne=$object->lines[$i]->total_localtax1;
     	                $localtax2ligne=$object->lines[$i]->total_localtax2;
     	                $localtax1_rate=$object->lines[$i]->localtax1_tx;
     	                $localtax2_rate=$object->lines[$i]->localtax2_tx;
     	                $localtax1_type=$object->lines[$i]->localtax1_type;
     	                $localtax2_type=$object->lines[$i]->localtax2_type;
    -	                
    +
     	                if ($object->remise_percent) $tvaligne-=($tvaligne*$object->remise_percent)/100;
     	                if ($object->remise_percent) $localtax1ligne-=($localtax1ligne*$object->remise_percent)/100;
     	                if ($object->remise_percent) $localtax2ligne-=($localtax2ligne*$object->remise_percent)/100;
    -	                
    +
     	                $vatrate=(string) $object->lines[$i]->tva_tx;
    -	                
    +
     	                // Retrieve type from database for backward compatibility with old records
     	                if ((! isset($localtax1_type) || $localtax1_type=='' || ! isset($localtax2_type) || $localtax2_type=='') // if tax type not defined
     	                    && (! empty($localtax1_rate) || ! empty($localtax2_rate))) // and there is local tax
    @@ -723,19 +723,19 @@ class pdf_sponge extends ModelePDFFactures
     	                    $localtax1_type = $localtaxtmp_array[0];
     	                    $localtax2_type = $localtaxtmp_array[2];
     	                }
    -	                
    +
     	                // retrieve global local tax
     	                if ($localtax1_type && $localtax1ligne != 0)
     	                    $this->localtax1[$localtax1_type][$localtax1_rate]+=$localtax1ligne;
     	                    if ($localtax2_type && $localtax2ligne != 0)
     	                        $this->localtax2[$localtax2_type][$localtax2_rate]+=$localtax2ligne;
    -	                        
    +
     	                        if (($object->lines[$i]->info_bits & 0x01) == 0x01) $vatrate.='*';
     	                        if (! isset($this->tva[$vatrate])) 				$this->tva[$vatrate]=0;
     	                        $this->tva[$vatrate] += $tvaligne;
    -	                        
    +
     	                        $nexY = max($nexY,$posYAfterImage);
    -	                        
    +
     	                        // Add line
     	                        if (! empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblignes - 1))
     	                        {
    @@ -745,9 +745,9 @@ class pdf_sponge extends ModelePDFFactures
     	                            $pdf->line($this->marge_gauche, $nexY+1, $this->page_largeur - $this->marge_droite, $nexY+1);
     	                            $pdf->SetLineStyle(array('dash'=>0));
     	                        }
    -	                        
    +
     	                        $nexY+=2;    // Passe espace entre les lignes
    -	                        
    +
     	                        // Detect if some page were added automatically and output _tableau for past pages
     	                        while ($pagenb < $pageposafter)
     	                        {
    @@ -766,7 +766,7 @@ class pdf_sponge extends ModelePDFFactures
     	                            $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
     	                            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     	                        }
    -	                        
    +
     	                        if (isset($object->lines[$i+1]->pagebreak) && $object->lines[$i+1]->pagebreak)
     	                        {
     	                            if ($pagenb == $pageposafter)
    @@ -784,9 +784,9 @@ class pdf_sponge extends ModelePDFFactures
     	                            $pagenb++;
     	                            if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     	                        }
    -	                  
    +
     	            }
    -	            
    +
     	            // Show square
     	            if ($pagenb == $pageposbeforeprintlines)
     	            {
    @@ -798,38 +798,38 @@ class pdf_sponge extends ModelePDFFactures
     	                $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code);
     	                $bottomlasttab=$this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1;
     	            }
    -	            
    +
     	            // Affiche zone infos
     	            $posy=$this->_tableau_info($pdf, $object, $bottomlasttab, $outputlangs);
    -	            
    +
     	            // Affiche zone totaux
     	            $posy=$this->_tableau_tot($pdf, $object, $deja_regle, $bottomlasttab, $outputlangs);
    -	            
    +
     	            // 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);
     	            }
    -	            
    +
     	            // Pied de page
     	            $this->_pagefoot($pdf,$object,$outputlangs);
     	            if (method_exists($pdf,'AliasNbPages')) $pdf->AliasNbPages();
    -	            
    +
     	            $pdf->Close();
    -	            
    +
     	            $pdf->Output($file,'F');
    -	            
    +
     	            // Add pdfgeneration hook
     	            $hookmanager->initHooks(array('pdfgeneration'));
     	            $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs);
     	            global $action;
     	            $reshook=$hookmanager->executeHooks('afterPDFCreation',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
    -	            
    +
     	            if (! empty($conf->global->MAIN_UMASK))
     	                @chmod($file, octdec($conf->global->MAIN_UMASK));
    -	                
    +
     	                $this->result = array('fullpath'=>$file);
    -	                
    +
     	                return 1;   // No error
     	        }
     	        else
    @@ -1511,29 +1511,29 @@ class pdf_sponge extends ModelePDFFactures
     		foreach ($this->cols as $colKey => $colDef)
     		{
     		    if(!$this->getColumnStatus($colKey)) continue;
    -		    
    +
     		    // get title label
     		    $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
    -		    
    +
     		    // Add column separator
     		    if(!empty($colDef['border-left'])){
     		        $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
     		    }
    -		    
    +
     		    if (empty($hidetop))
     		    {
     		      $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
    -		    
    +
     		      $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
     		      $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
     		    }
     		}
    -		
    +
     		if (empty($hidetop)){
     			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
     		}
     
    -		
    +
     	}
     
     	/**
    @@ -1548,7 +1548,7 @@ class pdf_sponge extends ModelePDFFactures
     	function _pagehead(&$pdf, $object, $showaddress, $outputlangs)
     	{
     		global $conf, $langs;
    -		
    +
     		// Translations
     		$outputlangs->loadLangs(array("main", "bills", "propal", "companies"));
     
    @@ -1573,27 +1573,30 @@ class pdf_sponge extends ModelePDFFactures
     		$pdf->SetXY($this->marge_gauche,$posy);
     
     		// Logo
    -		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    -		if ($this->emetteur->logo)
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
     		{
    -			if (is_readable($logo))
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
     			{
    -			    $height=pdf_getHeightForLogo($logo);
    -				$pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +					$pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B',$default_font_size - 2);
    +					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
     			}
     			else
     			{
    -				$pdf->SetTextColor(200,0,0);
    -				$pdf->SetFont('','B',$default_font_size - 2);
    -				$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    -				$pdf->MultiCell($w, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     			}
     		}
    -		else
    -		{
    -			$text=$this->emetteur->name;
    -			$pdf->MultiCell($w, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    -		}
     
     		$pdf->SetFont('','B', $default_font_size + 3);
     		$pdf->SetXY($posx,$posy);
    @@ -1822,9 +1825,9 @@ class pdf_sponge extends ModelePDFFactures
     		return pdf_pagefoot($pdf,$outputlangs,'INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
     
    -	
    -	
    -	
    +
    +
    +
     	/**
     	 *   	Define Array Column Field
     	 *
    @@ -1836,21 +1839,21 @@ class pdf_sponge extends ModelePDFFactures
     	 *      @return	null
     	 */
     	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    -	    
    +
     	    global $conf, $hookmanager;
    -	    
    +
     	    // Default field style for content
     	    $this->defaultContentsFieldsStyle = array(
     	        'align' => 'R', // R,C,L
     	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    // Default field style for content
     	    $this->defaultTitlesFieldsStyle = array(
    -	        'align' => 'C', // R,C,L 
    +	        'align' => 'C', // R,C,L
     	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    /*
     	     * For exemple
     	    $this->cols['theColKey'] = array(
    @@ -1859,19 +1862,19 @@ class pdf_sponge extends ModelePDFFactures
     	        'title' => array(
     	            'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label
     	            'label' => ' ', // the final label : used fore final generated text
    -	            'align' => 'L', // text alignement :  R,C,L 
    +	            'align' => 'L', // text alignement :  R,C,L
     	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	        ),
     	        'content' => array(
    -	            'align' => 'L', // text alignement :  R,C,L 
    +	            'align' => 'L', // text alignement :  R,C,L
     	            'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	        ),
     	    );
     	    */
    -	    
    +
     	    $rank=0; // do not use negative rank
     	    $this->cols['desc'] = array(
    -	        'rank' => $rank, 
    +	        'rank' => $rank,
     	        'width' => false, // only for desc
     	        'status' => true,
     	        'title' => array(
    @@ -1885,7 +1888,7 @@ class pdf_sponge extends ModelePDFFactures
     	            'align' => 'L',
     	        ),
     	    );
    -	    
    +
     	    // PHOTO
             $rank = $rank + 10;
             $this->cols['photo'] = array(
    @@ -1894,20 +1897,20 @@ class pdf_sponge extends ModelePDFFactures
                 'status' => false,
                 'title' => array(
                     'textkey' => 'Photo',
    -                'label' => ' ' 
    +                'label' => ' '
                 ),
                 'content' => array(
                     'padding' => array(0,0,0,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
                 ),
                 'border-left' => false, // remove left line separator
             );
    -	        
    +
     	    if (! empty($conf->global->MAIN_GENERATE_INVOICES_WITH_PICTURE) && !empty($this->atleastonephoto))
     	    {
     	        $this->cols['photo']['status'] = true;
     	    }
    -	    
    -	    
    +
    +
     	    $rank = $rank + 10;
     	    $this->cols['vat'] = array(
     	        'rank' => $rank,
    @@ -1918,12 +1921,12 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
     	    {
     	        $this->cols['vat']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['subprice'] = array(
     	        'rank' => $rank,
    @@ -1934,7 +1937,7 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['qty'] = array(
     	        'rank' => $rank,
    @@ -1945,7 +1948,7 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['progress'] = array(
     	        'rank' => $rank,
    @@ -1956,12 +1959,12 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    if($this->situationinvoice)
     	    {
     	        $this->cols['progress']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['unit'] = array(
     	        'rank' => $rank,
    @@ -1975,7 +1978,7 @@ class pdf_sponge extends ModelePDFFactures
     	    if($conf->global->PRODUCT_USE_UNITS){
     	        $this->cols['unit']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['discount'] = array(
     	        'rank' => $rank,
    @@ -1989,7 +1992,7 @@ class pdf_sponge extends ModelePDFFactures
     	    if ($this->atleastonediscount){
     	        $this->cols['discount']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['totalexcltax'] = array(
     	        'rank' => $rank,
    @@ -2000,8 +2003,8 @@ class pdf_sponge extends ModelePDFFactures
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    -	    
    +
    +
     	    $parameters=array(
     	        'object' => $object,
     	        'outputlangs' => $outputlangs,
    @@ -2009,7 +2012,7 @@ class pdf_sponge extends ModelePDFFactures
     	        'hidedesc' => $hidedesc,
     	        'hideref' => $hideref
     	    );
    -	    
    +
     	    $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this);    // Note that $object may have been modified by hook
     	    if ($reshook < 0)
     	    {
    @@ -2023,8 +2026,8 @@ class pdf_sponge extends ModelePDFFactures
     	    {
     	        $this->cols = $hookmanager->resArray;
     	    }
    -	    
    +
     	}
    -	
    -	
    +
    +
     }
    diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
    index 40b73e4bf7f..adb52867a36 100644
    --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php
    +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php
    @@ -1463,27 +1463,30 @@ class pdf_azur extends ModelePDFPropales
     		$pdf->SetXY($this->marge_gauche,$posy);
     
     		// Logo
    -		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    -		if ($this->emetteur->logo)
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
     		{
    -			if (is_readable($logo))
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
     			{
    -			    $height=pdf_getHeightForLogo($logo);
    -			    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +				    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B',$default_font_size - 2);
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
     			}
     			else
     			{
    -				$pdf->SetTextColor(200,0,0);
    -				$pdf->SetFont('','B',$default_font_size - 2);
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     			}
     		}
    -		else
    -		{
    -			$text=$this->emetteur->name;
    -			$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    -		}
     
     		$pdf->SetFont('','B',$default_font_size + 3);
     		$pdf->SetXY($posx,$posy);
    diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    index c9bce8b07a4..e1f874b6853 100644
    --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    @@ -68,7 +68,7 @@ class pdf_cyan extends ModelePDFPropales
     	function __construct($db)
     	{
     		global $conf,$langs,$mysoc;
    -		
    +
     		// Translations
     		$langs->loadLangs(array("main", "bills"));
     
    @@ -107,8 +107,8 @@ class pdf_cyan extends ModelePDFPropales
     
     		// Define position of columns
     		$this->posxdesc=$this->marge_gauche+1;
    -		
    -		
    +
    +
     
     		$this->tva=array();
     		$this->localtax1=array();
    @@ -286,8 +286,8 @@ class pdf_cyan extends ModelePDFPropales
     				        break;
     				    }
     				}
    -				
    -				
    +
    +
     
     				// New page
     				$pdf->AddPage();
    @@ -308,7 +308,7 @@ class pdf_cyan extends ModelePDFPropales
     
     	            $tab_top = 90+$top_shift;
     				$tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42+$top_shift:10);
    -				
    +
     
     				// Incoterm
     				$height_incoterms = 0;
    @@ -353,7 +353,7 @@ class pdf_cyan extends ModelePDFPropales
     				    if ($tmpuser->email) $notetoshow.=',  Mail: '.$tmpuser->email;
     				    if ($tmpuser->office_phone) $notetoshow.=', Tel: '.$tmpuser->office_phone;
     				}
    -				
    +
     				$pagenb = $pdf->getPage();
     				if ($notetoshow)
     				{
    @@ -361,24 +361,24 @@ class pdf_cyan extends ModelePDFPropales
     
     				    $tab_width = $this->page_largeur-$this->marge_gauche-$this->marge_droite;
     				    $pageposbeforenote = $pagenb;
    -				    
    +
     					$substitutionarray=pdf_getSubstitutionArray($outputlangs, null, $object);
     					complete_substitutions_array($substitutionarray, $outputlangs, $object);
     					$notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs);
     
     
     					$pdf->startTransaction();
    -					
    +
     					$pdf->SetFont('','', $default_font_size - 1);
     					$pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     					// Description
     					$pageposafternote=$pdf->getPage();
     					$posyafter = $pdf->GetY();
    -					
    +
     					if($pageposafternote>$pageposbeforenote )
     					{
     					    $pdf->rollbackTransaction(true);
    -					    
    +
     					    // prepar pages to receive notes
     					    while ($pagenb < $pageposafternote) {
     					        $pdf->AddPage();
    @@ -390,16 +390,16 @@ class pdf_cyan extends ModelePDFPropales
     					        // The only function to edit the bottom margin of current page to set it.
     					        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     					    }
    -					    
    +
     					    // back to start
     					    $pdf->setPage($pageposbeforenote);
     					    $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     					    $pdf->SetFont('','', $default_font_size - 1);
     					    $pdf->writeHTMLCell(190, 3, $this->posxdesc-1, $tab_top, dol_htmlentitiesbr($notetoshow), 0, 1);
     					    $pageposafternote=$pdf->getPage();
    -					    
    +
     					    $posyafter = $pdf->GetY();
    -					    
    +
     					    if ($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)))	// There is no space left for total+free text
     					    {
     					        $pdf->AddPage('','',true);
    @@ -411,14 +411,14 @@ class pdf_cyan extends ModelePDFPropales
     					        $pdf->setPageOrientation('', 1, $heightforfooter + $heightforfreetext);
     					        //$posyafter = $tab_top_newpage;
     					    }
    -					    
    -					    
    +
    +
     					    // apply note frame to previus pages
     					    $i = $pageposbeforenote;
     					    while ($i < $pageposafternote) {
     					        $pdf->setPage($i);
    -					        
    -					        
    +
    +
     					        $pdf->SetDrawColor(128,128,128);
     					        // Draw note frame
     					        if($i>$pageposbeforenote){
    @@ -429,21 +429,21 @@ class pdf_cyan extends ModelePDFPropales
     					            $height_note = $this->page_hauteur - ($tab_top + $heightforfooter);
     					            $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note + 1);
     					        }
    -					        
    +
     					        // Add footer
     					        $pdf->setPageOrientation('', 1, 0);	// The only function to edit the bottom margin of current page to set it.
     					        $this->_pagefoot($pdf,$object,$outputlangs,1);
    -					        
    +
     					        $i++;
     					    }
    -					    
    +
     					    // apply note frame to last page
     					    $pdf->setPage($pageposafternote);
     					    if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     					    if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
     					    $height_note=$posyafter-$tab_top_newpage;
     					    $pdf->Rect($this->marge_gauche, $tab_top_newpage-1, $tab_width, $height_note+1);
    -					    
    +
     					}
     					else // No pagebreak
     					{
    @@ -451,8 +451,8 @@ class pdf_cyan extends ModelePDFPropales
     					    $posyafter = $pdf->GetY();
     					    $height_note=$posyafter-$tab_top;
     					    $pdf->Rect($this->marge_gauche, $tab_top-1, $tab_width, $height_note+1);
    -					    
    -					    
    +
    +
     					    if($posyafter > ($this->page_hauteur - ($heightforfooter+$heightforfreetext+20)) )
     					    {
     					        // not enough space, need to add page
    @@ -462,12 +462,12 @@ class pdf_cyan extends ModelePDFPropales
     					        $pdf->setPage($pageposafternote);
     					        if (! empty($tplidx)) $pdf->useTemplate($tplidx);
     					        if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
    -					        
    +
     					        $posyafter = $tab_top_newpage;
     					    }
    -					    
    +
     					}
    -					
    +
     					$tab_height = $tab_height - $height_note;
     					$tab_top = $posyafter +6;
     				}
    @@ -479,10 +479,10 @@ class pdf_cyan extends ModelePDFPropales
     				$iniY = $tab_top + 7;
     				$curY = $tab_top + 7;
     				$nexY = $tab_top + 7;
    -				
    +
     				// Use new auto collum system
     				$this->prepareArrayColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    -				
    +
     				// Loop on each lines
     				$pageposbeforeprintlines=$pdf->getPage();
     				$pagenb = $pageposbeforeprintlines;
    @@ -513,12 +513,12 @@ class pdf_cyan extends ModelePDFPropales
         						if (! empty($tplidx)) $pdf->useTemplate($tplidx);
         						//if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $this->_pagehead($pdf, $object, 0, $outputlangs);
         						$pdf->setPage($pageposbefore+1);
    -    
    +
         						$curY = $tab_top_newpage;
         						$showpricebeforepagebreak=0;
         					}
    -    
    -    					
    +
    +
         					if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height']))
         					{
         						$pdf->Image($realpatharray[$i], $this->getColumnContentXStart('photo'), $curY, $imglinesize['width'], $imglinesize['height'], '', '', '', 2, 300);	// Use 300 dpi
    @@ -526,7 +526,7 @@ class pdf_cyan extends ModelePDFPropales
         						$posYAfterImage=$curY+$imglinesize['height'];
         					}
     					}
    -					
    +
     					// Description of product line
     					if($this->getColumnStatus('desc'))
     					{
    @@ -540,7 +540,7 @@ class pdf_cyan extends ModelePDFPropales
         						//print $pageposafter.'-'.$pageposbefore;exit;
         						$pdf->setPageOrientation('', 1, $heightforfooter);	// The only function to edit the bottom margin of current page to set it.
         						pdf_writelinedesc($pdf,$object,$i,$outputlangs,$this->getColumnContentWidth('desc'),3,$this->getColumnContentXStart('desc'),$curY,$hideref,$hidedesc);
    -    
    +
         						$pageposafter=$pdf->getPage();
         						$posyafter=$pdf->GetY();
         						//var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit;
    @@ -596,7 +596,7 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'subprice', $up_excl_tax);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Quantity
     					// Enough for 6 chars
     					if ($this->getColumnStatus('qty'))
    @@ -605,8 +605,8 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'qty', $qty);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    -					
    +
    +
     					// Unit
     					if ($this->getColumnStatus('unit'))
     					{
    @@ -614,7 +614,7 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'unit', $unit);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Discount on line
     					if ($this->getColumnStatus('discount') && $object->lines[$i]->remise_percent)
     					{
    @@ -622,7 +622,7 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'discount', $remise_percent);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    +
     					// Total HT line
     					if ($this->getColumnStatus('totalexcltax'))
     					{
    @@ -630,8 +630,8 @@ class pdf_cyan extends ModelePDFPropales
     					    $this->printStdColumnContent($pdf, $curY, 'totalexcltax', $total_excl_tax);
     					    $nexY = max($pdf->GetY(),$nexY);
     					}
    -					
    -					
    +
    +
     					$parameters=array(
     					    'object' => $object,
     					    'i' => $i,
    @@ -642,8 +642,8 @@ class pdf_cyan extends ModelePDFPropales
     					    'hidedetails' => $hidedetails
     					);
     					$reshook=$hookmanager->executeHooks('printPDFline',$parameters,$this);    // Note that $object may have been modified by hook
    -					
    -					
    +
    +
     
     					// Collecte des totaux par valeur de tva dans $this->tva["taux"]=total_tva
     					if ($conf->multicurrency->enabled && $object->multicurrency_tx != 1) $tvaligne=$object->lines[$i]->multicurrency_total_tva;
    @@ -1389,29 +1389,29 @@ class pdf_cyan extends ModelePDFPropales
     		foreach ($this->cols as $colKey => $colDef)
     		{
     		    if(!$this->getColumnStatus($colKey)) continue;
    -		    
    +
     		    // get title label
     		    $colDef['title']['label'] = !empty($colDef['title']['label'])?$colDef['title']['label']:$outputlangs->transnoentities($colDef['title']['textkey']);
    -		    
    +
     		    // Add column separator
     		    if(!empty($colDef['border-left'])){
     		        $pdf->line($colDef['xStartPos'], $tab_top, $colDef['xStartPos'], $tab_top + $tab_height);
     		    }
    -		    
    +
     		    if (empty($hidetop))
     		    {
     		      $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] );
    -		    
    +
     		      $textWidth = $colDef['width'] - $colDef['title']['padding'][3] -$colDef['title']['padding'][1];
     		      $pdf->MultiCell($textWidth,2,$colDef['title']['label'],'',$colDef['title']['align']);
     		    }
     		}
    -		
    +
     		if (empty($hidetop)){
     			$pdf->line($this->marge_gauche, $tab_top+5, $this->page_largeur-$this->marge_droite, $tab_top+5);	// line prend une position y en 2eme param et 4eme param
     		}
     
    -		
    +
     	}
     
     	/**
    @@ -1451,27 +1451,30 @@ class pdf_cyan extends ModelePDFPropales
     		$pdf->SetXY($this->marge_gauche,$posy);
     
     		// Logo
    -		$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    -		if ($this->emetteur->logo)
    +		if (empty($conf->global->PDF_DISABLE_MYCOMPANY_LOGO))
     		{
    -			if (is_readable($logo))
    +			$logo=$conf->mycompany->dir_output.'/logos/'.$this->emetteur->logo;
    +			if ($this->emetteur->logo)
     			{
    -			    $height=pdf_getHeightForLogo($logo);
    -			    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				if (is_readable($logo))
    +				{
    +				    $height=pdf_getHeightForLogo($logo);
    +				    $pdf->Image($logo, $this->marge_gauche, $posy, 0, $height);	// width=0 (auto)
    +				}
    +				else
    +				{
    +					$pdf->SetTextColor(200,0,0);
    +					$pdf->SetFont('','B',$default_font_size - 2);
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    +					$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				}
     			}
     			else
     			{
    -				$pdf->SetTextColor(200,0,0);
    -				$pdf->SetFont('','B',$default_font_size - 2);
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorLogoFileNotFound",$logo), 0, 'L');
    -				$pdf->MultiCell(100, 3, $outputlangs->transnoentities("ErrorGoToGlobalSetup"), 0, 'L');
    +				$text=$this->emetteur->name;
    +				$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
     			}
     		}
    -		else
    -		{
    -			$text=$this->emetteur->name;
    -			$pdf->MultiCell(100, 4, $outputlangs->convToOutputCharset($text), 0, 'L');
    -		}
     
     		$pdf->SetFont('','B',$default_font_size + 3);
     		$pdf->SetXY($posx,$posy);
    @@ -1686,8 +1689,8 @@ class pdf_cyan extends ModelePDFPropales
     
     		return ($tab_hl*7);
     	}
    -	
    -	
    +
    +
     	/**
     	 *   	Define Array Column Field
     	 *
    @@ -1699,21 +1702,21 @@ class pdf_cyan extends ModelePDFPropales
     	 *      @return	null
     	 */
     	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    -	    
    +
     	    global $conf, $hookmanager;
    -	    
    +
     	    // Default field style for content
     	    $this->defaultContentsFieldsStyle = array(
     	        'align' => 'R', // R,C,L
     	        'padding' => array(0.5,0.5,0.5,0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    // Default field style for content
     	    $this->defaultTitlesFieldsStyle = array(
     	        'align' => 'C', // R,C,L
     	        'padding' => array(0.5,0,0.5,0), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left
     	    );
    -	    
    +
     	    /*
     	     * For exemple
     	     $this->cols['theColKey'] = array(
    @@ -1731,7 +1734,7 @@ class pdf_cyan extends ModelePDFPropales
     	     ),
     	     );
     	     */
    -	    
    +
     	    $rank=0; // do not use negative rank
     	    $this->cols['desc'] = array(
     	        'rank' => $rank,
    @@ -1748,7 +1751,7 @@ class pdf_cyan extends ModelePDFPropales
     	            'align' => 'L',
     	        ),
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['photo'] = array(
     	        'rank' => $rank,
    @@ -1763,13 +1766,13 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => false, // remove left line separator
     	    );
    -	    
    +
     	    if (! empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE) && !empty($this->atleastonephoto))
     	    {
     	        $this->cols['photo']['status'] = true;
     	    }
    -	    
    -	    
    +
    +
     	    $rank = $rank + 10;
     	    $this->cols['vat'] = array(
     	        'rank' => $rank,
    @@ -1780,12 +1783,12 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    if (empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT) && empty($conf->global->MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_COLUMN))
     	    {
     	        $this->cols['vat']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['subprice'] = array(
     	        'rank' => $rank,
    @@ -1796,7 +1799,7 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['qty'] = array(
     	        'rank' => $rank,
    @@ -1807,7 +1810,7 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['progress'] = array(
     	        'rank' => $rank,
    @@ -1818,12 +1821,12 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => false, // add left line separator
     	    );
    -	    
    +
     	    if($this->situationinvoice)
     	    {
     	        $this->cols['progress']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['unit'] = array(
     	        'rank' => $rank,
    @@ -1837,7 +1840,7 @@ class pdf_cyan extends ModelePDFPropales
     	    if($conf->global->PRODUCT_USE_UNITS){
     	        $this->cols['unit']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['discount'] = array(
     	        'rank' => $rank,
    @@ -1851,7 +1854,7 @@ class pdf_cyan extends ModelePDFPropales
     	    if ($this->atleastonediscount){
     	        $this->cols['discount']['status'] = true;
     	    }
    -	    
    +
     	    $rank = $rank + 10;
     	    $this->cols['totalexcltax'] = array(
     	        'rank' => $rank,
    @@ -1862,8 +1865,8 @@ class pdf_cyan extends ModelePDFPropales
     	        ),
     	        'border-left' => true, // add left line separator
     	    );
    -	    
    -	    
    +
    +
     	    $parameters=array(
     	        'object' => $object,
     	        'outputlangs' => $outputlangs,
    @@ -1871,7 +1874,7 @@ class pdf_cyan extends ModelePDFPropales
     	        'hidedesc' => $hidedesc,
     	        'hideref' => $hideref
     	    );
    -	    
    +
     	    $reshook=$hookmanager->executeHooks('defineColumnField',$parameters,$this);    // Note that $object may have been modified by hook
     	    if ($reshook < 0)
     	    {
    @@ -1885,7 +1888,7 @@ class pdf_cyan extends ModelePDFPropales
     	    {
     	        $this->cols = $hookmanager->resArray;
     	    }
    -	    
    +
     	}
    -	
    +
     }
    
    From 38df6ac27b529057c4bdb1820d164e2ed946612f Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 22 Oct 2018 21:57:18 +0200
    Subject: [PATCH 384/433] remove deprecated form_confirm
    
    ---
     htdocs/expensereport/card.php | 18 +++++++++---------
     1 file changed, 9 insertions(+), 9 deletions(-)
    
    diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php
    index e19c7a841e1..d877ad00b2f 100644
    --- a/htdocs/expensereport/card.php
    +++ b/htdocs/expensereport/card.php
    @@ -1589,49 +1589,49 @@ else
     
     				if ($action == 'save')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_validate","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_validate","","",1);
     				}
     
     				if ($action == 'save_from_refuse')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_save_from_refuse","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_save_from_refuse","","",1);
     				}
     
     				if ($action == 'delete')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("DeleteTrip"),$langs->trans("ConfirmDeleteTrip"),"confirm_delete","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("DeleteTrip"),$langs->trans("ConfirmDeleteTrip"),"confirm_delete","","",1);
     				}
     
     				if ($action == 'validate')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("ValideTrip"),$langs->trans("ConfirmValideTrip"),"confirm_approve","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("ValideTrip"),$langs->trans("ConfirmValideTrip"),"confirm_approve","","",1);
     				}
     
     				if ($action == 'paid')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("PaidTrip"),$langs->trans("ConfirmPaidTrip"),"confirm_paid","","",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("PaidTrip"),$langs->trans("ConfirmPaidTrip"),"confirm_paid","","",1);
     				}
     
     				if ($action == 'cancel')
     				{
     					$array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text",'label'=>$langs->trans("Comment"),'name'=>"detail_cancel",'size'=>"50",'value'=>""));
    -					$formconfirm=$form->form_confirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("Cancel"),"","confirm_cancel",$array_input,"",1);
    +					$formconfirm=$form->formconfirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("Cancel"),"","confirm_cancel",$array_input,"",1);
     				}
     
     				if ($action == 'brouillonner')
     				{
    -				    $formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("BrouillonnerTrip"),$langs->trans("ConfirmBrouillonnerTrip"),"confirm_brouillonner","","",1);
    +				    $formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("BrouillonnerTrip"),$langs->trans("ConfirmBrouillonnerTrip"),"confirm_brouillonner","","",1);
     				}
     
     				if ($action == 'refuse')		// Deny
     				{
     					$array_input = array('text'=>$langs->trans("ConfirmRefuseTrip"), array('type'=>"text",'label'=>$langs->trans("Comment"),'name'=>"detail_refuse",'size'=>"50",'value'=>""));
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("Deny"),'',"confirm_refuse",$array_input,"yes",1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("Deny"),'',"confirm_refuse",$array_input,"yes",1);
     				}
     
     				if ($action == 'delete_line')
     				{
    -					$formconfirm=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id."&rowid=".GETPOST('rowid','int'),$langs->trans("DeleteLine"),$langs->trans("ConfirmDeleteLine"),"confirm_delete_line",'','yes',1);
    +					$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id."&rowid=".GETPOST('rowid','int'),$langs->trans("DeleteLine"),$langs->trans("ConfirmDeleteLine"),"confirm_delete_line",'','yes',1);
     				}
     
     				// Print form confirm
    
    From 4aec343b2410e4b1029a13b026eef9c3c440cc0e Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 22 Oct 2018 22:13:54 +0200
    Subject: [PATCH 385/433] Update html.form.class.php
    
    ---
     htdocs/core/class/html.form.class.php | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
    index 1cc02f0939a..00184499a9f 100644
    --- a/htdocs/core/class/html.form.class.php
    +++ b/htdocs/core/class/html.form.class.php
    @@ -3899,7 +3899,7 @@ class Form
     			$formconfirm.= ($question ? '<div class="confirmmessage">'.img_help('','').' '.$question . '</div>': '');
     			$formconfirm.= '</div>'."\n";
     
    -			$formconfirm.= "\n<!-- begin ajax form_confirm page=".$page." -->\n";
    +			$formconfirm.= "\n<!-- begin ajax formconfirm page=".$page." -->\n";
     			$formconfirm.= '<script type="text/javascript">'."\n";
     			$formconfirm.= 'jQuery(document).ready(function() {
                 $(function() {
    @@ -3970,11 +3970,11 @@ class Form
                 });
                 });
                 </script>';
    -			$formconfirm.= "<!-- end ajax form_confirm -->\n";
    +			$formconfirm.= "<!-- end ajax formconfirm -->\n";
     		}
     		else
     		{
    -			$formconfirm.= "\n<!-- begin form_confirm page=".$page." -->\n";
    +			$formconfirm.= "\n<!-- begin formconfirm page=".$page." -->\n";
     
     			if (empty($disableformtag)) $formconfirm.= '<form method="POST" action="'.$page.'" class="notoptoleftroright">'."\n";
     
    @@ -4008,7 +4008,7 @@ class Form
     			if (empty($disableformtag)) $formconfirm.= "</form>\n";
     			$formconfirm.= '<br>';
     
    -			$formconfirm.= "<!-- end form_confirm -->\n";
    +			$formconfirm.= "<!-- end formconfirm -->\n";
     		}
     
     		return $formconfirm;
    
    From e49f2bc5624e75c73c0826721ded739846dbf9a0 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 22 Oct 2018 22:20:26 +0200
    Subject: [PATCH 386/433] Update document_actions_post_headers.tpl.php
    
    ---
     htdocs/core/tpl/document_actions_post_headers.tpl.php | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php
    index aa7caaa1e87..429fe8ac682 100644
    --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php
    +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php
    @@ -52,7 +52,7 @@ if (in_array($modulepart, array('product', 'produit', 'societe', 'user', 'ticket
     if ($action == 'delete')
     {
     	$langs->load("companies");	// Need for string DeleteFile+ConfirmDeleteFiles
    -	$ret = $form->form_confirm(
    +	print $form->formconfirm(
     			$_SERVER["PHP_SELF"] . '?id=' . $object->id . '&urlfile=' . urlencode(GETPOST("urlfile")) . '&linkid=' . GETPOST('linkid', 'int') . (empty($param)?'':$param),
     			$langs->trans('DeleteFile'),
     			$langs->trans('ConfirmDeleteFile'),
    @@ -61,7 +61,6 @@ if ($action == 'delete')
     			0,
     			1
     	);
    -	if ($ret == 'html') print '<br>';
     }
     
     $formfile=new FormFile($db);
    
    From 90b85c1106efc19855301f2186a97f3aa23f6db7 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 22 Oct 2018 22:23:43 +0200
    Subject: [PATCH 387/433] Update html.form.class.php
    
    ---
     htdocs/core/class/html.form.class.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
    index 00184499a9f..03e339eebf4 100644
    --- a/htdocs/core/class/html.form.class.php
    +++ b/htdocs/core/class/html.form.class.php
    @@ -3722,6 +3722,7 @@ class Form
     	function form_confirm($page, $title, $question, $action, $formquestion='', $selectedchoice="", $useajax=0, $height=170, $width=500)
     	{
             // phpcs:enable
    +        dol_syslog(__METHOD__ . ': using form_confirm is deprecated. Use formconfim instead.', LOG_WARNING);
     		print $this->formconfirm($page, $title, $question, $action, $formquestion, $selectedchoice, $useajax, $height, $width);
     	}
     
    
    From 85a94ec5779460b09b3c938969a32f33dd22d176 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Mon, 22 Oct 2018 22:40:18 +0200
    Subject: [PATCH 388/433] Update view.php
    
    ---
     htdocs/public/ticket/view.php | 8 +++-----
     1 file changed, 3 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/public/ticket/view.php b/htdocs/public/ticket/view.php
    index b2bb0100d6d..b5288b97a25 100644
    --- a/htdocs/public/ticket/view.php
    +++ b/htdocs/public/ticket/view.php
    @@ -1,5 +1,6 @@
     <?php
    -/*  Copyright (C) - 2013-2016    Jean-François FERRY    <hello@librethic.io>
    +/* Copyright (C) 2013-2016  Jean-François FERRY     <hello@librethic.io>
    + * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
      *
      * This program is free software; you can redistribute it and/or modify
      * it under the terms of the GNU General Public License as published by
    @@ -145,10 +146,7 @@ if ($action == "view_ticket" || $action == "add_message" || $action == "close" |
         if ($display_ticket) {
             // Confirmation close
             if ($action == 'close') {
    -            $ret = $form->form_confirm($_SERVER["PHP_SELF"] . "?track_id=" . $track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_public_close", '', '', 1);
    -            if ($ret == 'html') {
    -                print '<br>';
    -            }
    +            print $form->form_confirm($_SERVER["PHP_SELF"] . "?track_id=" . $track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_public_close", '', '', 1);
             }
     
             print '<div id="form_view_ticket">';
    
    From 5bac6a92e66b2893e30aee4ec9e6d8416d2f9b70 Mon Sep 17 00:00:00 2001
    From: Abbes Bahfir <bafbes@gmail.com>
    Date: Tue, 23 Oct 2018 00:00:05 +0100
    Subject: [PATCH 389/433] Fix:empty value instead of 0 for empty links
    
    ---
     htdocs/core/class/commonobject.class.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
    index 2650c48b573..197f61735c3 100644
    --- a/htdocs/core/class/commonobject.class.php
    +++ b/htdocs/core/class/commonobject.class.php
    @@ -6219,6 +6219,7 @@ abstract class CommonObject
     					return 'Error bad setup of extrafield';
     				}
     			}
    +			else $value='';
     		}
     		elseif ($type == 'text' || $type == 'html')
     		{
    
    From 7e7473e7df80d9e4696911b30d9aad9afd68f8ff Mon Sep 17 00:00:00 2001
    From: Abbes Bahfir <bafbes@gmail.com>
    Date: Tue, 23 Oct 2018 01:25:26 +0100
    Subject: [PATCH 390/433] New : parameter for getnomurl in field dpecification
    
    ---
     htdocs/core/class/commonobject.class.php | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
    index 2650c48b573..bfb657f6216 100644
    --- a/htdocs/core/class/commonobject.class.php
    +++ b/htdocs/core/class/commonobject.class.php
    @@ -6203,6 +6203,7 @@ abstract class CommonObject
     				$InfoFieldList = explode(":", $param_list[0]);
     				$classname=$InfoFieldList[0];
     				$classpath=$InfoFieldList[1];
    +				$getnomurlparam=$InfoFieldList[2];
     				if (! empty($classpath))
     				{
     					dol_include_once($InfoFieldList[1]);
    @@ -6210,7 +6211,7 @@ abstract class CommonObject
     					{
     						$object = new $classname($this->db);
     						$object->fetch($value);
    -						$value=$object->getNomUrl(3);
    +						$value=$object->getNomUrl(!empty($getnomurlparam)?$getnomurlparam:3);
     					}
     				}
     				else
    
    From 7bb5e7c31f4a95c27bfbdb311d40312ae9b5bdd9 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 23 Oct 2018 11:52:21 +0200
    Subject: [PATCH 391/433] Fix responsive
    
    ---
     htdocs/product/list.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/product/list.php b/htdocs/product/list.php
    index d1ea3d08a4c..7c7619fe0d5 100644
    --- a/htdocs/product/list.php
    +++ b/htdocs/product/list.php
    @@ -866,7 +866,7 @@ if ($resql)
     			// Stock real
     			if (! empty($arrayfields['p.stock']['checked']))
     			{
    -				print '<td align="right">';
    +				print '<td align="right" class="nowraponall">';
     				if ($obj->fk_product_type != 1)
     				{
     					if ($obj->seuil_stock_alerte != '' && $product_static->stock_reel < (float) $obj->seuil_stock_alerte) print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
    @@ -878,7 +878,7 @@ if ($resql)
     			// Stock virtual
     			if (! empty($arrayfields['stock_virtual']['checked']))
     			{
    -				print '<td align="right">';
    +				print '<td align="right" class="nowraponall">';
     				if ($obj->fk_product_type != 1)
     				{
     					if ($obj->seuil_stock_alerte != '' && $product_static->stock_theorique < (float) $obj->seuil_stock_alerte) print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
    
    From b7d91c30d97823537538b4516d0c32e1b65b1a42 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 23 Oct 2018 12:38:12 +0200
    Subject: [PATCH 392/433] FIX missing symbol for indian rupies
    
    ---
     htdocs/install/mysql/data/llx_c_currencies.sql | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/install/mysql/data/llx_c_currencies.sql b/htdocs/install/mysql/data/llx_c_currencies.sql
    index db1ba19aa6e..5f561f26ba0 100644
    --- a/htdocs/install/mysql/data/llx_c_currencies.sql
    +++ b/htdocs/install/mysql/data/llx_c_currencies.sql
    @@ -80,7 +80,7 @@ INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'HNL'
     INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'HKD', '[36]', 1,				'Hong Kong Dollar');
     INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'HUF', '[70,116]', 1,			'Hungary Forint');
     INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'ISK', '[107,114]', 1,			'Iceland Krona');
    -INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'INR', NULL, 1,					'India Rupee'); 
    +INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'INR', '[8377]', 1,				'India Rupee'); 
     INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'IDR', '[82,112]', 1,			'Indonesia Rupiah');
     INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'IRR', '[65020]', 1,				'Iran Rial');
     INSERT INTO llx_c_currencies ( code_iso, unicode, active, label ) VALUES ( 'IMP', '[163]', 1,				'Isle of Man Pound');
    
    From e0b20c26329343df363624f09fa8a76a68feefd4 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 23 Oct 2018 12:49:48 +0200
    Subject: [PATCH 393/433] Add holiday for India
    
    ---
     htdocs/core/lib/date.lib.php | 42 +++++++++++++-----------------------
     1 file changed, 15 insertions(+), 27 deletions(-)
    
    diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php
    index f75e53939a2..84048ac9c66 100644
    --- a/htdocs/core/lib/date.lib.php
    +++ b/htdocs/core/lib/date.lib.php
    @@ -585,6 +585,7 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     	{
     		$ferie=false;
     		$countryfound=0;
    +		$includesaturdayandsunday=1;
     
     		$jour  = date("d", $timestampStart);
     		$mois  = date("m", $timestampStart);
    @@ -671,12 +672,6 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     			$mois_pentecote = date("m", $date_pentecote);
     			if($jour_pentecote == $jour && $mois_pentecote == $mois) $ferie=true;
     			// "Pentecote"
    -
    -			// Calul des samedis et dimanches
    -			$jour_julien = unixtojd($timestampStart);
    -			$jour_semaine = jddayofweek($jour_julien, 0);
    -			if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -			// Samedi (6) et dimanche (0)
     		}
     
     		// Pentecoste and Ascensione in Italy go to the sunday after: isn't holiday.
    @@ -703,12 +698,18 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     			$mois_paques = date("m", $date_paques);
     			if($jour_paques == $jour && $mois_paques == $mois) $ferie=true;
     			// Paques
    +		}
     
    -			// Calul des samedis et dimanches
    -			$jour_julien = unixtojd($timestampStart);
    -			$jour_semaine = jddayofweek($jour_julien, 0);
    -			if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -			//Samedi (6) et dimanche (0)
    +		if ($countrycode == 'IN')
    +		{
    +			$countryfound=1;
    +
    +			if($jour == 1 && $mois == 1) $ferie=true; // New Year's Day
    +			if($jour == 26 && $mois == 1) $ferie=true; // Republic Day
    +			if($jour == 1 && $mois == 5) $ferie=true; // May Day
    +			if($jour == 15 && $mois == 8) $ferie=true; // Independence Day
    +			if($jour == 2 && $mois == 10) $ferie=true; // Gandhi Jayanti
    +			if($jour == 25 && $mois == 12) $ferie=true; // Christmas
     		}
     
     		if ($countrycode == 'ES')
    @@ -746,12 +747,6 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     			$mois_viernes = date("m", $date_viernes);
     			if($jour_viernes == $jour && $mois_viernes == $mois) $ferie=true;
     			//Viernes Santo
    -
    -			// Calul des samedis et dimanches
    -			$jour_julien = unixtojd($timestampStart);
    -			$jour_semaine = jddayofweek($jour_julien, 0);
    -			if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -			//Samedi (6) et dimanche (0)
     		}
     
     		if ($countrycode == 'AT')
    @@ -833,22 +828,15 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $
     		    $mois_fronleichnam = date("m", $date_fronleichnam);
     		    if($jour_fronleichnam == $jour && $mois_fronleichnam == $mois) $ferie=true;
     		    // Fronleichnam
    -
    -		    // Calul des samedis et dimanches
    -		    $jour_julien = unixtojd($timestampStart);
    -		    $jour_semaine = jddayofweek($jour_julien, 0);
    -		    if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -		    //Samedi (6) et dimanche (0)
     		}
     
    -		// Cas pays non defini
    -		if (! $countryfound)
    +		// If we have to include saturday and sunday
    +		if ($includesaturdayandsunday)
     		{
    -			// Calul des samedis et dimanches
     			$jour_julien = unixtojd($timestampStart);
     			$jour_semaine = jddayofweek($jour_julien, 0);
     			if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true;
    -			//Samedi (6) et dimanche (0)
    +			//Saturday (6) and Sunday (0)
     		}
     
     		// On incremente compteur
    
    From e40ee879dcfa23cd96ff1da6f5a9d75fa918f863 Mon Sep 17 00:00:00 2001
    From: Juanjo Menent <jmenent@2byte.es>
    Date: Tue, 23 Oct 2018 13:07:09 +0200
    Subject: [PATCH 394/433] New: works with variants: - If product is variant
     disable prices modify - Add function isVariant for knowing if product is a
     Variant
    
    ---
     htdocs/langs/en_US/products.lang       |  1 +
     htdocs/product/class/product.class.php | 30 ++++++++++++++++
     htdocs/product/price.php               | 47 ++++++++++++++------------
     3 files changed, 56 insertions(+), 22 deletions(-)
    
    diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang
    index 8390eb5439d..95b93aba4e9 100644
    --- a/htdocs/langs/en_US/products.lang
    +++ b/htdocs/langs/en_US/products.lang
    @@ -331,6 +331,7 @@ NbProducts=No. of products
     ParentProduct=Parent product
     HideChildProducts=Hide variant products
     ShowChildProducts=Show variant products
    +NoEditVariants=Go to Parent product card and edit variants price impact in the variants tab
     ConfirmCloneProductCombinations=Would you like to copy all the product variants to the other parent product with the given reference?
     CloneDestinationReference=Destination product reference
     ErrorCopyProductCombinations=There was an error while copying the product variants
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 2d2e7b75ed2..f8326a60721 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -3529,6 +3529,36 @@ class Product extends CommonObject
     		return $nb;
     	}
     
    +
    +	/**
    +	 * Return if loaded product is a variant
    +	 *
    +	 * @return int
    +	 */
    +	function isVariant()
    +	{
    +		global $conf;
    +		if (!empty($conf->variants->enabled)) {
    +			$sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "product_attribute_combination WHERE fk_product_child = " . $this->id . " AND entity IN (" . getEntity('product') . ")";
    +
    +			$query = $this->db->query($sql);
    +
    +			if ($query) {
    +				if (!$this->db->num_rows($query)) {
    +					return false;
    +				}
    +				return true;
    +			} else {
    +				dol_print_error($this->db);
    +				return -1;
    +			}
    +
    +		} else {
    +			return false;
    +		}
    +
    +	}
    +
     	/**
     	 *  Return all parent products for current product (first level only)
     	 *
    diff --git a/htdocs/product/price.php b/htdocs/product/price.php
    index a72ea28928b..9fb67aaa86c 100644
    --- a/htdocs/product/price.php
    +++ b/htdocs/product/price.php
    @@ -5,7 +5,7 @@
      * Copyright (C) 2005-2017	Regis Houssin			<regis.houssin@capnetworks.com>
      * Copyright (C) 2006		Andre Cianfarani			<acianfa@free.fr>
      * Copyright (C) 2014		Florian Henry			<florian.henry@open-concept.pro>
    - * Copyright (C) 2014-2016	Juanjo Menent			<jmenent@2byte.es>
    + * Copyright (C) 2014-2018	Juanjo Menent			<jmenent@2byte.es>
      * Copyright (C) 2014-2018 	Philippe Grand 		    <philippe.grand@atoo-net.com>
      * Copyright (C) 2014		Ion agorria				<ion@agorria.com>
      * Copyright (C) 2015		Alexandre Spangaro		<aspangaro.dolibarr@gmail.com>
    @@ -1109,30 +1109,33 @@ if (! $action || $action == 'delete' || $action == 'showlog_customer_price' || $
     {
     	print "\n" . '<div class="tabsAction">' . "\n";
     
    -	if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
    -	{
    -    	if ($user->rights->produit->creer || $user->rights->service->creer) {
    -    		print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_price&amp;id=' . $object->id . '">' . $langs->trans("UpdateDefaultPrice") . '</a></div>';
    -    	}
    -	}
    +    if ($object->isVariant()) {
    +		if ($user->rights->produit->creer || $user->rights->service->creer) {
    +			print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoEditVariants")).'">'.$langs->trans("UpdateDefaultPrice").'</a></div>';
    +		}
    +	} else {
    +		if (empty($conf->global->PRODUIT_MULTIPRICES) && empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
    +			if ($user->rights->produit->creer || $user->rights->service->creer) {
    +				print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_price&amp;id=' . $object->id . '">' . $langs->trans("UpdateDefaultPrice") . '</a></div>';
    +			}
    +		}
     
    -	if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
    -	{
    -	    if ($user->rights->produit->creer || $user->rights->service->creer) {
    -	 		print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=add_customer_price&amp;id=' . $object->id . '">' . $langs->trans("AddCustomerPrice") . '</a></div>';
    -	  	}
    -	}
    +		if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
    +			if ($user->rights->produit->creer || $user->rights->service->creer) {
    +				print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=add_customer_price&amp;id=' . $object->id . '">' . $langs->trans("AddCustomerPrice") . '</a></div>';
    +			}
    +		}
     
    -	if (! empty($conf->global->PRODUIT_MULTIPRICES) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
    -	{
    -	    if ($user->rights->produit->creer || $user->rights->service->creer) {
    -    		print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_vat&amp;id=' . $object->id . '">' . $langs->trans("UpdateVAT") . '</a></div>';
    -    	}
    +		if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
    +			if ($user->rights->produit->creer || $user->rights->service->creer) {
    +				print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_vat&amp;id=' . $object->id . '">' . $langs->trans("UpdateVAT") . '</a></div>';
    +			}
     
    -	    if ($user->rights->produit->creer || $user->rights->service->creer) {
    -    		print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_price&amp;id=' . $object->id . '">' . $langs->trans("UpdateLevelPrices") . '</a></div>';
    -    	}
    -	}
    +			if ($user->rights->produit->creer || $user->rights->service->creer) {
    +				print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit_price&amp;id=' . $object->id . '">' . $langs->trans("UpdateLevelPrices") . '</a></div>';
    +			}
    +		}
    +    }
     
     	print "\n</div>\n";
     }
    
    From c8aa884462776ebea16c0ade7dd0775bbc4eadd4 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 23 Oct 2018 17:16:46 +0200
    Subject: [PATCH 395/433] Fix search all
    
    ---
     htdocs/asset/list.php       | 2 +-
     htdocs/comm/propal/list.php | 2 +-
     htdocs/commande/list.php    | 2 +-
     htdocs/compta/bank/list.php | 2 +-
     htdocs/product/reassort.php | 2 +-
     5 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/asset/list.php b/htdocs/asset/list.php
    index bcc2329f870..5dc8b2c6866 100644
    --- a/htdocs/asset/list.php
    +++ b/htdocs/asset/list.php
    @@ -317,7 +317,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
     if ($sall)
     {
     	foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
    -	print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $all) . join(', ',$fieldstosearchall).'</div>';
    +	print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall).'</div>';
     }
     
     $moreforfilter = '';
    diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php
    index 65d132d5654..980615828a5 100644
    --- a/htdocs/comm/propal/list.php
    +++ b/htdocs/comm/propal/list.php
    @@ -490,7 +490,7 @@ if ($resql)
     	if ($sall)
     	{
     		foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
    -		print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $all) . join(', ',$fieldstosearchall).'</div>';
    +		print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall).'</div>';
     	}
     
     	$i = 0;
    diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php
    index 3734ab18a93..a9da48fd626 100644
    --- a/htdocs/commande/list.php
    +++ b/htdocs/commande/list.php
    @@ -529,7 +529,7 @@ if ($resql)
     	if ($sall)
     	{
     		foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
    -		print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $all) . join(', ',$fieldstosearchall).'</div>';
    +		print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall).'</div>';
     	}
     
     	$moreforfilter='';
    diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php
    index e52e285742c..3a67a3d5309 100644
    --- a/htdocs/compta/bank/list.php
    +++ b/htdocs/compta/bank/list.php
    @@ -257,7 +257,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
     if ($sall)
     {
         foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val);
    -    print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $all) . join(', ',$fieldstosearchall).'</div>';
    +    print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall) . join(', ',$fieldstosearchall).'</div>';
     }
     
     $moreforfilter='';
    diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php
    index 6403878d853..9ee9ab0aead 100644
    --- a/htdocs/product/reassort.php
    +++ b/htdocs/product/reassort.php
    @@ -127,7 +127,7 @@ $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s on p.rowid = s.fk_produc
     if ($search_categ) $sql.= ", ".MAIN_DB_PREFIX."categorie_product as cp";
     $sql.= " WHERE p.entity IN (".getEntity('product').")";
     if ($search_categ) $sql.= " AND p.rowid = cp.fk_product";	// Join for the needed table to filter by categ
    -if ($sall) $sql.=natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $all);
    +if ($sall) $sql.=natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $sall);
     // if the type is not 1, we show all products (type = 0,2,3)
     if (dol_strlen($type))
     {
    
    From d9965d19864f7d0dda16b8aeb0710fb24023f581 Mon Sep 17 00:00:00 2001
    From: John BOTELLA <john.botella@atm-consulting.fr>
    Date: Tue, 23 Oct 2018 17:18:30 +0200
    Subject: [PATCH 396/433] Fix travis messages
    
    ---
     .../commande/doc/pdf_eratosthene.modules.php    | 17 +++++++++++------
     .../modules/facture/doc/pdf_sponge.modules.php  | 15 ++++++++++-----
     .../modules/propale/doc/pdf_cyan.modules.php    | 13 ++++++++-----
     3 files changed, 29 insertions(+), 16 deletions(-)
    
    diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    index 89297d1bdc6..0a14e50326d 100644
    --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    @@ -145,7 +145,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     		$this->atleastonediscount=0;
     	}
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
          *  Function to build pdf onto disk
          *
          *  @param		Object		$object				Object to generate
    @@ -158,6 +158,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 */
     	function write_file($object, $outputlangs, $srctemplatepath='', $hidedetails=0, $hidedesc=0, $hideref=0)
     	{
    +	    // phpcs:enable
     		global $user, $langs, $conf, $mysoc, $db, $hookmanager, $nblignes;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
    @@ -711,7 +712,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     		}
     	}
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	 *  Show payments table
          *
     	 *  @param	TCPDF		$pdf     		Object PDF
    @@ -722,11 +723,12 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 */
     	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
     	{
    -
    +	    // phpcs:enable
    +	    
     	}
     
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
     	 *   @param		TCPDF		$pdf     		Object PDF
    @@ -737,6 +739,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    +	    // phpcs:enable
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -912,7 +915,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	}
     
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	 *	Show total to pay
     	 *
     	 *	@param	TCPDF		$pdf           Object PDF
    @@ -924,6 +927,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 */
     	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    +	    // phpcs:enable
     	    global $conf,$mysoc;
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1485,7 +1489,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *      @param	int			   $hideref			Do not show ref
     	 *      @return	null
     	 */
    -	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    +	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +	{
     
     	    global $conf, $hookmanager;
     
    diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    index ca27bd09aff..2a5aeb3fadd 100644
    --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    @@ -159,7 +159,7 @@ class pdf_sponge extends ModelePDFFactures
     	}
     
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
          *  Function to build pdf onto disk
          *
          *  @param		Object		$object				Object to generate
    @@ -172,6 +172,7 @@ class pdf_sponge extends ModelePDFFactures
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +	    // phpcs:enable
     	    global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
     
     	    if (! is_object($outputlangs)) $outputlangs=$langs;
    @@ -846,7 +847,7 @@ class pdf_sponge extends ModelePDFFactures
     	}
     
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	 *  Show payments table
     	 *
          *  @param	PDF			$pdf           Object PDF
    @@ -857,6 +858,7 @@ class pdf_sponge extends ModelePDFFactures
     	 */
     	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
     	{
    +	    // phpcs:enable
     		global $conf;
     
             $sign=1;
    @@ -986,7 +988,7 @@ class pdf_sponge extends ModelePDFFactures
     	}
     
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
     	 *   @param		PDF			$pdf     		Object PDF
    @@ -997,6 +999,7 @@ class pdf_sponge extends ModelePDFFactures
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    +	    // phpcs:enable
     		global $conf;
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1143,7 +1146,7 @@ class pdf_sponge extends ModelePDFFactures
     	}
     
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	 *	Show total to pay
     	 *
     	 *	@param	PDF			$pdf           Object PDF
    @@ -1155,6 +1158,7 @@ class pdf_sponge extends ModelePDFFactures
     	 */
     	function _tableau_tot(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    +	    // phpcs:enable
     		global $conf,$mysoc;
     
             $sign=1;
    @@ -1838,7 +1842,8 @@ class pdf_sponge extends ModelePDFFactures
          *      @param	int			   $hideref			Do not show ref
     	 *      @return	null
     	 */
    -	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    +	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +	{
     
     	    global $conf, $hookmanager;
     
    diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    index e1f874b6853..509173a0aa7 100644
    --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    @@ -117,7 +117,7 @@ class pdf_cyan extends ModelePDFPropales
     		$this->atleastonediscount=0;
     	}
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
          *  Function to build pdf onto disk
          *
          *  @param		Object		$object				Object to generate
    @@ -130,6 +130,7 @@ class pdf_cyan extends ModelePDFPropales
     	 */
     	function write_file($object,$outputlangs,$srctemplatepath='',$hidedetails=0,$hidedesc=0,$hideref=0)
     	{
    +	    // phpcs:enable
     		global $user,$langs,$conf,$mysoc,$db,$hookmanager,$nblignes;
     
     		if (! is_object($outputlangs)) $outputlangs=$langs;
    @@ -872,7 +873,7 @@ class pdf_cyan extends ModelePDFPropales
     		}
     	}
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	 *  Show payments table
     	 *
          *  @param	TCPDF		$pdf           Object PDF
    @@ -883,11 +884,11 @@ class pdf_cyan extends ModelePDFPropales
     	 */
     	function _tableau_versements(&$pdf, $object, $posy, $outputlangs)
     	{
    -
    +	    // phpcs:enable
     	}
     
     
    -	/**
    +	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
     	 *   @param		TCPDF		$pdf     		Object PDF
    @@ -898,6 +899,7 @@ class pdf_cyan extends ModelePDFPropales
     	 */
     	function _tableau_info(&$pdf, $object, $posy, $outputlangs)
     	{
    +	    // phpcs:enable
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -1701,7 +1703,8 @@ class pdf_cyan extends ModelePDFPropales
     	 *      @param	int			   $hideref			Do not show ref
     	 *      @return	null
     	 */
    -	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    +	function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +	{
     
     	    global $conf, $hookmanager;
     
    
    From 0ad991766cb3319a5c54f07740bff3d702d1ac97 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 23 Oct 2018 17:53:01 +0200
    Subject: [PATCH 397/433] Fix deletion of project when there is events
    
    ---
     htdocs/projet/class/project.class.php | 7 ++++---
     1 file changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php
    index a8b34e9c57d..eaf1ad6ea67 100644
    --- a/htdocs/projet/class/project.class.php
    +++ b/htdocs/projet/class/project.class.php
    @@ -662,9 +662,10 @@ class Project extends CommonObject
     
             // Set fk_projet into elements to null
             $listoftables=array(
    -        		'facture'=>'fk_projet','propal'=>'fk_projet','commande'=>'fk_projet',
    -                'facture_fourn'=>'fk_projet','commande_fournisseur'=>'fk_projet','supplier_proposal'=>'fk_projet',
    -        		'expensereport_det'=>'fk_projet','contrat'=>'fk_projet','fichinter'=>'fk_projet','don'=>'fk_projet'
    +        		'propal'=>'fk_projet', 'commande'=>'fk_projet', 'facture'=>'fk_projet',
    +        		'supplier_proposal'=>'fk_projet', 'commande_fournisseur'=>'fk_projet', 'facture_fourn'=>'fk_projet',
    +        		'expensereport_det'=>'fk_projet', 'contrat'=>'fk_projet', 'fichinter'=>'fk_projet', 'don'=>'fk_projet',
    +        		'actioncomm'=>'fk_project'
             		);
             foreach($listoftables as $key => $value)
             {
    
    From bed5084bcfd2e5deab487e2034cbf064c08a7729 Mon Sep 17 00:00:00 2001
    From: atm-john <john.botella@atm-consulting.fr>
    Date: Tue, 23 Oct 2018 21:44:45 +0200
    Subject: [PATCH 398/433] Add missing Max payment date col
    
    ---
     htdocs/compta/paiement.php        | 23 +++++++++++++++++++++--
     htdocs/fourn/facture/paiement.php | 25 ++++++++++++++++++++++---
     2 files changed, 43 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php
    index 764ca818f7f..94cd53b5424 100644
    --- a/htdocs/compta/paiement.php
    +++ b/htdocs/compta/paiement.php
    @@ -526,7 +526,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
              */
     
             $sql = 'SELECT f.rowid as facid, f.facnumber, f.total_ttc, f.multicurrency_code, f.multicurrency_total_ttc, f.type,';
    -        $sql.= ' f.datef as df, f.fk_soc as socid';
    +        $sql.= ' f.datef as df, f.fk_soc as socid, f.date_lim_reglement as dlr';
             $sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
     		$sql.= ' WHERE f.entity IN ('.getEntity('facture', $conf->entity).')';
             $sql.= ' AND (f.fk_soc = '.$facture->socid;
    @@ -578,6 +578,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
                     print '<tr class="liste_titre">';
                     print '<td>'.$arraytitle.'</td>';
                     print '<td align="center">'.$langs->trans('Date').'</td>';
    +                print '<td align="center">'.$langs->trans('DateMaxPayment').'</td>';
                     if (!empty($conf->multicurrency->enabled)) print '<td>'.$langs->trans('Currency').'</td>';
                     if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
                     if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$multicurrencyalreadypayedlabel.'</td>';
    @@ -629,7 +630,25 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     
                         // Date
                         print '<td align="center">'.dol_print_date($db->jdate($objp->df),'day')."</td>\n";
    -
    +                    
    +                    // Date Max Payment
    +                    if ($objp->dlr > 0 )
    +                    {
    +                        print '<td align="center">';
    +                        print dol_print_date($db->jdate($objp->dlr), 'day');
    +                        
    +                        if ($invoice->hasDelay())
    +                        {
    +                            print img_warning($langs->trans('Late'));
    +                        }
    +                        
    +                        print '</td>';
    +                    }
    +                    else
    +                    {
    +                        print '<td align="center"><b>--</b></td>';
    +                    }
    +                    
                         // Currency
                         if (!empty($conf->multicurrency->enabled)) print '<td align="center">'.$objp->multicurrency_code."</td>\n";
     
    diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php
    index fdd358933d9..20ef0d4b9aa 100644
    --- a/htdocs/fourn/facture/paiement.php
    +++ b/htdocs/fourn/facture/paiement.php
    @@ -473,7 +473,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     	             * Autres factures impayees
     	             */
     	            $sql = 'SELECT f.rowid as facid, f.ref, f.ref_supplier, f.total_ht, f.total_ttc, f.multicurrency_total_ttc, f.datef as df,';
    -	            $sql.= ' SUM(pf.amount) as am, SUM(pf.multicurrency_amount) as multicurrency_am';
    +	            $sql.= ' SUM(pf.amount) as am, SUM(pf.multicurrency_amount) as multicurrency_am, f.date_lim_reglement as dlr';
     	            $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as f';
     	            $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid';
     	            $sql.= " WHERE f.entity = ".$conf->entity;
    @@ -511,6 +511,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     	                    print '<td>'.$langs->trans('Invoice').'</td>';
     	                    print '<td>'.$langs->trans('RefSupplier').'</td>';
     	                    print '<td align="center">'.$langs->trans('Date').'</td>';
    +	                    print '<td align="center">'.$langs->trans('DateMaxPayment').'</td>';
     	                    if (!empty($conf->multicurrency->enabled)) print '<td>'.$langs->trans('Currency').'</td>';
     						if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyAmountTTC').'</td>';
     						if (!empty($conf->multicurrency->enabled)) print '<td align="right">'.$langs->trans('MulticurrencyAlreadyPaid').'</td>';
    @@ -569,7 +570,25 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     	                        {
     	                            print '<td align="center"><b>!!!</b></td>';
     	                        }
    -
    +	                        
    +	                        // Date Max Payment
    +	                        if ($objp->dlr > 0 )
    +	                        {
    +	                            print '<td align="center">';
    +	                            print dol_print_date($db->jdate($objp->dlr), 'day');
    +	                            
    +	                            if ($invoice->hasDelay())
    +	                            {
    +	                                print img_warning($langs->trans('Late'));
    +	                            }
    +	                            
    +	                            print '</td>';
    +	                        }
    +	                        else
    +	                        {
    +	                            print '<td align="center"><b>--</b></td>';
    +	                        }
    +	                        
     	                        // Multicurrency
     	                        if (!empty($conf->multicurrency->enabled))
     	                        {
    @@ -661,7 +680,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     	                    {
     	                        // Print total
     	                        print '<tr class="liste_total">';
    -	                        print '<td colspan="3" align="left">'.$langs->trans('TotalTTC').':</td>';
    +	                        print '<td colspan="4" align="left">'.$langs->trans('TotalTTC').':</td>';
     							if (!empty($conf->multicurrency->enabled)) print '<td>&nbsp;</td>';
     							if (!empty($conf->multicurrency->enabled)) print '<td>&nbsp;</td>';
     							if (!empty($conf->multicurrency->enabled)) print '<td>&nbsp;</td>';
    
    From 0fe2c63bc09e0094787ee874dc860900cfb665e0 Mon Sep 17 00:00:00 2001
    From: atm-john <john.botella@atm-consulting.fr>
    Date: Tue, 23 Oct 2018 22:10:30 +0200
    Subject: [PATCH 399/433] FIX missing print button for delivery form
    
    ---
     htdocs/core/actions_printing.inc.php      | 18 ++++++++++++++----
     htdocs/core/class/html.formfile.class.php |  2 +-
     htdocs/livraison/card.php                 |  1 +
     3 files changed, 16 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php
    index d2d34cd523a..d5c40c17ad0 100644
    --- a/htdocs/core/actions_printing.inc.php
    +++ b/htdocs/core/actions_printing.inc.php
    @@ -47,11 +47,21 @@ if ($action == 'print_file' && $user->rights->printing->read) {
                 {
                     $printerfound++;
     
    -                $subdir=(GETPOST('printer', 'alpha')=='expedition'?'sending':'');
    +                $subdir='';
                     $module = GETPOST('printer', 'alpha');
    -                if ($module =='commande_fournisseur') {
    -                    $module = 'fournisseur';
    -                    $subdir = 'commande';
    +                switch ($module )
    +                {
    +                    case 'livraison' :
    +                        $subdir = 'receipt';
    +                        $module = 'expedition';
    +                        break;
    +                    case 'expedition' :
    +                        $subdir = 'sending';
    +                        break;
    +                    case 'commande_fournisseur' :
    +                        $module = 'fournisseur';
    +                        $subdir = 'commande';
    +                        break;
                     }
                     try {
                         $ret = $printer->printFile(GETPOST('file', 'alpha'), $module, $subdir);
    diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
    index e4c5b9a84b5..bfc67880a96 100644
    --- a/htdocs/core/class/html.formfile.class.php
    +++ b/htdocs/core/class/html.formfile.class.php
    @@ -310,7 +310,7 @@ class FormFile
     		$param.= 'entity='.(!empty($object->entity)?$object->entity:$conf->entity);
     
     		$printer=0;
    -		if (in_array($modulepart,array('facture','supplier_proposal','propal','proposal','order','commande','expedition', 'commande_fournisseur', 'expensereport')))	// The direct print feature is implemented only for such elements
    +		if (in_array($modulepart,array('facture','supplier_proposal','propal','proposal','order','commande','expedition', 'commande_fournisseur', 'expensereport','livraison')))	// The direct print feature is implemented only for such elements
     		{
     			$printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false;
     		}
    diff --git a/htdocs/livraison/card.php b/htdocs/livraison/card.php
    index 44eb12299d9..2fee2e100ba 100644
    --- a/htdocs/livraison/card.php
    +++ b/htdocs/livraison/card.php
    @@ -292,6 +292,7 @@ elseif ($action == 'remove_file')
     }
     */
     
    +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
     
     /*
      *	View
    
    From 82f40fb4b930ad83d9669ce98b80677493b38cb9 Mon Sep 17 00:00:00 2001
    From: atm-john <john.botella@atm-consulting.fr>
    Date: Tue, 23 Oct 2018 23:21:30 +0200
    Subject: [PATCH 400/433] NEW hidden conf to search by supplier ref
    
    ---
     htdocs/core/class/html.form.class.php | 7 +++++++
     1 file changed, 7 insertions(+)
    
    diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
    index 1cc02f0939a..5391dc0bd37 100644
    --- a/htdocs/core/class/html.form.class.php
    +++ b/htdocs/core/class/html.form.class.php
    @@ -2071,6 +2071,12 @@ class Form
     			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps on ps.fk_product = p.rowid";
     			$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e on ps.fk_entrepot = e.rowid";
     		}
    +		
    +		// include search in supplier ref
    +		if(!empty($conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF))
    +		{
    +            $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
    +		}
     
     		//Price by customer
     		if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) {
    @@ -2124,6 +2130,7 @@ class Form
     				if ($i > 0) $sql.=" AND ";
     				$sql.="(p.ref LIKE '".$db->escape($prefix.$crit)."%' OR p.label LIKE '".$db->escape($prefix.$crit)."%'";
     				if (! empty($conf->global->MAIN_MULTILANGS)) $sql.=" OR pl.label LIKE '".$db->escape($prefix.$crit)."%'";
    +				if (! empty($conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF)) $sql.=" OR pfp.ref_fourn LIKE '".$db->escape($prefix.$crit)."%'";
     				$sql.=")";
     				$i++;
     			}
    
    From 23a9416c193e79e5b1638a3a4845b5d228459950 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Tue, 23 Oct 2018 23:51:27 +0200
    Subject: [PATCH 401/433] Fix deprecated field
    
    ---
     htdocs/comm/action/class/actioncomm.class.php | 12 +++---------
     1 file changed, 3 insertions(+), 9 deletions(-)
    
    diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php
    index 969cb705bac..4a6cec809fe 100644
    --- a/htdocs/comm/action/class/actioncomm.class.php
    +++ b/htdocs/comm/action/class/actioncomm.class.php
    @@ -88,13 +88,6 @@ class ActionComm extends CommonObject
          */
         public $label;
     
    -    /**
    -     * @var string
    -     * @deprecated Use $label
    -     * @see label
    -     */
    -    public $libelle;
    -
         public $datec;			// Date creation record (datec)
         public $datem;			// Date modification record (tms)
     
    @@ -351,7 +344,7 @@ class ActionComm extends CommonObject
             $sql.= ($code?("'".$code."'"):"null").", ";
             $sql.= ((isset($this->socid) && $this->socid > 0) ? $this->socid:"null").", ";
             $sql.= ((isset($this->fk_project) && $this->fk_project > 0) ? $this->fk_project:"null").", ";
    -        $sql.= " '".$this->db->escape($this->note)."', ";
    +        $sql.= " '".$this->db->escape($this->note_private?$this->note_private:$this->note)."', ";
             $sql.= ((isset($this->contactid) && $this->contactid > 0) ? $this->contactid:"null").", ";
             $sql.= (isset($user->id) && $user->id > 0 ? $user->id:"null").", ";
             $sql.= ($userownerid>0 ? $userownerid:"null").", ";
    @@ -621,6 +614,7 @@ class ActionComm extends CommonObject
                     $this->datem   				= $this->db->jdate($obj->datem);
     
                     $this->note					= $obj->note;
    +                $this->note_private			= $obj->note;
                     $this->percentage			= $obj->percentage;
     
                     $this->authorid             = $obj->fk_user_author;
    @@ -870,7 +864,7 @@ class ActionComm extends CommonObject
             $sql.= ", datep = ".(strval($this->datep)!='' ? "'".$this->db->idate($this->datep)."'" : 'null');
             $sql.= ", datep2 = ".(strval($this->datef)!='' ? "'".$this->db->idate($this->datef)."'" : 'null');
             $sql.= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != ''?"'".$this->db->escape($this->durationp)."'":"null");	// deprecated
    -        $sql.= ", note = ".($this->note ? "'".$this->db->escape($this->note)."'":"null");
    +        $sql.= ", note = '".$this->db->escape($this->note_private?$this->note_private:$this->note)."'";
             $sql.= ", fk_project =". ($this->fk_project > 0 ? $this->fk_project:"null");
             $sql.= ", fk_soc =". ($socid > 0 ? $socid:"null");
             $sql.= ", fk_contact =". ($contactid > 0 ? $contactid:"null");
    
    From d5285ca359365cd2a809e5fd5ae4d3bcf3eab163 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 01:53:07 +0200
    Subject: [PATCH 402/433] Update commonobject.class.php
    
    ---
     htdocs/core/class/commonobject.class.php | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
    index bfb657f6216..ef42301b228 100644
    --- a/htdocs/core/class/commonobject.class.php
    +++ b/htdocs/core/class/commonobject.class.php
    @@ -6203,7 +6203,7 @@ abstract class CommonObject
     				$InfoFieldList = explode(":", $param_list[0]);
     				$classname=$InfoFieldList[0];
     				$classpath=$InfoFieldList[1];
    -				$getnomurlparam=$InfoFieldList[2];
    +				$getnomurlparam=(empty($InfoFieldList[2]) ? 3 : $InfoFieldList[2]);
     				if (! empty($classpath))
     				{
     					dol_include_once($InfoFieldList[1]);
    @@ -6211,7 +6211,7 @@ abstract class CommonObject
     					{
     						$object = new $classname($this->db);
     						$object->fetch($value);
    -						$value=$object->getNomUrl(!empty($getnomurlparam)?$getnomurlparam:3);
    +						$value=$object->getNomUrl($getnomurlparam);
     					}
     				}
     				else
    
    From ae44c4c7f54218dd4109a436996f74fd9dad5e38 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 02:00:43 +0200
    Subject: [PATCH 403/433] Disable duplicate feature with emailing module and
     field "unsubscribe requested"
    
    ---
     htdocs/core/modules/modDataPolicy.class.php | 8 +++-----
     1 file changed, 3 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/core/modules/modDataPolicy.class.php b/htdocs/core/modules/modDataPolicy.class.php
    index 2ecb5da4336..ca53440a3b9 100644
    --- a/htdocs/core/modules/modDataPolicy.class.php
    +++ b/htdocs/core/modules/modDataPolicy.class.php
    @@ -200,7 +200,7 @@ class modDataPolicy extends DolibarrModules {
             // unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
             $this->cronjobs = array(
                 0 => array('label' => 'DATAPOLICY Cron', 'jobtype' => 'method', 'class' => '/datapolicy/class/datapolicyCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'exec', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 1, 'test' => true),
    -            1 => array('label' => 'DATAPOLICY Mailing', 'jobtype' => 'method', 'class' => '/datapolicy/class/datapolicyCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'sendMailing', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 0, 'test' => true)
    +            //1 => array('label' => 'DATAPOLICY Mailing', 'jobtype' => 'method', 'class' => '/datapolicy/class/datapolicyCron.class.php', 'objectname' => 'RgpdCron', 'method' => 'sendMailing', 'parameters' => '', 'comment' => 'Comment', 'frequency' => 1, 'unitfrequency' => 86400, 'status' => 0, 'test' => true)
             );
             // Example: $this->cronjobs=array(0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>true),
             //                                1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>true)
    @@ -230,9 +230,8 @@ class modDataPolicy extends DolibarrModules {
             include_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
             $extrafields = new ExtraFields($this->db);
     
    -
    +		/*
             // Extrafield contact
    -        //$result1=$extrafields->addExtraField('datapolicy_separate', "DATAPOLICY_BLOCKCHECKBOX", 'separate', 100,  1, 'thirdparty',   0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'thirdparty', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    @@ -240,7 +239,6 @@ class modDataPolicy extends DolibarrModules {
             $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'thirdparty', 0, 0, '', '', 0, '', '0', 0);
     
             // Extrafield Tiers
    -        //$result1=$extrafields->addExtraField('datapolicy_separate', "DATAPOLICY_BLOCKCHECKBOX", 'separate', 100,  1, 'contact',   0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'contact', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
    @@ -248,12 +246,12 @@ class modDataPolicy extends DolibarrModules {
             $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'contact', 0, 0, '', '', 0, '', '0', 0);
     
             // Extrafield Adherent
    -        //$result1=$extrafields->addExtraField('datapolicy_separate', "DATAPOLICY_BLOCKCHECKBOX", 'separate', 100,  1, 'adherent',   0, 0, '', '', 1, '', '1', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_consentement', $langs->trans("DATAPOLICY_consentement"), 'boolean', 101, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_opposition_traitement', $langs->trans("DATAPOLICY_opposition_traitement"), 'boolean', 102, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_opposition_prospection', $langs->trans("DATAPOLICY_opposition_prospection"), 'boolean', 103, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0, '', '', 'datapolicy@datapolicy', '$conf->datapolicy->enabled');
             $result1 = $extrafields->addExtraField('datapolicy_date', $langs->trans("DATAPOLICY_date"), 'date', 104, 3, 'adherent', 0, 0, '', '', 1, '', '3', 0);
             $result1 = $extrafields->addExtraField('datapolicy_send', $langs->trans("DATAPOLICY_send"), 'date', 105, 3, 'adherent', 0, 0, '', '', 0, '', '0', 0);
    +		*/
     
             $sql = array();
     
    
    From 065d715d4197b25ef7f262e498bd5b18afbe4b8b Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 02:20:07 +0200
    Subject: [PATCH 404/433] FIX #9837 - The fetchAllXXX was not managing
     correctly the limit
    
    ---
     htdocs/accountancy/class/bookkeeping.class.php | 12 +++++++++---
     1 file changed, 9 insertions(+), 3 deletions(-)
    
    diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php
    index 0550fb5a438..fe3ef196d1b 100644
    --- a/htdocs/accountancy/class/bookkeeping.class.php
    +++ b/htdocs/accountancy/class/bookkeeping.class.php
    @@ -785,7 +785,8 @@ class BookKeeping extends CommonObject
     		if ($resql) {
     			$num = $this->db->num_rows($resql);
     
    -			while ( $obj = $this->db->fetch_object($resql) ) {
    +			$i = 0;
    +			while ($obj = $this->db->fetch_object($resql) && (empty($limit) || $i < min($limit, $num))) {
     				$line = new BookKeepingLine();
     
     				$line->id = $obj->rowid;
    @@ -817,6 +818,8 @@ class BookKeeping extends CommonObject
     				$line->date_creation = $obj->date_creation;
     
     				$this->lines[] = $line;
    +
    +				$i++;
     			}
     			$this->db->free($resql);
     
    @@ -914,7 +917,8 @@ class BookKeeping extends CommonObject
     		if ($resql) {
     			$num = $this->db->num_rows($resql);
     
    -			while ( $obj = $this->db->fetch_object($resql) ) {
    +			$i = 0;
    +			while ($obj = $this->db->fetch_object($resql) && (empty($limit) || $i < min($limit, $num))) {
     				$line = new BookKeepingLine();
     
     				$line->id = $obj->rowid;
    @@ -943,6 +947,8 @@ class BookKeeping extends CommonObject
     				$line->date_modification = $this->db->jdate($obj->date_modification);
     
     				$this->lines[] = $line;
    +
    +				$i++;
     			}
     			$this->db->free($resql);
     
    @@ -1021,7 +1027,7 @@ class BookKeeping extends CommonObject
     			$num = $this->db->num_rows($resql);
     
     			$i = 0;
    -			while (($obj = $this->db->fetch_object($resql)) && ($i < min($limit, $num)))
    +			while (($obj = $this->db->fetch_object($resql)) && (empty($limit) || $i < min($limit, $num)))
     			{
     				$line = new BookKeepingLine();
     
    
    From e39e57c5b9b51ba99d391703eac75ce119b1cb51 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 02:24:47 +0200
    Subject: [PATCH 405/433] Update expeditionbatch.class.php
    
    ---
     htdocs/expedition/class/expeditionbatch.class.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/expedition/class/expeditionbatch.class.php b/htdocs/expedition/class/expeditionbatch.class.php
    index 3df77b509e7..520f760aee0 100644
    --- a/htdocs/expedition/class/expeditionbatch.class.php
    +++ b/htdocs/expedition/class/expeditionbatch.class.php
    @@ -119,7 +119,7 @@ class ExpeditionLineBatch extends CommonObject
     		$sql.= " ".(! isset($this->sellby) || dol_strlen($this->sellby)==0?'NULL':("'".$this->db->idate($this->sellby))."'").",";
     		$sql.= " ".(! isset($this->eatby) || dol_strlen($this->eatby)==0?'NULL':("'".$this->db->idate($this->eatby))."'").",";
     		$sql.= " ".(! isset($this->batch)?'NULL':("'".$this->db->escape($this->batch)."'")).",";
    -		$sql.= " ".(! isset($this->qty)?(! isset($this->dluo_qty)?'NULL':$this->dluo_qty):$this->qty).","; // dluo_qty deprecated, use qty
    +		$sql.= " ".(! isset($this->qty)?((! isset($this->dluo_qty))?'NULL':$this->dluo_qty):$this->qty).","; // dluo_qty deprecated, use qty
     		$sql.= " ".(! isset($this->fk_origin_stock)?'NULL':$this->fk_origin_stock);
     		$sql.= ")";
     
    
    From 2ba6f967651e62c9f550e1b5e68fed6073978781 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 02:27:59 +0200
    Subject: [PATCH 406/433] Update style.css.php
    
    ---
     htdocs/theme/md/style.css.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php
    index 84384a9130e..b27bf4ad99c 100644
    --- a/htdocs/theme/md/style.css.php
    +++ b/htdocs/theme/md/style.css.php
    @@ -3018,7 +3018,7 @@ tr.box_titre {
         white-space: nowrap;
     }
     
    -tr.box_titre, td.boxclose {
    +tr.box_titre td.boxclose {
     	width: 30px;
     }
     img.boxhandle, img.boxclose {
    
    From a3d6146bed5b44b396cfed86ed85cd036545f0c3 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 02:32:01 +0200
    Subject: [PATCH 407/433] Code comment
    
    ---
     dev/dolibarr_changes.txt | 7 +++++++
     1 file changed, 7 insertions(+)
    
    diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt
    index 24832103c6c..37aef014e63 100644
    --- a/dev/dolibarr_changes.txt
    +++ b/dev/dolibarr_changes.txt
    @@ -78,17 +78,24 @@ In htdocs/includes/tcpdf/tcpdf.php
     +       protected $default_monospaced_font = 'freemono';
     
     
    +		
     
     TCPDI:
     ------
     Add fpdf_tpl.php 1.2
     Add tcpdi.php
    +
     Add tcpdi_parser.php and replace:
     require_once(dirname(__FILE__).'/include/tcpdf_filters.php');
     with:
     require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php');
     
     
    +* Fix by replacing
    +	} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1] >= 2))) {
    +with
    +	} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1]) >= 2)) {
    +
     
     
     JSGANTT:
    
    From 769bae75e94c3030f326e599efb356a782eb7171 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 02:48:38 +0200
    Subject: [PATCH 408/433] Update list.php
    
    ---
     htdocs/accountancy/bookkeeping/list.php | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php
    index 9e696b9d2af..4a4630edfa5 100644
    --- a/htdocs/accountancy/bookkeeping/list.php
    +++ b/htdocs/accountancy/bookkeeping/list.php
    @@ -145,6 +145,8 @@ $arrayfields=array(
     	't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0),
     );
     
    +if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) unset($arrayfields['t.lettering_code']);
    +
     
     /*
      * Actions
    
    From f0dc2df526b48a60e44204d91f268be44945121c Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 03:30:06 +0200
    Subject: [PATCH 409/433] Fix code comment
    
    ---
     htdocs/core/class/commondocgenerator.class.php | 12 ++++++------
     1 file changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php
    index e944467ca27..18e2817f040 100644
    --- a/htdocs/core/class/commondocgenerator.class.php
    +++ b/htdocs/core/class/commondocgenerator.class.php
    @@ -223,10 +223,10 @@ abstract class CommonDocGenerator
     	/**
     	 * Define array with couple subtitution key => subtitution value
     	 *
    -	 * @param	Contact 		$object        	contact
    +	 * @param	Contact 	$object        	contact
     	 * @param	Translate 	$outputlangs   	object for output
    -	 * @param   array_key	$array_key	    Name of the key for return array
    -	 * @return	array of substitution key->code
    +	 * @param   array		$array_key	    Name of the key for return array
    +	 * @return	array 						Array of substitution key->code
     	 */
     	function get_substitutionarray_contact($object, $outputlangs, $array_key = 'object') {
     		global $conf;
    @@ -552,9 +552,9 @@ abstract class CommonDocGenerator
         /**
          * Define array with couple substitution key => substitution value
          *
    -     * @param   Expedition			$object             Main object to use as data source
    +     * @param   Expedition		$object             Main object to use as data source
          * @param   Translate		$outputlangs        Lang object to use for output
    -     * @param   array_key		$array_key	        Name of the key for return array
    +     * @param   array			$array_key	        Name of the key for return array
          * @return	array								Array of substitution
          */
         function get_substitutionarray_shipment($object,$outputlangs,$array_key='object')
    @@ -746,7 +746,7 @@ abstract class CommonDocGenerator
     	/**
     	 * Rect pdf
     	 *
    -	 * @param	PDF		$pdf			Object PDF
    +	 * @param	TCPDF	$pdf			Object PDF
     	 * @param	float	$x				Abscissa of first point
     	 * @param	float	$y		        Ordinate of first point
     	 * @param	float	$l				??
    
    From 047d130081355df54c58b074d1a2911e45ad0885 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 03:38:12 +0200
    Subject: [PATCH 410/433] Fix phpcs
    
    ---
     .../core/class/commondocgenerator.class.php   | 83 +++++++++----------
     1 file changed, 41 insertions(+), 42 deletions(-)
    
    diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php
    index dc4f1242894..003d9591712 100644
    --- a/htdocs/core/class/commondocgenerator.class.php
    +++ b/htdocs/core/class/commondocgenerator.class.php
    @@ -823,8 +823,8 @@ abstract class CommonDocGenerator
             if (empty($hidebottom)) $pdf->line($x+$l, $y+$h, $x, $y+$h);
             $pdf->line($x, $y+$h, $x, $y);
         }
    -    
    -    
    +
    +
         /**
          *   	uasort callback function to Sort colums fields
          *
    @@ -832,55 +832,54 @@ abstract class CommonDocGenerator
          *   	@param	array			$b    			PDF lines array fields configs
          *      @return	int								Return compare result
          */
    -    function columnSort($a, $b) {
    -        
    +    function columnSort($a, $b)
    +    {
             if(empty($a['rank'])){ $a['rank'] = 0; }
             if(empty($b['rank'])){ $b['rank'] = 0; }
             if ($a['rank'] == $b['rank']) {
                 return 0;
             }
             return ($a['rank'] > $b['rank']) ? -1 : 1;
    -        
         }
    -    
    +
         /**
          *   	Prepare Array Column Field
          *
    -     *   	@param	object			$object    		common object
    -     *   	@param	outputlangs		$outputlangs    langs
    -     *      @param		int			$hidedetails		Do not show line details
    -     *      @param		int			$hidedesc			Do not show desc
    -     *      @param		int			$hideref			Do not show ref
    +     *   	@param	object			$object				common object
    +     *   	@param	Translate		$outputlangs		langs
    +     *      @param	int				$hidedetails		Do not show line details
    +     *      @param	int				$hidedesc			Do not show desc
    +     *      @param	int				$hideref			Do not show ref
          *      @return	null
          */
    -    function prepareArrayColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0){
    -        
    +    function prepareArrayColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    +    {
             global $conf;
    -        
    +
             $this->defineColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
    -        
    -        
    +
    +
             // Sorting
             uasort ( $this->cols, array( $this, 'columnSort' ) );
    -        
    +
             // Positionning
             $curX = $this->page_largeur-$this->marge_droite; // start from right
    -        
    +
             // Array witdh
             $arrayWidth = $this->page_largeur-$this->marge_droite-$this->marge_gauche;
    -        
    +
             // Count flexible column
             $totalDefinedColWidth = 0;
             $countFlexCol = 0;
             foreach ($this->cols as $colKey =>& $colDef)
             {
                 if(!$this->getColumnStatus($colKey)) continue; // continue if desable
    -            
    +
                 if(!empty($colDef['scale'])){
                     // In case of column widht is defined by percentage
                     $colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100 );
                 }
    -            
    +
                 if(empty($colDef['width'])){
                     $countFlexCol++;
                 }
    @@ -888,7 +887,7 @@ abstract class CommonDocGenerator
                     $totalDefinedColWidth += $colDef['width'];
                 }
             }
    -        
    +
             foreach ($this->cols as $colKey =>& $colDef)
             {
                 // setting empty conf with default
    @@ -898,7 +897,7 @@ abstract class CommonDocGenerator
                 else{
                     $colDef['title'] = $this->defaultTitlesFieldsStyle;
                 }
    -            
    +
                 // setting empty conf with default
                 if(!empty($colDef['content'])){
                     $colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']);
    @@ -906,14 +905,14 @@ abstract class CommonDocGenerator
                 else{
                     $colDef['content'] = $this->defaultContentsFieldsStyle;
                 }
    -            
    +
                 if($this->getColumnStatus($colKey))
                 {
                     // In case of flexible column
                     if(empty($colDef['width'])){
                         $colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol;
                     }
    -                
    +
                     // Set positions
                     $lastX = $curX;
                     $curX = $lastX - $colDef['width'];
    @@ -922,7 +921,7 @@ abstract class CommonDocGenerator
                 }
             }
         }
    -    
    +
         /**
          *   	get column content width from column key
          *
    @@ -934,8 +933,8 @@ abstract class CommonDocGenerator
             $colDef = $this->cols[$colKey];
             return  $colDef['width'] - $colDef['content']['padding'][3] - $colDef['content']['padding'][1];
         }
    -    
    -    
    +
    +
         /**
          *   	get column content X (abscissa) left position from column key
          *
    @@ -947,7 +946,7 @@ abstract class CommonDocGenerator
             $colDef = $this->cols[$colKey];
             return  $colDef['xStartPos'] + $colDef['content']['padding'][3];
         }
    -    
    +
         /**
          *   	get column position rank from column key
          *
    @@ -959,7 +958,7 @@ abstract class CommonDocGenerator
             if(!isset($this->cols[$colKey]['rank'])) return -1;
             return  $this->cols[$colKey]['rank'];
         }
    -    
    +
         /**
          *   	get column position rank from column key
          *
    @@ -973,21 +972,21 @@ abstract class CommonDocGenerator
         {
             // prepare wanted rank
             $rank = -1;
    -        
    +
             // try to get rank from target column
             if(!empty($targetCol)){
                 $rank = $this->getColumnRank($targetCol);
                 if($rank>=0 && $insertAfterTarget){ $rank++; }
             }
    -        
    +
             // get rank from new column definition
             if($rank<0 && !empty($defArray['rank'])){
                 $rank = $defArray['rank'];
             }
    -        
    +
             // error: no rank
             if($rank<0){ return -1; }
    -        
    +
             foreach ($this->cols as $colKey =>& $colDef)
             {
                 if( $rank <= $colDef['rank'])
    @@ -995,14 +994,14 @@ abstract class CommonDocGenerator
                     $colDef['rank'] = $colDef['rank'] + 1;
                 }
             }
    -        
    +
             $defArray['rank'] = $rank;
             $this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys
    -        
    +
             return $rank;
         }
    -    
    -    
    +
    +
         /**
          *   	print standard column content
          *
    @@ -1015,7 +1014,7 @@ abstract class CommonDocGenerator
         function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '')
         {
             global $hookmanager;
    -        
    +
             $parameters=array(
                 'object' => $object,
                 'curY' =>& $curY,
    @@ -1031,10 +1030,10 @@ abstract class CommonDocGenerator
                 $colDef = $this->cols[$colKey];
                 $pdf->MultiCell( $this->getColumnContentWidth($colKey),2, $columnText,'',$colDef['content']['align']);
             }
    -        
    +
         }
    -    
    -    
    +
    +
         /**
          *   	get column status from column key
          *
    
    From eaab953ba2a23ff5c35c103977fb2f6a35c395e0 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 03:50:18 +0200
    Subject: [PATCH 411/433] Renamed mouvement.php into movement_list.php to
     follow dev rules
    
    ---
     htdocs/core/lib/stock.lib.php                             | 2 +-
     htdocs/core/menus/init_menu_auguria.sql                   | 2 +-
     htdocs/core/menus/standard/eldy.lib.php                   | 2 +-
     htdocs/product/reassort.php                               | 2 +-
     htdocs/product/reassortlot.php                            | 2 +-
     htdocs/product/stock/card.php                             | 2 +-
     htdocs/product/stock/class/mouvementstock.class.php       | 2 +-
     htdocs/product/stock/index.php                            | 2 +-
     htdocs/product/stock/{mouvement.php => movement_list.php} | 6 +++---
     htdocs/product/stock/product.php                          | 4 ++--
     htdocs/product/stock/productlot_card.php                  | 2 +-
     11 files changed, 14 insertions(+), 14 deletions(-)
     rename htdocs/product/stock/{mouvement.php => movement_list.php} (99%)
    
    diff --git a/htdocs/core/lib/stock.lib.php b/htdocs/core/lib/stock.lib.php
    index ac59ab230c7..579944117ab 100644
    --- a/htdocs/core/lib/stock.lib.php
    +++ b/htdocs/core/lib/stock.lib.php
    @@ -39,7 +39,7 @@ function stock_prepare_head($object)
     	$head[$h][2] = 'card';
     	$h++;
     
    -	$head[$h][0] = DOL_URL_ROOT.'/product/stock/mouvement.php?id='.$object->id;
    +	$head[$h][0] = DOL_URL_ROOT.'/product/stock/movement_list.php?id='.$object->id;
     	$head[$h][1] = $langs->trans("StockMovements");
     	$head[$h][2] = 'movements';
     	$h++;
    diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql
    index afd7ba0ffcb..682746b3412 100644
    --- a/htdocs/core/menus/init_menu_auguria.sql
    +++ b/htdocs/core/menus/init_menu_auguria.sql
    @@ -120,7 +120,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3100__+MAX_llx_menu__, 'products', 'stock', 3__+MAX_llx_menu__, '/product/stock/index.php?leftmenu=stock', 'Stock', 0, 'stocks', '$user->rights->stock->lire', '', 2, 3, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3101__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/card.php?action=create', 'MenuNewWarehouse', 1, 'stocks', '$user->rights->stock->creer', '', 2, 0, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3102__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/list.php', 'List', 1, 'stocks', '$user->rights->stock->lire', '', 2, 1, __ENTITY__);
    -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3104__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/mouvement.php', 'Movements', 1, 'stocks', '$user->rights->stock->mouvement->lire', '', 2, 3, __ENTITY__);
    +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3104__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/movement_list.php', 'Movements', 1, 'stocks', '$user->rights->stock->mouvement->lire', '', 2, 3, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled && $conf->supplier_order->enabled', __HANDLER__, 'left', 3105__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/replenish.php', 'Replenishments', 1, 'stocks', '$user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire', '', 2, 4, __ENTITY__);
     insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->stock->enabled', __HANDLER__, 'left', 3106__+MAX_llx_menu__, 'products', '', 3100__+MAX_llx_menu__, '/product/stock/massstockmove.php', 'MassStockTransferShort', 1, 'stocks', '$user->rights->stock->mouvement->creer', '', 2, 5, __ENTITY__);
     
    diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php
    index 51a9907a16e..562ed99a020 100644
    --- a/htdocs/core/menus/standard/eldy.lib.php
    +++ b/htdocs/core/menus/standard/eldy.lib.php
    @@ -1310,7 +1310,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
     				$newmenu->add("/product/stock/index.php?leftmenu=stock", $langs->trans("Warehouses"), 0, $user->rights->stock->lire, '', $mainmenu, 'stock');
     				$newmenu->add("/product/stock/card.php?action=create", $langs->trans("MenuNewWarehouse"), 1, $user->rights->stock->creer);
     				$newmenu->add("/product/stock/list.php", $langs->trans("List"), 1, $user->rights->stock->lire);
    -				$newmenu->add("/product/stock/mouvement.php", $langs->trans("Movements"), 1, $user->rights->stock->mouvement->lire);
    +				$newmenu->add("/product/stock/movement_list.php", $langs->trans("Movements"), 1, $user->rights->stock->mouvement->lire);
     
                     $newmenu->add("/product/stock/massstockmove.php", $langs->trans("MassStockTransferShort"), 1, $user->rights->stock->mouvement->creer);
                     if ($conf->supplier_order->enabled) $newmenu->add("/product/stock/replenish.php", $langs->trans("Replenishment"), 1, $user->rights->stock->mouvement->creer && $user->rights->fournisseur->lire);
    diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php
    index 2aa8dc6fcc7..27ac0c4d522 100644
    --- a/htdocs/product/reassort.php
    +++ b/htdocs/product/reassort.php
    @@ -381,7 +381,7 @@ if ($resql)
     			print $product->stock_theorique;
     			print '</td>';
     		}
    -		print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$product->id.'">'.$langs->trans("Movements").'</a></td>';
    +		print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?idproduct='.$product->id.'">'.$langs->trans("Movements").'</a></td>';
     		print '<td align="right" class="nowrap">'.$product->LibStatut($objp->statut,5,0).'</td>';
             print '<td align="right" class="nowrap">'.$product->LibStatut($objp->tobuy,5,1).'</td>';
     		print '<td></td>';
    diff --git a/htdocs/product/reassortlot.php b/htdocs/product/reassortlot.php
    index bad733979b4..518a19d8407 100644
    --- a/htdocs/product/reassortlot.php
    +++ b/htdocs/product/reassortlot.php
    @@ -408,7 +408,7 @@ if ($resql)
             //if ($objp->seuil_stock_alerte && ($objp->stock_physique < $objp->seuil_stock_alerte)) print img_warning($langs->trans("StockTooLow")).' ';
     		print $objp->stock_physique;
     		print '</td>';
    -		print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?idproduct='.$product_static->id.'&search_warehouse='.$objp->fk_entrepot.'&search_batch='.($objp->batch != 'Undefined' ? $objp->batch : 'Undefined').'">'.$langs->trans("Movements").'</a></td>';
    +		print '<td align="right"><a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?idproduct='.$product_static->id.'&search_warehouse='.$objp->fk_entrepot.'&search_batch='.($objp->batch != 'Undefined' ? $objp->batch : 'Undefined').'">'.$langs->trans("Movements").'</a></td>';
     		print '<td align="right" class="nowrap">'.$product_static->LibStatut($objp->statut,5,0).'</td>';
             print '<td align="right" class="nowrap">'.$product_static->LibStatut($objp->tobuy,5,1).'</td>';
             print '<td></td>';
    diff --git a/htdocs/product/stock/card.php b/htdocs/product/stock/card.php
    index 334ccdb0b65..b24a37c4fe2 100644
    --- a/htdocs/product/stock/card.php
    +++ b/htdocs/product/stock/card.php
    @@ -384,7 +384,7 @@ else
     			if ($lastmovementdate)
     			{
     			    print dol_print_date($lastmovementdate,'dayhour').' ';
    -			    print '(<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?id='.$object->id.'">'.$langs->trans("FullList").'</a>)';
    +			    print '(<a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?id='.$object->id.'">'.$langs->trans("FullList").'</a>)';
     			}
     			else
     			{
    diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
    index f5fad015636..9012262d163 100644
    --- a/htdocs/product/stock/class/mouvementstock.class.php
    +++ b/htdocs/product/stock/class/mouvementstock.class.php
    @@ -1001,7 +1001,7 @@ class MouvementStock extends CommonObject
     		$label.= '<br><b>' . $langs->trans('Qty') . ':</b> ' .$this->qty;
     		$label.= '</div>';
     
    -		$link = '<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?id='.$this->warehouse_id.'&msid='.$this->id.'"';
    +		$link = '<a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?id='.$this->warehouse_id.'&msid='.$this->id.'"';
     		$link.= ($notooltip?'':' title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip'.($morecss?' '.$morecss:'').'"');
     		$link.= '>';
     		$linkend='</a>';
    diff --git a/htdocs/product/stock/index.php b/htdocs/product/stock/index.php
    index e658b794d4b..20054d8896b 100644
    --- a/htdocs/product/stock/index.php
    +++ b/htdocs/product/stock/index.php
    @@ -143,7 +143,7 @@ if ($resql)
     		print '<th>'.$langs->trans("EatByDate").'</th>';
     	}
     	print '<th>'.$langs->trans("Warehouse").'</th>';
    -	print '<th align="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/product/stock/mouvement.php">'.$langs->trans("FullList").'</a></th>';
    +	print '<th align="right"><a class="notasortlink" href="'.DOL_URL_ROOT.'/product/stock/movement_list.php">'.$langs->trans("FullList").'</a></th>';
     	print "</tr>\n";
     
     	$i=0;
    diff --git a/htdocs/product/stock/mouvement.php b/htdocs/product/stock/movement_list.php
    similarity index 99%
    rename from htdocs/product/stock/mouvement.php
    rename to htdocs/product/stock/movement_list.php
    index 8ee5383ded0..ec193e6dfc8 100644
    --- a/htdocs/product/stock/mouvement.php
    +++ b/htdocs/product/stock/movement_list.php
    @@ -20,7 +20,7 @@
      */
     
     /**
    - *	\file       htdocs/product/stock/mouvement.php
    + *	\file       htdocs/product/stock/movement_list.php
      *	\ingroup    stock
      *	\brief      Page to list stock movements
      */
    @@ -385,7 +385,7 @@ if ($action == "transfert_stock" && ! $cancel)
                     }
                     else
                     {
    -                    header("Location: mouvement.php?id=".$object->id);
    +                    header("Location: movement_list.php?id=".$object->id);
                         exit;
                     }
                 }
    @@ -1028,7 +1028,7 @@ if ($resql)
             {
     	        // Inventory code
     	        print '<td>'.'<a href="'
    -								.DOL_URL_ROOT.'/product/stock/mouvement.php'
    +								.DOL_URL_ROOT.'/product/stock/movement_list.php'
     								.'?id='.$objp->entrepot_id
     								.'&amp;search_inventorycode='.$objp->inventorycode
     							    .'&amp;search_type_mouvement='.$objp->type_mouvement
    diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php
    index 70a37a4bba6..07b4f5dcac3 100644
    --- a/htdocs/product/stock/product.php
    +++ b/htdocs/product/stock/product.php
    @@ -716,9 +716,9 @@ if ($id > 0 || $ref)
     			print '<tr><td class="tdtop">' . $langs->trans("LastMovement") . '</td><td>';
     			if ($lastmovementdate) {
     				print dol_print_date($lastmovementdate, 'dayhour') . ' ';
    -				print '(<a href="' . DOL_URL_ROOT . '/product/stock/mouvement.php?idproduct=' . $object->id . '">' . $langs->trans("FullList") . '</a>)';
    +				print '(<a href="' . DOL_URL_ROOT . '/product/stock/movement_list.php?idproduct=' . $object->id . '">' . $langs->trans("FullList") . '</a>)';
     			} else {
    -				print '<a href="' . DOL_URL_ROOT . '/product/stock/mouvement.php?idproduct=' . $object->id . '">' . $langs->trans("None") . '</a>';
    +				print '<a href="' . DOL_URL_ROOT . '/product/stock/movement_list.php?idproduct=' . $object->id . '">' . $langs->trans("None") . '</a>';
     			}
     			print "</td></tr>";
     		}
    diff --git a/htdocs/product/stock/productlot_card.php b/htdocs/product/stock/productlot_card.php
    index 08f28a7eb11..5ee52ce337a 100644
    --- a/htdocs/product/stock/productlot_card.php
    +++ b/htdocs/product/stock/productlot_card.php
    @@ -388,7 +388,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
     
     	print '<a href="'.DOL_URL_ROOT.'/product/reassortlot.php?sref='.urlencode($producttmp->ref).'&search_batch='.urlencode($object->batch).'">'.$langs->trans("ShowCurrentStockOfLot").'</a><br>';
     	print '<br>';
    -	print '<a href="'.DOL_URL_ROOT.'/product/stock/mouvement.php?search_product_ref='.urlencode($producttmp->ref).'&search_batch='.urlencode($object->batch).'">'.$langs->trans("ShowLogOfMovementIfLot").'</a><br>';
    +	print '<a href="'.DOL_URL_ROOT.'/product/stock/movement_list.php?search_product_ref='.urlencode($producttmp->ref).'&search_batch='.urlencode($object->batch).'">'.$langs->trans("ShowLogOfMovementIfLot").'</a><br>';
     
     	print '<br>';
     }
    
    From 2a6478a2c42c0fb2b0b90455664d809b1cc5bb65 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 24 Oct 2018 08:15:00 +0200
    Subject: [PATCH 412/433] fix phpcs
    
    ---
     htdocs/product/class/product.class.php | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index f8326a60721..24689e7b193 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -3556,7 +3556,6 @@ class Product extends CommonObject
     		} else {
     			return false;
     		}
    -
     	}
     
     	/**
    @@ -4864,4 +4863,4 @@ class Product extends CommonObject
     			dol_print_error($this->db);
     		}
     	}
    -}
    \ No newline at end of file
    +}
    
    From 4747e93e39df7a09f4867b9a57dfd45464dc01fc Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 24 Oct 2018 08:18:21 +0200
    Subject: [PATCH 413/433] Update pdf_eratosthene.modules.php
    
    ---
     .../modules/commande/doc/pdf_eratosthene.modules.php   | 10 +++-------
     1 file changed, 3 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    index 4b11c61b078..3c2189e05c4 100644
    --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    @@ -714,7 +714,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     		}
     	}
     
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *  Show payments table
          *
     	 *  @param	TCPDF		$pdf     		Object PDF
    @@ -725,12 +725,10 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 */
     	private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
     	{
    -	    // phpcs:enable
    -	    
     	}
     
     
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
     	 *   @param		TCPDF		$pdf     		Object PDF
    @@ -741,7 +739,6 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 */
     	private function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
     	{
    -	    // phpcs:enable
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    @@ -917,7 +914,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	}
     
     
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *	Show total to pay
     	 *
     	 *	@param	TCPDF		$pdf           Object PDF
    @@ -929,7 +926,6 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 */
     	private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    -	    // phpcs:enable
     	    global $conf,$mysoc;
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    
    From d9d346aab28ec1ebc4153fb6b63fde59a502cfb4 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 24 Oct 2018 08:22:17 +0200
    Subject: [PATCH 414/433] Update pdf_sponge.modules.php
    
    ---
     .../core/modules/facture/doc/pdf_sponge.modules.php  | 12 +++---------
     1 file changed, 3 insertions(+), 9 deletions(-)
    
    diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    index 4032a6c41a5..d03d60f50fe 100644
    --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php
    @@ -849,7 +849,7 @@ class pdf_sponge extends ModelePDFFactures
     	}
     
     
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *  Show payments table
     	 *
          *  @param	PDF			$pdf           Object PDF
    @@ -860,7 +860,6 @@ class pdf_sponge extends ModelePDFFactures
     	 */
     	function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
     	{
    -	    // phpcs:enable
     		global $conf;
     
             $sign=1;
    @@ -989,7 +988,7 @@ class pdf_sponge extends ModelePDFFactures
     	}
     
     
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
     	 *   @param		PDF			$pdf     		Object PDF
    @@ -1000,7 +999,6 @@ class pdf_sponge extends ModelePDFFactures
     	 */
     	private function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
     	{
    -	    // phpcs:enable
     		global $conf;
     
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
    @@ -1147,7 +1145,7 @@ class pdf_sponge extends ModelePDFFactures
     	}
     
     
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *	Show total to pay
     	 *
     	 *	@param	PDF			$pdf           Object PDF
    @@ -1159,7 +1157,6 @@ class pdf_sponge extends ModelePDFFactures
     	 */
     	private function drawTotalTable(&$pdf, $object, $deja_regle, $posy, $outputlangs)
     	{
    -	    // phpcs:enable
     		global $conf,$mysoc;
     
             $sign=1;
    @@ -1828,9 +1825,6 @@ class pdf_sponge extends ModelePDFFactures
     		return pdf_pagefoot($pdf,$outputlangs,'INVOICE_FREE_TEXT',$this->emetteur,$this->marge_basse,$this->marge_gauche,$this->page_hauteur,$object,$showdetails,$hidefreetext);
     	}
     
    -
    -
    -
     	/**
     	 *   	Define Array Column Field
     	 *
    
    From 2bc208675f88e282325395ba18d4efc5553e4c81 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?=
     <frederic34@users.noreply.github.com>
    Date: Wed, 24 Oct 2018 09:06:54 +0200
    Subject: [PATCH 415/433] Update pdf_cyan.modules.php
    
    ---
     htdocs/core/modules/propale/doc/pdf_cyan.modules.php | 7 ++-----
     1 file changed, 2 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    index 9dcc14bf384..e43734039ca 100644
    --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php
    @@ -875,7 +875,7 @@ class pdf_cyan extends ModelePDFPropales
     		}
     	}
     
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *  Show payments table
     	 *
          *  @param	TCPDF		$pdf           Object PDF
    @@ -886,11 +886,9 @@ class pdf_cyan extends ModelePDFPropales
     	 */
     	private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
     	{
    -	    // phpcs:enable
     	}
     
    -
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
     	 *   @param		TCPDF		$pdf     		Object PDF
    @@ -901,7 +899,6 @@ class pdf_cyan extends ModelePDFPropales
     	 */
     	function drawInfoTable(&$pdf, $object, $posy, $outputlangs)
     	{
    -	    // phpcs:enable
     		global $conf;
     		$default_font_size = pdf_getPDFFontSize($outputlangs);
     
    
    From a380d3e89b09d7bc29e3517b35a56f0953d4b58a Mon Sep 17 00:00:00 2001
    From: John BOTELLA <john.botella@atm-consulting.fr>
    Date: Wed, 24 Oct 2018 09:19:57 +0200
    Subject: [PATCH 416/433] Fix missing group by in query
    
    ---
     htdocs/fourn/facture/paiement.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php
    index 20ef0d4b9aa..7946f98cb66 100644
    --- a/htdocs/fourn/facture/paiement.php
    +++ b/htdocs/fourn/facture/paiement.php
    @@ -480,7 +480,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
     	            $sql.= ' AND f.fk_soc = '.$object->socid;
     	            $sql.= ' AND f.paye = 0';
     	            $sql.= ' AND f.fk_statut = 1';  // Statut=0 => non validee, Statut=2 => annulee
    -	            $sql.= ' GROUP BY f.rowid, f.ref, f.ref_supplier, f.total_ht, f.total_ttc, f.multicurrency_total_ttc, f.datef';
    +	            $sql.= ' GROUP BY f.rowid, f.ref, f.ref_supplier, f.total_ht, f.total_ttc, f.multicurrency_total_ttc, f.datef, f.date_lim_reglement';
     	            $resql = $db->query($sql);
     	            if ($resql)
     	            {
    
    From 036f70860e6440c3177439f6878de05ab2fefaff Mon Sep 17 00:00:00 2001
    From: gauthier <gauthier.verdol@atm-consulting.fr>
    Date: Wed, 24 Oct 2018 10:17:21 +0200
    Subject: [PATCH 417/433] FIX : wrong occurence number of contract on contact
     card, we must only count externals
    
    ---
     htdocs/contact/class/contact.class.php | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php
    index 036ee75a43d..bea6843de5f 100644
    --- a/htdocs/contact/class/contact.class.php
    +++ b/htdocs/contact/class/contact.class.php
    @@ -860,6 +860,7 @@ class Contact extends CommonObject
     		$sql.=" FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc";
     		$sql.=" WHERE ec.fk_c_type_contact = tc.rowid";
     		$sql.=" AND fk_socpeople = ". $this->id;
    +		$sql.=" AND tc.source = 'external'";
     		$sql.=" GROUP BY tc.element";
     
     		dol_syslog(get_class($this)."::load_ref_elements", LOG_DEBUG);
    
    From fccea99e23fd16f5cfed56db3f28b83e1bcfeae3 Mon Sep 17 00:00:00 2001
    From: John BOTELLA <john.botella@atm-consulting.fr>
    Date: Wed, 24 Oct 2018 10:23:27 +0200
    Subject: [PATCH 418/433] FIX translation in select unit form
    
    ---
     htdocs/core/class/html.form.class.php | 10 ++++++++--
     1 file changed, 8 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
    index 0ed036f1d1f..cebd49737e5 100644
    --- a/htdocs/core/class/html.form.class.php
    +++ b/htdocs/core/class/html.form.class.php
    @@ -3388,13 +3388,19 @@ class Form
     
     			while($res = $this->db->fetch_object($resql))
     			{
    +			    $unitLabel = $res->label;
    +			    if (! empty($langs->tab_translate['unit'.$res->code]))	// check if Translation is available before
    +			    {
    +			        $unitLabel = $langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label;
    +			    }
    +			    
     				if ($selected == $res->rowid)
     				{
    -					$return.='<option value="'.$res->rowid.'" selected>'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>';
    +				    $return.='<option value="'.$res->rowid.'" selected>'.$unitLabel.'</option>';
     				}
     				else
     				{
    -					$return.='<option value="'.$res->rowid.'">'.($langs->trans('unit'.$res->code)!=$res->label?$langs->trans('unit'.$res->code):$res->label).'</option>';
    +				    $return.='<option value="'.$res->rowid.'">'.$unitLabel.'</option>';
     				}
     			}
     			$return.='</select>';
    
    From d0ab12ba6e9b308567100cfeddb9f7b68fd9a618 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 11:10:55 +0200
    Subject: [PATCH 419/433] Fix not used var
    
    ---
     htdocs/societe/class/societeaccount.class.php | 4 +---
     htdocs/stripe/class/stripe.class.php          | 2 --
     2 files changed, 1 insertion(+), 5 deletions(-)
    
    diff --git a/htdocs/societe/class/societeaccount.class.php b/htdocs/societe/class/societeaccount.class.php
    index 12a664f2686..de228c576b5 100644
    --- a/htdocs/societe/class/societeaccount.class.php
    +++ b/htdocs/societe/class/societeaccount.class.php
    @@ -288,8 +288,6 @@ class SocieteAccount extends CommonObject
     	 */
     	public function getCustomerAccount($id, $site, $status=0)
     	{
    -		global $conf;
    -
     		$sql = "SELECT sa.key_account as key_account, sa.entity";
     		$sql.= " FROM " . MAIN_DB_PREFIX . "societe_account as sa";
     		$sql.= " WHERE sa.fk_soc = " . $id;
    @@ -298,7 +296,7 @@ class SocieteAccount extends CommonObject
     		$sql.= " AND key_account IS NOT NULL AND key_account <> ''";
     		//$sql.= " ORDER BY sa.key_account DESC";
     
    -		dol_syslog(get_class($this) . "::getCustomerAccount Try to find the system customer id of thirdparty id=".$id." (exemple: cus_.... for stripe)", LOG_DEBUG);
    +		dol_syslog(get_class($this) . "::getCustomerAccount Try to find the first system customer id for ".$site." of thirdparty id=".$id." (exemple: cus_.... for stripe)", LOG_DEBUG);
     		$result = $this->db->query($sql);
     		if ($result) {
     			if ($this->db->num_rows($result)) {
    diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php
    index cce7289fb48..0e9c3cbb4a8 100644
    --- a/htdocs/stripe/class/stripe.class.php
    +++ b/htdocs/stripe/class/stripe.class.php
    @@ -122,8 +122,6 @@ class Stripe extends CommonObject
     	 */
     	public function getStripeCustomerAccount($id, $status=0)
     	{
    -		global $conf;
    -
     		include_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
     		$societeaccount = new SocieteAccount($this->db);
     		return $societeaccount->getCustomerAccount($id, 'stripe', $status);		// Get thirdparty cus_...
    
    From 3e92582c1e2f9f05b4b7f719b887ba7e3ab921d4 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 11:14:44 +0200
    Subject: [PATCH 420/433] Fix phpcs
    
    ---
     .../modules/commande/doc/pdf_eratosthene.modules.php  | 11 +++++------
     1 file changed, 5 insertions(+), 6 deletions(-)
    
    diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    index 4b11c61b078..ee465ae2b6f 100644
    --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    @@ -726,7 +726,6 @@ class pdf_eratosthene extends ModelePDFCommandes
     	private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
     	{
     	    // phpcs:enable
    -	    
     	}
     
     
    @@ -1181,7 +1180,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	/**
     	 *   Show table for lines
     	 *
    -	 *   @param		PDF			$pdf     		Object PDF
    +	 *   @param		TCPDF		$pdf     		Object PDF
     	 *   @param		string		$tab_top		Top position of table
     	 *   @param		string		$tab_height		Height of table (rectangle)
     	 *   @param		int			$nexY			Y (not used)
    @@ -1483,10 +1482,10 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *   	Define Array Column Field
     	 *
     	 *   	@param	object			$object    		common object
    -	 *   	@param	outputlangs		$outputlangs    langs
    -	 *      @param	int			   $hidedetails		Do not show line details
    -	 *      @param	int			   $hidedesc		Do not show desc
    -	 *      @param	int			   $hideref			Do not show ref
    +	 *   	@param	Translate		$outputlangs    langs
    +	 *      @param	int				$hidedetails	Do not show line details
    +	 *      @param	int				$hidedesc		Do not show desc
    +	 *      @param	int				$hideref		Do not show ref
     	 *      @return	null
     	 */
         public function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    
    From aa0bcc68781282d2cecfaf3ef8765cc849bff2b3 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 11:14:44 +0200
    Subject: [PATCH 421/433] Fix phpcs
    
    ---
     .../commande/doc/pdf_eratosthene.modules.php    | 17 +++++++++--------
     1 file changed, 9 insertions(+), 8 deletions(-)
    
    diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    index 4b11c61b078..96357cdf508 100644
    --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php
    @@ -714,7 +714,8 @@ class pdf_eratosthene extends ModelePDFCommandes
     		}
     	}
     
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *  Show payments table
          *
     	 *  @param	TCPDF		$pdf     		Object PDF
    @@ -726,11 +727,11 @@ class pdf_eratosthene extends ModelePDFCommandes
     	private function drawPaymentsTable(&$pdf, $object, $posy, $outputlangs)
     	{
     	    // phpcs:enable
    -	    
     	}
     
     
    -	/** phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
    +	/**
     	 *   Show miscellaneous information (payment mode, payment term, ...)
     	 *
     	 *   @param		TCPDF		$pdf     		Object PDF
    @@ -1181,7 +1182,7 @@ class pdf_eratosthene extends ModelePDFCommandes
     	/**
     	 *   Show table for lines
     	 *
    -	 *   @param		PDF			$pdf     		Object PDF
    +	 *   @param		TCPDF		$pdf     		Object PDF
     	 *   @param		string		$tab_top		Top position of table
     	 *   @param		string		$tab_height		Height of table (rectangle)
     	 *   @param		int			$nexY			Y (not used)
    @@ -1483,10 +1484,10 @@ class pdf_eratosthene extends ModelePDFCommandes
     	 *   	Define Array Column Field
     	 *
     	 *   	@param	object			$object    		common object
    -	 *   	@param	outputlangs		$outputlangs    langs
    -	 *      @param	int			   $hidedetails		Do not show line details
    -	 *      @param	int			   $hidedesc		Do not show desc
    -	 *      @param	int			   $hideref			Do not show ref
    +	 *   	@param	Translate		$outputlangs    langs
    +	 *      @param	int				$hidedetails	Do not show line details
    +	 *      @param	int				$hidedesc		Do not show desc
    +	 *      @param	int				$hideref		Do not show ref
     	 *      @return	null
     	 */
         public function defineColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
    
    From 1a4bb7ed120b4672bd3b897c8ea8baba83524354 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 11:23:21 +0200
    Subject: [PATCH 422/433] FIX hover on line of movement list
    
    ---
     htdocs/product/stock/movement_list.php | 6 ++++--
     1 file changed, 4 insertions(+), 2 deletions(-)
    
    diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php
    index ec193e6dfc8..d6ec1982569 100644
    --- a/htdocs/product/stock/movement_list.php
    +++ b/htdocs/product/stock/movement_list.php
    @@ -579,8 +579,10 @@ if ($resql)
     
             print '<table class="border" width="100%">';
     
    +        print '<tr>';
    +
             // Description
    -        print '<tr><td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>'.dol_htmlentitiesbr($object->description).'</td></tr>';
    +        print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>'.dol_htmlentitiesbr($object->description).'</td></tr>';
     
             $calcproductsunique=$object->nb_different_products();
             $calcproducts=$object->nb_products();
    @@ -966,7 +968,7 @@ if ($resql)
     			$origin = '';
     		}
     
    -        print "<tr>";
    +        print '<tr class="oddeven">';
             // Id movement
             if (! empty($arrayfields['m.rowid']['checked']))
             {
    
    From f0743c55bb678d6546b8db516a7456bb24562e70 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 11:24:10 +0200
    Subject: [PATCH 423/433] Fix phpcs
    
    ---
     htdocs/product/class/product.class.php | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index f8326a60721..49d4d9a290c 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -3556,7 +3556,6 @@ class Product extends CommonObject
     		} else {
     			return false;
     		}
    -
     	}
     
     	/**
    
    From 2e0de15f958116f083950881231cc1d49345080d Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 11:26:50 +0200
    Subject: [PATCH 424/433] Add public
    
    ---
     htdocs/product/class/product.class.php | 14 +++++++-------
     1 file changed, 7 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
    index 49d4d9a290c..6748ecdef69 100644
    --- a/htdocs/product/class/product.class.php
    +++ b/htdocs/product/class/product.class.php
    @@ -3488,7 +3488,7 @@ class Product extends CommonObject
     	 *
     	 *  @return 	int			Nb of father + child
     	 */
    -	function hasFatherOrChild()
    +	public function hasFatherOrChild()
     	{
     		$nb = 0;
     
    @@ -3514,7 +3514,7 @@ class Product extends CommonObject
     	 *
     	 * @return 	int		Number of variants
     	 */
    -	function hasVariants()
    +	public function hasVariants()
     	{
     		$nb = 0;
     		$sql = "SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."product_attribute_combination WHERE fk_product_parent = ".$this->id;
    @@ -3535,7 +3535,7 @@ class Product extends CommonObject
     	 *
     	 * @return int
     	 */
    -	function isVariant()
    +	public function isVariant()
     	{
     		global $conf;
     		if (!empty($conf->variants->enabled)) {
    @@ -3563,7 +3563,7 @@ class Product extends CommonObject
     	 *
     	 *  @return 	array 		Array of product
     	 */
    -	function getFather()
    +	public function getFather()
     	{
     		$sql = "SELECT p.rowid, p.label as label, p.ref as ref, pa.fk_product_pere as id, p.fk_product_type, pa.qty, pa.incdec, p.entity";
     		$sql.= " FROM ".MAIN_DB_PREFIX."product_association as pa,";
    @@ -3604,7 +3604,7 @@ class Product extends CommonObject
     	 *  @param		int		$level				Level of recursing call (start to 1)
     	 *  @return     array       				Return array(prodid=>array(0=prodid, 1=>qty, 2=> ...)
     	 */
    -	function getChildsArbo($id, $firstlevelonly=0, $level=1)
    +	public function getChildsArbo($id, $firstlevelonly=0, $level=1)
     	{
     		global $alreadyfound;
     
    @@ -3692,7 +3692,7 @@ class Product extends CommonObject
          *  @param      int     $save_lastsearch_value		-1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
     	 *	@return		string								String with URL
     	 */
    -	function getNomUrl($withpicto=0, $option='', $maxlength=0, $save_lastsearch_value=-1)
    +	public function getNomUrl($withpicto=0, $option='', $maxlength=0, $save_lastsearch_value=-1)
     	{
     		global $conf, $langs, $hookmanager;
     		include_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
    @@ -3848,7 +3848,7 @@ class Product extends CommonObject
     	 *	@param      int	$type       0=Sell, 1=Buy, 2=Batch Number management
     	 *	@return     string      	Label of status
     	 */
    -	function getLibStatut($mode=0, $type=0)
    +	public function getLibStatut($mode=0, $type=0)
     	{
     		switch ($type)
     		{
    
    From 6d86727c0bd7da3c52d884f2e58f5f0f82791361 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 11:34:00 +0200
    Subject: [PATCH 425/433] Lang not loaded
    
    ---
     htdocs/product/stock/movement_list.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php
    index d6ec1982569..31394144337 100644
    --- a/htdocs/product/stock/movement_list.php
    +++ b/htdocs/product/stock/movement_list.php
    @@ -43,7 +43,7 @@ if (! empty($conf->projet->enabled))
     }
     
     // Load translation files required by the page
    -$langs->loadLangs(array('products', 'stocks'));
    +$langs->loadLangs(array('products', 'stocks', 'orders'));
     if (! empty($conf->productbatch->enabled)) $langs->load("productbatch");
     
     // Security check
    
    From c2c4366c629a64fa91fa47bc7c81bce66c900188 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 11:38:16 +0200
    Subject: [PATCH 426/433] Removed duplicate translation
    
    ---
     htdocs/core/modules/modStock.class.php | 2 +-
     htdocs/langs/en_US/stocks.lang         | 2 +-
     htdocs/product/stock/massstockmove.php | 4 ++--
     htdocs/product/stock/movement_list.php | 2 +-
     4 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php
    index e9e33c8bbf3..d4f79f1efcf 100644
    --- a/htdocs/core/modules/modStock.class.php
    +++ b/htdocs/core/modules/modStock.class.php
    @@ -273,7 +273,7 @@ class modStock extends DolibarrModules
     			'e.rowid'=>'IdWarehouse','e.ref'=>'LocationSummary','e.description'=>'DescWareHouse','e.lieu'=>'LieuWareHouse','e.address'=>'Address','e.zip'=>'Zip',
     			'e.town'=>'Town','p.rowid'=>"ProductId",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",
     			'p.price'=>"Price",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell",'p.tobuy'=>'OnBuy','p.duration'=>"Duration",'p.datec'=>'DateCreation',
    -			'p.tms'=>'DateModification','sm.rowid'=>'MovementId','sm.value'=>'Qty','sm.datem'=>'DateMovement','sm.label'=>'LabelMovement',
    +			'p.tms'=>'DateModification','sm.rowid'=>'MovementId','sm.value'=>'Qty','sm.datem'=>'DateMovement','sm.label'=>'MovementLabel',
     			'sm.inventorycode'=>'InventoryCode'
     		);
     		$this->export_TypeFields_array[$r]=array(
    diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
    index b3313f5ff73..57138a75153 100644
    --- a/htdocs/langs/en_US/stocks.lang
    +++ b/htdocs/langs/en_US/stocks.lang
    @@ -44,7 +44,6 @@ TransferStock=Transfer stock
     MassStockTransferShort=Mass stock transfer
     StockMovement=Stock movement
     StockMovements=Stock movements
    -LabelMovement=Movement label
     NumberOfUnit=Number of units
     UnitPurchaseValue=Unit purchase price
     StockTooLow=Stock too low
    @@ -134,6 +133,7 @@ StockMustBeEnoughForInvoice=Stock level must be enough to add product/service to
     StockMustBeEnoughForOrder=Stock level must be enough to add product/service to order (check is done on current real stock when adding a line into order whatever the rule for automatic stock change)
     StockMustBeEnoughForShipment= Stock level must be enough to add product/service to shipment (check is done on current real stock when adding a line into shipment whatever the rule for automatic stock change)
     MovementLabel=Label of movement
    +TypeMovement=Type of movement
     DateMovement=Date of movement
     InventoryCode=Movement or inventory code
     IsInPackage=Contained into package
    diff --git a/htdocs/product/stock/massstockmove.php b/htdocs/product/stock/massstockmove.php
    index c585b7a7e89..e456f966cf5 100644
    --- a/htdocs/product/stock/massstockmove.php
    +++ b/htdocs/product/stock/massstockmove.php
    @@ -161,7 +161,7 @@ if ($action == 'createmovements')
     	if (! GETPOST("label"))
     	{
     		$error++;
    -		setEventMessages($langs->trans("ErrorFieldRequired"),$langs->transnoentitiesnoconv("LabelMovement"), null, 'errors');
    +		setEventMessages($langs->trans("ErrorFieldRequired"),$langs->transnoentitiesnoconv("MovementLabel"), null, 'errors');
     	}
     
     	$db->begin();
    @@ -451,7 +451,7 @@ print '<table class="noborder" width="100%">';
     	print '</td>';
     	print '</tr>';
     	print '<tr>';
    -	print '<td>'.$langs->trans("LabelMovement").'</td>';
    +	print '<td>'.$langs->trans("MovementLabel").'</td>';
     	print '<td>';
     	print '<input type="text" name="label" class="quatrevingtpercent" value="'.dol_escape_htmltag($labelmovement).'">';
     	print '</td>';
    diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php
    index 31394144337..053fe3a458b 100644
    --- a/htdocs/product/stock/movement_list.php
    +++ b/htdocs/product/stock/movement_list.php
    @@ -103,7 +103,7 @@ $arrayfields=array(
         'e.ref'=>array('label'=>$langs->trans("Warehouse"), 'checked'=>1, 'enabled'=>(! $id > 0)),	// If we are on specific warehouse, we hide it
         'm.fk_user_author'=>array('label'=>$langs->trans("Author"), 'checked'=>0),
         'm.inventorycode'=>array('label'=>$langs->trans("InventoryCodeShort"), 'checked'=>1),
    -    'm.label'=>array('label'=>$langs->trans("LabelMovement"), 'checked'=>1),
    +    'm.label'=>array('label'=>$langs->trans("MovementLabel"), 'checked'=>1),
         'm.type_mouvement'=>array('label'=>$langs->trans("TypeMovement"), 'checked'=>1),
         'origin'=>array('label'=>$langs->trans("Origin"), 'checked'=>1),
     	'm.value'=>array('label'=>$langs->trans("Qty"), 'checked'=>1),
    
    From 36323752ed1e8d0611d27164d15440cae28601f2 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 12:00:54 +0200
    Subject: [PATCH 427/433] Project must be on a dedicated field
    
    ---
     htdocs/install/mysql/migration/8.0.0-9.0.0.sql    |  1 +
     .../install/mysql/tables/llx_stock_mouvement.sql  |  1 +
     htdocs/langs/en_US/stocks.lang                    |  4 ++++
     .../product/stock/class/mouvementstock.class.php  |  7 +++++++
     htdocs/product/stock/movement_list.php            | 15 ++++++++-------
     5 files changed, 21 insertions(+), 7 deletions(-)
    
    diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
    index 09908ac86f5..c29cc803836 100644
    --- a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
    +++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
    @@ -54,6 +54,7 @@ ALTER TABLE llx_product_fournisseur_price ADD COLUMN desc_fourn text after ref_f
     
     ALTER TABLE llx_user ADD COLUMN dateemploymentend date after dateemployment;
     
    +ALTER TABLE llx_stock_mouvement ADD COLUMN fk_project integer;
     
     ALTER TABLE llx_c_field_list ADD COLUMN visible tinyint	DEFAULT 1 NOT NULL AFTER search;
     
    diff --git a/htdocs/install/mysql/tables/llx_stock_mouvement.sql b/htdocs/install/mysql/tables/llx_stock_mouvement.sql
    index 1e78e7a9820..fdeab913268 100644
    --- a/htdocs/install/mysql/tables/llx_stock_mouvement.sql
    +++ b/htdocs/install/mysql/tables/llx_stock_mouvement.sql
    @@ -33,6 +33,7 @@ create table llx_stock_mouvement
       fk_user_author  integer,							-- Id user making movement
       label           varchar(255),						-- Comment on movement
       inventorycode   varchar(128),						-- Code used to group different movement line into one operation (may be an inventory, a mass picking)
    +  fk_project	  integer,
       fk_origin       integer,
       origintype      varchar(32),
       model_pdf       varchar(255)
    diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
    index 57138a75153..21ed7f4085e 100644
    --- a/htdocs/langs/en_US/stocks.lang
    +++ b/htdocs/langs/en_US/stocks.lang
    @@ -204,3 +204,7 @@ ListInventory=List
     StockSupportServices=Stock management supports Services
     StockSupportServicesDesc=By default, you can stock only product with type "product". If on, and if module service is on, you can also stock a product with type "service"
     ReceiveProducts=Receive items
    +StockIncreaseAfterCorrectTransfer=Increase after correction/transfer
    +StockDecreaseAfterCorrectTransfer=Decrease after correction/transfer
    +StockIncrease=Stock increase
    +StockDecrease=Stock decrease
    diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php
    index 9012262d163..395c192311f 100644
    --- a/htdocs/product/stock/class/mouvementstock.class.php
    +++ b/htdocs/product/stock/class/mouvementstock.class.php
    @@ -44,6 +44,13 @@ class MouvementStock extends CommonObject
     	public $product_id;
     	public $warehouse_id;
     	public $qty;
    +
    +	/**
    +	 * @var int Type of movement
    +	 * 0=input (stock increase by a stock transfer), 1=output (stock decrease after by a stock transfer),
    +	 * 2=output (stock decrease), 3=input (stock increase)
    +	 * Note that qty should be > 0 with 0 or 3, < 0 with 1 or 2.
    +	 */
     	public $type;
     
     	public $tms = '';
    diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php
    index 053fe3a458b..1d8999d319c 100644
    --- a/htdocs/product/stock/movement_list.php
    +++ b/htdocs/product/stock/movement_list.php
    @@ -478,11 +478,11 @@ if (! empty($search_movement))      $sql.= natural_search('m.label', $search_mov
     if (! empty($search_inventorycode)) $sql.= natural_search('m.inventorycode', $search_inventorycode);
     if (! empty($search_product_ref))   $sql.= natural_search('p.ref', $search_product_ref);
     if (! empty($search_product))       $sql.= natural_search('p.label', $search_product);
    -if ($search_warehouse > 0)          $sql.= " AND e.rowid = '".$db->escape($search_warehouse)."'";
    +if ($search_warehouse != '' && $search_warehouse != '-1')          $sql.= natural_search('e.rowid', $search_warehouse, 2);
     if (! empty($search_user))          $sql.= natural_search('u.login', $search_user);
     if (! empty($search_batch))         $sql.= natural_search('m.batch', $search_batch);
     if ($search_qty != '')				$sql.= natural_search('m.value', $search_qty, 1);
    -if ($search_type_mouvement)	$sql.= " AND m.type_mouvement = '".$db->escape($search_type_mouvement)."'";
    +if ($search_type_mouvement != '' && $search_type_mouvement != '-1')	$sql.= natural_search('m.type_mouvement', $search_type_mouvement, 2);
     // Add where from extra fields
     include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
     // Add where from hooks
    @@ -843,13 +843,14 @@ if ($resql)
     	    // Type of movement
     	    print '<td class="liste_titre" align="center">';
     	    //print '<input class="flat" type="text" size="3" name="search_type_mouvement" value="'.dol_escape_htmltag($search_type_mouvement).'">';
    -		print '<select name="search_type_mouvement">';
    +		print '<select id="search_type_mouvement" name="search_type_mouvement" class="maxwidth150">';
     		print '<option value="" '.(($search_type_mouvement=="")?'selected="selected"':'').'></option>';
    -		print '<option value="0" '.(($search_type_mouvement=="0")?'selected="selected"':'').'>0</option>';
    -		print '<option value="1" '.(($search_type_mouvement=="1")?'selected="selected"':'').'>1</option>';
    -		print '<option value="2" '.(($search_type_mouvement=="2")?'selected="selected"':'').'>2</option>';
    -		print '<option value="3" '.(($search_type_mouvement=="3")?'selected="selected"':'').'>3</option>';
    +		print '<option value="0" '.(($search_type_mouvement=="0")?'selected="selected"':'').'>'.$langs->trans('StockIncreaseAfterCorrectTransfer').'</option>';
    +		print '<option value="1" '.(($search_type_mouvement=="1")?'selected="selected"':'').'>'.$langs->trans('StockDecreaseAfterCorrectTransfer').'</option>';
    +		print '<option value="2" '.(($search_type_mouvement=="2")?'selected="selected"':'').'>'.$langs->trans('StockDecrease').'</option>';
    +		print '<option value="3" '.(($search_type_mouvement=="3")?'selected="selected"':'').'>'.$langs->trans('StockIncrease').'</option>';
     		print '</select>';
    +		print ajax_combobox('search_type_mouvement');
     		// TODO: add new function $formentrepot->selectTypeOfMovement(...) like
     		// print $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'maxwidth200');
     	    print '</td>';
    
    From 24f37c7bd71c76a161e6cef75c3ea9b6ae9513a9 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 12:12:06 +0200
    Subject: [PATCH 428/433] CSS
    
    ---
     htdocs/langs/en_US/stocks.lang         | 4 ++--
     htdocs/product/stock/movement_list.php | 6 +++---
     2 files changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang
    index 21ed7f4085e..fbbc00887aa 100644
    --- a/htdocs/langs/en_US/stocks.lang
    +++ b/htdocs/langs/en_US/stocks.lang
    @@ -204,7 +204,7 @@ ListInventory=List
     StockSupportServices=Stock management supports Services
     StockSupportServicesDesc=By default, you can stock only product with type "product". If on, and if module service is on, you can also stock a product with type "service"
     ReceiveProducts=Receive items
    -StockIncreaseAfterCorrectTransfer=Increase after correction/transfer
    -StockDecreaseAfterCorrectTransfer=Decrease after correction/transfer
    +StockIncreaseAfterCorrectTransfer=Increase by correction/transfer
    +StockDecreaseAfterCorrectTransfer=Decrease by correction/transfer
     StockIncrease=Stock increase
     StockDecrease=Stock decrease
    diff --git a/htdocs/product/stock/movement_list.php b/htdocs/product/stock/movement_list.php
    index 1d8999d319c..27c50d075aa 100644
    --- a/htdocs/product/stock/movement_list.php
    +++ b/htdocs/product/stock/movement_list.php
    @@ -983,7 +983,7 @@ if ($resql)
             if (! empty($arrayfields['p.ref']['checked']))
             {
     	        // Product ref
    -	        print '<td>';
    +	        print '<td class="nowraponall">';
     	        print $productstatic->getNomUrl(1,'stock',16);
     	        print "</td>\n";
             }
    @@ -1000,7 +1000,7 @@ if ($resql)
             }
             if (! empty($arrayfields['m.batch']['checked']))
             {
    -	    	print '<td align="center">';
    +	    	print '<td class="center nowraponall">';
     	    	if ($productlot->id > 0) print $productlot->getNomUrl(1);
     	    	else print $productlot->batch;		// the id may not be defined if movement was entered when lot was not saved or if lot was removed after movement.
     	    	print '</td>';
    @@ -1053,7 +1053,7 @@ if ($resql)
             if (! empty($arrayfields['origin']['checked']))
             {
             	// Origin of movement
    -        	print '<td>'.$origin.'</td>';
    +        	print '<td class="nowraponall">'.$origin.'</td>';
             }
             if (! empty($arrayfields['m.value']['checked']))
             {
    
    From 8eb1af2b40f25831f0bf6d90b0c21e2760efb898 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Wed, 24 Oct 2018 13:29:59 +0200
    Subject: [PATCH 429/433] Start beta
    
    ---
     htdocs/filefunc.inc.php | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php
    index 18c5dd4962a..f886266a701 100644
    --- a/htdocs/filefunc.inc.php
    +++ b/htdocs/filefunc.inc.php
    @@ -31,7 +31,7 @@
      */
     
     if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr');
    -if (! defined('DOL_VERSION')) define('DOL_VERSION','9.0.0-alpha');		// a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
    +if (! defined('DOL_VERSION')) define('DOL_VERSION','9.0.0-beta');		// a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
     
     if (! defined('EURO')) define('EURO',chr(128));
     
    
    From 25a374bd9a44d70d35bf2eae0ca9dba1615b6461 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 25 Oct 2018 12:45:13 +0200
    Subject: [PATCH 430/433] NEW Notification module support expense
     report+holiday validation and approval event.
    
    ---
     htdocs/admin/notification.php                 |   7 +
     htdocs/core/class/notify.class.php            |  80 ++++--
     ..._50_modNotification_Notification.class.php |  13 +-
     htdocs/holiday/card.php                       |  32 +--
     htdocs/holiday/class/holiday.class.php        | 228 ++++++++++++++++++
     .../mysql/data/llx_c_action_trigger.sql       |   2 +
     .../install/mysql/migration/8.0.0-9.0.0.sql   |   2 +
     htdocs/langs/en_US/other.lang                 |  13 +-
     8 files changed, 341 insertions(+), 36 deletions(-)
    
    diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php
    index d93421ef6fb..92ba0bec200 100644
    --- a/htdocs/admin/notification.php
    +++ b/htdocs/admin/notification.php
    @@ -166,12 +166,15 @@ foreach($listofnotifiedevents as $notifiedevent)
     {
     
         $label=$langs->trans("Notify_".$notifiedevent['code']); //!=$langs->trans("Notify_".$notifiedevent['code'])?$langs->trans("Notify_".$notifiedevent['code']):$notifiedevent['label'];
    +    $elementLabel = $langs->trans(ucfirst($notifiedevent['elementtype']));
     
         if ($notifiedevent['elementtype'] == 'order_supplier') $elementLabel = $langs->trans('SupplierOrder');
         elseif ($notifiedevent['elementtype'] == 'propal') $elementLabel = $langs->trans('Proposal');
         elseif ($notifiedevent['elementtype'] == 'facture') $elementLabel = $langs->trans('Bill');
         elseif ($notifiedevent['elementtype'] == 'commande') $elementLabel = $langs->trans('Order');
         elseif ($notifiedevent['elementtype'] == 'ficheinter') $elementLabel = $langs->trans('Intervention');
    +    elseif ($notifiedevent['elementtype'] == 'shipping') $elementLabel = $langs->trans('Shipping');
    +    elseif ($notifiedevent['elementtype'] == 'expensereport') $elementLabel = $langs->trans('ExpenseReport');
     
         if ($i) print ', ';
         print $label;
    @@ -209,11 +212,15 @@ foreach($listofnotifiedevents as $notifiedevent)
     
         $label=$langs->trans("Notify_".$notifiedevent['code']); //!=$langs->trans("Notify_".$notifiedevent['code'])?$langs->trans("Notify_".$notifiedevent['code']):$notifiedevent['label'];
     
    +    $elementLabel = $langs->trans(ucfirst($notifiedevent['elementtype']));
    +	// Special cases
         if ($notifiedevent['elementtype'] == 'order_supplier') $elementLabel = $langs->trans('SupplierOrder');
         elseif ($notifiedevent['elementtype'] == 'propal') $elementLabel = $langs->trans('Proposal');
         elseif ($notifiedevent['elementtype'] == 'facture') $elementLabel = $langs->trans('Bill');
         elseif ($notifiedevent['elementtype'] == 'commande') $elementLabel = $langs->trans('Order');
     	elseif ($notifiedevent['elementtype'] == 'ficheinter') $elementLabel = $langs->trans('Intervention');
    +	elseif ($notifiedevent['elementtype'] == 'shipping') $elementLabel = $langs->trans('Shipping');
    +	elseif ($notifiedevent['elementtype'] == 'expensereport') $elementLabel = $langs->trans('ExpenseReport');
     
         print '<tr class="oddeven">';
         print '<td>'.$elementLabel.'</td>';
    diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php
    index 344b8050b65..7a24e4928c7 100644
    --- a/htdocs/core/class/notify.class.php
    +++ b/htdocs/core/class/notify.class.php
    @@ -65,6 +65,7 @@ class Notify
     	// Les codes actions sont definis dans la table llx_notify_def
     
     	// codes actions supported are
    +	// @TODO defined also into interface_50_modNotificiation_Notificiation.class.php
     	public $arrayofnotifsupported = array(
     		'BILL_VALIDATE',
     		'BILL_PAYED',
    @@ -76,7 +77,11 @@ class Notify
     		'ORDER_SUPPLIER_VALIDATE',
     		'ORDER_SUPPLIER_APPROVE',
     		'ORDER_SUPPLIER_REFUSE',
    -		'SHIPPING_VALIDATE'
    +		'SHIPPING_VALIDATE',
    +		'EXPENSE_REPORT_VALIDATE',
    +		'EXPENSE_REPORT_APPROVE',
    +		'HOLIDAY_VALIDATE',
    +		'HOLIDAY_APPROVE'
     	);
     
     
    @@ -340,22 +345,27 @@ class Notify
     		$oldref=(empty($object->oldref)?$object->ref:$object->oldref);
     		$newref=(empty($object->newref)?$object->ref:$object->newref);
     
    +		$sql = '';
    +
     		// Check notification per third party
    -		$sql = "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
    -		$sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
    -		$sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,";
    -		$sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
    -		$sql.= " ".MAIN_DB_PREFIX."notify_def as n,";
    -		$sql.= " ".MAIN_DB_PREFIX."societe as s";
    -		$sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
    -		$sql.= " AND n.fk_soc = s.rowid";
    -		if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
    -		else $sql.= " AND a.code = '".$notifcode."'";	// New usage
    -		$sql .= " AND s.rowid = ".$object->socid;
    +		if ($object->socid > 0)
    +		{
    +			$sql.= "SELECT 'tocontactid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.default_lang,";
    +			$sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
    +			$sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,";
    +			$sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
    +			$sql.= " ".MAIN_DB_PREFIX."notify_def as n,";
    +			$sql.= " ".MAIN_DB_PREFIX."societe as s";
    +			$sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
    +			$sql.= " AND n.fk_soc = s.rowid";
    +			if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
    +			else $sql.= " AND a.code = '".$notifcode."'";	// New usage
    +			$sql .= " AND s.rowid = ".$object->socid;
    +
    +			$sql.= "\nUNION\n";
    +		}
     
     		// Check notification per user
    -		$sql.= "\nUNION\n";
    -
     		$sql.= "SELECT 'touserid' as type_target, c.email, c.rowid as cid, c.lastname, c.firstname, c.lang as default_lang,";
     		$sql.= " a.rowid as adid, a.label, a.code, n.rowid, n.type";
     		$sql.= " FROM ".MAIN_DB_PREFIX."user as c,";
    @@ -363,7 +373,7 @@ class Notify
     		$sql.= " ".MAIN_DB_PREFIX."notify_def as n";
     		$sql.= " WHERE n.fk_user = c.rowid AND a.rowid = n.fk_action";
     		if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode;	// Old usage
    -		else $sql.= " AND a.code = '".$notifcode."'";	// New usage
    +		else $sql.= " AND a.code = '".$this->db->escape($notifcode)."'";	// New usage
     
     		$result = $this->db->query($sql);
     		if ($result)
    @@ -473,6 +483,26 @@ class Notify
     								$object_type = 'order_supplier';
     								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
     								break;
    +							case 'EXPENSE_REPORT_VALIDATE':
    +								$dir_output = $conf->expensereport->dir_output;
    +								$object_type = 'expensereport';
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
    +								break;
    +							case 'EXPENSE_REPORT_APPROVE':
    +								$dir_output = $conf->expensereport->dir_output;
    +								$object_type = 'expensereport';
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
    +								break;
    +							case 'HOLIDAY_VALIDATE':
    +								$dir_output = $conf->holiday->dir_output;
    +								$object_type = 'holiday';
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
    +								break;
    +							case 'HOLIDAY_APPROVE':
    +								$dir_output = $conf->holiday->dir_output;
    +								$object_type = 'holiday';
    +								$mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
    +								break;
     						}
     						$ref = dol_sanitizeFileName($newref);
     						$pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
    @@ -663,6 +693,26 @@ class Notify
     						$object_type = 'order_supplier';
     						$mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated",$newref);
     						break;
    +					case 'EXPENSE_REPORT_VALIDATE':
    +						$dir_output = $conf->expensereport->dir_output;
    +						$object_type = 'expensereport';
    +						$mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated",$newref);
    +						break;
    +					case 'EXPENSE_REPORT_APPROVE':
    +						$dir_output = $conf->expensereport->dir_output;
    +						$object_type = 'expensereport';
    +						$mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved",$newref);
    +						break;
    +					case 'HOLIDAY_VALIDATE':
    +						$dir_output = $conf->holiday->dir_output;
    +						$object_type = 'holiday';
    +						$mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated",$newref);
    +						break;
    +					case 'HOLIDAY_APPROVE':
    +						$dir_output = $conf->holiday->dir_output;
    +						$object_type = 'holiday';
    +						$mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved",$newref);
    +						break;
     				}
     				$ref = dol_sanitizeFileName($newref);
     				$pdf_path = $dir_output."/".$ref."/".$ref.".pdf";
    diff --git a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
    index 26b36964676..f5995c47c84 100644
    --- a/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
    +++ b/htdocs/core/triggers/interface_50_modNotification_Notification.class.php
    @@ -44,6 +44,7 @@ class InterfaceNotification extends DolibarrTriggers
     	 */
     	public $picto = 'email';
     
    +	// @TODO Defined also into notify.class.php)
     	public $listofmanagedevents=array(
     		'BILL_VALIDATE',
     		'BILL_PAYED',
    @@ -55,8 +56,12 @@ class InterfaceNotification extends DolibarrTriggers
     		'ORDER_SUPPLIER_VALIDATE',
     		'ORDER_SUPPLIER_APPROVE',
     		'ORDER_SUPPLIER_REFUSE',
    -		'SHIPPING_VALIDATE'
    -   	);
    +		'SHIPPING_VALIDATE',
    +		'EXPENSE_REPORT_VALIDATE',
    +		'EXPENSE_REPORT_APPROVE',
    +		'HOLIDAY_VALIDATE',
    +		'HOLIDAY_APPROVE'
    +	);
     
     	/**
     	 * Function called when a Dolibarrr business event is done.
    @@ -112,7 +117,7 @@ class InterfaceNotification extends DolibarrTriggers
     
     				$qualified=0;
     				// Check is this event is supported by notification module
    -				if (in_array($obj->code,$this->listofmanagedevents)) $qualified=1;
    +				if (in_array($obj->code, $this->listofmanagedevents)) $qualified=1;
     				// Check if module for this event is active
     				if ($qualified)
     				{
    @@ -125,7 +130,7 @@ class InterfaceNotification extends DolibarrTriggers
     					elseif ($element == 'withdraw' && empty($conf->prelevement->enabled)) $qualified=0;
     					elseif ($element == 'shipping' && empty($conf->expedition->enabled)) $qualified=0;
     					elseif ($element == 'member' && empty($conf->adherent->enabled)) $qualified=0;
    -					elseif (! in_array($element,array('order_supplier','invoice_supplier','withdraw','shipping','member')) && empty($conf->$element->enabled)) $qualified=0;
    +					elseif (! in_array($element,array('order_supplier','invoice_supplier','withdraw','shipping','member','expensereport')) && empty($conf->$element->enabled)) $qualified=0;
     				}
     
     				if ($qualified)
    diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php
    index be365c52351..9c89124c577 100644
    --- a/htdocs/holiday/card.php
    +++ b/htdocs/holiday/card.php
    @@ -214,7 +214,7 @@ if ($action == 'update')
         $object->fetch($id);
     
     	// If under validation
    -    if ($object->statut == 1)
    +    if ($object->statut == Holiday::STATUS_DRAFT)
         {
             // If this is the requestor or has read/write rights
             if ($cancreate)
    @@ -298,7 +298,7 @@ if ($action == 'confirm_delete' && GETPOST('confirm') == 'yes' && $user->rights-
     	$object->fetch($id);
     
         // If this is a rough draft, approved, canceled or refused
    -	if ($object->statut == 1 || $object->statut == 4 || $object->statut == 5)
    +	if ($object->statut == Holiday::STATUS_DRAFT || $object->statut == Holiday::STATUS_CANCELED || $object->statut == Holiday::STATUS_REFUSED)
     	{
     		// Si l'utilisateur à le droit de lire cette demande, il peut la supprimer
     		if ($candelete)
    @@ -332,11 +332,13 @@ if ($action == 'confirm_send')
         $object->fetch($id);
     
         // Si brouillon et créateur
    -    if($object->statut == 1 && $cancreate)
    +    if($object->statut == Holiday::STATUS_DRAFT && $cancreate)
         {
    -        $object->statut = 2;
    +    	$object->oldcopy = dol_clone($object);
     
    -        $verif = $object->update($user);
    +    	$object->statut = Holiday::STATUS_VALIDATED;
    +
    +        $verif = $object->validate($user);
     
             // Si pas d'erreur SQL on redirige vers la fiche de la demande
             if ($verif > 0)
    @@ -435,13 +437,15 @@ if ($action == 'confirm_valid')
         $object->fetch($id);
     
         // Si statut en attente de validation et valideur = utilisateur
    -    if ($object->statut == 2 && $user->id == $object->fk_validator)
    +    if ($object->statut == Holiday::STATUS_VALIDATED && $user->id == $object->fk_validator)
         {
    +    	$object->oldcopy = dol_clone($object);
    +
             $object->date_valid = dol_now();
             $object->fk_user_valid = $user->id;
    -        $object->statut = 3;
    +        $object->statut = Holiday::STATUS_APPROVED;
     
    -        $verif = $object->update($user);
    +        $verif = $object->approve($user);
     
             // Si pas d'erreur SQL on redirige vers la fiche de la demande
             if ($verif > 0)
    @@ -530,11 +534,11 @@ if ($action == 'confirm_refuse' && GETPOST('confirm','alpha') == 'yes')
             $object->fetch($id);
     
             // Si statut en attente de validation et valideur = utilisateur
    -        if ($object->statut == 2 && $user->id == $object->fk_validator)
    +        if ($object->statut == Holiday::STATUS_VALIDATED && $user->id == $object->fk_validator)
             {
                 $object->date_refuse = dol_print_date('dayhour', dol_now());
                 $object->fk_user_refuse = $user->id;
    -            $object->statut = 5;
    +            $object->statut = Holiday::STATUS_REFUSED;
                 $object->detail_refuse = GETPOST('detail_refuse','alphanohtml');
     
                 $verif = $object->update($user);
    @@ -615,7 +619,7 @@ if ($action == 'confirm_draft' && GETPOST('confirm') == 'yes')
         $object->fetch($id);
     
         $oldstatus = $object->statut;
    -    $object->statut = 1;
    +    $object->statut = Holiday::STATUS_DRAFT;
     
         $result = $object->update($user);
         if ($result < 0)
    @@ -646,18 +650,18 @@ if ($action == 'confirm_cancel' && GETPOST('confirm') == 'yes')
         $object->fetch($id);
     
         // Si statut en attente de validation et valideur = valideur ou utilisateur, ou droits de faire pour les autres
    -    if (($object->statut == 2 || $object->statut == 3) && ($user->id == $object->fk_validator || in_array($object->fk_user, $childids) || ! empty($user->rights->holiday->write_all)))
    +    if (($object->statut == Holiday::STATUS_VALIDATED || $object->statut == Holiday::STATUS_APPROVED) && ($user->id == $object->fk_validator || in_array($object->fk_user, $childids) || ! empty($user->rights->holiday->write_all)))
         {
         	$db->begin();
     
         	$oldstatus = $object->statut;
             $object->date_cancel = dol_now();
             $object->fk_user_cancel = $user->id;
    -        $object->statut = 4;
    +        $object->statut = Holiday::STATUS_CANCELED;
     
             $result = $object->update($user);
     
    -        if ($result >= 0 && $oldstatus == 3)	// holiday was already validated, status 3, so we must increase back sold
    +        if ($result >= 0 && $oldstatus == Holiday::STATUS_APPROVED)	// holiday was already validated, status 3, so we must increase back sold
             {
             	// Calculcate number of days consummed
             	$nbopenedday=num_open_day($object->date_debut_gmt,$object->date_fin_gmt,0,1,$object->halfday);
    diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php
    index a888a4919a6..bc964ec7fc6 100644
    --- a/htdocs/holiday/class/holiday.class.php
    +++ b/htdocs/holiday/class/holiday.class.php
    @@ -598,6 +598,234 @@ class Holiday extends CommonObject
     		}
     	}
     
    +
    +	/**
    +	 *	Validate leave request
    +	 *
    +	 *  @param	User	$user        	User that validate
    +	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
    +	 *  @return int         			<0 if KO, >0 if OK
    +	 */
    +	function validate($user=null, $notrigger=0)
    +	{
    +		global $conf, $langs;
    +		$error=0;
    +
    +		// Update request
    +		$sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
    +
    +		$sql.= " description= '".$this->db->escape($this->description)."',";
    +
    +		if(!empty($this->date_debut)) {
    +			$sql.= " date_debut = '".$this->db->idate($this->date_debut)."',";
    +		} else {
    +			$error++;
    +		}
    +		if(!empty($this->date_fin)) {
    +			$sql.= " date_fin = '".$this->db->idate($this->date_fin)."',";
    +		} else {
    +			$error++;
    +		}
    +		$sql.= " halfday = ".$this->halfday.",";
    +		if(!empty($this->statut) && is_numeric($this->statut)) {
    +			$sql.= " statut = ".$this->statut.",";
    +		} else {
    +			$error++;
    +		}
    +		if(!empty($this->fk_validator)) {
    +			$sql.= " fk_validator = '".$this->db->escape($this->fk_validator)."',";
    +		} else {
    +			$error++;
    +		}
    +		if(!empty($this->date_valid)) {
    +			$sql.= " date_valid = '".$this->db->idate($this->date_valid)."',";
    +		} else {
    +			$sql.= " date_valid = NULL,";
    +		}
    +		if(!empty($this->fk_user_valid)) {
    +			$sql.= " fk_user_valid = '".$this->db->escape($this->fk_user_valid)."',";
    +		} else {
    +			$sql.= " fk_user_valid = NULL,";
    +		}
    +		if(!empty($this->date_refuse)) {
    +			$sql.= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
    +		} else {
    +			$sql.= " date_refuse = NULL,";
    +		}
    +		if(!empty($this->fk_user_refuse)) {
    +			$sql.= " fk_user_refuse = '".$this->db->escape($this->fk_user_refuse)."',";
    +		} else {
    +			$sql.= " fk_user_refuse = NULL,";
    +		}
    +		if(!empty($this->date_cancel)) {
    +			$sql.= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
    +		} else {
    +			$sql.= " date_cancel = NULL,";
    +		}
    +		if(!empty($this->fk_user_cancel)) {
    +			$sql.= " fk_user_cancel = '".$this->db->escape($this->fk_user_cancel)."',";
    +		} else {
    +			$sql.= " fk_user_cancel = NULL,";
    +		}
    +		if(!empty($this->detail_refuse)) {
    +			$sql.= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
    +		} else {
    +			$sql.= " detail_refuse = NULL";
    +		}
    +
    +		$sql.= " WHERE rowid= ".$this->id;
    +
    +		$this->db->begin();
    +
    +		dol_syslog(get_class($this)."::validate", LOG_DEBUG);
    +		$resql = $this->db->query($sql);
    +		if (! $resql) {
    +			$error++; $this->errors[]="Error ".$this->db->lasterror();
    +		}
    +
    +		if (! $error)
    +		{
    +			if (! $notrigger)
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('HOLIDAY_VALIDATE',$user);
    +				if ($result < 0) { $error++; }
    +				// End call triggers
    +			}
    +		}
    +
    +		// Commit or rollback
    +		if ($error)
    +		{
    +			foreach($this->errors as $errmsg)
    +			{
    +				dol_syslog(get_class($this)."::validate ".$errmsg, LOG_ERR);
    +				$this->error.=($this->error?', '.$errmsg:$errmsg);
    +			}
    +			$this->db->rollback();
    +			return -1*$error;
    +		}
    +		else
    +		{
    +			$this->db->commit();
    +			return 1;
    +		}
    +	}
    +
    +
    +	/**
    +	 *	Approve leave request
    +	 *
    +	 *  @param	User	$user        	User that approve
    +	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
    +	 *  @return int         			<0 if KO, >0 if OK
    +	 */
    +	function approve($user=null, $notrigger=0)
    +	{
    +		global $conf, $langs;
    +		$error=0;
    +
    +		// Update request
    +		$sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
    +
    +		$sql.= " description= '".$this->db->escape($this->description)."',";
    +
    +		if(!empty($this->date_debut)) {
    +			$sql.= " date_debut = '".$this->db->idate($this->date_debut)."',";
    +		} else {
    +			$error++;
    +		}
    +		if(!empty($this->date_fin)) {
    +			$sql.= " date_fin = '".$this->db->idate($this->date_fin)."',";
    +		} else {
    +			$error++;
    +		}
    +		$sql.= " halfday = ".$this->halfday.",";
    +		if(!empty($this->statut) && is_numeric($this->statut)) {
    +			$sql.= " statut = ".$this->statut.",";
    +		} else {
    +			$error++;
    +		}
    +		if(!empty($this->fk_validator)) {
    +			$sql.= " fk_validator = '".$this->db->escape($this->fk_validator)."',";
    +		} else {
    +			$error++;
    +		}
    +		if(!empty($this->date_valid)) {
    +			$sql.= " date_valid = '".$this->db->idate($this->date_valid)."',";
    +		} else {
    +			$sql.= " date_valid = NULL,";
    +		}
    +		if(!empty($this->fk_user_valid)) {
    +			$sql.= " fk_user_valid = '".$this->db->escape($this->fk_user_valid)."',";
    +		} else {
    +			$sql.= " fk_user_valid = NULL,";
    +		}
    +		if(!empty($this->date_refuse)) {
    +			$sql.= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
    +		} else {
    +			$sql.= " date_refuse = NULL,";
    +		}
    +		if(!empty($this->fk_user_refuse)) {
    +			$sql.= " fk_user_refuse = '".$this->db->escape($this->fk_user_refuse)."',";
    +		} else {
    +			$sql.= " fk_user_refuse = NULL,";
    +		}
    +		if(!empty($this->date_cancel)) {
    +			$sql.= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
    +		} else {
    +			$sql.= " date_cancel = NULL,";
    +		}
    +		if(!empty($this->fk_user_cancel)) {
    +			$sql.= " fk_user_cancel = '".$this->db->escape($this->fk_user_cancel)."',";
    +		} else {
    +			$sql.= " fk_user_cancel = NULL,";
    +		}
    +		if(!empty($this->detail_refuse)) {
    +			$sql.= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
    +		} else {
    +			$sql.= " detail_refuse = NULL";
    +		}
    +
    +		$sql.= " WHERE rowid= ".$this->id;
    +
    +		$this->db->begin();
    +
    +		dol_syslog(get_class($this)."::approve", LOG_DEBUG);
    +		$resql = $this->db->query($sql);
    +		if (! $resql) {
    +			$error++; $this->errors[]="Error ".$this->db->lasterror();
    +		}
    +
    +		if (! $error)
    +		{
    +			if (! $notrigger)
    +			{
    +				// Call trigger
    +				$result=$this->call_trigger('HOLIDAY_APPROVE',$user);
    +				if ($result < 0) { $error++; }
    +				// End call triggers
    +			}
    +		}
    +
    +		// Commit or rollback
    +		if ($error)
    +		{
    +			foreach($this->errors as $errmsg)
    +			{
    +				dol_syslog(get_class($this)."::approve ".$errmsg, LOG_ERR);
    +				$this->error.=($this->error?', '.$errmsg:$errmsg);
    +			}
    +			$this->db->rollback();
    +			return -1*$error;
    +		}
    +		else
    +		{
    +			$this->db->commit();
    +			return 1;
    +		}
    +	}
    +
     	/**
     	 *	Update database
     	 *
    diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql
    index 435d98a7a88..6f3bb5461f8 100644
    --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql
    +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql
    @@ -101,6 +101,8 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_APPROVE','Expense report approved','Executed when an expense report is approved','expensereport',203);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_REPORT_PAYED','Expense report billed','Executed when an expense report is set as billed','expensereport',204);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_DELETE','Expense report deleted','Executed when an expense report is deleted','expensereport',204);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_VALIDATE','Expense report validated','Executed when an expense report is validated','expensereport',202);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_APPROVE','Expense report approved','Executed when an expense report is approved','expensereport',203);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_VALIDATE','Project validation','Executed when a project is validated','project',141);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('PROJECT_DELETE','Project deleted','Executed when a project is deleted','project',143);
     -- actions not enabled by default (no constant created for that) when we enable module agenda 
    diff --git a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
    index c29cc803836..9048c681aa1 100644
    --- a/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
    +++ b/htdocs/install/mysql/migration/8.0.0-9.0.0.sql
    @@ -69,6 +69,8 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('CONTRACT_DELETE','Contract deleted','Executed when a contract is deleted','contrat',18);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('FICHINTER_DELETE','Intervention is deleted','Executed when a intervention is deleted','ficheinter',35);
     insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('EXPENSE_DELETE','Expense report deleted','Executed when an expense report is deleted','expensereport',204);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_VALIDATE','Expense report validated','Executed when an expense report is validated','expensereport',202);
    +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('HOLIDAY_APPROVE','Expense report approved','Executed when an expense report is approved','expensereport',203);
     
     ALTER TABLE llx_payment_salary ADD COLUMN fk_projet integer DEFAULT NULL after amount;
     
    diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang
    index 67b9681fa3b..91442bbd05d 100644
    --- a/htdocs/langs/en_US/other.lang
    +++ b/htdocs/langs/en_US/other.lang
    @@ -31,9 +31,6 @@ NextYearOfInvoice=Following year of invoice date
     DateNextInvoiceBeforeGen=Date of next invoice (before generation)
     DateNextInvoiceAfterGen=Date of next invoice (after generation)
     
    -Notify_FICHINTER_ADD_CONTACT=Added contact to Intervention
    -Notify_FICHINTER_VALIDATE=Intervention validated
    -Notify_FICHINTER_SENTBYMAIL=Intervention sent by mail
     Notify_ORDER_VALIDATE=Customer order validated
     Notify_ORDER_SENTBYMAIL=Customer order sent by mail
     Notify_ORDER_SUPPLIER_SENTBYMAIL=Supplier order sent by mail
    @@ -60,6 +57,8 @@ Notify_BILL_SUPPLIER_SENTBYMAIL=Supplier invoice sent by mail
     Notify_BILL_SUPPLIER_CANCELED=Supplier invoice cancelled
     Notify_CONTRACT_VALIDATE=Contract validated
     Notify_FICHEINTER_VALIDATE=Intervention validated
    +Notify_FICHINTER_ADD_CONTACT=Added contact to Intervention
    +Notify_FICHINTER_SENTBYMAIL=Intervention sent by mail
     Notify_SHIPPING_VALIDATE=Shipping validated
     Notify_SHIPPING_SENTBYMAIL=Shipping sent by mail
     Notify_MEMBER_VALIDATE=Member validated
    @@ -71,6 +70,10 @@ Notify_PROJECT_CREATE=Project creation
     Notify_TASK_CREATE=Task created
     Notify_TASK_MODIFY=Task modified
     Notify_TASK_DELETE=Task deleted
    +Notify_EXPENSE_REPORT_VALIDATE=Expense report validated (approval required)
    +Notify_EXPENSE_REPORT_APPROVE=Expense report approved
    +Notify_HOLIDAY_VALIDATE=Leave request validated (approval required)
    +Notify_HOLIDAY_APPROVE=Leave request approved
     SeeModuleSetup=See setup of module %s
     NbOfAttachedFiles=Number of attached files/documents
     TotalSizeOfAttachedFiles=Total size of attached files/documents
    @@ -198,6 +201,10 @@ EMailTextOrderApprovedBy=The order %s has been approved by %s.
     EMailTextOrderRefused=The order %s has been refused.
     EMailTextOrderRefusedBy=The order %s has been refused by %s.
     EMailTextExpeditionValidated=The shipping %s has been validated.
    +EMailTextExpenseReportValidated=The expense report %s has been validated.
    +EMailTextExpenseReportApproved=The expensereport %s has been approved.
    +EMailTextHolidayValidated=The leave request %s has been validated.
    +EMailTextHolidayApproved=The leave request %s has been approved.
     ImportedWithSet=Importation data set
     DolibarrNotification=Automatic notification
     ResizeDesc=Enter new width <b>OR</b> new height. Ratio will be kept during resizing...
    
    From 9ccdd10a818f9ec28bb789cfa6ceacf35b8d737f Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 25 Oct 2018 13:19:56 +0200
    Subject: [PATCH 431/433] FIXx format (html/text) of emails sent on leave
     request module
    
    ---
     htdocs/core/class/CMailFile.class.php |   2 +-
     htdocs/core/class/translate.class.php |  10 +-
     htdocs/expensereport/card.php         | 249 +++++++++++++-------------
     3 files changed, 135 insertions(+), 126 deletions(-)
    
    diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
    index b3027b90885..a37f6b1562b 100644
    --- a/htdocs/core/class/CMailFile.class.php
    +++ b/htdocs/core/class/CMailFile.class.php
    @@ -117,7 +117,7 @@ class CMailFile
     	 *  @param  string  $sendcontext      	 'standard', 'emailing', ... (used to define with sending mode and parameters to use)
     	 *  @param	string	$replyto			 Reply-to email (will be set to same value than From by default if not provided)
     	 */
    -	function __construct($subject,$to,$from,$msg,$filename_list=array(),$mimetype_list=array(),$mimefilename_list=array(),$addr_cc="",$addr_bcc="",$deliveryreceipt=0,$msgishtml=0,$errors_to='',$css='',$trackid='',$moreinheader='',$sendcontext='standard',$replyto='')
    +	function __construct($subject, $to, $from, $msg, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=0, $errors_to='', $css='', $trackid='', $moreinheader='', $sendcontext='standard', $replyto='')
     	{
     		global $conf, $dolibarr_main_data_root;
     
    diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php
    index 17f83452ba5..2e489f6ba65 100644
    --- a/htdocs/core/class/translate.class.php
    +++ b/htdocs/core/class/translate.class.php
    @@ -655,11 +655,12 @@ class Translate
     	 *  @param  string	$param2     chaine de param2
     	 *  @param  string	$param3     chaine de param3
     	 *  @param  string	$param4     chaine de param4
    +	 *  @param  string	$param5     chaine de param5
     	 *  @return string      		Translated string (encoded into UTF8)
     	 */
    -	function transnoentities($key, $param1='', $param2='', $param3='', $param4='')
    +	function transnoentities($key, $param1='', $param2='', $param3='', $param4='', $param5='')
     	{
    -		return $this->convToOutputCharset($this->transnoentitiesnoconv($key, $param1, $param2, $param3, $param4));
    +		return $this->convToOutputCharset($this->transnoentitiesnoconv($key, $param1, $param2, $param3, $param4, $param5));
     	}
     
     
    @@ -675,9 +676,10 @@ class Translate
     	 *  @param  string	$param2     chaine de param2
     	 *  @param  string	$param3     chaine de param3
     	 *  @param  string	$param4     chaine de param4
    +	 *  @param  string	$param5     chaine de param5
     	 *  @return string      		Translated string
     	 */
    -	function transnoentitiesnoconv($key, $param1='', $param2='', $param3='', $param4='')
    +	function transnoentitiesnoconv($key, $param1='', $param2='', $param3='', $param4='', $param5='')
     	{
     		global $conf;
     
    @@ -700,7 +702,7 @@ class Translate
                 if (! preg_match('/^Format/',$key))
                 {
                 	//print $str;
    -           		$str=sprintf($str,$param1,$param2,$param3,$param4);	// Replace %s and %d except for FormatXXX strings.
    +           		$str=sprintf($str, $param1, $param2, $param3, $param4, $param5);	// Replace %s and %d except for FormatXXX strings.
                 }
     
                 return $str;
    diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php
    index d877ad00b2f..62315912209 100644
    --- a/htdocs/expensereport/card.php
    +++ b/htdocs/expensereport/card.php
    @@ -375,7 +375,7 @@ if (empty($reshook))
         			*/
     
         			// PREPARE SEND
    -    			$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +    			$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
         			if ($mailfile)
         			{
    @@ -496,7 +496,7 @@ if (empty($reshook))
     
     
         			// PREPARE SEND
    -    			$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +    			$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
         			if ($mailfile)
         			{
    @@ -615,7 +615,7 @@ if (empty($reshook))
         			}
         			*/
     
    -        		$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +        		$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
            			if ($mailfile)
            			{
    @@ -735,7 +735,7 @@ if (empty($reshook))
         			*/
     
             		// PREPARE SEND
    -        		$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +        		$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
             		if ($mailfile)
             		{
    @@ -788,126 +788,133 @@ if (empty($reshook))
         }
     
         //var_dump($user->id == $object->fk_user_validator);exit;
    -    if ($action == "confirm_cancel" && GETPOST('confirm', 'alpha')=="yes" && GETPOST('detail_cancel', 'alpha') && $id > 0 && $user->rights->expensereport->creer)
    +    if ($action == "confirm_cancel" && GETPOST('confirm', 'alpha')=="yes" && $id > 0 && $user->rights->expensereport->creer)
         {
    -    	$object = new ExpenseReport($db);
    -    	$object->fetch($id);
    -
    -    	if ($user->id == $object->fk_user_valid || $user->id == $object->fk_user_author)
    +    	if (! GETPOST('detail_cancel', 'alpha'))
         	{
    -    		$result = $object->set_cancel($user, GETPOST('detail_cancel', 'alpha'));
    -
    -    		if ($result > 0)
    -    		{
    -    			// Define output language
    -    			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
    -    			{
    -    				$outputlangs = $langs;
    -    				$newlang = '';
    -    				if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
    -    				if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
    -    				if (! empty($newlang)) {
    -    					$outputlangs = new Translate("", $conf);
    -    					$outputlangs->setDefaultLang($newlang);
    -    				}
    -    				$model=$object->modelpdf;
    -    				$ret = $object->fetch($id); // Reload to get new records
    -
    -    				$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
    -    			}
    -    		}
    -
    -    		if ($result > 0)
    -    		{
    -    			// Send mail
    -
    -    			// TO
    -    			$destinataire = new User($db);
    -    			$destinataire->fetch($object->fk_user_author);
    -    			$emailTo = $destinataire->email;
    -
    -    			// FROM
    -    			$expediteur = new User($db);
    -    			$expediteur->fetch($object->fk_user_cancel);
    -    			$emailFrom = $expediteur->email;
    -
    -    			if ($emailFrom && $emailTo)
    -    			{
    -    			    $filename=array(); $filedir=array(); $mimetype=array();
    -
    -    			    // SUBJECT
    -    				$subject = $langs->transnoentities("ExpenseReportCanceled");
    -
    -    				// CONTENT
    -    				$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    -    				$message = $langs->transnoentities("ExpenseReportCanceledMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $_POST['detail_cancel'], $link);
    -
    -    				// Rebuilt pdf
    -    				/*
    -    				$object->setDocModel($user,"");
    -    				$resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
    -
    -    				if($resultPDF
    -    				{
    -    					// ATTACHMENT
    -    					$filename=array(); $filedir=array(); $mimetype=array();
    -    					array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
    -    					array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
    -    					array_push($mimetype,"application/pdf");
    -    				}
    -    				*/
    -
    -        			// PREPARE SEND
    -        			$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    -
    -        			if ($mailfile)
    -        			{
    -        				// SEND
    -        				$result=$mailfile->sendfile();
    -        				if ($result)
    -        				{
    -        					$mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($emailFrom,2),$mailfile->getValidAddress($emailTo,2));
    -        					setEventMessages($mesg, null, 'mesgs');
    -        					header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
    -        					exit;
    -        				}
    -        				else
    -        				{
    -        					$langs->load("other");
    -        					if ($mailfile->error)
    -        					{
    -        						$mesg='';
    -        						$mesg.=$langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
    -        						$mesg.='<br>'.$mailfile->error;
    -        						setEventMessages($mesg, null, 'errors');
    -        					}
    -        					else
    -        					{
    -        						setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
    -        					}
    -        				}
    -        			}
    -        			else
    -        			{
    -        				setEventMessages($mailfile->error,$mailfile->errors,'errors');
    -        				$action='';
    -        			}
    -    			}
    -    			else
    -    			{
    -    			    setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
    -    			    $action='';
    -    			}
    -    		}
    -    		else
    -    		{
    -    			setEventMessages($langs->trans("FailedToSetToCancel"), null, 'warnings');
    -    			$action='';
    -    		}
    +    		setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Comment")), null, 'errors');
         	}
         	else
         	{
    -    		setEventMessages($object->error, $object->errors, 'errors');
    +	    	$object = new ExpenseReport($db);
    +	    	$object->fetch($id);
    +
    +	    	if ($user->id == $object->fk_user_valid || $user->id == $object->fk_user_author)
    +	    	{
    +	    		$result = $object->set_cancel($user, GETPOST('detail_cancel', 'alpha'));
    +
    +	    		if ($result > 0)
    +	    		{
    +	    			// Define output language
    +	    			if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
    +	    			{
    +	    				$outputlangs = $langs;
    +	    				$newlang = '';
    +	    				if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
    +	    				if ($conf->global->MAIN_MULTILANGS && empty($newlang))	$newlang = $object->thirdparty->default_lang;
    +	    				if (! empty($newlang)) {
    +	    					$outputlangs = new Translate("", $conf);
    +	    					$outputlangs->setDefaultLang($newlang);
    +	    				}
    +	    				$model=$object->modelpdf;
    +	    				$ret = $object->fetch($id); // Reload to get new records
    +
    +	    				$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
    +	    			}
    +	    		}
    +
    +	    		if ($result > 0)
    +	    		{
    +	    			// Send mail
    +
    +	    			// TO
    +	    			$destinataire = new User($db);
    +	    			$destinataire->fetch($object->fk_user_author);
    +	    			$emailTo = $destinataire->email;
    +
    +	    			// FROM
    +	    			$expediteur = new User($db);
    +	    			$expediteur->fetch($object->fk_user_cancel);
    +	    			$emailFrom = $expediteur->email;
    +
    +	    			if ($emailFrom && $emailTo)
    +	    			{
    +	    			    $filename=array(); $filedir=array(); $mimetype=array();
    +
    +	    			    // SUBJECT
    +	    				$subject = $langs->transnoentities("ExpenseReportCanceled");
    +
    +	    				// CONTENT
    +	    				$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    +	    				$message = $langs->transnoentities("ExpenseReportCanceledMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), GETPOST('detail_cancel','alpha'), $link);
    +
    +	    				// Rebuilt pdf
    +	    				/*
    +	    				$object->setDocModel($user,"");
    +	    				$resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
    +
    +	    				if($resultPDF
    +	    				{
    +	    					// ATTACHMENT
    +	    					$filename=array(); $filedir=array(); $mimetype=array();
    +	    					array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
    +	    					array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
    +	    					array_push($mimetype,"application/pdf");
    +	    				}
    +	    				*/
    +
    +	        			// PREPARE SEND
    +	        			$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
    +
    +	        			if ($mailfile)
    +	        			{
    +	        				// SEND
    +	        				$result=$mailfile->sendfile();
    +	        				if ($result)
    +	        				{
    +	        					$mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($emailFrom,2),$mailfile->getValidAddress($emailTo,2));
    +	        					setEventMessages($mesg, null, 'mesgs');
    +	        					header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
    +	        					exit;
    +	        				}
    +	        				else
    +	        				{
    +	        					$langs->load("other");
    +	        					if ($mailfile->error)
    +	        					{
    +	        						$mesg='';
    +	        						$mesg.=$langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
    +	        						$mesg.='<br>'.$mailfile->error;
    +	        						setEventMessages($mesg, null, 'errors');
    +	        					}
    +	        					else
    +	        					{
    +	        						setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
    +	        					}
    +	        				}
    +	        			}
    +	        			else
    +	        			{
    +	        				setEventMessages($mailfile->error,$mailfile->errors,'errors');
    +	        				$action='';
    +	        			}
    +	    			}
    +	    			else
    +	    			{
    +	    			    setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
    +	    			    $action='';
    +	    			}
    +	    		}
    +	    		else
    +	    		{
    +	    			setEventMessages($langs->trans("FailedToSetToCancel"), null, 'warnings');
    +	    			$action='';
    +	    		}
    +	    	}
    +	    	else
    +	    	{
    +	    		setEventMessages($object->error, $object->errors, 'errors');
    +	    	}
         	}
         }
     
    @@ -1019,7 +1026,7 @@ if (empty($reshook))
             		$resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
     
             		// PREPARE SEND
    -        		$mailfile = new CMailFile($subject,$emailTo,$emailFrom,$message,$filedir,$mimetype,$filename);
    +        		$mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
     
             		if ($mailfile)
             		{
    @@ -1614,7 +1621,7 @@ else
     
     				if ($action == 'cancel')
     				{
    -					$array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text",'label'=>$langs->trans("Comment"),'name'=>"detail_cancel",'size'=>"50",'value'=>""));
    +					$array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text",'label'=>'<strong>'.$langs->trans("Comment").'</strong>','name'=>"detail_cancel",'size'=>"50",'value'=>""));
     					$formconfirm=$form->formconfirm($_SEVER["PHP_SELF"]."?id=".$id,$langs->trans("Cancel"),"","confirm_cancel",$array_input,"",1);
     				}
     
    
    From 5daf095fc60f5bbed9fdbb3cdec8db4e109f7869 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 25 Oct 2018 14:05:22 +0200
    Subject: [PATCH 432/433] FIX Title and content of automatic email of expense
     report
    
    ---
     htdocs/expensereport/card.php | 37 +++++++++++++++++++++++------------
     1 file changed, 24 insertions(+), 13 deletions(-)
    
    diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php
    index 62315912209..50205fd12d4 100644
    --- a/htdocs/expensereport/card.php
    +++ b/htdocs/expensereport/card.php
    @@ -356,7 +356,10 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
         			// SUBJECT
    -    			$subject = $langs->transnoentities("ExpenseReportWaitingForApproval");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportWaitingForApproval");
     
         			// CONTENT
         			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    @@ -472,7 +475,10 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
        			    // SUBJECT
    -    			$subject = $langs->transnoentities("ExpenseReportWaitingForReApproval");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportWaitingForReApproval");
     
         			// CONTENT
         			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    @@ -594,7 +600,10 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
        			    // SUBJECT
    -       			$subject = $langs->transnoentities("ExpenseReportApproved");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportApproved");
     
            			// CONTENT
            			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    @@ -713,7 +722,10 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
         		    // SUBJECT
    -       			$subject = $langs->transnoentities("ExpenseReportRefused");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportRefused");
     
            			// CONTENT
            			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    @@ -842,7 +854,10 @@ if (empty($reshook))
     	    			    $filename=array(); $filedir=array(); $mimetype=array();
     
     	    			    // SUBJECT
    -	    				$subject = $langs->transnoentities("ExpenseReportCanceled");
    +	    			    $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +	    			    if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +	    			    $subject = $societeName." - ".$langs->transnoentities("ExpenseReportCanceled");
     
     	    				// CONTENT
     	    				$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
    @@ -1008,19 +1023,15 @@ if (empty($reshook))
         			$filename=array(); $filedir=array(); $mimetype=array();
     
         		    // SUBJECT
    -    			$subject = $langs->transnoentities("ExpenseReportPaid");
    +    			$societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
    +    			if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
    +
    +    			$subject = $societeName." - ".$langs->transnoentities("ExpenseReportPaid");
     
         			// CONTENT
         			$link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
         			$message = $langs->transnoentities("ExpenseReportPaidMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $link);
     
    -        		// CONTENT
    -        		$message = "Bonjour {$destinataire->firstname},\n\n";
    -        		$message.= "Votre note de frais \"{$object->ref}\" vient d'être payée.\n";
    -        		$message.= "- Payeur : {$expediteur->firstname} {$expediteur->lastname}\n";
    -        		$message.= "- Lien : {$dolibarr_main_url_root}/expensereport/card.php?id={$object->id}\n\n";
    -        		$message.= "Bien cordialement,\n' SI";
    -
             		// Generate pdf before attachment
             		$object->setDocModel($user,"");
             		$resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
    
    From 1ba716b82c760e39efb281e4fb1a41513211eba1 Mon Sep 17 00:00:00 2001
    From: Laurent Destailleur <eldy@destailleur.fr>
    Date: Thu, 25 Oct 2018 14:39:54 +0200
    Subject: [PATCH 433/433] Fix do not allow use of second or third tax without
     using 1st one.
    
    ---
     htdocs/admin/company.php      | 40 ++++++++++++++++++++++++++++-------
     htdocs/langs/en_US/admin.lang | 18 ++++++++--------
     2 files changed, 41 insertions(+), 17 deletions(-)
    
    diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php
    index e3ea95d18b5..cc564bfb08e 100644
    --- a/htdocs/admin/company.php
    +++ b/htdocs/admin/company.php
    @@ -75,6 +75,8 @@ if ( ($action == 'update' && ! GETPOST("cancel",'alpha'))
     		activateModulesRequiredByCountry($mysoc->country_code);
     	}
     
    +	$db->begin();
    +
     	dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", GETPOST("nom",'nohtml'),'chaine',0,'',$conf->entity);
     	dolibarr_set_const($db, "MAIN_INFO_SOCIETE_ADDRESS", GETPOST("MAIN_INFO_SOCIETE_ADDRESS",'nohtml'),'chaine',0,'',$conf->entity);
     	dolibarr_set_const($db, "MAIN_INFO_SOCIETE_TOWN", GETPOST("MAIN_INFO_SOCIETE_TOWN",'nohtml'),'chaine',0,'',$conf->entity);
    @@ -173,11 +175,24 @@ if ( ($action == 'update' && ! GETPOST("cancel",'alpha'))
     
     	dolibarr_set_const($db, "SOCIETE_FISCAL_MONTH_START", GETPOST("SOCIETE_FISCAL_MONTH_START",'int'),'chaine',0,'',$conf->entity);
     
    -	dolibarr_set_const($db, "FACTURE_TVAOPTION", GETPOST("optiontva",'aZ09'),'chaine',0,'',$conf->entity);
    +	// Sale tax options
    +	$usevat = GETPOST("optiontva",'aZ09');
    +	$uselocaltax1 = GETPOST("optionlocaltax1",'aZ09');
    +	$uselocaltax2 = GETPOST("optionlocaltax2",'aZ09');
    +	if ($uselocaltax1 == 'localtax1on' && ! $usevat)
    +	{
    +		setEventMessages($langs->trans("IfYouUseASecondTaxYouMustSetYouUseTheMainTax"), null, 'errors');
    +		$error++;
    +	}
    +	if ($uselocaltax2 == 'localtax2on' && ! $usevat)
    +	{
    +		setEventMessages($langs->trans("IfYouUseAThirdTaxYouMustSetYouUseTheMainTax"), null, 'errors');
    +		$error++;
    +	}
     
    -	// Local taxes
    -	dolibarr_set_const($db, "FACTURE_LOCAL_TAX1_OPTION", GETPOST("optionlocaltax1",'aZ09'),'chaine',0,'',$conf->entity);
    -	dolibarr_set_const($db, "FACTURE_LOCAL_TAX2_OPTION", GETPOST("optionlocaltax2",'aZ09'),'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "FACTURE_TVAOPTION", $usevat,'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "FACTURE_LOCAL_TAX1_OPTION", $uselocaltax1,'chaine',0,'',$conf->entity);
    +	dolibarr_set_const($db, "FACTURE_LOCAL_TAX2_OPTION", $uselocaltax2,'chaine',0,'',$conf->entity);
     
     	if($_POST["optionlocaltax1"]=="localtax1on")
     	{
    @@ -204,6 +219,15 @@ if ( ($action == 'update' && ! GETPOST("cancel",'alpha'))
     		dolibarr_set_const($db,"MAIN_INFO_LOCALTAX_CALC2", GETPOST("clt2",'aZ09'),'chaine',0,'',$conf->entity);
     	}
     
    +	if (! $error)
    +	{
    +		$db->commit();
    +	}
    +	else
    +	{
    +		$db->rollback();
    +	}
    +
     	if ($action != 'updateedit' && ! $error)
     	{
     		header("Location: ".$_SERVER["PHP_SELF"]);
    @@ -586,7 +610,7 @@ if ($action == 'edit' || $action == 'updateedit')
     	print '<td colspan="2">';
     	print "<table>";
     	print "<tr><td><label for=\"use_vat\">".$langs->trans("VATIsUsedDesc")."</label></td></tr>";
    -	print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsUsedExampleFR")."</i></td></tr>\n";
    +	if ($mysoc->country_code == 'FR') print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsUsedExampleFR")."</i></td></tr>\n";
     	print "</table>";
     	print "</td></tr>\n";
     
    @@ -595,7 +619,7 @@ if ($action == 'edit' || $action == 'updateedit')
     	print '<td colspan="2">';
     	print "<table>";
     	print "<tr><td><label for=\"no_vat\">".$langs->trans("VATIsNotUsedDesc")."</label></td></tr>";
    -	print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsNotUsedExampleFR")."</i></td></tr>\n";
    +	if ($mysoc->country_code == 'FR') print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsNotUsedExampleFR")."</i></td></tr>\n";
     	print "</table>";
     	print "</td></tr>\n";
     
    @@ -1024,7 +1048,7 @@ else
     	print '<td colspan="2">';
     	print "<table>";
     	print "<tr><td><label for=\"use_vat\">".$langs->trans("VATIsUsedDesc")."</label></td></tr>";
    -	print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsUsedExampleFR")."</i></td></tr>\n";
    +	if ($mysoc->country_code == 'FR') print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsUsedExampleFR")."</i></td></tr>\n";
     	print "</table>";
     	print "</td></tr>\n";
     
    @@ -1034,7 +1058,7 @@ else
     	print '<td colspan="2">';
     	print "<table>";
     	print "<tr><td><label=\"no_vat\">".$langs->trans("VATIsNotUsedDesc")."</label></td></tr>";
    -	print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsNotUsedExampleFR")."</i></td></tr>\n";
    +	if ($mysoc->country_code == 'FR') print "<tr><td><i>".$langs->trans("Example").': '.$langs->trans("VATIsNotUsedExampleFR")."</i></td></tr>\n";
     	print "</table>";
     	print "</td></tr>\n";
     
    diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang
    index 52445134f0f..190b7cded97 100644
    --- a/htdocs/langs/en_US/admin.lang
    +++ b/htdocs/langs/en_US/admin.lang
    @@ -924,22 +924,22 @@ SetupNotSaved=Setup not saved
     BackToModuleList=Back to modules list
     BackToDictionaryList=Back to list of Dictionaries
     TypeOfRevenueStamp=Type of tax stamp
    -VATManagement=VAT Management
    -VATIsUsedDesc=By default when creating prospects, invoices, orders etc. the VAT rate follows the active standard rule:<br>If the seller is not subject to VAT, then VAT defaults to 0. End of rule.<br>If the (seller's country = buyer's country), then the VAT by default equals the VAT of the product in the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and goods are transport-related products (haulage, shipping, airline), the default VAT is 0. This rule is dependant on the seller's country - please consult with your accountant. The VAT should be paid by the buyer to their customs office in their country and not to the seller. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is not a company (with a registered intra-Community VAT number) then the VAT by defaults to the VAT of the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is a company (with a registered intra-Community VAT number), then the VAT is 0 by default. End of rule.<br>In any other case the proposed default is VAT=0. End of rule.
    -VATIsNotUsedDesc=By default the proposed VAT is 0 which can be used for cases like associations, individuals or small companies.
    -VATIsUsedExampleFR=In France, it means companies or organizations having a real fiscal system (Simplified real or normal real).  A system in which VAT is declared.
    -VATIsNotUsedExampleFR=In France, it means associations that are non VAT declared or companies, organizations or liberal professions that have chosen the micro enterprise fiscal system (VAT in franchise) and paid a franchise VAT without any VAT declaration.  This choice will display the reference "Non applicable VAT - art-293B of CGI" on invoices.
    +VATManagement=Sale Tax Management
    +VATIsUsedDesc=By default when creating prospects, invoices, orders etc. the Sale Tax rate follows the active standard rule:<br>If the seller is not subject to Sale tax, then Sale tax defaults to 0. End of rule.<br>If the (seller's country = buyer's country), then the Sale tax by default equals the Sale tax of the product in the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and goods are transport-related products (haulage, shipping, airline), the default Sale tax is 0. This rule is dependant on the seller's country - please consult with your accountant. The Sale tax should be paid by the buyer to their customs office in their country and not to the seller. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is not a company (with a registered intra-Community Sale tax number) then the Sale tax by defaults to the Sale tax of the seller's country. End of rule.<br>If the seller and buyer are both in the European Community and the buyer is a company (with a registered intra-Community Sale tax number), then the Sale tax is 0 by default. End of rule.<br>In any other case the proposed default is Sale tax=0. End of rule.
    +VATIsNotUsedDesc=By default the proposed Sale tax is 0 which can be used for cases like associations, individuals or small companies.
    +VATIsUsedExampleFR=In France, it means companies or organizations having a real fiscal system (Simplified real or normal real).  A system in which Sale tax is declared.
    +VATIsNotUsedExampleFR=In France, it means associations that are non Sale tax declared or companies, organizations or liberal professions that have chosen the micro enterprise fiscal system (Sale tax in franchise) and paid a franchise Sale tax without any Sale tax declaration.  This choice will display the reference "Non applicable Sale tax - art-293B of CGI" on invoices.
     ##### Local Taxes #####
     LTRate=Rate
     LocalTax1IsNotUsed=Do not use second tax
    -LocalTax1IsUsedDesc=Use a second type of tax (other than VAT)
    -LocalTax1IsNotUsedDesc=Do not use other type of tax (other than VAT)
    +LocalTax1IsUsedDesc=Use a second type of tax (other than first one)
    +LocalTax1IsNotUsedDesc=Do not use other type of tax (other than first one)
     LocalTax1Management=Second type of tax
     LocalTax1IsUsedExample=
     LocalTax1IsNotUsedExample=
     LocalTax2IsNotUsed=Do not use third tax
    -LocalTax2IsUsedDesc=Use a third type of tax (other than VAT)
    -LocalTax2IsNotUsedDesc=Do not use other type of tax (other than VAT)
    +LocalTax2IsUsedDesc=Use a third type of tax (other than first one)
    +LocalTax2IsNotUsedDesc=Do not use other type of tax (other than first one)
     LocalTax2Management=Third type of tax
     LocalTax2IsUsedExample=
     LocalTax2IsNotUsedExample=
    
".dol_print_date($db->jdate($obj->da),"day")."
'.dol_print_date($db->jdate($obj->da),"day").''.$obj->libelle.' '.$obj->label.'
' . $langs->trans("Date") . '
' . fieldLabel( 'Categories', 'usercats' ) . ''; - $cate_arbo = $form->select_all_categories( Categorie::TYPE_CONTACT, null, null, null, null, 1 ); + $cate_arbo = $form->select_all_categories( Categorie::TYPE_USER, null, null, null, null, 1 ); $c = new Categorie( $db ); $cats = $c->containing($object->id, Categorie::TYPE_USER); foreach ($cats as $cat) { From 06a943fc804fbefd1f4f30552ee561046d8df88e Mon Sep 17 00:00:00 2001 From: Abbes Bahfir Date: Tue, 9 Oct 2018 00:01:58 +0100 Subject: [PATCH 058/433] Fix: Category filter on user list --- htdocs/user/list.php | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/htdocs/user/list.php b/htdocs/user/list.php index 088148ba4af..d08a4442296 100644 --- a/htdocs/user/list.php +++ b/htdocs/user/list.php @@ -26,6 +26,9 @@ */ require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +if (! empty($conf->categorie->enabled)) + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; if (! $user->rights->user->user->lire && ! $user->admin) accessforbidden(); @@ -123,6 +126,8 @@ $search_thirdparty=GETPOST('search_thirdparty','alpha'); $search_supervisor=GETPOST('search_supervisor','intcomma'); $search_previousconn=GETPOST('search_previousconn','alpha'); $optioncss = GETPOST('optioncss','alpha'); +$search_categ = GETPOST("search_categ",'int'); +$catid = GETPOST('catid','int'); // Default search if ($search_statut == '') $search_statut='1'; @@ -165,6 +170,7 @@ if (empty($reshook)) $search_date_creation=""; $search_date_update=""; $search_array_options=array(); + $search_categ=0; } } @@ -173,6 +179,8 @@ if (empty($reshook)) * View */ +$htmlother=new FormOther($db); + $user2=new User($db); $buttonviewhierarchy='
'; @@ -193,6 +201,7 @@ $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user_extrafields as ef on (u.rowid = ef.fk_object)"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON u.fk_soc = s.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u2 ON u.fk_user = u2.rowid"; +if (! empty($search_categ) || ! empty($catid)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_user as cu ON u.rowid = cu.fk_user"; // We'll need this table joined to the select in order to filter by categ // Add fields from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printUserListWhere',$parameters); // Note that $action and $object may have been modified by hook @@ -216,6 +225,10 @@ if ($search_accountancy_code != '') $sql.= natural_search("u.accountancy_code", if ($search_email != '') $sql.= natural_search("u.email", $search_email); if ($search_statut != '' && $search_statut >= 0) $sql.= " AND u.statut IN (".$db->escape($search_statut).")"; if ($sall) $sql.= natural_search(array_keys($fieldstosearchall), $sall); +if ($catid > 0) $sql.= " AND cu.fk_categorie = ".$catid; +if ($catid == -2) $sql.= " AND cu.fk_categorie IS NULL"; +if ($search_categ > 0) $sql.= " AND cu.fk_categorie = ".$db->escape($search_categ); +if ($search_categ == -2) $sql.= " AND cu.fk_categorie IS NULL"; // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks @@ -268,6 +281,7 @@ if ($search_supervisor > 0) $param.="&search_supervisor=".$search_supervisor; if ($search_statut != '') $param.="&search_statut=".$search_statut; if ($optioncss != '') $param.='&optioncss='.$optioncss; if ($mode != '') $param.='&mode='.$mode; +if ($search_categ > 0) $param.="&search_categ=".urlencode($search_categ); // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; @@ -296,6 +310,15 @@ $morehtmlright = '"; + $c = new Categorie($db); + $ways = $c->print_all_ways(' > ','user/list.php'); + print " > ".$ways[0]."
\n"; + print "
"; +} + if ($sall) { foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); @@ -304,7 +327,29 @@ if ($sall) $moreforfilter=''; +// Filter on categories +if (! empty($conf->categorie->enabled)) +{ + $moreforfilter.='
'; + $moreforfilter.=$langs->trans('Categories'). ': '; + $moreforfilter.=$htmlother->select_categories(Categorie::TYPE_USER,$search_categ,'search_categ',1); + $moreforfilter.='
'; +} + +$parameters=array(); +$reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook +if (empty($reshook)) $moreforfilter.=$hookmanager->resPrint; +else $moreforfilter=$hookmanager->resPrint; + +if ($moreforfilter) +{ + print '
'; + print $moreforfilter; + print '
'; +} + $varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; + $selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields From 6ded9e843d3448bcec8e7789b59fdf5e96075b8a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 9 Oct 2018 01:03:46 +0200 Subject: [PATCH 059/433] NEW The binding step in accountancy has a country filter like a combo --- htdocs/accountancy/customer/lines.php | 14 +++++++++----- htdocs/accountancy/customer/list.php | 10 +++++++--- htdocs/accountancy/expensereport/lines.php | 2 -- htdocs/accountancy/supplier/lines.php | 15 +++++++++++---- htdocs/accountancy/supplier/list.php | 14 +++++++++----- htdocs/core/class/html.form.class.php | 2 +- 6 files changed, 37 insertions(+), 20 deletions(-) diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index 83ddd1bd888..d9e5aa80a3f 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -17,7 +17,6 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * */ /** @@ -173,7 +172,8 @@ $sql.= " fd.rowid, fd.description, fd.product_type as line_type, fd.total_ht, fd $sql.= " s.rowid as socid, s.nom as name, s.code_compta, s.code_client,"; $sql.= " p.rowid as product_id, p.fk_product_type as product_type, p.ref as product_ref, p.label as product_label, p.accountancy_code_sell, aa.rowid as fk_compte, aa.account_number, aa.label as label_compte,"; $sql.= " fd.situation_percent,"; -$sql.= " co.label as country, s.tva_intra"; +$sql.= " co.code as country_code, co.label as country,"; +$sql.= " s.tva_intra"; $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook $sql.=$hookmanager->resPrint; @@ -229,7 +229,7 @@ else if ($search_year > 0) $sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'"; } if (strlen(trim($search_country))) { - $sql .= natural_search("co.label", $search_country); + $sql .= natural_search("co.code", $search_country); } if (strlen(trim($search_tvaintra))) { $sql .= natural_search("s.tva_intra", $search_tvaintra); @@ -307,7 +307,10 @@ if ($result) { print '
'; + print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth200', 'code2'); + //print ''; + print ''; @@ -370,9 +373,10 @@ if ($result) { print '' . price($objp->total_ht) . '' . vatrate($objp->tva_tx.($objp->vat_src_code?' ('.$objp->vat_src_code.')':'')) . '' . $objp->country .'' . $langs->trans("Country".$objp->country_code) .' ('.$objp->country_code.')' . $objp->tva_intra . ''; + print $form->select_country($search_country, 'search_country', '', 0, 'maxwidth200', 'code2'); + //print ''; + print '