From 232f20100706b9d93c5e081f670d7daf44b892fd Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Sun, 23 Feb 2020 17:02:08 +0100 Subject: [PATCH 001/137] Merge remote-tracking branch 'Dolibarr/11.0' into 11 --- htdocs/compta/facture/class/facture.class.php | 9 +++++++++ htdocs/core/lib/pdf.lib.php | 2 +- htdocs/cron/class/cronjob.class.php | 4 ++-- .../framework/Luracast/Restler/AutoLoader.php | 8 +------- .../framework/Luracast/Restler/CommentParser.php | 12 ++++++------ .../framework/Luracast/Restler/Format/XmlFormat.php | 2 +- .../restler/framework/Luracast/Restler/Resources.php | 6 +++--- .../restler/framework/Luracast/Restler/Restler.php | 4 ++-- .../restler/framework/Luracast/Restler/Routes.php | 6 +++--- .../restler/framework/Luracast/Restler/Scope.php | 2 +- .../restler/framework/Luracast/Restler/UI/Emmet.php | 4 ++-- htdocs/projet/element.php | 2 +- htdocs/theme/eldy/global.inc.php | 2 +- 13 files changed, 33 insertions(+), 30 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index d4a7efd3cf4..99cc638c36f 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1156,6 +1156,14 @@ class Facture extends CommonInvoice $line->date_start = $object->lines[$i]->date_start; $line->date_end = $object->lines[$i]->date_end; + // Multicurrency + $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency; + $line->multicurrency_code = $object->lines[$i]->multicurrency_code; + $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice; + $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht; + $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva; + $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc; + $line->fk_fournprice = $object->lines[$i]->fk_fournprice; $marginInfos = getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht); $line->pa_ht = $marginInfos[0]; @@ -1170,6 +1178,7 @@ class Facture extends CommonInvoice $this->socid = $object->socid; $this->fk_project = $object->fk_project; + $this->fk_account = $object->fk_account; $this->cond_reglement_id = $object->cond_reglement_id; $this->mode_reglement_id = $object->mode_reglement_id; $this->availability_id = $object->availability_id; diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index a5ba08bb139..59035258c74 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1401,7 +1401,7 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, foreach ($tblcateg as $cate) { // Adding the descriptions if they are filled - $desccateg = $cate->add_description; + $desccateg = $cate->description; if ($desccateg) $libelleproduitservice .= '__N__'.$desccateg; } diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 5cde792bbb5..6139f157f8a 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1320,9 +1320,9 @@ class Cronjob extends CommonObject if ($processing) $moretext = ' ('.$langs->trans("Running").')'; elseif ($lastresult) $moretext .= ' ('.$langs->trans("Error").')'; - $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Draft').$moretext; + $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Disabled').$moretext; $this->labelStatus[self::STATUS_ENABLED] = $langs->trans('Enabled').$moretext; - $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Disabled'); $this->labelStatusShort[self::STATUS_ENABLED] = $langs->trans('Enabled'); } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php index eff8bb61f29..d8445fdc70c 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php @@ -263,13 +263,7 @@ class AutoLoader * @return bool false unless className now exists */ private function loadLastResort($className, $loader = null) { - // @CHANGE LDR Add protection to avoid conflict with other autoloader - /*print 'Try to load '.$className."\n"; - if (in_array($className, array('Google_Client'))) - { - return false; - }*/ - $loaders = array_unique(static::$rogueLoaders); + $loaders = array_unique(static::$rogueLoaders); if (isset($loader)) { if (false === array_search($loader, $loaders)) static::$rogueLoaders[] = $loader; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php index e8248a385fa..2815f1f6c70 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php @@ -159,7 +159,7 @@ class CommentParser $addNewline = true; } continue; - } elseif ($line{0} == '@') { + } elseif ($line[0] == '@') { $mode = 2; $newParam = true; } @@ -353,7 +353,7 @@ class CommentParser $data = $format->decode($str); } } else { // auto detect - if ($str{0} == '{') { + if ($str[0] == '{') { $d = json_decode($str, true); if (json_last_error() != JSON_ERROR_NONE) { throw new Exception('Error parsing embedded JSON data' @@ -445,7 +445,7 @@ class CommentParser { $r = array(); $email = end($value); - if ($email{0} == '<') { + if ($email[0] == '<') { $email = substr($email, 1, -1); array_pop($value); $r['email'] = $email; @@ -470,7 +470,7 @@ class CommentParser $data = array_shift($value); if (empty($data)) { $r['type'] = 'mixed'; - } elseif ($data{0} == '$') { + } elseif ($data[0] == '$') { $r['name'] = substr($data, 1); $r['type'] = 'mixed'; } else { @@ -478,7 +478,7 @@ class CommentParser $r['type'] = count($data) == 1 ? $data[0] : $data; $data = array_shift($value); - if (!empty($data) && $data{0} == '$') { + if (!empty($data) && $data[0] == '$') { $r['name'] = substr($data, 1); } } @@ -498,7 +498,7 @@ class CommentParser $data = array_shift($value); if (empty($data)) { $r['type'] = 'mixed'; - } elseif ($data{0} == '$') { + } elseif ($data[0] == '$') { $r['name'] = substr($data, 1); $r['type'] = 'mixed'; } else { diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php index b51fa707a53..ceec32e4cb5 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php @@ -221,7 +221,7 @@ class XmlFormat extends Format $namespaces = $xml->getNamespaces(); if (count($namespaces)) { $p = strpos($data, $xml->getName()); - if ($p && $data{$p - 1} == ':') { + if ($p && $data[$p - 1] == ':') { $s = strpos($data, '<') + 1; $prefix = substr($data, $s, $p - $s - 1); static::$namespacedProperties[static::$rootName] = $prefix; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Resources.php b/htdocs/includes/restler/framework/Luracast/Restler/Resources.php index 43e95fa02be..2986968a990 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Resources.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Resources.php @@ -198,7 +198,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi } elseif (false !== ($pos = strpos($id, '-v'))) { //$version = intval(substr($id, $pos + 2)); $id = substr($id, 0, $pos); - } elseif ($id{0} == 'v' && is_numeric($v = substr($id, 1))) { + } elseif ($id[0] == 'v' && is_numeric($v = substr($id, 1))) { $id = ''; //$version = $v; } elseif ($id == 'root' || $id == 'index') { @@ -233,7 +233,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi if ($tSlash) { if ($fLen != $tLen && !Text::beginsWith($fullPath, $target . '/')) continue; - } elseif ($fLen > $tLen + 1 && $fullPath{$tLen + 1} != '{' && !Text::beginsWith($fullPath, '{')) { + } elseif ($fLen > $tLen + 1 && $fullPath[$tLen + 1] != '{' && !Text::beginsWith($fullPath, '{')) { //when mapped to root exclude paths that have static parts //they are listed else where under that static part name continue; @@ -275,7 +275,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi if (count($parts) == 1 && $httpMethod == 'GET') { } else { for ($i = 0; $i < count($parts); $i++) { - if (strlen($parts[$i]) && $parts[$i]{0} == '{') { + if (strlen($parts[$i]) && $parts[$i][0] == '{') { $pos = $i - 1; break; } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Restler.php b/htdocs/includes/restler/framework/Luracast/Restler/Restler.php index c2e9b1acb73..fcb5388726c 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Restler.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Restler.php @@ -533,7 +533,7 @@ class Restler extends EventDispatcher rtrim($path, '/') //remove trailing slash if found ); - if (Defaults::$useUrlBasedVersioning && strlen($path) && $path{0} == 'v') { + if (Defaults::$useUrlBasedVersioning && strlen($path) && $path[0] == 'v') { $version = intval(substr($path, 1)); if ($version && $version <= $this->apiVersion) { $this->requestedApiVersion = $version; @@ -1599,7 +1599,7 @@ class Restler extends EventDispatcher */ public function __get($name) { - if ($name{0} == '_') { + if ($name[0] == '_') { $hiddenProperty = substr($name, 1); if (isset($this->$hiddenProperty)) { return $this->$hiddenProperty; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Routes.php b/htdocs/includes/restler/framework/Luracast/Restler/Routes.php index 73e78dc0039..999094dec4c 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Routes.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Routes.php @@ -87,7 +87,7 @@ class Routes foreach ($methods as $method) { $methodUrl = strtolower($method->getName()); //method name should not begin with _ - if ($methodUrl{0} == '_') { + if ($methodUrl[0] == '_') { continue; } $doc = $method->getDocComment(); @@ -330,7 +330,7 @@ class Routes if (!$type) { return 's'; } - switch ($type{0}) { + switch ($type[0]) { case 'i': case 'f': return 'n'; @@ -428,7 +428,7 @@ class Routes } $index = intval(substr($k, 1)); $details = $value[$httpMethod]['metadata']['param'][$index]; - if ($k{0} == 's' || strpos($k, static::pathVarTypeOf($v)) === 0) { + if ($k[0] == 's' || strpos($k, static::pathVarTypeOf($v)) === 0) { //remove the newlines $data[$details['name']] = trim($v, PHP_EOL); } else { diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Scope.php b/htdocs/includes/restler/framework/Luracast/Restler/Scope.php index 251262017c3..16ccdd33561 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Scope.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Scope.php @@ -203,7 +203,7 @@ class Scope $divider = '\\'; $qualified = false; - if ($className{0} == $divider) { + if ($className[0] == $divider) { $qualified = trim($className, $divider); } elseif (array_key_exists($className, $scope)) { $qualified = $scope[$className]; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/UI/Emmet.php b/htdocs/includes/restler/framework/Luracast/Restler/UI/Emmet.php index abd4a3a73ba..435804b4469 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/UI/Emmet.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/UI/Emmet.php @@ -356,7 +356,7 @@ class Emmet $pos = strpos($string, $f, $start); $tokens = array(); for ($i = $start; $i < $pos; $i++) { - $token = $string{$i}; + $token = $string[$i]; if (('#' == $token || '.' == $token) && (!empty($tokens) || $i == 0) ) { @@ -368,7 +368,7 @@ class Emmet $r[] = $f; } while (false != ($f = strtok(static::DELIMITERS))); for ($i = $pos; $i < strlen($string); $i++) { - $token = $string{$i}; + $token = $string[$i]; $r[] = $tokens[] = $token; } return $r; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 46cf12356c5..ffd083d2359 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -606,7 +606,7 @@ foreach ($listofreferent as $key => $value) $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field)?$project_field:'fk_projet'); - if (count($elementarray)>0 && is_array($elementarray)) + if (is_array($elementarray) && count($elementarray) > 0) { $total_ht = 0; $total_ttc = 0; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index fa4f751d6a6..2eebcb19a6b 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -1297,7 +1297,7 @@ div.fichetwothirdright { browser->layout == 'phone') { print "padding-bottom: 6px\n"; } ?> } div.fichetwothirdright div.ficheaddleft { - padding-left: 20px; + padding-: 20px; } div.fichehalfleft { browser->layout != 'phone') { print "float: ".$left.";\n"; } ?> From 047785b273a06a996aa6febf79fccd3b672563af Mon Sep 17 00:00:00 2001 From: atm-lena Date: Fri, 6 Nov 2020 11:58:36 +0100 Subject: [PATCH 002/137] FIX - Don't display inactive users in birthday box and soc card --- htdocs/core/boxes/box_birthdays.php | 3 ++- htdocs/societe/card.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/boxes/box_birthdays.php b/htdocs/core/boxes/box_birthdays.php index 2df1f0d331e..4f7eb6890b4 100644 --- a/htdocs/core/boxes/box_birthdays.php +++ b/htdocs/core/boxes/box_birthdays.php @@ -89,7 +89,8 @@ class box_birthdays extends ModeleBoxes $sql = "SELECT u.rowid, u.firstname, u.lastname, u.birth"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; $sql.= " WHERE u.entity IN (".getEntity('user').")"; - $sql.= dolSqlDateFilter('u.birth', 0, $tmparray['mon'], 0); + $sql.= " AND u.statut = 1"; + $sql.= dolSqlDateFilter('u.birth', 0, $tmparray['mon'], 0); $sql.= " ORDER BY u.birth ASC"; $sql.= $this->db->plimit($max, 0); diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index ee252677bf2..f6abc142054 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1570,7 +1570,7 @@ else print ''; print ''.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; print ''; - $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, '', 0, '', '', 0, 1); + $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'AND u.statut = 1', 0, '', '', 0, 1); // Note: If user has no right to "see all thirdparties", we force selection of sale representative to him, so after creation he can see the record. $selected = (count(GETPOST('commercial', 'array')) > 0 ? GETPOST('commercial', 'array') : (GETPOST('commercial', 'int') > 0 ? array(GETPOST('commercial', 'int')) : (empty($user->rights->societe->client->voir) ? array($user->id) : array()))); print $form->multiselectarray('commercial', $userlist, $selected, null, null, null, null, "90%"); From 2f11f4e104b881c7e58e5bc6de6b015edace9d3e Mon Sep 17 00:00:00 2001 From: Got2be Date: Mon, 9 Nov 2020 11:22:07 +0100 Subject: [PATCH 003/137] FIX : disabled users must not be available in sales representative list on societe edit mode --- htdocs/societe/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index f6abc142054..022727f7003 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -2252,7 +2252,7 @@ else print ''; print ''.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; print ''; - $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, '', 0, '', '', 0, 1); + $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'AND u.statut = 1', 0, '', '', 0, 1); $arrayselected = GETPOST('commercial', 'array'); if (empty($arrayselected)) $arrayselected = $object->getSalesRepresentatives($user, 1); print $form->multiselectarray('commercial', $userlist, $arrayselected, null, null, null, null, "90%"); From 617c93057484554faa131ca32eca9f303a006961 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 9 Nov 2020 14:13:09 +0100 Subject: [PATCH 004/137] FIX: Accountancy - Some ajustments on length of the account (general & auxiliary) --- htdocs/accountancy/class/accountancyexport.class.php | 2 +- htdocs/accountancy/journal/bankjournal.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index b3a4430db36..11486bf76c9 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -351,7 +351,7 @@ class AccountancyExport print price($line->debit) . $separator; print price($line->credit) . $separator; print 'E' . $separator; - print length_accountg($line->subledger_account) . $separator; + print length_accounta($line->subledger_account) . $separator; print $end_line; } } diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 070e58f5c0d..c69806862c6 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -866,7 +866,7 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! print '"' . $date . '"' . $sep; print '"' . $val["type_payment"] . '"' . $sep; print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep; - print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep; + print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep; print " " . $sep; print '"' . $reflabel . '"' . $sep; print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep; @@ -896,7 +896,7 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! print '"' . $key . '"' . $sep; print '"' . $date . '"' . $sep; print '"' . $val["type_payment"] . '"' . $sep; - print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep; + print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep; if ($tabtype[$key] == 'payment_supplier') { print '"' . $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER . '"' . $sep; } elseif($tabtype[$key] == 'payment') { @@ -906,7 +906,7 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! } elseif($tabtype[$key] == 'payment_salary') { print '"' . $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT . '"' . $sep; } else { - print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep; + print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep; } print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep; print '"' . $reflabel . '"' . $sep; @@ -929,7 +929,7 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! print '"' . $date . '"' . $sep; print '"' . $val["type_payment"] . '"' . $sep; print '"' . length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . '"' . $sep; - print '"' . length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . '"' . $sep; + print '"' . length_accounta($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . '"' . $sep; print "" . $sep; print '"' . $reflabel . '"' . $sep; print '"' . ($mt < 0 ? price(- $mt) : '') . '"' . $sep; From 0a078da8e47f096f098d1c7d7f08bf22a846fd8d Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 9 Nov 2020 14:59:29 +0100 Subject: [PATCH 005/137] FIX: Accountancy - Some ajustments on length of the account --- htdocs/accountancy/journal/bankjournal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index c69806862c6..081104ce7a1 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -1133,7 +1133,7 @@ if (empty($action) || $action == 'view') { if ($tabtype[$key] == 'payment_vat') $account_ledger = $conf->global->ACCOUNTING_VAT_PAY_ACCOUNT; if ($tabtype[$key] == 'member') $account_ledger = $conf->global->ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT; if ($tabtype[$key] == 'payment_various') $account_ledger = $tabpay[$key]["account_various"]; - $accounttoshow = length_accounta($account_ledger); + $accounttoshow = length_accountg($account_ledger); if (empty($accounttoshow) || $accounttoshow == 'NotDefined') { if ($tabtype[$key] == 'unknown') From bf27c56fa7f0b2c12311ec50286487192971da10 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Mon, 9 Nov 2020 17:09:06 +0100 Subject: [PATCH 006/137] Following PR#15336: it should not be possible to modify the third party of an invoice --- htdocs/compta/facture/card.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 93ce8bc0f5f..34a051508f8 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -345,15 +345,6 @@ if (empty($reshook)) } } - elseif ($action == 'set_thirdparty' && $usercancreate) - { - $object->fetch($id); - $object->setValueFrom('fk_soc', $socid, '', null, 'int', '', $user, 'BILL_MODIFY'); - - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id); - exit(); - } - elseif ($action == 'classin' && $usercancreate) { $object->fetch($id); From fb27c98f9ca3b0bd1b6a72beca34c5052e6a5ddc Mon Sep 17 00:00:00 2001 From: quentin Date: Tue, 10 Nov 2020 09:40:45 +0100 Subject: [PATCH 007/137] FIX : handling $heightforinfotot when he's superior to a page height --- htdocs/core/modules/facture/doc/pdf_crabe.modules.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index a32ba1308a3..87fbf1f5085 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -328,6 +328,7 @@ class pdf_crabe extends ModelePDFFactures $pdf->SetAutoPageBreak(1, 0); $heightforinfotot = 50 + (4 * $nbpayments); // Height reserved to output the info and total part and payment part + if($heightforinfotot > 220) $heightforinfotot = 220; $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 + 8; // Height reserved to output the footer (value include bottom margin) if ($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS > 0) $heightforfooter += 6; From b16af0a7c3f2a674eae83206f817b368d2e7b022 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 11 Nov 2020 15:43:36 +0100 Subject: [PATCH 008/137] fix deprecated warning php 7.4 --- htdocs/contact/list.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 843a894a0fd..295e63c9606 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -76,7 +76,7 @@ $search_no_email = GETPOST("search_no_email", 'int'); if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { if ($value['active']) { - $search_{$key} = GETPOST("search_".$key, 'alpha'); + ${"search_".$key} = GETPOST("search_".$key, 'alpha'); } } } @@ -259,7 +259,7 @@ if (empty($reshook)) if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { if ($value['active']) { - $search_{$key} = ""; + ${"search_".$key} = ""; } } } @@ -363,8 +363,8 @@ if (strlen($search_phone_mobile)) $sql .= natural_search('p.phone_mobile', $se if (strlen($search_fax)) $sql .= natural_search('p.fax', $search_fax); if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { - if ($value['active'] && strlen($search_{$key})) { - $sql .= ' AND p.socialnetworks LIKE \'%"'.$key.'":"'.$search_{$key}.'%\''; + if ($value['active'] && strlen(${"search_".$key})) { + $sql .= ' AND p.socialnetworks LIKE \'%"'.$key.'":"'.${"search_".$key}.'%\''; } } } @@ -674,7 +674,7 @@ if (!empty($conf->socialnetworks->enabled)) { if (!empty($arrayfields['p.'.$key]['checked'])) { print ''; - print ''; + print ''; print ''; } } From ad05451427d77f11ab7d4ee72eacb606585da4ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 12 Nov 2020 11:23:03 +0100 Subject: [PATCH 009/137] Fix missing getpost for scandir odt path --- htdocs/admin/user.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index 56602502715..e71088da27a 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -6,6 +6,7 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2015 Juanjo Menent + * Copyright (C) 2020 Frédéric France * * 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 @@ -42,6 +43,8 @@ $action = GETPOST('action', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); $value = GETPOST('value', 'alpha'); +$label = GETPOST('label', 'alpha'); +$scandir = GETPOST('scandir', 'alpha'); $type = 'user'; From 02158928cc4603949b5f216a35ab62fb3ac86938 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 12 Nov 2020 14:11:59 +0100 Subject: [PATCH 010/137] FIX #15365 export of extrafields for user and resources --- htdocs/core/modules/modResource.class.php | 4 ++-- htdocs/core/modules/modUser.class.php | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php index 0e96b8d4c11..0d1353076ec 100644 --- a/htdocs/core/modules/modResource.class.php +++ b/htdocs/core/modules/modResource.class.php @@ -246,9 +246,9 @@ class modResource extends DolibarrModules $this->export_dependencies_array[$r] = array('resource'=>array('r.rowid')); // We must keep this until the aggregate_array is used. To add unique key if we ask a field of a child to avoid the DISTINCT to discard them. $this->export_sql_start[$r] = 'SELECT DISTINCT '; - $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'resource as r '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'resource as r'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_resource as c ON c.rowid=r.fk_code_type_resource'; - $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'resource_extrafields as extra ON extra.fk_object = c.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'resource_extrafields as extra ON extra.fk_object = r.rowid'; $this->export_sql_end[$r] .= ' AND r.entity IN ('.getEntity('resource').')'; diff --git a/htdocs/core/modules/modUser.class.php b/htdocs/core/modules/modUser.class.php index c2ce0fec86f..e5ba3289d05 100644 --- a/htdocs/core/modules/modUser.class.php +++ b/htdocs/core/modules/modUser.class.php @@ -255,13 +255,16 @@ class modUser extends DolibarrModules 'u.admin'=>"user", 'u.statut'=>'user', 'u.datelastlogin'=>'user', 'u.datepreviouslogin'=>'user', 'u.fk_socpeople'=>"contact", 'u.fk_soc'=>"company", 'u.fk_member'=>"member" ); - if (empty($conf->adherent->enabled)) + $keyforselect = 'user'; $keyforelement = 'user'; $keyforaliasextra = 'extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + if (empty($conf->adherent->enabled)) { unset($this->export_fields_array[$r]['u.fk_member']); unset($this->export_entities_array[$r]['u.fk_member']); } $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'user as u'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user_extrafields as extra ON u.rowid = extra.fk_object'; $this->export_sql_end[$r] .= ' WHERE u.entity IN ('.getEntity('user').')'; // Imports From 0c37d31e040e94f46c120a6467857ae21a0a4bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20MARTIN?= <52456749+BlueGarm@users.noreply.github.com> Date: Sat, 14 Nov 2020 13:01:36 +0100 Subject: [PATCH 011/137] Update box_supplier_orders_awaiting_reception.php --- htdocs/core/boxes/box_supplier_orders_awaiting_reception.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php index 86a2b7b3086..6c3b906cb0f 100644 --- a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php +++ b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php @@ -96,7 +96,7 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql .= " WHERE c.fk_soc = s.rowid"; $sql .= " AND c.entity IN (".getEntity('supplier_order').")"; - $sql .= " AND c.fk_statut = ".CommandeFournisseur::STATUS_ORDERSENT; + $sql .= " AND c.fk_statut IN (".CommandeFournisseur::STATUS_ORDERSENT.", ".CommandeFournisseur::STATUS_RECEIVED_PARTIALLY.")"; if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; if ($user->socid) $sql .= " AND s.rowid = ".$user->socid; if ($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE) $sql .= " ORDER BY c.date_commande DESC, c.ref DESC "; From 2425cf82d3522771313b16ca3759c0ac1288b040 Mon Sep 17 00:00:00 2001 From: BlueGarm Date: Sat, 14 Nov 2020 13:25:02 +0100 Subject: [PATCH 012/137] Add Partially Received Order and Delay Edit file to allow following order received partially and to upgrade lisibility of delayed orders --- htdocs/fourn/class/fournisseur.commande.class.php | 8 ++++---- htdocs/fourn/commande/card.php | 6 +++--- htdocs/fourn/commande/list.php | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 2b90af268c5..21399b7d674 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2987,7 +2987,7 @@ class CommandeFournisseur extends CommonOrder } $sql .= $clause." c.entity = ".$conf->entity; if ($mode === 'awaiting') { - $sql .= " AND c.fk_statut = ".self::STATUS_ORDERSENT; + $sql .= " AND c.fk_statut IN (".self::STATUS_ORDERSENT.", ".self::STATUS_RECEIVED_PARTIALLY.")"; } else { $sql .= " AND c.fk_statut IN (".self::STATUS_VALIDATED.", ".self::STATUS_ACCEPTED.")"; @@ -3009,7 +3009,7 @@ class CommandeFournisseur extends CommonOrder if ($mode === 'awaiting') { $response->label = $langs->trans("SuppliersOrdersAwaitingReception"); $response->labelShort = $langs->trans("AwaitingReception"); - $response->url = DOL_URL_ROOT.'/fourn/commande/list.php?statut=3&mainmenu=commercial&leftmenu=orders_suppliers'; + $response->url = DOL_URL_ROOT.'/fourn/commande/list.php?statut=3,4&mainmenu=commercial&leftmenu=orders_suppliers'; } while ($obj = $this->db->fetch_object($resql)) @@ -3175,9 +3175,9 @@ class CommandeFournisseur extends CommonOrder if (empty($this->date_delivery) && !empty($this->date_livraison)) $this->date_delivery = $this->date_livraison; // For backward compatibility $now = dol_now(); - $date_to_test = empty($this->date_delivery) ? $this->date_commande : $this->date_delivery; + $date_to_test = empty($this->date_livraison) ? $this->date_commande : $this->date_livraison; - return ($this->statut > 0 && $this->statut < 4) && $date_to_test && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay); + return ($this->statut > 0 && $this->statut < 5) && $date_to_test && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay); } /** diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 3fb7ae18cbc..846113176c1 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -2065,9 +2065,9 @@ elseif (!empty($object->id)) if ($object->methode_commande_id > 0) { print ''.$langs->trans("Date").''; - if ($object->date_commande) - { - print dol_print_date($object->date_commande, "dayhour")."\n"; + print $object->date_commande ? dol_print_date($object->date_commande, $usehourmin) : ' '; + if ($object->hasDelay() && empty($object->date_livraison) && !empty($object->date_commande)) { + print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning"); } print ""; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 417e78023a8..c21e7ee4999 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -1001,6 +1001,7 @@ if ($resql) $objectstatic->total_ht = $obj->total_ht; $objectstatic->total_tva = $obj->total_tva; $objectstatic->total_ttc = $obj->total_ttc; + $objectstatic->date_commande = $db->jdate($obj->date_commande); $objectstatic->date_delivery = $db->jdate($obj->date_delivery); $objectstatic->note_public = $obj->note_public; $objectstatic->note_private = $obj->note_private; @@ -1110,8 +1111,10 @@ if ($resql) if (!empty($arrayfields['cf.date_commande']['checked'])) { print ''; - if ($obj->date_commande) print dol_print_date($db->jdate($obj->date_commande), 'day'); - else print ''; + print dol_print_date($db->jdate($obj->date_commande), 'day'); + if ($objectstatic->hasDelay() && empty($objectstatic->date_delivery)) { + print ' '.img_picto($langs->trans("Late").' : '.$objectstatic->showDelay(), "warning"); + } print ''; if (!$i) $totalarray['nbfield']++; } From 44c59888535e51f37fd645a133971619593e9341 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sun, 15 Nov 2020 10:42:15 +0100 Subject: [PATCH 013/137] Fix #15377 ticket list filter on author --- htdocs/ticket/list.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 08419e5c46d..bc54195c467 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -229,7 +229,7 @@ if ($socid > 0) foreach ($search as $key => $val) { - if ($key == 'fk_statut') + if ($key == 'fk_statut' && !empty($search['fk_statut'])) { $tmpstatus = ''; if ($search['fk_statut'] == 'openall' || in_array('openall', $search['fk_statut'])) $tmpstatus .= ($tmpstatus ? ',' : '')."'".Ticket::STATUS_NOT_READ."', '".Ticket::STATUS_READ."', '".Ticket::STATUS_ASSIGNED."', '".Ticket::STATUS_IN_PROGRESS."', '".Ticket::STATUS_NEED_MORE_INFO."', '".Ticket::STATUS_WAITING."'"; @@ -238,7 +238,7 @@ foreach ($search as $key => $val) elseif (is_array($search[$key]) && count($search[$key])) $sql .= natural_search($key, join(',', $search[$key]), 2); continue; } - if ($key == 'fk_user_assign') + if ($key == 'fk_user_assign' || $key == 'fk_user_create') { if ($search[$key] > 0) $sql .= natural_search($key, $search[$key], 2); continue; @@ -536,7 +536,7 @@ foreach ($object->fields as $key => $val) print ''; $formTicket->selectSeveritiesTickets(dol_escape_htmltag($search[$key]), 'search_'.$key.'', '', 2, 1, 1, 0, ($val['css'] ? $val['css'] : 'maxwidth150')); print ''; - } elseif ($key == 'fk_user_assign') { + } elseif ($key == 'fk_user_assign' || $key == 'fk_user_create') { print ''; print $form->select_dolusers($search[$key], 'search_'.$key, 1, null, 0, '', '', '0', 0, 0, '', 0, '', ($val['css'] ? $val['css'] : 'maxwidth150')); print ''; From 5e1cd459b107fd8ab971dc5db019124a297503ce Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 15 Nov 2020 23:47:53 +0100 Subject: [PATCH 014/137] Fix travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4e947325633..8a782146c26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -120,6 +120,7 @@ install: composer self-update composer -n init composer -n config vendor-dir htdocs/includes + composer -n config -g vendor-dir htdocs/includes echo - | From 217aa9c4204c49f2b217e5f5f745fbc0f3b7bc21 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 15 Nov 2020 23:50:11 +0100 Subject: [PATCH 015/137] Clean CI --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index af695d4672e..082847d8c30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -112,7 +112,6 @@ install: rm $TRAVIS_BUILD_DIR/composer.lock composer self-update # To have composer making parallel downloads - composer global require hirak/prestissimo composer -n init composer -n config vendor-dir htdocs/includes composer -n config -g vendor-dir htdocs/includes From 6ce006f853053a5e24daad7a128f3403de9002e2 Mon Sep 17 00:00:00 2001 From: quentin Date: Mon, 16 Nov 2020 15:46:16 +0100 Subject: [PATCH 016/137] FIX cant empty action comm desc --- htdocs/comm/action/card.php | 1 - htdocs/comm/action/class/actioncomm.class.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 129696a60d9..0709a2571ad 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -469,7 +469,6 @@ if (empty($reshook) && $action == 'update') $object->note_private = trim(GETPOST("note", "none")); $object->fk_element = GETPOST("fk_element", "int"); $object->elementtype = GETPOST("elementtype", "alphanohtml"); - if (!$datef && $percentage == 100) { $error++; $donotclearsession = 1; diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index 3c060ffdc39..7355040e00c 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -983,7 +983,7 @@ class ActionComm extends CommonObject // Clean parameters $this->label = trim($this->label); - $this->note_private = dol_htmlcleanlastbr(trim(empty($this->note_private) ? $this->note : $this->note_private)); + $this->note_private = dol_htmlcleanlastbr(trim(!isset($this->note_private) ? $this->note : $this->note_private)); if (empty($this->percentage)) $this->percentage = 0; if (empty($this->priority) || !is_numeric($this->priority)) $this->priority = 0; if (empty($this->transparency)) $this->transparency = 0; From 4ae121d870865ee5f8edba8b422fa59d94daf976 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 16 Nov 2020 19:43:45 +0100 Subject: [PATCH 017/137] FIX Can't create shipment for virtual product. Add STOCK_EXCLUDE_VIRTUAL_PRODUCTS as a quick hack to solve this. --- htdocs/expedition/class/expedition.class.php | 31 +++++++------- htdocs/product/class/product.class.php | 43 ++++++++++++-------- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index f3e9d5f26f8..d14a34515c4 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -954,33 +954,36 @@ class Expedition extends CommonObject { $fk_product = $orderline->fk_product; - if (!($entrepot_id > 0) && empty($conf->global->STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS)) - { + if (!($entrepot_id > 0) && empty($conf->global->STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS)) { $langs->load("errors"); $this->error = $langs->trans("ErrorWarehouseRequiredIntoShipmentLine"); return -1; } - if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT) - { - // Check must be done for stock of product into warehouse if $entrepot_id defined + if ($conf->global->STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT) { $product = new Product($this->db); - $result = $product->fetch($fk_product); + $product->fetch($fk_product); + // Check must be done for stock of product into warehouse if $entrepot_id defined if ($entrepot_id > 0) { $product->load_stock('warehouseopen'); $product_stock = $product->stock_warehouse[$entrepot_id]->real; - } - else + } else { $product_stock = $product->stock_reel; + } $product_type = $product->type; - if ($product_type == 0 && $product_stock < $qty) - { - $langs->load("errors"); - $this->error = $langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $product->ref); - $this->db->rollback(); - return -3; + if ($product_type == 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + $isavirtualproduct = ($product->hasFatherOrChild(1) > 0); + // The product is qualified for a check of quantity (must be enough in stock to be added into shipment). + if (!$isavirtualproduct || empty($conf->global->PRODUIT_SOUSPRODUITS) || ($isavirtualproduct && empty($conf->global->STOCK_EXCLUDE_VIRTUAL_PRODUCTS))) { // If STOCK_EXCLUDE_VIRTUAL_PRODUCTS is set, we do not manage stock for kits/virtual products. + if ($product_stock < $qty) { + $langs->load("errors"); + $this->error = $langs->trans('ErrorStockIsNotEnoughToAddProductOnShipment', $product->ref); + $this->db->rollback(); + return -3; + } + } } } } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 55cc67de4a5..3630155662e 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -4208,29 +4208,36 @@ class Product extends CommonObject } /** - * Return all parent products for current product (first level only) + * Count all parent and children products for current product (first level only) * - * @return int Nb of father + child + * @param int $mode 0=Both parent and child, -1=Parents only, 1=Children only + * @return int Nb of father + child + * @see getFather(), get_sousproduits_arbo() */ - public function hasFatherOrChild() + public function hasFatherOrChild($mode = 0) { - $nb = 0; + $nb = 0; - $sql = "SELECT COUNT(pa.rowid) as nb"; - $sql .= " FROM ".MAIN_DB_PREFIX."product_association as pa"; - $sql .= " WHERE pa.fk_product_fils = ".$this->id." OR pa.fk_product_pere = ".$this->id; - $resql = $this->db->query($sql); - if ($resql) { - $obj = $this->db->fetch_object($resql); - if ($obj) { $nb = $obj->nb; - } - } - else - { - return -1; - } + $sql = "SELECT COUNT(pa.rowid) as nb"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_association as pa"; + if ($mode == 0) { + $sql .= " WHERE pa.fk_product_fils = ".$this->id." OR pa.fk_product_pere = ".$this->id; + } elseif ($mode == -1) { + $sql .= " WHERE pa.fk_product_fils = ".$this->id; // We are a child, so we found lines that link to parents (can have several parents) + } elseif ($mode == 1) { + $sql .= " WHERE pa.fk_product_pere = ".$this->id; // We are a parent, so we found lines that link to children (can have several children) + } - return $nb; + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + if ($obj) { $nb = $obj->nb; + } + } else { + return -1; + } + + return $nb; } /** From f7228d96af13d800324f75d711ba05cc1df042b4 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Fri, 20 Nov 2020 19:12:59 +0100 Subject: [PATCH 018/137] FIX 12.0 - when the cronjob 'params' field is empty, the cron method is called with one empty string param instead of no params at all --- htdocs/cron/class/cronjob.class.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 39220f0cebe..ba7adfd320f 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1052,7 +1052,10 @@ class Cronjob extends CommonObject $object = new $this->objectname($this->db); if ($this->entity > 0) $object->entity = $this->entity; // We work on a dedicated entity - $params_arr = array_map('trim', explode(",", $this->params)); + $params_arr = array(); + if (!empty($this->params) || $this->params === '0'){ + $params_arr = array_map('trim', explode(",", $this->params)); + } if (!is_array($params_arr)) { @@ -1113,7 +1116,7 @@ class Cronjob extends CommonObject } dol_syslog(get_class($this)."::run_jobs ".$this->libname."::".$this->methodename."(".$this->params.");", LOG_DEBUG); - $params_arr = explode(", ", $this->params); + $params_arr = explode(", ", $this->params); if (!is_array($params_arr)) { $result = call_user_func($this->methodename, $this->params); From 6c75997b271821de38f0d81859812d944f09cd46 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Fri, 20 Nov 2020 19:15:15 +0100 Subject: [PATCH 019/137] FIX wrong tab --- htdocs/cron/class/cronjob.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index ba7adfd320f..e8b3fd8e96b 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1116,7 +1116,7 @@ class Cronjob extends CommonObject } dol_syslog(get_class($this)."::run_jobs ".$this->libname."::".$this->methodename."(".$this->params.");", LOG_DEBUG); - $params_arr = explode(", ", $this->params); + $params_arr = explode(", ", $this->params); if (!is_array($params_arr)) { $result = call_user_func($this->methodename, $this->params); From fbc911aea1e82dfa711d9bc7b41c0c458dc1e417 Mon Sep 17 00:00:00 2001 From: ATM john Date: Mon, 23 Nov 2020 16:40:31 +0100 Subject: [PATCH 020/137] Fix conf usage thirdparty propagate extrafields to --- htdocs/commande/card.php | 2 +- htdocs/compta/facture/card.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index ed1f27e3c82..4175509eb28 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1772,7 +1772,7 @@ if ($action == 'create' && $usercancreate) $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); print $hookmanager->resPrint; if (empty($reshook)) { - if (!empty($conf->global->THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_ORDER)) { + if (!empty($conf->global->THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_ORDER) && !empty($soc->id)) { // copy from thirdparty $tpExtrafields = new Extrafields($db); $tpExtrafieldLabels = $tpExtrafields->fetch_name_optionals_label($soc->table_element); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 9118944d9f9..3362d23e532 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3571,7 +3571,7 @@ if ($action == 'create') $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (empty($reshook)) { - if (!empty($conf->global->THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_INVOICE)) { + if (!empty($conf->global->THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_INVOICE) && !empty($soc->id)) { // copy from thirdparty $tpExtrafields = new Extrafields($db); $tpExtrafieldLabels = $tpExtrafields->fetch_name_optionals_label($soc->table_element); From e7dbc8407f532b8be44163f4490092ca5905157f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 23 Nov 2020 19:08:26 +0100 Subject: [PATCH 021/137] FIX formating of prices with foreign languages --- htdocs/product/price.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 6fa2a77d5da..48cf4722ae7 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -226,6 +226,7 @@ if (empty($reshook)) $tva_tx = $tva_tx_txt; $vatratecode = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { $vat_src_code = $reg[1]; @@ -261,8 +262,8 @@ if (empty($reshook)) } $pricestoupdate[$i] = array( - 'price' => $newprice[$i], - 'price_min' => $newprice_min[$i], + 'price' => price2num($newprice[$i]), + 'price_min' => price2num($newprice_min[$i]), 'price_base_type' => $newpricebase[$i], 'default_vat_code' => $vatratecode, 'vat_tx' => $tva_tx, // default_vat_code should be used in priority in a future @@ -278,10 +279,15 @@ if (empty($reshook)) } elseif (!$error) { + $newprice = price2num(GETPOST('price', 'alpha')); + $newprice_min = price2num(GETPOST('price_min', 'alpha')); + $newpricebase = GETPOST('price_base_type', 'alpha'); + $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' $tva_tx = $tva_tx_txt; $vatratecode = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { $vat_src_code = $reg[1]; @@ -321,9 +327,9 @@ if (empty($reshook)) } } $pricestoupdate[0] = array( - 'price' => $_POST["price"], - 'price_min' => $_POST["price_min"], - 'price_base_type' => $_POST["price_base_type"], + 'price' => $newprice, + 'price_min' => $newprice_min, + 'price_base_type' => $newpricebase, 'default_vat_code' => $vatratecode, 'vat_tx' => $tva_tx, // default_vat_code should be used in priority in a future 'npr' => $npr, // default_vat_code should be used in priority in a future From c5278197fb9772cdd0f4d5a2f641d9abd7e305a2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 23 Nov 2020 19:45:11 +0100 Subject: [PATCH 022/137] More phpunit test for price2num --- htdocs/core/lib/functions.lib.php | 9 ++++++-- htdocs/product/price.php | 3 ++- test/phpunit/FunctionsLibTest.php | 35 +++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1e6ef8d6ebe..efeed543865 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4726,6 +4726,9 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0) // Convert amount to format with dolibarr dec and thousand (this is because PHP convert a number // to format defined by LC_NUMERIC after a calculation and we want source format to be like defined by Dolibarr setup. + if ($thousand == '.') { + $amount = str_replace($thousand, '', $amount); // Replace of thousand before test of is_numeric to avoid pb if thousand is . + } if (is_numeric($amount)) { // We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10 @@ -4735,9 +4738,11 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0) $amount = number_format($amount, $nbofdec, $dec, $thousand); } //print "QQ".$amount.'
'; - + // Now make replace (the main goal of function) - if ($thousand != ',' && $thousand != '.') $amount = str_replace(',', '.', $amount); // To accept 2 notations for french users + if ($thousand != ',' && $thousand != '.') { + $amount = str_replace(',', '.', $amount); // To accept 2 notations for french users + } $amount = str_replace(' ', '', $amount); // To avoid spaces $amount = str_replace($thousand, '', $amount); // Replace of thousand before replace of dec to avoid pb if thousand is . $amount = str_replace($dec, '.', $amount); diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 48cf4722ae7..d89020b33a3 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -279,10 +279,11 @@ if (empty($reshook)) } elseif (!$error) { + var_dump(GETPOST('price', 'alpha')); $newprice = price2num(GETPOST('price', 'alpha')); + var_dump($newprice);exit; $newprice_min = price2num(GETPOST('price_min', 'alpha')); $newpricebase = GETPOST('price_base_type', 'alpha'); - $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' $tva_tx = $tva_tx_txt; diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index e3dabff6df9..0fc2583178c 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1225,6 +1225,15 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase */ public function testDolPrice2Num() { + global $langs, $conf; + + $oldlangs = $langs; + + $newlangs = new Translate('', $conf); + $newlangs->setDefaultLang('en_US'); + $newlangs->load("main"); + $langs = $newlangs; + $this->assertEquals(1000, price2num('1 000.0')); $this->assertEquals(1000, price2num('1 000', 'MT')); $this->assertEquals(1000, price2num('1 000', 'MU')); @@ -1239,10 +1248,36 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $this->assertEquals(1000.13, price2num('1 000.125456', 'MT')); $this->assertEquals(1000.12546, price2num('1 000.125456', 'MU'), "Test MU"); + $this->assertEquals(1, price2num('1.000'), 'Test 1.000 give 1 with english language'); + // Text can't be converted $this->assertEquals('12.4$', price2num('12.4$')); $this->assertEquals('12r.4$', price2num('12r.4$')); + // For spanish language + $newlangs2 = new Translate('', $conf); + $newlangs2->setDefaultLang('es_ES'); + $newlangs2->load("main"); + $langs = $newlangs2; + + $this->assertEquals(1000, price2num('1.000'), 'Test 1.000 give 1000 with spanish language'); + $this->assertEquals(1000, price2num('1 000'), 'Test 1 000 give 1000 with spanish language'); + $this->assertEquals(1234, price2num('1.234'), 'Test 1.234 give 1234 with spanish language'); + $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with spanish language'); + + // For french language + $newlangs3 = new Translate('', $conf); + $newlangs3->setDefaultLang('fr_FR'); + $newlangs3->load("main"); + $langs = $newlangs3; + + $this->assertEquals(1, price2num('1.000'), 'Test 1.000 give 1 with french language'); + $this->assertEquals(1000, price2num('1 000'), 'Test 1.000 give 1 with french language'); + $this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with french language'); + $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with french language'); + + $langs = $oldlangs; + return true; } From 9cb5673c36561aba1a251ee712add0f98199f245 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 23 Nov 2020 19:46:24 +0100 Subject: [PATCH 023/137] Fix remove var_dump --- htdocs/product/price.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index d89020b33a3..f93545ee19e 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -279,9 +279,7 @@ if (empty($reshook)) } elseif (!$error) { - var_dump(GETPOST('price', 'alpha')); $newprice = price2num(GETPOST('price', 'alpha')); - var_dump($newprice);exit; $newprice_min = price2num(GETPOST('price_min', 'alpha')); $newpricebase = GETPOST('price_base_type', 'alpha'); $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' From 5822fcfbedf3dd62398ed1785d70a815bdb7e8cb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 23 Nov 2020 21:38:45 +0100 Subject: [PATCH 024/137] FIX several warning with the barcode use in ODT templates --- htdocs/comm/propal/class/propal.class.php | 20 ++++++++++++++++--- htdocs/commande/class/commande.class.php | 7 +++++-- .../core/class/commondocgenerator.class.php | 11 ++++++---- htdocs/core/class/commonorder.class.php | 12 +++++++++++ 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index c6d6f18e109..144374ab47c 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1344,7 +1344,6 @@ class Propal extends CommonObject // Load source object $object->fetch($this->id); - $object->fetch_lines(); $objsoc = new Societe($this->db); @@ -1738,7 +1737,7 @@ class Propal extends CommonObject $sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,'; $sql .= ' d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,'; $sql .= ' d.fk_unit,'; - $sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_batch,'; + $sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_tobatch, p.barcode as product_barcode,'; $sql .= ' p.weight, p.weight_units, p.volume, p.volume_units,'; $sql .= ' d.date_start, d.date_end,'; $sql .= ' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc'; @@ -1800,11 +1799,14 @@ class Propal extends CommonObject $line->fk_product = $objp->fk_product; $line->ref = $objp->product_ref; // deprecated - $line->product_ref = $objp->product_ref; $line->libelle = $objp->product_label; // deprecated + + $line->product_ref = $objp->product_ref; $line->product_label = $objp->product_label; $line->product_desc = $objp->product_desc; // Description produit $line->product_tobatch = $objp->product_tobatch; + $line->product_barcode = $objp->product_barcode; + $line->fk_product_type = $objp->fk_product_type; // deprecated $line->fk_unit = $objp->fk_unit; $line->weight = $objp->weight; @@ -3924,6 +3926,18 @@ class PropaleLigne extends CommonObjectLine */ public $product_desc; + /** + * Product use lot + * @var string + */ + public $product_tobatch; + + /** + * Product barcode + * @var string + */ + public $product_barcode; + public $localtax1_tx; // Local tax 1 public $localtax2_tx; // Local tax 2 public $localtax1_type; // Local tax 1 type diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 07f483da931..fbbd40265a1 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -2033,7 +2033,7 @@ class Commande extends CommonOrder $sql .= ' l.total_ht, l.total_ttc, l.total_tva, l.total_localtax1, l.total_localtax2, l.date_start, l.date_end,'; $sql .= ' l.fk_unit,'; $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc,'; - $sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_tobatch,'; + $sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_tobatch, p.barcode as product_barcode,'; $sql .= ' p.weight, p.weight_units, p.volume, p.volume_units'; $sql .= ' FROM '.MAIN_DB_PREFIX.'commandedet as l'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON (p.rowid = l.fk_product)'; @@ -2091,11 +2091,14 @@ class Commande extends CommonOrder $line->fk_parent_line = $objp->fk_parent_line; $line->ref = $objp->product_ref; - $line->product_ref = $objp->product_ref; $line->libelle = $objp->product_label; + + $line->product_ref = $objp->product_ref; $line->product_label = $objp->product_label; $line->product_desc = $objp->product_desc; $line->product_tobatch = $objp->product_tobatch; + $line->product_barcode = $objp->product_barcode; + $line->fk_product_type = $objp->fk_product_type; // Produit ou service $line->fk_unit = $objp->fk_unit; diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 544cc105416..2900a4cd173 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -529,10 +529,13 @@ abstract class CommonDocGenerator $resarray = array( 'line_pos' => $linenumber, 'line_fulldesc'=>doc_getlinedesc($line, $outputlangs), - 'line_product_ref'=>$line->product_ref, - 'line_product_ref_fourn'=>$line->ref_fourn, // for supplier doc lines - 'line_product_label'=>$line->product_label, - 'line_product_type'=>$line->product_type, + + 'line_product_ref'=>(empty($line->product_ref) ? '' : $line->product_ref), + 'line_product_ref_fourn'=>(empty($line->ref_fourn) ? '' : $line->ref_fourn), // for supplier doc lines + 'line_product_label'=>(empty($line->product_label) ? '' :$line->product_label), + 'line_product_type'=>(empty($line->product_type) ? '' : $line->product_type), + 'line_product_barcode'=>(empty($line->product_barcode) ? '' : $line->product_barcode), + 'line_desc'=>$line->desc, 'line_vatrate'=>vatrate($line->tva_tx, true, $line->info_bits), 'line_localtax1_rate'=>vatrate($line->localtax1_tx), diff --git a/htdocs/core/class/commonorder.class.php b/htdocs/core/class/commonorder.class.php index e45d08a9396..7f2c9fef684 100644 --- a/htdocs/core/class/commonorder.class.php +++ b/htdocs/core/class/commonorder.class.php @@ -71,6 +71,18 @@ abstract class CommonOrderLine extends CommonObjectLine */ public $product_desc; + /** + * Product use lot + * @var string + */ + public $product_tobatch; + + /** + * Product barcode + * @var string + */ + public $product_barcode; + /** * Quantity * @var float From c7d886c918eb6b454017281396952800f76792db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 23 Nov 2020 23:25:09 +0100 Subject: [PATCH 025/137] fix status on tooltip in box last product --- htdocs/core/boxes/box_produits.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php index 38f9a73f57f..7f4b66f5f58 100644 --- a/htdocs/core/boxes/box_produits.php +++ b/htdocs/core/boxes/box_produits.php @@ -133,6 +133,8 @@ class box_produits extends ModeleBoxes $productstatic->type = $objp->fk_product_type; $productstatic->label = $objp->label; $productstatic->entity = $objp->entity; + $productstatic->status = $objp->tosell; + $productstatic->status_buy = $objp->tobuy; $this->info_box_contents[$line][] = array( 'td' => 'class="tdoverflowmax100 maxwidth100onsmartphone"', From 69ea0ea791a4daa0e030aed894eae5b39eb37d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 23 Nov 2020 23:44:15 +0100 Subject: [PATCH 026/137] Update box_produits.php --- htdocs/core/boxes/box_produits.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php index 7f4b66f5f58..5b490ac32f4 100644 --- a/htdocs/core/boxes/box_produits.php +++ b/htdocs/core/boxes/box_produits.php @@ -87,6 +87,11 @@ class box_produits extends ModeleBoxes if ($user->rights->produit->lire || $user->rights->service->lire) { $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.fk_price_expression, p.entity"; + $sql .= ", p.accountancy_code_sell"; + $sql .= ", p.accountancy_code_sell_intra"; + $sql .= ", p.accountancy_code_sell_export"; + $sql .= ", p.accountancy_code_buy"; + $sql .= ', p.barcode'; $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; $sql.= ' WHERE p.entity IN ('.getEntity($productstatic->element).')'; if (empty($user->rights->produit->lire)) $sql.=' AND p.fk_product_type != 0'; @@ -135,6 +140,11 @@ class box_produits extends ModeleBoxes $productstatic->entity = $objp->entity; $productstatic->status = $objp->tosell; $productstatic->status_buy = $objp->tobuy; + $productstatic->barcode = $objp->barcode; + $productstatic->accountancy_code_sell = $objp->accountancy_code_sell; + $productstatic->accountancy_code_sell_intra = $objp->accountancy_code_sell_intra; + $productstatic->accountancy_code_sell_export = $objp->accountancy_code_sell_export; + $productstatic->accountancy_code_buy = $objp->accountancy_code_buy; $this->info_box_contents[$line][] = array( 'td' => 'class="tdoverflowmax100 maxwidth100onsmartphone"', From 53208e620e81f135c50f4b0308ac4a3a9661009a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 24 Nov 2020 10:56:05 +0100 Subject: [PATCH 027/137] Use of . as thousand separator. Can use it for decimal if not 3 digits. --- htdocs/core/lib/functions.lib.php | 38 +++++++++++++++---------------- test/phpunit/FunctionsLibTest.php | 16 +++++++++++-- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index efeed543865..ef0703d635a 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4691,19 +4691,19 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $ * Function to use on each input amount before any numeric test or database insert. A better name for this function * should be roundtext2num(). * - * @param float $amount Amount to convert/clean or round - * @param string $rounding ''=No rounding - * 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT) - * 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT) - * 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK) - * 'CR'=Currency rate - * Numeric = Nb of digits for rounding - * @param int $alreadysqlnb Put 1 if you know that content is already universal format number - * @return string Amount with universal numeric format (Example: '99.99999'). - * If conversion fails, it return text unchanged if $rounding = '' or '0' if $rounding is defined. - * If amount is null or '', it returns '' if $rounding = '' or '0' if $rounding is defined.. + * @param string|float $amount Amount to convert/clean or round + * @param string $rounding ''=No rounding + * 'MU'=Round to Max unit price (MAIN_MAX_DECIMALS_UNIT) + * 'MT'=Round to Max for totals with Tax (MAIN_MAX_DECIMALS_TOT) + * 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK) + * 'CR'=Currency rate + * Numeric = Nb of digits for rounding + * @param int $alreadysqlnb Put 1 if you know that content is already universal format number + * @return string Amount with universal numeric format (Example: '99.99999'). + * If conversion fails, it return text unchanged if $rounding = '' or '0' if $rounding is defined. + * If amount is null or '', it returns '' if $rounding = '' or '0' if $rounding is defined.. * - * @see price() Opposite function of price2num + * @see price() Opposite function of price2num */ function price2num($amount, $rounding = '', $alreadysqlnb = 0) { @@ -4720,15 +4720,15 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0) //print "amount=".$amount." html=".$form." trunc=".$trunc." nbdecimal=".$nbdecimal." dec='".$dec."' thousand='".$thousand."'
"; // Convert value to universal number format (no thousand separator, '.' as decimal separator) - if ($alreadysqlnb != 1) // If not a PHP number or unknown, we change format - { - //print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'
'; + if ($alreadysqlnb != 1) { // If not a PHP number or unknown, we change or clean format + print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'
'; + if ($thousand == '.' && preg_match('/\.(\d\d\d)$/', (string) $amount)) { // It means the . is used as a thousand separator, not as a decimal separator + $amount = str_replace($thousand, '', $amount); // Replace of thousand before test of is_numeric to avoid pb if thousand is . and there is 3 numbers after + print 'TTTT'.$amount; + } // Convert amount to format with dolibarr dec and thousand (this is because PHP convert a number // to format defined by LC_NUMERIC after a calculation and we want source format to be like defined by Dolibarr setup. - if ($thousand == '.') { - $amount = str_replace($thousand, '', $amount); // Replace of thousand before test of is_numeric to avoid pb if thousand is . - } if (is_numeric($amount)) { // We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10 @@ -4738,7 +4738,7 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0) $amount = number_format($amount, $nbofdec, $dec, $thousand); } //print "QQ".$amount.'
'; - + // Now make replace (the main goal of function) if ($thousand != ',' && $thousand != '.') { $amount = str_replace(',', '.', $amount); // To accept 2 notations for french users diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 0fc2583178c..85937147cff 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1260,10 +1260,18 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $newlangs2->load("main"); $langs = $newlangs2; - $this->assertEquals(1000, price2num('1.000'), 'Test 1.000 give 1000 with spanish language'); - $this->assertEquals(1000, price2num('1 000'), 'Test 1 000 give 1000 with spanish language'); + // Test with 3 chars after . or , + // If a . is used and there is 3 digits after, it is a thousand separator + $this->assertEquals(1234, price2num('1.234'), 'Test 1.234 give 1234 with spanish language'); + $this->assertEquals(1234, price2num('1 234'), 'Test 1 234 give 1234 with spanish language'); $this->assertEquals(1234, price2num('1.234'), 'Test 1.234 give 1234 with spanish language'); $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with spanish language'); + $this->assertEquals(21500123, price2num('21.500.123'), 'Test 21.500.123 give 21500123 with spanish language'); + $this->assertEquals(21500123, price2num('21500.123'), 'Test 21500.123 give 21500123 with spanish language'); + $this->assertEquals(21500.123, price2num('21500,123'), 'Test 21500,123 give 21500.123 with spanish language'); + // Test with 2 digits + $this->assertEquals(21500.12, price2num('21500.12'), 'Test 21500.12 give 21500.12 with spanish language'); + $this->assertEquals(21500.12, price2num('21500,12'), 'Test 21500,12 give 21500.12 with spanish language'); // For french language $newlangs3 = new Translate('', $conf); @@ -1275,6 +1283,10 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $this->assertEquals(1000, price2num('1 000'), 'Test 1.000 give 1 with french language'); $this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with french language'); $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with french language'); + $this->assertEquals(21500000, price2num('21500 000'), 'Test 21500 000 give 21500000 with french language'); + $this->assertEquals(21500000, price2num('21 500 000'), 'Test 21 500 000 give 21500000 with french language'); + $this->assertEquals(21500, price2num('21500.00'), 'Test 21500.00 give 21500 with french language'); + $this->assertEquals(21500, price2num('21500,00'), 'Test 21500,00 give 21500 with french language'); $langs = $oldlangs; From 817de18a5d9ad9f6d3c9fa3f7ae87f7a0e899e2e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 24 Nov 2020 12:25:32 +0100 Subject: [PATCH 028/137] Fix remove log --- htdocs/core/lib/functions.lib.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ef0703d635a..155b1d74a5f 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4721,11 +4721,10 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0) // Convert value to universal number format (no thousand separator, '.' as decimal separator) if ($alreadysqlnb != 1) { // If not a PHP number or unknown, we change or clean format - print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'
'; + //print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'
'; if ($thousand == '.' && preg_match('/\.(\d\d\d)$/', (string) $amount)) { // It means the . is used as a thousand separator, not as a decimal separator $amount = str_replace($thousand, '', $amount); // Replace of thousand before test of is_numeric to avoid pb if thousand is . and there is 3 numbers after - print 'TTTT'.$amount; } // Convert amount to format with dolibarr dec and thousand (this is because PHP convert a number // to format defined by LC_NUMERIC after a calculation and we want source format to be like defined by Dolibarr setup. From faa33f2d3c71526fc5e6fb8c27754c0340cb6b91 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 24 Nov 2020 12:52:39 +0100 Subject: [PATCH 029/137] FIX #15501 --- htdocs/product/list.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index efe63001349..d2f212df8da 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -57,7 +57,6 @@ $search_ref = GETPOST("search_ref", 'alpha'); $search_barcode = GETPOST("search_barcode", 'alpha'); $search_label = GETPOST("search_label", 'alpha'); $search_type = GETPOST("search_type", 'int'); -$search_sale = GETPOST("search_sale", 'int'); $search_vatrate = GETPOST("search_vatrate", 'alpha'); $searchCategoryProductOperator = (GETPOST('search_category_product_operator', 'int') ? GETPOST('search_category_product_operator', 'int') : 0); $searchCategoryProductList = GETPOST('search_category_product_list', 'array'); @@ -257,8 +256,8 @@ if (empty($reshook)) $searchCategoryProductList = array(); $search_tosell = ""; $search_tobuy = ""; - $search_vatrate = ""; $search_tobatch = ''; + $search_vatrate = ""; //$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 = ''; @@ -355,8 +354,9 @@ if (!empty($conf->variants->enabled) && (!empty($conf->global->PRODUIT_ATTRIBUTE 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); -if (isset($search_tosell) && dol_strlen($search_tosell) > 0 && $search_tosell != -1) $sql .= " AND p.tosell = ".$db->escape($search_tosell); -if (isset($search_tobuy) && dol_strlen($search_tobuy) > 0 && $search_tobuy != -1) $sql .= " AND p.tobuy = ".$db->escape($search_tobuy); +if (isset($search_tosell) && dol_strlen($search_tosell) > 0 && $search_tosell != -1) $sql .= " AND p.tosell = ".((int) $search_tosell); +if (isset($search_tobuy) && dol_strlen($search_tobuy) > 0 && $search_tobuy != -1) $sql .= " AND p.tobuy = ".((int) $search_tobuy); +if (isset($search_tobatch) && dol_strlen($search_tobatch) > 0 && $search_tobatch != -1) $sql .= " AND p.tobatch = ".((int) $search_tobatch); if ($search_vatrate) $sql .= natural_search('p.tva_tx', $search_vatrate); if (dol_strlen($canvas) > 0) $sql .= " AND p.canvas = '".$db->escape($canvas)."'"; if ($catid > 0) $sql .= " AND cp.fk_categorie = ".$catid; @@ -385,8 +385,7 @@ if ($searchCategoryProductOperator == 1) { $sql .= " AND (".implode(' AND ', $searchCategoryProductSqlList).")"; } } -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 ($fourn_id > 0) $sql .= " AND pfp.fk_soc = ".((int) $fourn_id); if ($search_accountancy_code_sell) $sql .= natural_search('p.accountancy_code_sell', $search_accountancy_code_sell); if ($search_accountancy_code_sell_intra) $sql .= natural_search('p.accountancy_code_sell_intra', $search_accountancy_code_sell_intra); if ($search_accountancy_code_sell_export) $sql .= natural_search('p.accountancy_code_sell_export', $search_accountancy_code_sell_export); @@ -485,14 +484,14 @@ if ($resql) if ($search_label) $param .= "&search_label=".urlencode($search_label); if ($search_tosell != '') $param .= "&search_tosell=".urlencode($search_tosell); if ($search_tobuy != '') $param .= "&search_tobuy=".urlencode($search_tobuy); - if ($search_vatrate) $sql .= natural_search('p.tva_tx', $search_vatrate); + if ($search_tobatch) $param = "&search_tobatch=".urlencode($search_tobatch); + if ($search_vatrate) $param = "&search_vatrate=".urlencode($search_vatrate); 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 ? "&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); - if ($search_tobatch) $param = "&search_ref_supplier=".urlencode($search_ref_supplier); if ($search_accountancy_code_sell) $param = "&search_accountancy_code_sell=".urlencode($search_accountancy_code_sell); if ($search_accountancy_code_sell_intra) $param = "&search_accountancy_code_sell_intra=".urlencode($search_accountancy_code_sell_intra); if ($search_accountancy_code_sell_export) $param = "&search_accountancy_code_sell_export=".urlencode($search_accountancy_code_sell_export); @@ -785,7 +784,7 @@ if ($resql) // Stock if (!empty($arrayfields['stock_virtual']['checked'])) print ' '; // To batch - if (!empty($arrayfields['p.tobatch']['checked'])) print ''.$form->selectyesno($search_tobatch, '', '', '', 1).''; + if (!empty($arrayfields['p.tobatch']['checked'])) print ''.$form->selectyesno('search_tobatch', $search_tobatch, 1, false, 1).''; // Accountancy code sell if (!empty($arrayfields['p.accountancy_code_sell']['checked'])) print ''; if (!empty($arrayfields['p.accountancy_code_sell_intra']['checked'])) print ''; From 7eec1155a05e77ce8feab8068341ec3b3d405df5 Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Tue, 24 Nov 2020 18:58:37 +0100 Subject: [PATCH 030/137] Fix issue #15506 tansfer line extrafield order to expedition --- htdocs/expedition/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index f2cb455cc6b..7614ba01df3 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1599,7 +1599,7 @@ if ($action == 'create') $srcLine = new OrderLine($db); $srcLine->id = $line->id; $srcLine->fetch_optionals(); // fetch extrafields also available in orderline - $line->array_options = array_merge($line->array_options, $srcLine->array_options); + $expLine->array_options = array_merge($line->array_options, $srcLine->array_options); print $expLine->showOptionals($extrafields, 'edit', array('style'=>'class="drag drop oddeven"', 'colspan'=>$colspan), $indiceAsked, '', 1); } From d17ecbeccda8265be541758e53e3886daa53f1f9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 24 Nov 2020 20:56:11 +0100 Subject: [PATCH 031/137] Fix #15438 --- .../modules/commande/doc/pdf_eratosthene.modules.php | 11 +++++++++++ .../core/modules/facture/doc/pdf_sponge.modules.php | 11 +++++++++++ htdocs/core/modules/propale/doc/pdf_cyan.modules.php | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php index 1910dd0c048..d936fd75a30 100644 --- a/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php @@ -1780,6 +1780,17 @@ class pdf_eratosthene extends ModelePDFCommandes 'border-left' => true, // add left line separator ); + // Adapt dynamically the width of subprice, if text is too long. + $tmpwidth = 0; + $nblines = count($object->lines); + for ($i = 0; $i < $nblines; $i++) { + $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails))); + $tmpwidth = max($tmpwidth, $tmpwidth2); + } + if ($tmpwidth > 10) { + $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10)); + } + $rank = $rank + 10; $this->cols['qty'] = array( 'rank' => $rank, diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 8f48f31fddb..94eeca2a8ab 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -2307,6 +2307,17 @@ class pdf_sponge extends ModelePDFFactures 'border-left' => true, // add left line separator ); + // Adapt dynamically the width of subprice, if text is too long. + $tmpwidth = 0; + $nblines = count($object->lines); + for ($i = 0; $i < $nblines; $i++) { + $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails))); + $tmpwidth = max($tmpwidth, $tmpwidth2); + } + if ($tmpwidth > 10) { + $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10)); + } + $rank = $rank + 10; $this->cols['qty'] = array( 'rank' => $rank, diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index 1af66ca645e..fce874d7bdf 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -1933,6 +1933,17 @@ class pdf_cyan extends ModelePDFPropales 'border-left' => true, // add left line separator ); + // Adapt dynamically the width of subprice, if text is too long. + $tmpwidth = 0; + $nblines = count($object->lines); + for ($i = 0; $i < $nblines; $i++) { + $tmpwidth2 = dol_strlen(dol_string_nohtmltag(pdf_getlineupexcltax($object, $i, $outputlangs, $hidedetails))); + $tmpwidth = max($tmpwidth, $tmpwidth2); + } + if ($tmpwidth > 10) { + $this->cols['subprice']['width'] += (2 * ($tmpwidth - 10)); + } + $rank = $rank + 10; $this->cols['qty'] = array( 'rank' => $rank, From 9b1dbf8d2af2ce535f2c701bb0922595111cdad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?= Date: Tue, 24 Nov 2020 22:10:01 +0100 Subject: [PATCH 032/137] llx_accounting_account_fr.sql: Remove left over field data In commit 86d9622360b6682d9a75b1c9f9fa15dfa2e4805c, the `pcg_subtype` was removed from the inserted values. In commit a85dfaf71e7300d878af0b656de853e77b9bde92, values associated with this field were removed. However, at least two lines in the PCG99-BASE accounting accounts still had that field values. This led to errors when importing the PCG99-BASE accounts. This patch fixes the problem and the accounts can be imported successfully. --- htdocs/install/mysql/data/llx_accounting_account_fr.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/install/mysql/data/llx_accounting_account_fr.sql b/htdocs/install/mysql/data/llx_accounting_account_fr.sql index 34e8882609d..d49e509a5be 100644 --- a/htdocs/install/mysql/data/llx_accounting_account_fr.sql +++ b/htdocs/install/mysql/data/llx_accounting_account_fr.sql @@ -468,7 +468,7 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 413,'PCG99-BASE','INCOME', '754', '409', 'Ristournes perçues des coopératives (provenant des excédents)', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 414,'PCG99-BASE','INCOME', '755', '409', 'Quotes-parts de résultat sur opérations faites en commun', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 415,'PCG99-BASE','INCOME', '758', '409', 'Produits divers de gestion courante', 1); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 416,'PCG99-BASE','INCOME', 'FIN', '76','1507', 'Produits financiers', 1); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 416,'PCG99-BASE','INCOME', '76','1507', 'Produits financiers', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 417,'PCG99-BASE','INCOME', '761', '416', 'Produits de participations', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 418,'PCG99-BASE','INCOME', '762', '416', 'Produits des autres immobilisations financières', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 419,'PCG99-BASE','INCOME', '763', '416', 'Revenus des autres créances', 1); @@ -476,7 +476,7 @@ INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, acc INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 421,'PCG99-BASE','INCOME', '765', '416', 'Escomptes obtenus', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 422,'PCG99-BASE','INCOME', '766', '416', 'Gains de change', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 423,'PCG99-BASE','INCOME', '767', '416', 'Produits nets sur cessions de valeurs mobilières de placement', 1); -INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 424,'PCG99-BASE','INCOME', 'FIN', '768', '416', 'Autres produits financiers', 1); +INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 424,'PCG99-BASE','INCOME', '768', '416', 'Autres produits financiers', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 425,'PCG99-BASE','INCOME', '77','1507', 'Produits exceptionnels', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 426,'PCG99-BASE','INCOME', '771', '425', 'Produits exceptionnels sur opérations de gestion', 1); INSERT INTO llx_accounting_account (entity, rowid, fk_pcg_version, pcg_type, account_number, account_parent, label, active) VALUES (__ENTITY__, 427,'PCG99-BASE','INCOME', '772', '425', '(Compte à la disposition des entités pour enregistrer, en cours d''exercice, les produits sur exercices antérieurs)', 1); From a734e1caa7e59722dcea810164962784311c3ee6 Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Wed, 25 Nov 2020 15:06:07 +0100 Subject: [PATCH 033/137] line is order line not exp line --- htdocs/expedition/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 7614ba01df3..12a5e5747b3 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1599,7 +1599,7 @@ if ($action == 'create') $srcLine = new OrderLine($db); $srcLine->id = $line->id; $srcLine->fetch_optionals(); // fetch extrafields also available in orderline - $expLine->array_options = array_merge($line->array_options, $srcLine->array_options); + $expLine->array_options = array_merge($expLine->array_options, $srcLine->array_options); print $expLine->showOptionals($extrafields, 'edit', array('style'=>'class="drag drop oddeven"', 'colspan'=>$colspan), $indiceAsked, '', 1); } From 551256b77936fc4d24b5f3b7fd93c91603ae1eb0 Mon Sep 17 00:00:00 2001 From: Muhammad Aboelfotoh <> Date: Wed, 25 Nov 2020 15:11:09 +0000 Subject: [PATCH 034/137] FIX #13067 including opening balance in calculation of displayed balance --- htdocs/accountancy/bookkeeping/balance.php | 30 ++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 456da29d954..ef19a6ae330 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -265,10 +265,16 @@ if ($action != 'export_csv') $total_credit = 0; $sous_total_debit = 0; $sous_total_credit = 0; + $total_opening_balance = 0; + $sous_total_opening_balance = 0; $displayed_account = ""; - $sql = "select t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance from ".MAIN_DB_PREFIX."accounting_bookkeeping as t where entity in ".$conf->entity; - $sql .= " AND t.doc_date < '".$db->idate($search_date_start)."' GROUP BY t.numero_compte"; + $sql = "SELECT t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance"; + $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as t"; + $sql .= " WHERE t.entity = ".$conf->entity; // Never do sharing into accounting features + $sql .= " AND t.doc_date < '".$db->idate($search_date_start)."'"; + $sql .= " GROUP BY t.numero_compte"; + $resql = $db->query($sql); $nrows = $resql->num_rows; $opening_balances = array(); @@ -284,17 +290,19 @@ if ($action != 'export_csv') $total_credit += $line->credit; $description = $object->get_compte_desc($line->numero_compte); // Search description of the account $root_account_description = $object->get_compte_racine($line->numero_compte); + $opening_balance = isset($opening_balances["'".$line->numero_compte."'"]) ? $opening_balances["'".$line->numero_compte."'"] : 0; + $total_opening_balance += $opening_balance; if (empty($description)) { $link = ''.img_edit_add().''; } print ''; - // Permet d'afficher le compte comptable + // Display the accounting account if (empty($displayed_account) || $root_account_description != $displayed_account) { - // Affiche un Sous-Total par compte comptable + // Display a sub-total per account if ($displayed_account != "") { - print ''.$langs->trans("SubTotal").':'.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_credit - $sous_total_debit)).''; + print ''.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_credit - $sous_total_debit)).''; print " \n"; print ''; } @@ -307,30 +315,32 @@ if ($action != 'export_csv') $displayed_account = $root_account_description; $sous_total_debit = 0; $sous_total_credit = 0; + $sous_total_opening_balance = 0; } // $object->get_compte_racine($line->numero_compte); print ''.length_accountg($line->numero_compte).''; print ''.$description.''; - print ''.price($opening_balances["'".$line->numero_compte."'"]).''; + print ''.price($opening_balance).''; print ''.price($line->debit).''; print ''.price($line->credit).''; - print ''.price($line->debit - $line->credit).''; + print ''.price($opening_balance + $line->debit - $line->credit).''; print ''.$link; print ''; print "\n"; - // Comptabilise le sous-total + // Records the sub-total $sous_total_debit += $line->debit; $sous_total_credit += $line->credit; + $sous_total_opening_balance += $opening_balance; } - print ''.$langs->trans("SubTotal").':'.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_debit - $sous_total_credit)).''; + print ''.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit)).''; print " \n"; print ''; - print ''.$langs->trans("AccountBalance").':'.price($total_debit).''.price($total_credit).''.price(price2num($total_debit - $total_credit)).''; + print ''.$langs->trans("AccountBalance").':'.price($total_opening_balance).''.price($total_debit).''.price($total_credit).''.price(price2num($total_opening_balance + $total_debit - $total_credit)).''; print " \n"; print ''; From 16e3baeff2e7851e1f92a5ddcd8d843e9da82e75 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 25 Nov 2020 17:28:53 +0100 Subject: [PATCH 035/137] FIX filter on project list --- htdocs/core/menus/standard/eldy.lib.php | 2 +- htdocs/projet/list.php | 41 +++++++++++++------------ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index e07bbcac70e..0f85d824ca2 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -1733,7 +1733,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM elseif ($conf->global->PROJECT_USE_OPPORTUNITIES == 1) { $newmenu->add("/projet/list.php?leftmenu=projets".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("List"), 1, $showmode, '', 'project', 'list'); - $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_usage_opportunity=1&search_status=99&contextpage=lead', $langs->trans("ListOpenLeads"), 2, $showmode); + $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_usage_opportunity=1&search_status=99&search_opp_status=openedopp&contextpage=lead', $langs->trans("ListOpenLeads"), 2, $showmode); $newmenu->add('/projet/list.php?mainmenu=project&leftmenu=list&search_opp_status=notopenedopp&search_status=99&contextpage=project', $langs->trans("ListOpenProjects"), 2, $showmode); } elseif ($conf->global->PROJECT_USE_OPPORTUNITIES == 2) { // 2 = leads only diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 43d0e0b7f7f..2f58c782c24 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -402,28 +402,29 @@ $help_url = "EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"; llxHeader("", $title, $help_url); $param = ''; -if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.$contextpage; -if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.$limit; -if ($search_all != '') $param .= '&search_all='.$search_all; -if ($search_sday) $param .= '&search_sday='.$search_sday; -if ($search_smonth) $param .= '&search_smonth='.$search_smonth; -if ($search_syear) $param .= '&search_syear='.$search_syear; -if ($search_eday) $param .= '&search_eday='.$search_eday; -if ($search_emonth) $param .= '&search_emonth='.$search_emonth; -if ($search_eyear) $param .= '&search_eyear='.$search_eyear; -if ($socid) $param .= '&socid='.$socid; -if ($search_ref != '') $param .= '&search_ref='.$search_ref; -if ($search_label != '') $param .= '&search_label='.$search_label; -if ($search_societe != '') $param .= '&search_societe='.$search_societe; -if ($search_status >= 0) $param .= '&search_status='.$search_status; +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); +if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); +if ($search_all != '') $param .= '&search_all='.urlencode($search_all); +if ($search_sday) $param .= '&search_sday='.urlencode($search_sday); +if ($search_smonth) $param .= '&search_smonth='.urlencode($search_smonth); +if ($search_syear) $param .= '&search_syear='.urlencode($search_syear); +if ($search_eday) $param .= '&search_eday='.urlencode($search_eday); +if ($search_emonth) $param .= '&search_emonth='.urlencode($search_emonth); +if ($search_eyear) $param .= '&search_eyear='.urlencode($search_eyear); +if ($socid) $param .= '&socid='.urlencode($socid); +if ($search_categ) $param .= '&search_categ='.urlencode($search_categ); +if ($search_ref != '') $param .= '&search_ref='.urlencode($search_ref); +if ($search_label != '') $param .= '&search_label='.urlencode($search_label); +if ($search_societe != '') $param .= '&search_societe='.urlencode($search_societe); +if ($search_status >= 0) $param .= '&search_status='.urlencode($search_status); if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all', 'openedopp', 'notopenedopp', 'none'))) $param .= '&search_opp_status='.urlencode($search_opp_status); if ($search_opp_percent != '') $param .= '&search_opp_percent='.urlencode($search_opp_percent); -if ($search_public != '') $param .= '&search_public='.$search_public; -if ($search_project_user != '') $param .= '&search_project_user='.$search_project_user; -if ($search_sale > 0) $param .= '&search_sale='.$search_sale; -if ($search_opp_amount != '') $param .= '&search_opp_amount='.$search_opp_amount; -if ($search_budget_amount != '') $param .= '&search_budget_amount='.$search_budget_amount; -if ($optioncss != '') $param .= '&optioncss='.$optioncss; +if ($search_public != '') $param .= '&search_public='.urlencode($search_public); +if ($search_project_user != '') $param .= '&search_project_user='.urlencode($search_project_user); +if ($search_sale > 0) $param .= '&search_sale='.urlencode($search_sale); +if ($search_opp_amount != '') $param .= '&search_opp_amount='.urlencode($search_opp_amount); +if ($search_budget_amount != '') $param .= '&search_budget_amount='.urlencode($search_budget_amount); +if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss); // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; From bd780a8c5113a34ee49dc7c59bcdfa7d46216b56 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2020 15:29:18 +0100 Subject: [PATCH 036/137] FIX Warning on late purchase order delivery --- .travis.yml | 50 ++++--------------- .../class/fournisseur.commande.class.php | 2 +- 2 files changed, 12 insertions(+), 40 deletions(-) diff --git a/.travis.yml b/.travis.yml index 082847d8c30..3a89572148b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,53 +31,25 @@ addons: # We need pgloader for import mysql database into pgsql - pgloader -php: -- '5.6' -- '7.0' -- '7.1' -- '7.2' -- '7.3' -- '7.4' -- nightly - env: global: # Set to true for very verbose output - DEBUG=false - jobs: - # MariaDB overrides MySQL installation so it's not possible to test both yet - #- DB=mariadb - - DB=mysql - - DB=postgresql - # See https://docs.travis-ci.com/user/languages/php/#Apache-%2B-PHP - #- WS=apache - # See https://github.com/DracoBlue/travis-ci-nginx-php-fpm-test - #- WS=nginx jobs: fast_finish: true allow_failures: - php: nightly - # We exclude some combinations not usefull to save Travis CPU - exclude: - - php: '7.0' - env: DB=mysql - - php: '7.1' - env: DB=mysql - - php: '7.2' - env: DB=mysql - - php: '7.3' - env: DB=mysql - - php: '7.0' - env: DB=postgresql - - php: '7.1' - env: DB=postgresql - - php: '7.2' - env: DB=postgresql - - php: '7.3' - env: DB=postgresql - - php: nightly - env: DB=postgresql + include: + - if: type = push + php: '5.6' + env: DB=postgresql + - if: type = pull_request OR type = push + php: '7.4' + env: DB=mysql + - if: type = push AND branch = develop + php: nightly + env: DB=mysql notifications: email: @@ -110,8 +82,8 @@ install: echo "Updating Composer" rm $TRAVIS_BUILD_DIR/composer.json rm $TRAVIS_BUILD_DIR/composer.lock + composer -V composer self-update - # To have composer making parallel downloads composer -n init composer -n config vendor-dir htdocs/includes composer -n config -g vendor-dir htdocs/includes diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 21399b7d674..eb5a2e26de0 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3175,7 +3175,7 @@ class CommandeFournisseur extends CommonOrder if (empty($this->date_delivery) && !empty($this->date_livraison)) $this->date_delivery = $this->date_livraison; // For backward compatibility $now = dol_now(); - $date_to_test = empty($this->date_livraison) ? $this->date_commande : $this->date_livraison; + $date_to_test = empty($this->date_delivery) ? $this->date_commande : $this->date_delivery; return ($this->statut > 0 && $this->statut < 5) && $date_to_test && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay); } From dfa161ca3006af965fcc2a8ada30b7beee76ef80 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2020 16:19:45 +0100 Subject: [PATCH 037/137] Fix property --- scripts/members/sync_members_types_dolibarr2ldap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/members/sync_members_types_dolibarr2ldap.php b/scripts/members/sync_members_types_dolibarr2ldap.php index a07ec0a1ff3..682c2943368 100755 --- a/scripts/members/sync_members_types_dolibarr2ldap.php +++ b/scripts/members/sync_members_types_dolibarr2ldap.php @@ -85,7 +85,7 @@ if ($resql) { $membertype->id = $obj->rowid; $membertype->fetch($membertype->id); - print $langs->trans("UpdateMemberType")." rowid=".$membertype->id." ".$membertype - label; + print $langs->trans("UpdateMemberType")." rowid=".$membertype->id." ".$membertype->label; $oldobject = $membertype; From 22c2cfd9ecfce75f62827f59b92db2c1e8cf999b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2020 16:57:39 +0100 Subject: [PATCH 038/137] FIX warning for purchase order delivery late. --- htdocs/fourn/class/fournisseur.commande.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index eb5a2e26de0..a95ef1bc7c7 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3016,7 +3016,8 @@ class CommandeFournisseur extends CommonOrder { $response->nbtodo++; - $commandestatic->date_livraison = $this->db->jdate($obj->delivery_date); + $commandestatic->date_livraison = $this->db->jdate($obj->delivery_date); // deprecated + $commandestatic->date_delivery = $this->db->jdate($obj->delivery_date); $commandestatic->date_commande = $this->db->jdate($obj->date_commande); $commandestatic->statut = $obj->fk_statut; From b043442b91db3da57ff84cf7a0ccb27531ec0b70 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2020 17:53:57 +0100 Subject: [PATCH 039/137] Fix link and selection of status of purchase order. --- htdocs/core/class/html.formorder.class.php | 5 ++- htdocs/fourn/commande/list.php | 39 ++++++++++------------ 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/htdocs/core/class/html.formorder.class.php b/htdocs/core/class/html.formorder.class.php index d3dbe27ceac..32fd279b8e1 100644 --- a/htdocs/core/class/html.formorder.class.php +++ b/htdocs/core/class/html.formorder.class.php @@ -62,7 +62,10 @@ class FormOrder extends Form $options[$value] = $tmpsupplierorder->getLibStatut($short); } - print Form::selectarray($hmlname, $options, $selected, 1); + if (is_array($selected)) $selectedarray = $selected; + else $selectedarray = explode(',', $selected); + + print Form::multiselectarray($hmlname, $options, $selectedarray, 0); } /** diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index c21e7ee4999..00b620a201b 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -73,7 +73,6 @@ $search_user = GETPOST('search_user', 'int'); $search_request_author = GETPOST('search_request_author', 'alpha'); $search_ht = GETPOST('search_ht', 'alpha'); $search_ttc = GETPOST('search_ttc', 'alpha'); -$search_status = (GETPOST('search_status', 'alpha') != '' ?GETPOST('search_status', 'alpha') : GETPOST('statut', 'alpha')); // alpha and not intbecause it can be '6,7' $optioncss = GETPOST('optioncss', 'alpha'); $socid = GETPOST('socid', 'int'); $search_sale = GETPOST('search_sale', 'int'); @@ -91,8 +90,11 @@ $search_project_ref = GETPOST('search_project_ref', 'alpha'); $search_btn = GETPOST('button_search', 'alpha'); $search_remove_btn = GETPOST('button_removefilter', 'alpha'); -$status = GETPOST('statut', 'alpha'); -$search_status = GETPOST('search_status'); +if (is_array(GETPOST('search_status', 'intcomma'))) { + $search_status = join(',', GETPOST('search_status', 'intcomma')); +} else { + $search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : GETPOST('statut', 'intcomma')); +} // Security check $orderid = GETPOST('orderid', 'int'); @@ -173,6 +175,7 @@ if (is_array($extrafields->attributes[$object->table_element]['label']) && count $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); +$error = 0; /* @@ -475,18 +478,21 @@ $formorder = new FormOrder($db); $formother = new FormOther($db); $formcompany = new FormCompany($db); -$title = $langs->trans("SuppliersOrders"); +$title = $langs->trans("ListOfSupplierOrders"); if ($socid > 0) { $fourn = new Fournisseur($db); $fourn->fetch($socid); $title .= ' - '.$fourn->name; } -if ($status) + +if ($search_status) { - if ($status == '1,2,3') $title .= ' - '.$langs->trans("StatusOrderToProcessShort"); - if ($status == '6,7') $title .= ' - '.$langs->trans("StatusOrderCanceled"); - else $title .= ' - '.$commandestatic->LibStatut($status); + if ($search_status == '1,2') $title .= ' - '.$langs->trans("SuppliersOrdersToProcess"); + elseif ($search_status == '3,4') $title .= ' - '.$langs->trans("SuppliersOrdersAwaitingReception"); + elseif ($search_status == '1,2,3') $title .= ' - '.$langs->trans("StatusOrderToProcessShort"); + elseif ($search_status == '6,7') $title .= ' - '.$langs->trans("StatusOrderCanceled"); + elseif(is_numeric($search_status)) $title .= ' - '.$commandestatic->LibStatut($search_status); } if ($search_billed > 0) $title .= ' - '.$langs->trans("Billed"); @@ -544,7 +550,7 @@ if ($search_product_category > 0) $sql .= " AND cp.fk_categorie = ".$search_prod //Required triple check because statut=0 means draft filter if (GETPOST('statut', 'intcomma') !== '') $sql .= " AND cf.fk_statut IN (".$db->escape($db->escape(GETPOST('statut', 'intcomma'))).")"; -if ($search_status != '' && $search_status >= 0) +if ($search_status != '' && $search_status != '-1') $sql .= " AND cf.fk_statut IN (".$db->escape($search_status).")"; $sql .= dolSqlDateFilter("cf.date_commande", $search_orderday, $search_ordermonth, $search_orderyear); $sql .= dolSqlDateFilter("cf.date_livraison", $search_deliveryday, $search_deliverymonth, $search_deliveryyear); @@ -591,17 +597,6 @@ $sql .= $db->plimit($limit + 1, $offset); $resql = $db->query($sql); if ($resql) { - if ($socid > 0) - { - $soc = new Societe($db); - $soc->fetch($socid); - $title = $langs->trans('ListOfSupplierOrders').' - '.$soc->name; - } - else - { - $title = $langs->trans('ListOfSupplierOrders'); - } - $num = $db->num_rows($resql); $arrayofselected = is_array($toselect) ? $toselect : array(); @@ -640,7 +635,7 @@ if ($resql) if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat); if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc); if ($search_refsupp) $param .= "&search_refsupp=".urlencode($search_refsupp); - if ($search_status >= 0) $param .= "&search_status=".urlencode($search_status); + if ($search_status != '' && $search_status != '-1') $param .= "&search_status=".urlencode($search_status); if ($search_project_ref >= 0) $param .= "&search_project_ref=".urlencode($search_project_ref); if ($search_billed != '') $param .= "&search_billed=".urlencode($search_billed); if ($show_files) $param .= '&show_files='.urlencode($show_files); @@ -927,7 +922,7 @@ if ($resql) if (!empty($arrayfields['cf.fk_statut']['checked'])) { print ''; - $formorder->selectSupplierOrderStatus((strstr($search_status, ',') ?-1 : $search_status), 1, 'search_status'); + $formorder->selectSupplierOrderStatus($search_status, 1, 'search_status'); print ''; } // Status billed From 4da44995691d3499124ca94760c7b4b46b85c1fb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 26 Nov 2020 23:05:49 +0100 Subject: [PATCH 040/137] FIX Param joinfiles not sanitized Conflicts: htdocs/admin/mails_templates.php --- htdocs/admin/mails_templates.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index a26e0801238..ef251846d99 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -280,7 +280,7 @@ if (empty($reshook)) elseif ($keycode == 'content') { $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; } - elseif (in_array($keycode, array('joinfile', 'private', 'position', 'scale'))) { + elseif (in_array($keycode, array('joinfiles', 'private', 'position', 'scale'))) { $sql .= (int) GETPOST($keycode, 'int'); } else { From 6de24e0c2e8b7ba734e288a0d8f4d8e1314cc657 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 00:19:45 +0100 Subject: [PATCH 041/137] Reduce travis load for v12 --- .travis.yml | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3a89572148b..edd7582b1e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ # We use dist: xenial to have php 5.6+ available os: linux dist: xenial -sudo: required +#dist: bionic language: php @@ -115,6 +115,9 @@ install: - | echo "Adding path of binaries tools installed by composer to the PATH" export PATH="$TRAVIS_BUILD_DIR/htdocs/includes/bin:$PATH" + echo $PATH + ls $TRAVIS_BUILD_DIR/vendor + ls $TRAVIS_BUILD_DIR/htdocs/includes/bin echo @@ -141,15 +144,20 @@ before_script: - | echo "Versions information" + echo # Check PHP echo "PHP version" php -i | head - - # Check PHP CodeSniffer installation + # Check Parallel-lint version + echo "Parallel-lint version" + which parallel-lint + parallel-lint -V + # Check PHP CodeSniffer version echo "PHPCS version" which phpcs phpcs --version | head - phpcs -i | head - - # Check PHPUnit installation + # Check PHPUnit version echo "PHPUnit version" which phpunit phpunit --version | head - @@ -254,17 +262,18 @@ script: # Ensure we catch errors set -e #parallel-lint --exclude htdocs/includes --blame . - parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/ --exclude htdocs/includes/composer/autoload_static.php --blame . + parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/composer --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/ --exclude htdocs/includes/composer/autoload_static.php --blame . set +e echo - | - echo "Checking coding style (excluding Pull Requests builds)" + echo "Checking coding style (excluding Pull Requests builds to not overload travis, excluding also some jobs to avoid duplicate tests)" # Ensure we catch errors 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 . - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; fi + if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4" ] && [ "$DB" = "mysql" ]; then + phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; + fi set +e echo @@ -376,6 +385,7 @@ script: php upgrade.php 11.0.0 12.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade11001200.log php upgrade2.php 11.0.0 12.0.0 > $TRAVIS_BUILD_DIR/upgrade11001200-2.log php step5.php 11.0.0 12.0.0 > $TRAVIS_BUILD_DIR/upgrade11001200-3.log + # Enable modules not enabled into original dump php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_API,MAIN_MODULE_SUPPLIERPROPOSAL,MAIN_MODULE_WEBSITE,MAIN_MODULE_TICKETSUP,MAIN_MODULE_ACCOUNTING > $TRAVIS_BUILD_DIR/enablemodule.log echo $? @@ -396,7 +406,7 @@ script: after_script: - | - echo "After script - Output lines of dolibarr.log" + echo "After script - Output last lines of dolibarr.log" ls $TRAVIS_BUILD_DIR/documents #cat $TRAVIS_BUILD_DIR/documents/dolibarr.log sudo tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log From 26f07992a96694d66cb47c794a825874d8b2e243 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 00:27:52 +0100 Subject: [PATCH 042/137] Reduce travis load for v11 --- .travis.yml | 86 +++++++++++++++++------------------------------------ 1 file changed, 28 insertions(+), 58 deletions(-) diff --git a/.travis.yml b/.travis.yml index bd0fd6f1fb8..1002216b7cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,13 +5,15 @@ # We use dist: trusty to have php 5.4+ available os: linux dist: trusty -sudo: required +#sudo: required language: php # Start on every boot services: - memcached +- mysql +- postgresql addons: mariadb: '10.0' @@ -29,60 +31,25 @@ addons: # We need pgloader for import mysql database into pgsql - pgloader -php: -- '5.5' -- '5.6' -- '7.0' -- '7.1' -- '7.2' -- '7.3' -- '7.4' -- nightly - env: global: # Set to true for very verbose output - DEBUG=false - jobs: - # MariaDB overrides MySQL installation so it's not possible to test both yet - #- DB=mysql - - DB=mariadb - - DB=postgresql - # TODO - #- DB=sqlite - # See https://docs.travis-ci.com/user/languages/php/#Apache-%2B-PHP - #- WS=apache - # See https://github.com/DracoBlue/travis-ci-nginx-php-fpm-test - #- WS=nginx jobs: fast_finish: true allow_failures: - php: nightly - # We exclude some combinations not usefull to save Travis CPU - exclude: - - php: '5.6' - env: DB=mariadb - - php: '7.0' - env: DB=mariadb - - php: '7.1' - env: DB=mariadb - - php: '7.2' - env: DB=mariadb - - php: '7.3' - env: DB=mariadb - - php: '5.6' - env: DB=postgresql - - php: '7.0' - env: DB=postgresql - - php: '7.1' - env: DB=postgresql - - php: '7.2' - env: DB=postgresql - - php: '7.3' - env: DB=postgresql - - php: nightly - env: DB=postgresql + include: + - if: type = push + php: '5.5' + env: DB=postgresql + - if: type = pull_request OR type = push + php: '7.4' + env: DB=mysql + - if: type = push AND branch = develop + php: nightly + env: DB=mysql notifications: email: @@ -115,6 +82,7 @@ install: echo "Updating Composer" rm $TRAVIS_BUILD_DIR/composer.json rm $TRAVIS_BUILD_DIR/composer.lock + composer -V composer self-update # To have composer making parallel downloads composer global require hirak/prestissimo @@ -149,6 +117,9 @@ install: - | echo "Adding path of binaries tools installed by composer to the PATH" export PATH="$TRAVIS_BUILD_DIR/htdocs/includes/bin:$PATH" + echo $PATH + ls $TRAVIS_BUILD_DIR/vendor + ls $TRAVIS_BUILD_DIR/htdocs/includes/bin echo @@ -175,15 +146,16 @@ before_script: - | echo "Versions information" + echo # Check PHP echo "PHP version" php -i | head - - # Check PHP CodeSniffer installation + # Check PHP CodeSniffer version echo "PHPCS version" which phpcs phpcs --version | head - phpcs -i | head - - # Check PHPUnit installation + # Check PHPUnit version echo "PHPUnit version" which phpunit phpunit --version | head - @@ -264,10 +236,7 @@ before_script: - sudo sed -i -e "s,www-data,travis,g" /etc/apache2/envvars - sudo chown -R travis:travis /var/lib/apache2/fastcgi - ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm - # configure apache virtual hosts for precise - #- sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/default - #- sudo cat /etc/apache2/sites-available/default - # configure apache virtual hosts for trusty + # configure apache virtual hosts - sudo cp -f build/travis-ci/apache.conf /etc/apache2/sites-available/000-default.conf - sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/000-default.conf - sudo cat /etc/apache2/sites-available/000-default.conf @@ -292,17 +261,18 @@ script: # Ensure we catch errors set -e #parallel-lint --exclude htdocs/includes --blame . - parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer/tests --exclude htdocs/includes/jakub-onderka/php-parallel-lint/tests --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/php-token-stream/tests --exclude htdocs/includes/composer/autoload_static.php --blame . + parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/composer --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer/tests --exclude htdocs/includes/jakub-onderka/php-parallel-lint/tests --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/php-token-stream/tests --exclude htdocs/includes/composer/autoload_static.php --blame . set +e echo - | - echo "Checking coding style (excluding Pull Requests builds)" + echo "Checking coding style (excluding Pull Requests builds to not overload travis, excluding also some jobs to avoid duplicate tests)" # Ensure we catch errors 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 . - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; fi + if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4" ]; then + phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; + fi set +e echo @@ -431,7 +401,7 @@ script: after_script: - | - echo "After script - Output lines of dolibarr.log" + echo "After script - Output last lines of dolibarr.log" ls $TRAVIS_BUILD_DIR/documents #cat $TRAVIS_BUILD_DIR/documents/dolibarr.log sudo tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log @@ -457,7 +427,7 @@ after_failure: # Dolibarr log file echo "Debugging informations for file dolibarr.log (latest 50 lines)" tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log - # MariaDB log file + # Database log file echo "Debugging informations for file mysql error.log" sudo tail -n 50 /var/log/mysql/error.log # TODO: PostgreSQL log file From ac3c12973559b3c3cb5f5e356dd9fa00ce50f1c8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 14:24:15 +0100 Subject: [PATCH 043/137] Clean code --- htdocs/accountancy/bookkeeping/balance.php | 4 +-- htdocs/adherents/class/subscription.class.php | 7 ++++- htdocs/categories/edit.php | 4 +-- htdocs/commande/class/commande.class.php | 1 + htdocs/compta/bank/card.php | 2 +- htdocs/compta/bank/categ.php | 2 +- htdocs/compta/facture/class/facture.class.php | 1 + htdocs/contrat/class/contrat.class.php | 2 +- htdocs/core/boxes/box_task.php | 2 +- .../core/class/commondocgenerator.class.php | 2 +- htdocs/core/lib/functions.lib.php | 27 ++++++++++--------- htdocs/core/lib/price.lib.php | 8 ++++-- htdocs/core/lib/project.lib.php | 10 +++---- .../class/expensereport.class.php | 6 ++--- htdocs/fichinter/class/fichinterrec.class.php | 1 - .../class/fournisseur.commande.class.php | 11 +++----- .../fourn/class/fournisseur.facture.class.php | 6 ++--- htdocs/main.inc.php | 2 +- htdocs/product/price.php | 9 ++++--- htdocs/projet/tasks/time.php | 8 +++--- htdocs/reception/card.php | 2 +- htdocs/societe/class/societe.class.php | 2 +- test/phpunit/FunctionsLibTest.php | 19 ++++++++++--- 23 files changed, 78 insertions(+), 60 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index ef19a6ae330..29e56cd4233 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -336,11 +336,11 @@ if ($action != 'export_csv') $sous_total_opening_balance += $opening_balance; } - print ''.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit)).''; + print ''.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit, 'MT')).''; print " \n"; print ''; - print ''.$langs->trans("AccountBalance").':'.price($total_opening_balance).''.price($total_debit).''.price($total_credit).''.price(price2num($total_opening_balance + $total_debit - $total_credit)).''; + print ''.$langs->trans("AccountBalance").':'.price($total_opening_balance).''.price($total_debit).''.price($total_credit).''.price(price2num($total_opening_balance + $total_debit - $total_credit, 'MT')).''; print " \n"; print ''; diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php index e512e1152bb..6e96ac64d2c 100644 --- a/htdocs/adherents/class/subscription.class.php +++ b/htdocs/adherents/class/subscription.class.php @@ -257,13 +257,18 @@ class Subscription extends CommonObject { $error = 0; + if (!is_numeric($this->amount)) { + $this->error = 'BadValueForParameterAmount'; + return -1; + } + $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."subscription SET "; $sql .= " fk_type = ".$this->fk_type.","; $sql .= " fk_adherent = ".$this->fk_adherent.","; $sql .= " note=".($this->note ? "'".$this->db->escape($this->note)."'" : 'null').","; - $sql .= " subscription = '".price2num($this->amount)."',"; + $sql .= " subscription = ".price2num($this->amount).","; $sql .= " dateadh='".$this->db->idate($this->dateh)."',"; $sql .= " datef='".$this->db->idate($this->datef)."',"; $sql .= " datec='".$this->db->idate($this->datec)."',"; diff --git a/htdocs/categories/edit.php b/htdocs/categories/edit.php index 48bd82b9326..cd8a718279e 100644 --- a/htdocs/categories/edit.php +++ b/htdocs/categories/edit.php @@ -157,7 +157,7 @@ print ''; // Description print ''; print ''.$langs->trans("Description").''; -print ''; +print ''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor = new DolEditor('description', $object->description, '', 200, 'dolibarr_notes', '', false, true, $conf->fckeditor->enabled, ROWS_6, '90%'); $doleditor->Create(); @@ -166,7 +166,7 @@ print ''; // Color print ''; print ''.$langs->trans("Color").''; -print ''; +print ''; print $formother->selectColor($object->color, 'color'); print ''; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index fbbd40265a1..5402d31ba7d 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3135,6 +3135,7 @@ class Commande extends CommonOrder // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $txtva, $reg)) { $vat_src_code = $reg[1]; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 593893878e0..1403ecc66b8 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -907,7 +907,7 @@ else print 'min_allowed).'">'; print ''.$langs->trans("BalanceMinimalDesired").''; - print 'min_desired).'">'; + print 'min_desired).'">'; // Web print ''.$langs->trans("Web").''; diff --git a/htdocs/compta/bank/categ.php b/htdocs/compta/bank/categ.php index 308dad5dbca..d24b49ce426 100644 --- a/htdocs/compta/bank/categ.php +++ b/htdocs/compta/bank/categ.php @@ -135,7 +135,7 @@ if ($result) } else { - print "".$objp->label.""; + print "".$objp->label.""; print ''; print ''.img_edit().''; print ''.img_delete().''; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 8a2c75037ba..4bfc36a3e78 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3326,6 +3326,7 @@ class Facture extends CommonInvoice // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $txtva, $reg)) { $vat_src_code = $reg[1]; diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 31730353ea1..e38c24565dd 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -1504,9 +1504,9 @@ class Contrat extends CommonObject } $txtva = price2num($txtva); - $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); + $remise_percent = price2num($remise_percent); $qty = price2num($qty); if (empty($qty)) $qty = 1; diff --git a/htdocs/core/boxes/box_task.php b/htdocs/core/boxes/box_task.php index 4239e6f1b28..b9c40a9098c 100644 --- a/htdocs/core/boxes/box_task.php +++ b/htdocs/core/boxes/box_task.php @@ -139,7 +139,7 @@ class box_task extends ModeleBoxes $boxcontent .= ''; } $this->info_box_contents[0][] = array( - 'tr'=>'class="nohover showiffilter'.$this->boxcode.' hideobject"', + 'tr' => 'class="nohover showiffilter'.$this->boxcode.' hideobject"', 'td' => 'class="nohover"', 'textnoformat' => $boxcontent, ); diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 2900a4cd173..90cfd84cf69 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -1347,7 +1347,7 @@ abstract class CommonDocGenerator if ($itemsInRow > 0) { // close table row and empty cols for ($i = $itemsInRow; $i <= $maxItemsInRow; $i++) { - $html .= ""; + $html .= ""; } $html .= ""; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 155b1d74a5f..24ec5645ffd 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4698,14 +4698,15 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $ * 'MS'=Round to Max for stock quantity (MAIN_MAX_DECIMALS_STOCK) * 'CR'=Currency rate * Numeric = Nb of digits for rounding - * @param int $alreadysqlnb Put 1 if you know that content is already universal format number + * @param int $option Put 1 if you know that content is already universal format number (so no correction on decimal will be done) + * Put 2 if you know that number is a user input (so we know we don't have to fix decimal separator). * @return string Amount with universal numeric format (Example: '99.99999'). * If conversion fails, it return text unchanged if $rounding = '' or '0' if $rounding is defined. * If amount is null or '', it returns '' if $rounding = '' or '0' if $rounding is defined.. * * @see price() Opposite function of price2num */ -function price2num($amount, $rounding = '', $alreadysqlnb = 0) +function price2num($amount, $rounding = '', $option = 0) { global $langs, $conf; @@ -4720,14 +4721,16 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0) //print "amount=".$amount." html=".$form." trunc=".$trunc." nbdecimal=".$nbdecimal." dec='".$dec."' thousand='".$thousand."'
"; // Convert value to universal number format (no thousand separator, '.' as decimal separator) - if ($alreadysqlnb != 1) { // If not a PHP number or unknown, we change or clean format + if ($option != 1) { // If not a PHP number or unknown, we change or clean format //print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'
'; - if ($thousand == '.' && preg_match('/\.(\d\d\d)$/', (string) $amount)) { // It means the . is used as a thousand separator, not as a decimal separator - $amount = str_replace($thousand, '', $amount); // Replace of thousand before test of is_numeric to avoid pb if thousand is . and there is 3 numbers after + if ($option == 2 && $thousand == '.' && preg_match('/\.(\d\d\d)$/', (string) $amount)) { // It means the . is used as a thousand separator and string come frominput data, so 1.123 is 1123 + $amount = str_replace($thousand, '', $amount); } + // Convert amount to format with dolibarr dec and thousand (this is because PHP convert a number // to format defined by LC_NUMERIC after a calculation and we want source format to be like defined by Dolibarr setup. + // So if number was already a good number, it is converted into local Dolibarr setup. if (is_numeric($amount)) { // We put in temps value of decimal ("0.00001"). Works with 0 and 2.0E-5 and 9999.10 @@ -4736,7 +4739,7 @@ function price2num($amount, $rounding = '', $alreadysqlnb = 0) $nbofdec = max(0, dol_strlen($temps) - 2); // -2 to remove "0." $amount = number_format($amount, $nbofdec, $dec, $thousand); } - //print "QQ".$amount.'
'; + //print "QQ".$amount."
\n"; // Now make replace (the main goal of function) if ($thousand != ',' && $thousand != '.') { @@ -4960,10 +4963,10 @@ function get_localtax($vatrate, $local, $thirdparty_buyer = "", $thirdparty_sell // By default, search value of local tax on line of common tax $sql = "SELECT t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; - $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$thirdparty_seller->country_code."'"; + $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($thirdparty_seller->country_code)."'"; $sql .= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1"; - if ($vatratecode) $sql .= " AND t.code ='".$vatratecode."'"; // If we have the code, we use it in priority - else $sql .= " AND t.recuperableonly ='".$vatnpr."'"; + if ($vatratecode) $sql .= " AND t.code ='".$db->escape($vatratecode)."'"; // If we have the code, we use it in priority + else $sql .= " AND t.recuperableonly ='".$db->escape($vatnpr)."'"; dol_syslog("get_localtax", LOG_DEBUG); $resql = $db->query($sql); @@ -5119,10 +5122,10 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi } $sql .= ", ".MAIN_DB_PREFIX."c_country as c"; - if ($mysoc->country_code == 'ES') $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$buyer->country_code."'"; // local tax in spain use the buyer country ?? - else $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$seller->country_code."'"; + if ($mysoc->country_code == 'ES') $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($buyer->country_code)."'"; // local tax in spain use the buyer country ?? + else $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$db->escape($seller->country_code)."'"; $sql .= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1"; - if ($vatratecode) $sql .= " AND t.code = '".$vatratecode."'"; + if ($vatratecode) $sql .= " AND t.code = '".$db->escape($vatratecode)."'"; } $resql = $db->query($sql); diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index 2cb8d8e30f6..dfb5f4ffaf1 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -103,10 +103,14 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt $seller = $mysoc; // If sell is done to a customer, $seller is not provided, we use $mysoc //var_dump($seller->country_id);exit; } - if (empty($localtaxes_array) || !is_array($localtaxes_array)) - { + if (empty($localtaxes_array) || !is_array($localtaxes_array)) { dol_syslog("Price.lib::calcul_price_total Warning: function is called with parameter localtaxes_array that is missing", LOG_WARNING); } + if (!is_numeric($txtva)) { + dol_syslog("Price.lib::calcul_price_total Warning: function was called with a parameter vat rate that is not a real numeric value. There is surely a bug.", LOG_ERR); + } elseif ($txtva >= 1000) { + dol_syslog("Price.lib::calcul_price_total Warning: function was called with a bad value for vat rate (should be often < 100, always < 1000). There is surely a bug.", LOG_ERR); + } // Too verbose. Enable for debug only //dol_syslog("Price.lib::calcul_price_total qty=".$qty." pu=".$pu." remiserpercent_ligne=".$remise_percent_ligne." txtva=".$txtva." uselocaltax1_rate=".$uselocaltax1_rate." uselocaltax2_rate=".$uselocaltax2_rate.' remise_percent_global='.$remise_percent_global.' price_base_type='.$ice_base_type.' type='.$type.' progress='.$progress); diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index ac8530b4aa5..284ebb3ad37 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -2397,24 +2397,24 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide // this conf is actually hidden, by default we use 10% for "be carefull or warning" $warningRatio = !empty($conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT) ? (1 + $conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT / 100) : 1.10; - $diffTitle = '
'.$langs->trans('ProgressDeclared').' : '.$task->progress.($task->progress ? '%' : ''); - $diffTitle .= '
'.$langs->trans('ProgressCalculated').' : '.$progressCalculated.($progressCalculated ? '%' : ''); + $diffTitle = '
'.$langs->trans('ProgressDeclared').' : '.$task->progress.($task->progress ? '%' : ''); + $diffTitle .= '
'.$langs->trans('ProgressCalculated').' : '.$progressCalculated.($progressCalculated ? '%' : ''); //var_dump($progressCalculated.' '.$warningRatio.' '.$task->progress.' '.doubleval($task->progress * $warningRatio)); if (doubleval($progressCalculated) > doubleval($task->progress * $warningRatio)) { $progressBarClass = 'progress-bar-danger'; $title = $langs->trans('TheReportedProgressIsLessThanTheCalculatedProgressionByX', abs($task->progress - $progressCalculated).' '.$langs->trans("point")); - $diff = ' '.($task->progress - $progressCalculated).'%'; + $diff = ' '.($task->progress - $progressCalculated).'%'; } elseif (doubleval($progressCalculated) > doubleval($task->progress)) { // warning if close at 10% $progressBarClass = 'progress-bar-warning'; $title = $langs->trans('TheReportedProgressIsLessThanTheCalculatedProgressionByX', abs($task->progress - $progressCalculated).' '.$langs->trans("point")); - $diff = ' '.($task->progress - $progressCalculated).'%'; + $diff = ' '.($task->progress - $progressCalculated).'%'; } else { $progressBarClass = 'progress-bar-success'; $title = $langs->trans('TheReportedProgressIsMoreThanTheCalculatedProgressionByX', ($task->progress - $progressCalculated).' '.$langs->trans("point")); - $diff = ' '.($task->progress - $progressCalculated).'%'; + $diff = ' '.($task->progress - $progressCalculated).'%'; } } diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index c56a0ecae64..3c18805362f 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1801,6 +1801,7 @@ class ExpenseReport extends CommonObject $localtaxes_type = getLocalTaxesFromRate($vatrate, 0, $mysoc, $this->thirdparty); $vat_src_code = ''; + $reg = array(); if (preg_match('/\s*\((.*)\)/', $vatrate, $reg)) { $vat_src_code = $reg[1]; @@ -2046,6 +2047,7 @@ class ExpenseReport extends CommonObject // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $vatrate, $reg)) { $vat_src_code = $reg[1]; @@ -2060,10 +2062,6 @@ class ExpenseReport extends CommonObject $tx_tva = $vatrate / 100; $tx_tva = $tx_tva + 1; - $total_ht = price2num($total_ttc / $tx_tva, 'MT'); - - $total_tva = price2num($total_ttc - $total_ht, 'MT'); - // fin calculs $this->line = new ExpenseReportLine($this->db); $this->line->comments = $comments; diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index a09547b3164..5b3dfb3a2fc 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -481,7 +481,6 @@ class FichinterRec extends Fichinter $pu = $pu_ttc; } - // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index a95ef1bc7c7..dc3113f2554 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1776,8 +1776,6 @@ class CommandeFournisseur extends CommonOrder $localtax1_type = $localtaxes_type[0]; $localtax2_type = $localtaxes_type[2]; - $subprice = price2num($pu, 'MU'); - $rangmax = $this->line_max(); $rang = $rangmax + 1; @@ -2635,9 +2633,9 @@ class CommandeFournisseur extends CommonOrder if (!$qty) $qty = 1; $pu = price2num($pu); $pu_ht_devise = price2num($pu_ht_devise); - $txtva = price2num($txtva); - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); + $txtva = price2num($txtva); + $txlocaltax1 = price2num($txlocaltax1); + $txlocaltax2 = price2num($txlocaltax2); // Check parameters if ($type < 0) return -1; @@ -2658,6 +2656,7 @@ class CommandeFournisseur extends CommonOrder // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $txtva, $reg)) { $vat_src_code = $reg[1]; @@ -2683,8 +2682,6 @@ class CommandeFournisseur extends CommonOrder $localtax1_type = $localtaxes_type[0]; $localtax2_type = $localtaxes_type[2]; - $subprice = price2num($pu_ht, 'MU'); - //Fetch current line from the database and then clone the object and set it in $oldline property $this->line = new CommandeFournisseurLigne($this->db); $this->line->fetch($rowid); diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 952e609555d..72d040583b2 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1679,11 +1679,11 @@ class FactureFournisseur extends CommonInvoice $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); if (!preg_match('/\((.*)\)/', $txtva)) { $txtva = price2num($txtva); // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1' } + $txlocaltax1 = price2num($txlocaltax1); + $txlocaltax2 = price2num($txlocaltax2); if ($date_start && $date_end && $date_start > $date_end) { $langs->load("errors"); @@ -1939,8 +1939,6 @@ class FactureFournisseur extends CommonInvoice $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); - $localtaxes_type = array($txlocaltax1, $txlocaltax2); - // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 9b85e62880a..84c695d9978 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1705,7 +1705,7 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead } if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $text = ''.DOL_VERSION.''; + $text = ''.DOL_VERSION.''; $toprightmenu .= @Form::textwithtooltip('', $appli, 2, 1, $text, 'login_block_elem', 2); } diff --git a/htdocs/product/price.php b/htdocs/product/price.php index f93545ee19e..12029ea7cdc 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -110,6 +110,7 @@ if (empty($reshook)) // We must define tva_tx, npr and local taxes $tva_tx = $tva_tx_txt; $vatratecode = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) { $vat_src_code = $reg[1]; @@ -262,8 +263,8 @@ if (empty($reshook)) } $pricestoupdate[$i] = array( - 'price' => price2num($newprice[$i]), - 'price_min' => price2num($newprice_min[$i]), + 'price' => price2num($newprice[$i], '', 2), + 'price_min' => price2num($newprice_min[$i], '', 2), 'price_base_type' => $newpricebase[$i], 'default_vat_code' => $vatratecode, 'vat_tx' => $tva_tx, // default_vat_code should be used in priority in a future @@ -279,8 +280,8 @@ if (empty($reshook)) } elseif (!$error) { - $newprice = price2num(GETPOST('price', 'alpha')); - $newprice_min = price2num(GETPOST('price_min', 'alpha')); + $newprice = price2num(GETPOST('price', 'alpha'), '', 2); + $newprice_min = price2num(GETPOST('price_min', 'alpha'), '', 2); $newpricebase = GETPOST('price_base_type', 'alpha'); $tva_tx_txt = GETPOST('tva_tx', 'alpha'); // tva_tx can be '8.5' or '8.5*' or '8.5 (XXX)' or '8.5* (XXX)' diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 4a5d484abf8..b95f285c628 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1463,7 +1463,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) if (!empty($arrayfields['value']['checked'])) { print ''; - $value = price2num($task_time->thm * $task_time->task_duration / 3600); + $value = price2num($task_time->thm * $task_time->task_duration / 3600, 'MT', 1); print price($value, 1, $langs, 1, -1, -1, $conf->currency); print ''; if (!$i) $totalarray['nbfield']++; @@ -1680,7 +1680,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) if (!empty($arrayfields['value']['checked'])) { print ''; - $value = price2num($task_time->thm * $task_time->task_duration / 3600); + $value = price2num($task_time->thm * $task_time->task_duration / 3600, 'MT', 1); print price($value, 1, $langs, 1, -1, -1, $conf->currency); print ''; } @@ -1689,7 +1689,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) if (!empty($arrayfields['valuebilled']['checked'])) { print ''; - $valuebilled = price2num($task_time->total_ht); + $valuebilled = price2num($task_time->total_ht, '', 1); if (isset($task_time->total_ht)) print price($valuebilled, 1, $langs, 1, -1, -1, $conf->currency); print ''; } @@ -1837,7 +1837,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) if (!empty($arrayfields['valuebilled']['checked'])) { print ''; - $valuebilled = price2num($task_time->total_ht); + $valuebilled = price2num($task_time->total_ht, '', 1); if (isset($task_time->total_ht)) print price($valuebilled, 1, $langs, 1, -1, -1, $conf->currency); print ''; } diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 3d8547f9322..47a7af62bb0 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -1804,7 +1804,7 @@ elseif ($id || $ref) if ($action == 'editline' && $lines[$i]->id == $line_id) { - print ''; + print ''; } else { diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 30a90a884bd..ee91363dba1 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2077,7 +2077,7 @@ class Societe extends CommonObject $discount->amount_tva = $discount->multicurrency_amount_tva = price2num($remise * $vatrate / 100, 'MT'); $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num($discount->amount_ht + $discount->amount_tva, 'MT'); - $discount->tva_tx = price2num($vatrate, 'MT'); + $discount->tva_tx = price2num($vatrate); $discount->vat_src_code = $vat_src_code; $discount->description = $desc; diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 85937147cff..a987f28c7ed 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1262,16 +1262,24 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase // Test with 3 chars after . or , // If a . is used and there is 3 digits after, it is a thousand separator - $this->assertEquals(1234, price2num('1.234'), 'Test 1.234 give 1234 with spanish language'); + $this->assertEquals(1234, price2num('1.234', '', 2), 'Test 1.234 give 1234 with spanish language if user input'); + $this->assertEquals(1.234, price2num('1,234', '', 2), 'Test 1,234 give 1234 with spanish language if user input'); + $this->assertEquals(1234, price2num('1 234', '', 2), 'Test 1 234 give 1234 with spanish language if user input'); + $this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with spanish language'); + $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1234 with spanish language'); $this->assertEquals(1234, price2num('1 234'), 'Test 1 234 give 1234 with spanish language'); - $this->assertEquals(1234, price2num('1.234'), 'Test 1.234 give 1234 with spanish language'); - $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with spanish language'); $this->assertEquals(21500123, price2num('21.500.123'), 'Test 21.500.123 give 21500123 with spanish language'); - $this->assertEquals(21500123, price2num('21500.123'), 'Test 21500.123 give 21500123 with spanish language'); + $this->assertEquals(21500123, price2num('21500.123', 0, 2), 'Test 21500.123 give 21500123 with spanish language if user input'); + $this->assertEquals(21500.123, price2num('21500.123'), 'Test 21500.123 give 21500123 with spanish language'); $this->assertEquals(21500.123, price2num('21500,123'), 'Test 21500,123 give 21500.123 with spanish language'); // Test with 2 digits $this->assertEquals(21500.12, price2num('21500.12'), 'Test 21500.12 give 21500.12 with spanish language'); $this->assertEquals(21500.12, price2num('21500,12'), 'Test 21500,12 give 21500.12 with spanish language'); + // Test with 3 digits + $this->assertEquals(12123, price2num('12.123', '', 2), 'Test 12.123 give 12123 with spanish language if user input'); + $this->assertEquals(12.123, price2num('12,123', '', 2), 'Test 12,123 give 12.123 with spanish language if user input'); + $this->assertEquals(12.123, price2num('12.123'), 'Test 12.123 give 12.123 with spanish language'); + $this->assertEquals(12.123, price2num('12,123'), 'Test 12,123 give 12.123 with spanish language'); // For french language $newlangs3 = new Translate('', $conf); @@ -1279,9 +1287,12 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $newlangs3->load("main"); $langs = $newlangs3; + $this->assertEquals(1, price2num('1.000', '', 2), 'Test 1.000 give 1 with french language if user input'); $this->assertEquals(1, price2num('1.000'), 'Test 1.000 give 1 with french language'); $this->assertEquals(1000, price2num('1 000'), 'Test 1.000 give 1 with french language'); + $this->assertEquals(1.234, price2num('1.234', '', 2), 'Test 1.234 give 1.234 with french language if user input'); $this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with french language'); + $this->assertEquals(1.234, price2num('1,234', '', 2), 'Test 1,234 give 1.234 with french language if user input'); $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with french language'); $this->assertEquals(21500000, price2num('21500 000'), 'Test 21500 000 give 21500000 with french language'); $this->assertEquals(21500000, price2num('21 500 000'), 'Test 21 500 000 give 21500000 with french language'); From 4a5cdd00921b19b32945332aede507c31d479c01 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 15:27:35 +0100 Subject: [PATCH 044/137] Several fixes in export and repair tool --- htdocs/core/class/interfaces.class.php | 2 +- htdocs/core/modules/modBom.class.php | 1 + htdocs/core/modules/modCategorie.class.php | 50 +++------------------- htdocs/exports/class/export.class.php | 1 + htdocs/install/repair.php | 3 +- 5 files changed, 12 insertions(+), 45 deletions(-) diff --git a/htdocs/core/class/interfaces.class.php b/htdocs/core/class/interfaces.class.php index 4199e51cb68..3f542f845b9 100644 --- a/htdocs/core/class/interfaces.class.php +++ b/htdocs/core/class/interfaces.class.php @@ -212,7 +212,7 @@ class Interfaces if ($result < 0) { // Action KO - //dol_syslog("Error in trigger ".$action." - Nb of error string returned = ".count($objMod->errors), LOG_ERR); + //dol_syslog("Error in trigger ".$action." - result = ".$result." - Nb of error strings returned = ".count($objMod->errors), LOG_ERR); $nbtotal++; $nbko++; if (!empty($objMod->errors)) $this->errors = array_merge($this->errors, $objMod->errors); diff --git a/htdocs/core/modules/modBom.class.php b/htdocs/core/modules/modBom.class.php index 7258541a7da..062b89d218d 100644 --- a/htdocs/core/modules/modBom.class.php +++ b/htdocs/core/modules/modBom.class.php @@ -300,6 +300,7 @@ class modBom extends DolibarrModules $this->export_dependencies_array[$r] = array('bomline'=>'tl.rowid'); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields) $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'bom_bom as t'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bom_bom_extrafields as extra on (t.rowid = extra.fk_object)'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bom_bomline as tl ON tl.fk_bom = t.rowid'; $this->export_sql_end[$r] .= ' WHERE 1 = 1'; $this->export_sql_end[$r] .= ' AND t.entity IN ('.getEntity('bom').')'; diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index 4f0c1e04307..0ea473ed95b 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -176,56 +176,20 @@ class modCategorie extends DolibarrModules 's.idprof4'=>"company", 's.tva_intra'=>"company", 's.capital'=>"company", 's.note_public'=>"company", 's.fk_prospectlevel'=>'company', 's.fk_stcomm'=>'company' ); // We define here only fields that use another picto + + $keyforselect = 'societe'; $keyforelement = 'company'; $keyforaliasextra = 'extrasoc'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '; $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'categorie_societe as cf, '; - $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extra ON s.rowid = extra.fk_object '; + $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extrasoc ON s.rowid = extrasoc.fk_object '; $this->export_sql_end[$r] .= ' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid'; $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')'; $this->export_sql_end[$r] .= ' AND u.type = 2'; // Customer/Prospect categories - // Add extra fields - $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); - if ($resql) // This can fail when class is used on old database (during migration for example) - { - while ($obj = $this->db->fetch_object($resql)) - { - $fieldname = 'extra.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $typeFilter = "Text"; - switch ($obj->type) - { - case 'int': - case 'double': - case 'price': - $typeFilter = "Numeric"; - break; - case 'date': - case 'datetime': - $typeFilter = "Date"; - break; - case 'boolean': - $typeFilter = "Boolean"; - break; - case 'sellist': - $typeFilter = "List:".$obj->param; - break; - case 'select': - $typeFilter = "Select:".$obj->param; - break; - } - $this->export_fields_array[$r][$fieldname] = $fieldlabel; - $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; - $this->export_entities_array[$r][$fieldname] = 'company'; - } - } - // End add axtra fields - - - - - $r++; $this->export_code[$r] = 'category_'.$r; $this->export_label[$r] = 'CatProdList'; diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php index 978a3059ace..6b939dca247 100644 --- a/htdocs/exports/class/export.class.php +++ b/htdocs/exports/class/export.class.php @@ -102,6 +102,7 @@ class Export // Search module files while (($file = readdir($handle)) !== false) { + $reg = array(); if (is_readable($dir.$file) && preg_match("/^(mod.*)\.class\.php$/i", $file, $reg)) { $modulename = $reg[1]; diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index 034741c7c7e..e0402bb88a1 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -231,7 +231,7 @@ if ($ok && GETPOST('standard', 'alpha')) $listofmodulesextra = array('societe'=>'societe', 'adherent'=>'adherent', 'product'=>'product', 'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture', 'supplier_proposal'=>'supplier_proposal', 'commande_fournisseur'=>'commande_fournisseur', 'facture_fourn'=>'facture_fourn', - 'actioncomm'=>'actioncomm', + 'actioncomm'=>'actioncomm', 'bom_bom'=>'bom_bom', 'mrp_mo'=>'mrp_mo', 'adherent_type'=>'adherent_type', 'user'=>'user', 'projet'=>'projet', 'projet_task'=>'projet_task'); print '
*** Check fields into extra table structure match table of definition. If not add column into table'; foreach ($listofmodulesextra as $tablename => $elementtype) @@ -268,6 +268,7 @@ if ($ok && GETPOST('standard', 'alpha')) $arrayoffieldsfound[$fieldname] = array('type'=>$fieldtype); } + // If it does not match, we create fields foreach ($arrayoffieldsdesc as $code => $label) { From 5ed2bbb2047b9d921c3e2430be3f41c71e6d71dc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 16:13:27 +0100 Subject: [PATCH 045/137] Fix error message --- htdocs/expedition/card.php | 13 ++++--------- htdocs/product/stock/class/mouvementstock.class.php | 1 + 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 12a5e5747b3..289d317abb7 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -435,16 +435,11 @@ if (empty($reshook)) $result = $object->valid($user); - if ($result < 0) - { - $langs->load("errors"); - setEventMessages($langs->trans($object->error), $object->errors, 'errors'); - } - else - { + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } else { // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { + 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'); diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index ffc84f41e92..5c44019b1fc 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -204,6 +204,7 @@ class MouvementStock extends CommonObject { if (empty($batch)) { + $langs->load("errors"); $this->errors[] = $langs->transnoentitiesnoconv("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->ref); dol_syslog("Try to make a movement of a product with status_batch on without any batch data"); From df17c2f26adcee1a292fc3022bcaec90ee64cccc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 28 Nov 2020 16:48:32 +0100 Subject: [PATCH 046/137] Removed dead code generating warning. CSS --- htdocs/admin/system/phpinfo.php | 84 ++------------------------------- 1 file changed, 4 insertions(+), 80 deletions(-) diff --git a/htdocs/admin/system/phpinfo.php b/htdocs/admin/system/phpinfo.php index 3627daab7d9..c5d3e2d7b7e 100644 --- a/htdocs/admin/system/phpinfo.php +++ b/htdocs/admin/system/phpinfo.php @@ -137,7 +137,7 @@ print ''; print '
'; -$activatedExtensions = array_map('strtolower', getActivatedExtensions()); +$activatedExtensions = array(); $loadedExtensions = array_map('strtolower', get_loaded_extensions(false)); print ''; @@ -154,7 +154,6 @@ $name = "GD"; print ""; print ""; -//print getTableColumn($name, $activatedExtensions); print getTableColumn($name, $loadedExtensions); print getTableColumnFunction($functions); print getResultColumn($name, $activatedExtensions, $loadedExtensions, $functions); @@ -165,7 +164,6 @@ $name = "Curl"; print ""; print ""; -//print getTableColumn($name, $activatedExtensions); print getTableColumn($name, $loadedExtensions); print getTableColumnFunction($functions); print getResultColumn($name, $activatedExtensions, $loadedExtensions, $functions); @@ -178,7 +176,6 @@ if (empty($_SERVER["SERVER_ADMIN"]) || $_SERVER["SERVER_ADMIN"] != 'doliwamp@loc print ""; print ""; - //print getTableColumn($name, $activatedExtensions); print getTableColumn($name, $loadedExtensions); print getTableColumnFunction($functions); print getResultColumn($name, $activatedExtensions, $loadedExtensions, $functions); @@ -191,7 +188,6 @@ $name = "xDebug"; print ""; print ""; -//print getTableColumn($name, $activatedExtensions); print getTableColumn($name, $loadedExtensions); print getTableColumnFunction($functions); print getResultColumn($name, $activatedExtensions, $loadedExtensions, $functions); @@ -221,7 +217,7 @@ foreach ($phparray as $key => $value) print ''; $valtoshow = $keyvalue; if ($keyparam == 'X-ChromePhp-Data') $valtoshow = dol_trunc($keyvalue, 80); - print ''; - print ''; + print ''; $i = 0; foreach ($keyvalue as $keyparam2 => $keyvalue2) { @@ -256,78 +252,6 @@ foreach ($phparray as $key => $value) llxFooter(); $db->close(); -/** - * Return all list with all activated, but possible not loaded PHP extensions - * - * @return array - */ -function getActivatedExtensions() -{ - $file = getConfigFilePath(); - $handle = fopen(GetConfigFilePath(), "r"); - $content = fread($handle, filesize($file)); - - fclose($handle); - - $configLines = explode("\r", $content); - - $extensions = array(); - $lastLine = ""; - - foreach ($configLines as $line) - { - $line = trim($line); - - // ignore comment lines - if (substr($line, 0, 1) === ";") - { - continue; - } - - // extension - if (substr($line, 0, 9) === "extension" && substr($line, 0, 10) !== "extension_") - { - $value = trim(end(explode("=", $line))); - - $extensions[] = $value === "gd2" ? "gd" : $value; - } - - // zend_extension - if (substr($line, 0, 14) === "zend_extension") - { - $extensions[] = str_replace("[", "", str_replace("]", "", $lastLine)); - } - - $lastLine = $line; - } - - return array_unique($extensions); -} - -/** - * Return the path to the current used php config file - * - * @return string - */ -function getConfigFilePath() -{ - $phparray = phpinfo_array(); - - foreach ($phparray as $value) - { - foreach ($value as $keyparam => $keyvalue) - { - if (strtolower($keyparam) !== "loaded configuration file") - { - continue; - } - - return $keyvalue; - } - } - - return ""; -} /** * Return a table column with a indicator (okay or warning), based on the given name and list @@ -400,7 +324,7 @@ function getTableColumnFunction(array $functions) * Return a result column with a translated result text * * @param string $name The name of the PHP extension - * @param array $activated A list with all activated PHP extensions + * @param array $activated A list with all activated PHP extensions. Deprecated. * @param array $loaded A list with all loaded PHP extensions * @param array $functions A list with all PHP functions to check * From d3a2aa664fb5f67c76f5afddc4c9b7d34dca4f56 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 29 Nov 2020 20:27:40 +0100 Subject: [PATCH 047/137] FIX #15572 --- htdocs/comm/propal/stats/index.php | 6 +++--- htdocs/commande/card.php | 15 ++------------- htdocs/commande/stats/index.php | 8 ++++---- htdocs/compta/facture/stats/index.php | 4 ++-- htdocs/core/lib/functions.lib.php | 1 + htdocs/expensereport/stats/index.php | 8 ++++---- htdocs/fichinter/stats/index.php | 4 ++-- htdocs/ticket/stats/index.php | 6 +++--- test/phpunit/FunctionsLibTest.php | 6 ++++-- 9 files changed, 25 insertions(+), 33 deletions(-) diff --git a/htdocs/comm/propal/stats/index.php b/htdocs/comm/propal/stats/index.php index add31f13f08..da3c24f6f01 100644 --- a/htdocs/comm/propal/stats/index.php +++ b/htdocs/comm/propal/stats/index.php @@ -37,11 +37,11 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; $WIDTH = DolGraph::getDefaultGraphSizeForStats('width'); $HEIGHT = DolGraph::getDefaultGraphSizeForStats('height'); -$mode = GETPOST("mode") ?GETPOST("mode") : 'customer'; +$mode = GETPOSTISSET("mode") ? GETPOST("mode", 'aZ09') : 'customer'; if ($mode == 'customer' && !$user->rights->propale->lire) accessforbidden(); if ($mode == 'supplier' && !$user->rights->supplier_proposal->lire) accessforbidden(); -$object_status = GETPOST('object_status'); +$object_status = GETPOST('object_status', 'intcomma'); $typent_id = GETPOST('typent_id', 'int'); $categ_id = GETPOST('categ_id', 'categ_id'); @@ -55,7 +55,7 @@ if ($user->socid > 0) } $nowyear = strftime("%Y", dol_now()); -$year = GETPOST('year') > 0 ?GETPOST('year') : $nowyear; +$year = GETPOST('year') > 0 ? GETPOST('year', 'int') : $nowyear; //$startyear=$year-2; $startyear = $year - 1; $endyear = $year; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 4175509eb28..8ba4620b108 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -460,26 +460,15 @@ if (empty($reshook)) if (!$error) { $object_id = $object->create($user); - - // If some invoice's lines already known - $NBLINES = 8; - for ($i = 1; $i <= $NBLINES; $i++) { - if ($_POST['idprod'.$i]) { - $xid = 'idprod'.$i; - $xqty = 'qty'.$i; - $xremise = 'remise_percent'.$i; - $object->add_product($_POST[$xid], $_POST[$xqty], $_POST[$xremise]); - } - } } } // Insert default contacts if defined if ($object_id > 0) { - if (GETPOST('contactid')) + if (GETPOST('contactid', 'int')) { - $result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external'); + $result = $object->add_contact(GETPOST('contactid', 'int'), 'CUSTOMER', 'external'); if ($result < 0) { setEventMessages($langs->trans("ErrorFailedToAddContact"), null, 'errors'); $error++; diff --git a/htdocs/commande/stats/index.php b/htdocs/commande/stats/index.php index 4e7ed481882..d89559af113 100644 --- a/htdocs/commande/stats/index.php +++ b/htdocs/commande/stats/index.php @@ -38,11 +38,11 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $WIDTH = DolGraph::getDefaultGraphSizeForStats('width'); $HEIGHT = DolGraph::getDefaultGraphSizeForStats('height'); -$mode = GETPOST("mode") ?GETPOST("mode") : 'customer'; +$mode = GETPOSTISSET("mode") ? GETPOST("mode", 'aZ09') : 'customer'; if ($mode == 'customer' && !$user->rights->commande->lire) accessforbidden(); if ($mode == 'supplier' && !$user->rights->fournisseur->commande->lire) accessforbidden(); -$object_status = GETPOST('object_status'); +$object_status = GETPOST('object_status', 'intcomma'); $typent_id = GETPOST('typent_id', 'int'); $categ_id = GETPOST('categ_id', 'categ_id'); @@ -308,11 +308,11 @@ if ($mode == 'customer') Commande::STATUS_CLOSED=>$langs->trans("StatusOrderDelivered"), Commande::STATUS_CANCELED=>$langs->trans("StatusOrderCanceled") ); - print $form->selectarray('object_status', $liststatus, GETPOST('object_status', 'int'), -4); + print $form->selectarray('object_status', $liststatus, GETPOST('object_status', 'intcomma'), -4); } if ($mode == 'supplier') { - $formorder->selectSupplierOrderStatus((strstr($object_status, ',') ?-1 : $object_status), 0, 'object_status'); + $formorder->selectSupplierOrderStatus((strstr($object_status, ',') ? -1 : $object_status), 0, 'object_status'); } print ''; // Year diff --git a/htdocs/compta/facture/stats/index.php b/htdocs/compta/facture/stats/index.php index 284186b73ce..49f9be88ac6 100644 --- a/htdocs/compta/facture/stats/index.php +++ b/htdocs/compta/facture/stats/index.php @@ -44,7 +44,7 @@ $mode = GETPOST("mode") ?GETPOST("mode") : 'customer'; if ($mode == 'customer' && !$user->rights->facture->lire) accessforbidden(); if ($mode == 'supplier' && !$user->rights->fournisseur->facture->lire) accessforbidden(); -$object_status = GETPOST('object_status'); +$object_status = GETPOST('object_status', 'intcomma'); $typent_id = GETPOST('typent_id', 'int'); $categ_id = GETPOST('categ_id', 'categ_id'); @@ -59,7 +59,7 @@ if ($user->socid > 0) } $nowyear = strftime("%Y", dol_now()); -$year = GETPOST('year') > 0 ?GETPOST('year') : $nowyear; +$year = GETPOST('year') > 0 ? GETPOST('year', 'int') : $nowyear; if(!empty($conf->global->INVOICE_STATS_GRAPHS_SHOW_2_YEARS)) $startyear=$year-2; else $startyear=$year-1; $endyear = $year; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 24ec5645ffd..02a78b87c92 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4723,6 +4723,7 @@ function price2num($amount, $rounding = '', $option = 0) // Convert value to universal number format (no thousand separator, '.' as decimal separator) if ($option != 1) { // If not a PHP number or unknown, we change or clean format //print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'
'; + $amount = preg_replace('/[a-zA-Z\/\\\*\(\)\<\>\-]/', '', $amount); if ($option == 2 && $thousand == '.' && preg_match('/\.(\d\d\d)$/', (string) $amount)) { // It means the . is used as a thousand separator and string come frominput data, so 1.123 is 1123 $amount = str_replace($thousand, '', $amount); diff --git a/htdocs/expensereport/stats/index.php b/htdocs/expensereport/stats/index.php index 3b931bd4418..5a781942095 100644 --- a/htdocs/expensereport/stats/index.php +++ b/htdocs/expensereport/stats/index.php @@ -34,8 +34,8 @@ $langs->loadLangs(array('trips', 'companies')); $WIDTH = DolGraph::getDefaultGraphSizeForStats('width'); $HEIGHT = DolGraph::getDefaultGraphSizeForStats('height'); -$mode = GETPOST("mode") ?GETPOST("mode") : 'customer'; -$object_status = GETPOST('object_status'); +$mode = GETPOSTISSET("mode") ? GETPOST("mode", 'aZ09') : 'customer'; +$object_status = GETPOST('object_status', 'intcomma'); $userid = GETPOST('userid', 'int'); $socid = GETPOST('socid', 'int'); if ($socid < 0) $socid = 0; @@ -51,7 +51,7 @@ if ($user->socid) $socid = $user->socid; $result = restrictedArea($user, 'expensereport', $id, ''); $nowyear = strftime("%Y", dol_now()); -$year = GETPOST('year') > 0 ?GETPOST('year') : $nowyear; +$year = GETPOST('year') > 0 ? GETPOST('year', 'int') : $nowyear; //$startyear=$year-2; $startyear = $year - 1; $endyear = $year; @@ -231,7 +231,7 @@ print ''; // Status print ''; // Year print ''; // Year print ' +global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { ?> - + - + + + diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 191b4cf40c8..3af89dcede5 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -263,11 +263,14 @@ else +global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { ?> - + - + + + From 1c4876b417d24e80aa380a7deaf179afc302aa5b Mon Sep 17 00:00:00 2001 From: Stephane Lesage Date: Tue, 1 Dec 2020 21:17:03 +0100 Subject: [PATCH 056/137] more transporters in llx_c_shipment_mode.sql --- htdocs/install/mysql/data/llx_c_shipment_mode.sql | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/install/mysql/data/llx_c_shipment_mode.sql b/htdocs/install/mysql/data/llx_c_shipment_mode.sql index af3cf09f9f8..e5026f8d2f7 100644 --- a/htdocs/install/mysql/data/llx_c_shipment_mode.sql +++ b/htdocs/install/mysql/data/llx_c_shipment_mode.sql @@ -37,3 +37,9 @@ INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (6,'KIALA','KIALA','Relais Kiala','http://www.kiala.fr/tnt/delivery/{TRACKID}', 0); INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (7,'GLS','GLS','General Logistics Systems','https://gls-group.eu/FR/fr/suivi-colis?match={TRACKID}', 0); INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (8,'CHRONO','Chronopost','Chronopost','http://www.chronopost.fr/expedier/inputLTNumbersNoJahia.do?listeNumeros={TRACKID}', 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (9,'INPERSON', 'In person at your site', NULL, NULL, 0, NULL), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (10,'FEDEX', 'Fedex', NULL, 'https://www.fedex.com/apps/fedextrack/index.html?tracknumbers={TRACKID}', 0, NULL), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (11,'TNT', 'TNT', NULL, 'https://www.tnt.com/express/fr_fr/site/outils-expedition/suivi.html?searchType=con&cons=={TRACKID}', 0, NULL), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (12,'DHL', 'DHL', NULL, 'https://www.dhl.com/fr-fr/home/tracking/tracking-global-forwarding.html?submit=1&tracking-id={TRACKID}', 0, NULL), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (13,'DPD', 'DPD', NULL, 'https://www.dpd.fr/trace/{TRACKID}', 0, NULL), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (14,'MAINFREIGHT', 'Mainfreight', NULL, 'https://www.mainfreight.com/track?{TRACKID}', 0, NULL); From a2dca42965f1f64c6d32699bd7302d1863b71d7e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 2 Dec 2020 18:55:55 +0100 Subject: [PATCH 057/137] Revert "Create/Edit extra-field with multi-line text area for computed value" --- htdocs/core/tpl/admin_extrafields_add.tpl.php | 7 ++----- htdocs/core/tpl/admin_extrafields_edit.tpl.php | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index fca100b2e07..6c25b5c07b5 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -180,14 +180,11 @@ $langs->load("modulebuilder"); -global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { ?> - + - + - - diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 3af89dcede5..191b4cf40c8 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -263,14 +263,11 @@ else -global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { ?> - + - + - - From bc1dc1e9f01aafb109858533c54c3a67578bf92a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 2 Dec 2020 19:34:04 +0100 Subject: [PATCH 058/137] FIX #15590 manually --- htdocs/core/modules/modProduct.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 87f11decb5e..b029448cd58 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -194,7 +194,7 @@ class modProduct extends DolibarrModules ); if (is_object($mysoc) && $mysoc->useNPR()) $this->export_fields_array[$r]['p.recuperableonly'] = 'NPR'; if (!empty($conf->fournisseur->enabled) || !empty($conf->margin->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.cost_price'=>'CostPrice')); - if (!empty($conf->stock->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue')); + if (!empty($conf->stock->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.tobatch'=>'ManageLotSerial', 'p.stock'=>'Stock', 'p.seuil_stock_alerte'=>'StockLimit', 'p.desiredstock'=>'DesiredStock', 'p.pmp'=>'PMPValue')); if (!empty($conf->barcode->enabled)) $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('p.barcode'=>'BarCode')); $keyforselect = 'product'; $keyforelement = 'product'; $keyforaliasextra = 'extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; @@ -216,7 +216,7 @@ class modProduct extends DolibarrModules 'p.price_base_type'=>"Text", 'p.price'=>"Numeric", 'p.price_ttc'=>"Numeric", 'p.tva_tx'=>'Numeric', 'p.datec'=>'Date', 'p.tms'=>'Date' ); - if (!empty($conf->stock->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric')); + if (!empty($conf->stock->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.tobatch'=>'Numeric', 'p.stock'=>'Numeric', 'p.seuil_stock_alerte'=>'Numeric', 'p.desiredstock'=>'Numeric', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric')); if (!empty($conf->barcode->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('p.barcode'=>'Text')); if (!empty($conf->fournisseur->enabled)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('s.nom'=>'Text', 'pf.ref_fourn'=>'Text', 'pf.unitprice'=>'Numeric', 'pf.quantity'=>'Numeric', 'pf.remise_percent'=>'Numeric', 'pf.delivery_time_days'=>'Numeric')); if (!empty($conf->global->MAIN_MULTILANGS)) $this->export_TypeFields_array[$r] = array_merge($this->export_TypeFields_array[$r], array('l.lang'=>'Text', 'l.label'=>'Text', 'l.description'=>'Text', 'l.note'=>'Text')); @@ -559,6 +559,7 @@ class modProduct extends DolibarrModules ); //clauses copied from import_fields_array if (!empty($conf->stock->enabled)) $import_sample = array_merge($import_sample, array( + 'p.tobatch'=>"0 (don't use) / 1 (use batch/serial number)", 'p.seuil_stock_alerte' => '', 'p.pmp' => '0', 'p.desiredstock' => '' From 17d5bb5cd450f659634dbf4e6e79d03a5cd9b8ea Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Wed, 2 Dec 2020 22:25:08 +0100 Subject: [PATCH 059/137] FIX 12.0 - error when displaying lines on order after adding a line if both MAIN_MULTILANGS and MAIN_DISABLE_PDF_AUTOUPDATE are activated --- htdocs/commande/card.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 8ba4620b108..2c5157ff228 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -966,6 +966,8 @@ if (empty($reshook)) } $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } else { + $object->fetch_thirdparty(); } unset($_POST['prod_entry_mode']); From 0fd865d8afb6b64fcfe8f926a2131ffba47c9fb5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Dec 2020 11:16:02 +0100 Subject: [PATCH 060/137] FIX Better error message with IMAP when connection fails --- htdocs/admin/emailcollector_card.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 80161eaadc6..b7c7e4abca2 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -448,6 +448,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (!$connection) { $morehtml .= 'Failed to open IMAP connection '.$connectstringsource; + $morehtml .= '
'.imap_last_error(); } else { From b324425db815d4a90a7f11c43d7f241a5b39c2e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Dec 2020 11:19:41 +0100 Subject: [PATCH 061/137] code comment --- htdocs/admin/emailcollector_card.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index b7c7e4abca2..07cd5be7b78 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -449,6 +449,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea { $morehtml .= 'Failed to open IMAP connection '.$connectstringsource; $morehtml .= '
'.imap_last_error(); + //var_dump(imap_errors()) } else { From 068587fcee84f7016418ca4064243758a98010e4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Dec 2020 14:30:07 +0100 Subject: [PATCH 062/137] Update card.php --- htdocs/commande/card.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 2c5157ff228..d9817dc38c3 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -953,7 +953,8 @@ if (empty($reshook)) if ($result > 0) { $ret = $object->fetch($object->id); // Reload to get new records - + $object->fetch_thirdparty(); + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { // Define output language $outputlangs = $langs; @@ -966,8 +967,6 @@ if (empty($reshook)) } $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } else { - $object->fetch_thirdparty(); } unset($_POST['prod_entry_mode']); From ac29db92cbd2f462c7ead86f86a61cb0f8d4af35 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Dec 2020 16:35:42 +0100 Subject: [PATCH 063/137] FIX #15618 --- htdocs/admin/system/dolibarr.php | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/htdocs/admin/system/dolibarr.php b/htdocs/admin/system/dolibarr.php index 97e7370a148..a2dcc434723 100644 --- a/htdocs/admin/system/dolibarr.php +++ b/htdocs/admin/system/dolibarr.php @@ -83,17 +83,23 @@ else if (DOL_VERSION != $conf->global->MAIN_VERSION_LAST_UPGRADE) print ' '.img_warning($langs->trans("RunningUpdateProcessMayBeRequired", DOL_VERSION, $conf->global->MAIN_VERSION_LAST_UPGRADE)); } +$version = DOL_VERSION; +if (preg_match('/[a-z]+/i', $version)) $version = 'develop'; // If version contains text, it is not an official tagged version, so we use the full change log. +print '   '.$langs->trans("SeeChangeLog").''; + +$newversion = ''; if (function_exists('curl_init')) { $conf->global->MAIN_USE_RESPONSE_TIMEOUT = 10; print '     -     '; if ($action == 'getlastversion') { - if ($sfurl) - { + if ($sfurl) { + $i = 0; while (!empty($sfurl->channel[0]->item[$i]->title) && $i < 10000) { $title = $sfurl->channel[0]->item[$i]->title; + $reg = array(); if (preg_match('/([0-9]+\.([0-9\.]+))/', $title, $reg)) { $newversion = $reg[1]; @@ -107,25 +113,23 @@ if (function_exists('curl_init')) // Show version print $langs->trans("LastStableVersion").' : '.(($version != '0.0') ? $version : $langs->trans("Unknown")).''; - } - else - { + if ($version != '0.0') { + print '   '.$langs->trans("SeeChangeLog").''; + } + } else { print $langs->trans("LastStableVersion").' : '.$langs->trans("UpdateServerOffline").''; } - } - else - { + } else { print $langs->trans("LastStableVersion").' : '.$langs->trans("Check").''; } } // Now show link to the changelog -print '     -     '; +//print '     -     '; $version = DOL_VERSION; if (preg_match('/[a-z]+/i', $version)) $version = 'develop'; // If version contains text, it is not an official tagged version, so we use the full change log. -print ''.$langs->trans("SeeChangeLog").''; print ''."\n"; print '
'."\n"; print ''."\n"; From a1428c963b642d09d00d7b6df2483b9ae03709c6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Dec 2020 16:53:26 +0100 Subject: [PATCH 064/137] Fix phpcs --- htdocs/commande/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index d9817dc38c3..f59038aceae 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -954,7 +954,7 @@ if (empty($reshook)) if ($result > 0) { $ret = $object->fetch($object->id); // Reload to get new records $object->fetch_thirdparty(); - + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { // Define output language $outputlangs = $langs; From 8a7f7b355134e8572b93e48b0a97dc20e0d55b82 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Dec 2020 18:38:18 +0100 Subject: [PATCH 065/137] FIX Request on purchase orders in timeout even on very small databases --- htdocs/install/mysql/migration/11.0.0-12.0.0.sql | 3 +++ .../install/mysql/tables/llx_commande_fournisseurdet.key.sql | 3 +++ 2 files changed, 6 insertions(+) diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index a7cb8a4729f..8d80486fcf8 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -338,3 +338,6 @@ ALTER TABLE llx_expedition ADD COLUMN billed smallint DEFAULT 0; -- VMYSQL4.3 ALTER TABLE llx_mrp_mo MODIFY COLUMN tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; +ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_commande (fk_commande); +ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_product (fk_product); + diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseurdet.key.sql b/htdocs/install/mysql/tables/llx_commande_fournisseurdet.key.sql index 6c2da9cf094..5d30ddf8817 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseurdet.key.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseurdet.key.sql @@ -17,3 +17,6 @@ -- ============================================================================ ALTER TABLE llx_commande_fournisseurdet ADD CONSTRAINT fk_commande_fournisseurdet_fk_unit FOREIGN KEY (fk_unit) REFERENCES llx_c_units (rowid); + +ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_commande (fk_commande); +ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_product (fk_product); From df48704154522ad77ebefb323ebfd88ddd471e35 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Dec 2020 18:45:56 +0100 Subject: [PATCH 066/137] Fix label --- htdocs/fourn/commande/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 69db75ce5fc..ce638cdffcb 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -129,7 +129,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // List of fields to search into when doing a "search in all" $fieldstosearchall = array( 'cf.ref'=>'Ref', - 'cf.ref_supplier'=>'RefSupplierOrder', + 'cf.ref_supplier'=>'RefOrderSupplier', 'pd.description'=>'Description', 's.nom'=>"ThirdParty", 'cf.note_public'=>'NotePublic', From ac30348081c0bde8005541a6e471fdb5dc746ac0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Dec 2020 19:16:34 +0100 Subject: [PATCH 067/137] Prepare 12.0.4 --- 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 e1aced7ddf0..b57228f24e9 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', '12.0.3'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (!defined('DOL_VERSION')) define('DOL_VERSION', '12.0.4'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (!defined('EURO')) define('EURO', chr(128)); From 0a242983859f864d36ea2760af713098cbc49041 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 4 Dec 2020 02:57:40 +0100 Subject: [PATCH 068/137] FIX: Problem on supplier payment card --- htdocs/fourn/class/paiementfourn.class.php | 1 + htdocs/fourn/paiement/card.php | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index b48fef9759a..fd07cc7bf89 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -118,6 +118,7 @@ class PaiementFourn extends Paiement $this->bank_account = $obj->fk_account; $this->bank_line = $obj->fk_bank; $this->montant = $obj->amount; + $this->amount = $obj->amount; $this->note = $obj->note; $this->type_code = $obj->paiement_code; $this->type_libelle = $obj->paiement_type; diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index 6d9661ded5d..6aec24bb0a8 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -274,10 +274,9 @@ if ($result > 0) $i = 0; $total = 0; - print ''.$langs->trans("Invoices").'
'; print '
".$name."
".$name."
".$name."
".$name."'.$keyparam.''; + print ''; if ($keyparam == 'Path') $valtoshow = implode('; ', explode(';', trim($valtoshow))); if ($keyparam == 'PATH') $valtoshow = implode('; ', explode(';', trim($valtoshow))); if ($keyparam == '_SERVER["PATH"]') $valtoshow = implode('; ', explode(';', trim($valtoshow))); @@ -232,7 +228,7 @@ foreach ($phparray as $key => $value) else { print '
'.$keyparam.''.$keyparam.'
'.$langs->trans("Status").''; $liststatus = $tmpexpensereport->statuts; -print $form->selectarray('object_status', $liststatus, GETPOST('object_status', 'int'), -4, 0, 0, '', 1); +print $form->selectarray('object_status', $liststatus, GETPOST('object_status', 'intcomma'), -4, 0, 0, '', 1); print '
'; diff --git a/htdocs/fichinter/stats/index.php b/htdocs/fichinter/stats/index.php index 0ca948312c6..8e385ebb5d7 100644 --- a/htdocs/fichinter/stats/index.php +++ b/htdocs/fichinter/stats/index.php @@ -42,12 +42,12 @@ if ($user->socid > 0) } $nowyear = strftime("%Y", dol_now()); -$year = GETPOST('year') > 0 ?GETPOST('year') : $nowyear; +$year = GETPOST('year') > 0 ? GETPOST('year', 'int') : $nowyear; //$startyear=$year-2; $startyear = $year - 1; $endyear = $year; -$object_status = GETPOST('object_status'); +$object_status = GETPOST('object_status', 'intcomma'); // Load translation files required by the page $langs->loadLangs(array('interventions', 'companies', 'other', 'suppliers')); diff --git a/htdocs/ticket/stats/index.php b/htdocs/ticket/stats/index.php index b39ba0fd366..e48c0147fad 100644 --- a/htdocs/ticket/stats/index.php +++ b/htdocs/ticket/stats/index.php @@ -32,7 +32,7 @@ $HEIGHT = DolGraph::getDefaultGraphSizeForStats('height'); if (!$user->rights->ticket->read) accessforbidden(); -$object_status = GETPOST('object_status'); +$object_status = GETPOST('object_status', 'intcomma'); $userid = GETPOST('userid', 'int'); $socid = GETPOST('socid', 'int'); @@ -44,7 +44,7 @@ if ($user->socid > 0) } $nowyear = strftime("%Y", dol_now()); -$year = GETPOST('year') > 0 ?GETPOST('year') : $nowyear; +$year = GETPOST('year') > 0 ? GETPOST('year', 'int') : $nowyear; //$startyear=$year-2; $startyear = $year - 1; $endyear = $year; @@ -241,7 +241,7 @@ print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0 // Status print '
'.$langs->trans("Status").''; $liststatus = $object->fields['fk_statut']['arrayofkeyval']; -print $form->selectarray('object_status', $liststatus, GETPOST('object_status', 'int'), -4, 0, 0, '', 1); +print $form->selectarray('object_status', $liststatus, GETPOST('object_status', 'intcomma'), -4, 0, 0, '', 1); print '
'.$langs->trans("Year").''; diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index a987f28c7ed..3d098131f21 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1234,7 +1234,9 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $newlangs->load("main"); $langs = $newlangs; - $this->assertEquals(1000, price2num('1 000.0')); + $this->assertEquals(150, price2num('(SELECT/**/CASE/**/WHEN/**/(0<1)/**/THEN/**/SLEEP(5)/**/ELSE/**/SLEEP(0)/**/END)')); + + $this->assertEquals(1000, price2num('1 000.0')); $this->assertEquals(1000, price2num('1 000', 'MT')); $this->assertEquals(1000, price2num('1 000', 'MU')); @@ -1252,7 +1254,7 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase // Text can't be converted $this->assertEquals('12.4$', price2num('12.4$')); - $this->assertEquals('12r.4$', price2num('12r.4$')); + $this->assertEquals('12.4$', price2num('12r.4$')); // For spanish language $newlangs2 = new Translate('', $conf); From d45fe6c17f6c93333aa3caf47056f9d01bcdec07 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 29 Nov 2020 20:39:11 +0100 Subject: [PATCH 048/137] FIx #15551 --- htdocs/install/mysql/migration/11.0.0-12.0.0.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index 994e5d89495..a7cb8a4729f 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -335,3 +335,6 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (72 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,note,active) values (722, 72, '18','0', '0.9', '1', 'VAT Rate 18+0.9', 1); ALTER TABLE llx_expedition ADD COLUMN billed smallint DEFAULT 0; + +-- VMYSQL4.3 ALTER TABLE llx_mrp_mo MODIFY COLUMN tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; + From 58eaef37d28c3f6fa1578d301a6e6c68434d7756 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 29 Nov 2020 21:29:22 +0100 Subject: [PATCH 049/137] Fix regression --- htdocs/core/lib/functions.lib.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 02a78b87c92..2a9052d0916 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4723,7 +4723,9 @@ function price2num($amount, $rounding = '', $option = 0) // Convert value to universal number format (no thousand separator, '.' as decimal separator) if ($option != 1) { // If not a PHP number or unknown, we change or clean format //print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'
'; - $amount = preg_replace('/[a-zA-Z\/\\\*\(\)\<\>\-]/', '', $amount); + if (!is_numeric($amount)) { + $amount = preg_replace('/[a-zA-Z\/\\\*\(\)\<\>\-]/', '', $amount); + } if ($option == 2 && $thousand == '.' && preg_match('/\.(\d\d\d)$/', (string) $amount)) { // It means the . is used as a thousand separator and string come frominput data, so 1.123 is 1123 $amount = str_replace($thousand, '', $amount); From 0046bfc53fd910ea7002eb65c4cc0fac76d710f1 Mon Sep 17 00:00:00 2001 From: Stephane Lesage Date: Sun, 29 Nov 2020 23:42:47 +0100 Subject: [PATCH 050/137] Fix Users list filter by gender --- htdocs/user/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/user/list.php b/htdocs/user/list.php index ef6e205fd0d..1f59656dcbd 100644 --- a/htdocs/user/list.php +++ b/htdocs/user/list.php @@ -231,7 +231,7 @@ if ($search_thirdparty != '') $sql .= natural_search(array('s.nom'), $search_thi if ($search_login != '') $sql .= natural_search("u.login", $search_login); if ($search_lastname != '') $sql .= natural_search("u.lastname", $search_lastname); if ($search_firstname != '') $sql .= natural_search("u.firstname", $search_firstname); -if ($search_gender != '' && $search_gender != '-1') $sql .= " AND u.gender = '".$search_gender."'"; +if ($search_gender != '' && $search_gender != '-1') $sql .= " AND u.gender = '".$db->escape($search_gender)."'"; // Cannot use natural_search as looking for %man% also includes woman if (is_numeric($search_employee) && $search_employee >= 0) { $sql .= ' AND u.employee = '.(int) $search_employee; } From 4f762cf73d81163ccc17fb0a6aab369b83592d24 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 30 Nov 2020 08:29:19 +0100 Subject: [PATCH 051/137] Fix label --- htdocs/fourn/commande/list.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 00b620a201b..69db75ce5fc 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -486,14 +486,14 @@ if ($socid > 0) $title .= ' - '.$fourn->name; } -if ($search_status) +/*if ($search_status) { if ($search_status == '1,2') $title .= ' - '.$langs->trans("SuppliersOrdersToProcess"); elseif ($search_status == '3,4') $title .= ' - '.$langs->trans("SuppliersOrdersAwaitingReception"); elseif ($search_status == '1,2,3') $title .= ' - '.$langs->trans("StatusOrderToProcessShort"); elseif ($search_status == '6,7') $title .= ' - '.$langs->trans("StatusOrderCanceled"); - elseif(is_numeric($search_status)) $title .= ' - '.$commandestatic->LibStatut($search_status); -} + elseif (is_numeric($search_status) && $search_status >= 0) $title .= ' - '.$commandestatic->LibStatut($search_status); +}*/ if ($search_billed > 0) $title .= ' - '.$langs->trans("Billed"); //$help_url="EN:Module_Customers_Orders|FR:Module_Commandes_Clients|ES:Módulo_Pedidos_de_clientes"; From 560194c3b95e4eac183d0e6a1245e474fa0b6c4f Mon Sep 17 00:00:00 2001 From: teleassist <30868208+teleassist@users.noreply.github.com> Date: Mon, 30 Nov 2020 11:22:49 +0100 Subject: [PATCH 052/137] FIX #15374 : "New" doesn't clear total amounts Invoice's total amounts where not updated because of direct lines deleting in database. --- htdocs/takepos/invoice.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 1ff0db279b0..7bd15687037 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -411,17 +411,18 @@ if ($action == "delete") { if ($result > 0 && $invoice->statut == Facture::STATUS_DRAFT) { $db->begin(); - - // We delete the lines - $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet_extrafields where fk_object = ".$placeid; - $resql1 = $db->query($sql); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet where fk_facture = ".$placeid; - $resql2 = $db->query($sql); + + // We delete the lines + $resdeletelines = 1; + foreach($invoice->lines as $line){ + $resdeletelines *= $invoice->deleteline($line->id); + } + $sql = "UPDATE ".MAIN_DB_PREFIX."facture set fk_soc=".$conf->global->{'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"]}; $sql .= " WHERE ref='(PROV-POS".$_SESSION["takeposterminal"]."-".$place.")'"; - $resql3 = $db->query($sql); + $resql1 = $db->query($sql); - if ($resql1 && $resql2 && $resql3) + if ($resdeletelines && $resql1) { $db->commit(); } @@ -429,8 +430,8 @@ if ($action == "delete") { { $db->rollback(); } - - $invoice->fetch($placeid); + + $invoice->fetch($placeid); } } } From 9ee37153f77ed142e21483854de03296fe06d8b4 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Mon, 30 Nov 2020 10:32:58 +0000 Subject: [PATCH 053/137] Fixing style errors. --- htdocs/takepos/invoice.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 7bd15687037..323b105caed 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -411,13 +411,13 @@ if ($action == "delete") { if ($result > 0 && $invoice->statut == Facture::STATUS_DRAFT) { $db->begin(); - + // We delete the lines $resdeletelines = 1; foreach($invoice->lines as $line){ $resdeletelines *= $invoice->deleteline($line->id); } - + $sql = "UPDATE ".MAIN_DB_PREFIX."facture set fk_soc=".$conf->global->{'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"]}; $sql .= " WHERE ref='(PROV-POS".$_SESSION["takeposterminal"]."-".$place.")'"; $resql1 = $db->query($sql); @@ -430,7 +430,7 @@ if ($action == "delete") { { $db->rollback(); } - + $invoice->fetch($placeid); } } From 7870a33fd3de524674ad2dd919929cc89132ec06 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 30 Nov 2020 15:39:35 +0100 Subject: [PATCH 054/137] Update invoice.php --- htdocs/takepos/invoice.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 323b105caed..493202376a9 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -415,7 +415,11 @@ if ($action == "delete") { // We delete the lines $resdeletelines = 1; foreach($invoice->lines as $line){ - $resdeletelines *= $invoice->deleteline($line->id); + $tmpres = $invoice->deleteline($line->id); + if ($tmpres < 0) { + $resdeletelines = 0; + break; + } } $sql = "UPDATE ".MAIN_DB_PREFIX."facture set fk_soc=".$conf->global->{'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"]}; From 3caf65ce6f9b9da799925aa52fd247252d20df55 Mon Sep 17 00:00:00 2001 From: Stephane Lesage Date: Tue, 1 Dec 2020 19:30:09 +0100 Subject: [PATCH 055/137] Create/Edit extra-field with multi-line text area for computed value --- htdocs/core/tpl/admin_extrafields_add.tpl.php | 7 +++++-- htdocs/core/tpl/admin_extrafields_edit.tpl.php | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index 6c25b5c07b5..fca100b2e07 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -180,11 +180,14 @@ $langs->load("modulebuilder");
trans("LanguageFile"); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?>
trans("DefaultValue").' ('.$langs->trans("Database").')'; ?>
trans("LanguageFile"); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?>
trans("DefaultValue").' ('.$langs->trans("Database").')'; ?>
trans("LanguageFile"); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?>
trans("DefaultValue").' ('.$langs->trans("Database").')'; ?>
trans("LanguageFile"); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?>
textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?>
trans("DefaultValue").' ('.$langs->trans("Database").')'; ?>
'.$langs->trans("VersionLastUpgrade").' ('.$langs->trans("Database").')'.$conf->global->MAIN_VERSION_LAST_UPGRADE.'
'.$langs->trans("VersionLastInstall").''.$conf->global->MAIN_VERSION_LAST_INSTALL.'
'; print ''; - print ''; + print ''; print ''; print ''; print ''; From 7a5a6a14f0d3ea5f53a6295ddb4c9a6f664d32ad Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 4 Dec 2020 09:10:36 +0100 Subject: [PATCH 069/137] fix At install insert shipment mode failed --- htdocs/install/mysql/data/llx_c_shipment_mode.sql | 12 ++++++------ htdocs/install/mysql/migration/11.0.0-12.0.0.sql | 8 ++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_shipment_mode.sql b/htdocs/install/mysql/data/llx_c_shipment_mode.sql index e5026f8d2f7..0dd00f27bb4 100644 --- a/htdocs/install/mysql/data/llx_c_shipment_mode.sql +++ b/htdocs/install/mysql/data/llx_c_shipment_mode.sql @@ -37,9 +37,9 @@ INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (6,'KIALA','KIALA','Relais Kiala','http://www.kiala.fr/tnt/delivery/{TRACKID}', 0); INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (7,'GLS','GLS','General Logistics Systems','https://gls-group.eu/FR/fr/suivi-colis?match={TRACKID}', 0); INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (8,'CHRONO','Chronopost','Chronopost','http://www.chronopost.fr/expedier/inputLTNumbersNoJahia.do?listeNumeros={TRACKID}', 0); -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (9,'INPERSON', 'In person at your site', NULL, NULL, 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (10,'FEDEX', 'Fedex', NULL, 'https://www.fedex.com/apps/fedextrack/index.html?tracknumbers={TRACKID}', 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (11,'TNT', 'TNT', NULL, 'https://www.tnt.com/express/fr_fr/site/outils-expedition/suivi.html?searchType=con&cons=={TRACKID}', 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (12,'DHL', 'DHL', NULL, 'https://www.dhl.com/fr-fr/home/tracking/tracking-global-forwarding.html?submit=1&tracking-id={TRACKID}', 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (13,'DPD', 'DPD', NULL, 'https://www.dpd.fr/trace/{TRACKID}', 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (14,'MAINFREIGHT', 'Mainfreight', NULL, 'https://www.mainfreight.com/track?{TRACKID}', 0, NULL); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (9,'INPERSON', 'In person at your site', NULL, NULL, 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (10,'FEDEX', 'Fedex', NULL, 'https://www.fedex.com/apps/fedextrack/index.html?tracknumbers={TRACKID}', 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (11,'TNT', 'TNT', NULL, 'https://www.tnt.com/express/fr_fr/site/outils-expedition/suivi.html?searchType=con&cons=={TRACKID}', 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (12,'DHL', 'DHL', NULL, 'https://www.dhl.com/fr-fr/home/tracking/tracking-global-forwarding.html?submit=1&tracking-id={TRACKID}', 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (13,'DPD', 'DPD', NULL, 'https://www.dpd.fr/trace/{TRACKID}', 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (14,'MAINFREIGHT', 'Mainfreight', NULL, 'https://www.mainfreight.com/track?{TRACKID}', 0); diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index 8d80486fcf8..fddfb8c8097 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -341,3 +341,11 @@ ALTER TABLE llx_expedition ADD COLUMN billed smallint DEFAULT 0; ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_commande (fk_commande); ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_product (fk_product); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (9,'INPERSON', 'In person at your site', NULL, NULL, 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (10,'FEDEX', 'Fedex', NULL, 'https://www.fedex.com/apps/fedextrack/index.html?tracknumbers={TRACKID}', 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (11,'TNT', 'TNT', NULL, 'https://www.tnt.com/express/fr_fr/site/outils-expedition/suivi.html?searchType=con&cons=={TRACKID}', 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (12,'DHL', 'DHL', NULL, 'https://www.dhl.com/fr-fr/home/tracking/tracking-global-forwarding.html?submit=1&tracking-id={TRACKID}', 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (13,'DPD', 'DPD', NULL, 'https://www.dpd.fr/trace/{TRACKID}', 0); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (14,'MAINFREIGHT', 'Mainfreight', NULL, 'https://www.mainfreight.com/track?{TRACKID}', 0); + + From d712e1e6d46fdb58eb8db0e78a2ad39e3cc68109 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Fri, 4 Dec 2020 09:42:30 +0100 Subject: [PATCH 070/137] Fix limit product in customer margins Fix limit of 20 products in product list/search --- htdocs/margin/customerMargins.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/margin/customerMargins.php b/htdocs/margin/customerMargins.php index 3cdd9c3c650..a0b5ad2be04 100644 --- a/htdocs/margin/customerMargins.php +++ b/htdocs/margin/customerMargins.php @@ -134,7 +134,7 @@ if (!$sortfield) } // Products -$TRes = $form->select_produits_list('', '', '', 20, 0, '', 1, 2, 1, 0, '', 1); +$TRes = $form->select_produits_list('', '', '', '', 0, '', 1, 2, 1, 0, '', 1); $TProducts = array(); foreach ($TRes as $prod) { From c752bfe1a6b39f409c3d4c900b338b4da922291c Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Fri, 4 Dec 2020 10:02:39 +0100 Subject: [PATCH 071/137] FIX 12.0 - set entity to $conf->entity (instead of 1 by default) when creating a survey; otherwise the survey cannot be listed from the entity it was created on unless it is the main entity --- htdocs/opensurvey/class/opensurveysondage.class.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php index c971b69b208..83902f8c678 100644 --- a/htdocs/opensurvey/class/opensurveysondage.class.php +++ b/htdocs/opensurvey/class/opensurveysondage.class.php @@ -128,6 +128,7 @@ class Opensurveysondage extends CommonObject */ public function create(User $user, $notrigger = 0) { + global $conf; $error = 0; // Clean parameters @@ -153,7 +154,8 @@ class Opensurveysondage extends CommonObject $sql .= "mailsonde,"; $sql .= "allow_comments,"; $sql .= "allow_spy,"; - $sql .= "sujet"; + $sql .= "sujet,"; + $sql .= "entity"; $sql .= ") VALUES ("; $sql .= "'".$this->db->escape($this->id_sondage)."',"; $sql .= " ".(empty($this->commentaires) ? 'NULL' : "'".$this->db->escape($this->commentaires)."'").","; @@ -165,7 +167,8 @@ class Opensurveysondage extends CommonObject $sql .= " ".$this->db->escape($this->mailsonde).","; $sql .= " ".$this->db->escape($this->allow_comments).","; $sql .= " ".$this->db->escape($this->allow_spy).","; - $sql .= " '".$this->db->escape($this->sujet)."'"; + $sql .= " '".$this->db->escape($this->sujet)."',"; + $sql .= " '".$conf->entity."',"; $sql .= ")"; $this->db->begin(); From 94d57cd462ca57ee7ad8283321822dabaa34f3e2 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Fri, 4 Dec 2020 10:03:06 +0100 Subject: [PATCH 072/137] fix rounding --- htdocs/fourn/class/fournisseur.commande.class.php | 2 +- htdocs/fourn/class/fournisseur.product.class.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index dc3113f2554..af283d8cdf0 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1729,9 +1729,9 @@ class CommandeFournisseur extends CommonOrder { $coeff = intval($qty / $prod->packaging) + 1; $qty = $prod->packaging * $coeff; - setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs'); } } + setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs'); } } else diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 1643ae69846..5a36e6bdabf 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -274,7 +274,7 @@ class ProductFournisseur extends Product $charges = price2num($charges, 'MU'); $qty = price2num($qty, 'MS'); $unitBuyPrice = price2num($buyprice / $qty, 'MU'); - $packaging = ($this->packaging < $qty) ? $qty : $this->packaging; + $packaging = price2num((($this->packaging < $qty) ? $qty : $this->packaging), 'MS'); $error = 0; $now = dol_now(); From 7685ed8295ab60e6c3668610fdba56ad18e45d98 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Fri, 4 Dec 2020 10:10:44 +0100 Subject: [PATCH 073/137] FIX excess comma --- htdocs/opensurvey/class/opensurveysondage.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php index 83902f8c678..9d7462e87b6 100644 --- a/htdocs/opensurvey/class/opensurveysondage.class.php +++ b/htdocs/opensurvey/class/opensurveysondage.class.php @@ -168,7 +168,7 @@ class Opensurveysondage extends CommonObject $sql .= " ".$this->db->escape($this->allow_comments).","; $sql .= " ".$this->db->escape($this->allow_spy).","; $sql .= " '".$this->db->escape($this->sujet)."',"; - $sql .= " '".$conf->entity."',"; + $sql .= " ".$conf->entity; $sql .= ")"; $this->db->begin(); From 575bb7d420a3f8f2638c40baca817f5618f562b8 Mon Sep 17 00:00:00 2001 From: atm-benoit Date: Fri, 4 Dec 2020 14:20:25 +0100 Subject: [PATCH 074/137] FIX SHIP MODE install v12 bug insert --- htdocs/install/mysql/data/llx_c_shipment_mode.sql | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_shipment_mode.sql b/htdocs/install/mysql/data/llx_c_shipment_mode.sql index e5026f8d2f7..97c05b13d0c 100644 --- a/htdocs/install/mysql/data/llx_c_shipment_mode.sql +++ b/htdocs/install/mysql/data/llx_c_shipment_mode.sql @@ -37,9 +37,9 @@ INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (6,'KIALA','KIALA','Relais Kiala','http://www.kiala.fr/tnt/delivery/{TRACKID}', 0); INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (7,'GLS','GLS','General Logistics Systems','https://gls-group.eu/FR/fr/suivi-colis?match={TRACKID}', 0); INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (8,'CHRONO','Chronopost','Chronopost','http://www.chronopost.fr/expedier/inputLTNumbersNoJahia.do?listeNumeros={TRACKID}', 0); -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (9,'INPERSON', 'In person at your site', NULL, NULL, 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (10,'FEDEX', 'Fedex', NULL, 'https://www.fedex.com/apps/fedextrack/index.html?tracknumbers={TRACKID}', 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (11,'TNT', 'TNT', NULL, 'https://www.tnt.com/express/fr_fr/site/outils-expedition/suivi.html?searchType=con&cons=={TRACKID}', 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (12,'DHL', 'DHL', NULL, 'https://www.dhl.com/fr-fr/home/tracking/tracking-global-forwarding.html?submit=1&tracking-id={TRACKID}', 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (13,'DPD', 'DPD', NULL, 'https://www.dpd.fr/trace/{TRACKID}', 0, NULL), -INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (14,'MAINFREIGHT', 'Mainfreight', NULL, 'https://www.mainfreight.com/track?{TRACKID}', 0, NULL); +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (9,'INPERSON', 'In person at your site', NULL, NULL, 0), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (10,'FEDEX', 'Fedex', NULL, 'https://www.fedex.com/apps/fedextrack/index.html?tracknumbers={TRACKID}', 0), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (11,'TNT', 'TNT', NULL, 'https://www.tnt.com/express/fr_fr/site/outils-expedition/suivi.html?searchType=con&cons=={TRACKID}', 0), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (12,'DHL', 'DHL', NULL, 'https://www.dhl.com/fr-fr/home/tracking/tracking-global-forwarding.html?submit=1&tracking-id={TRACKID}', 0), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (13,'DPD', 'DPD', NULL, 'https://www.dpd.fr/trace/{TRACKID}', 0, ), +INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (14,'MAINFREIGHT', 'Mainfreight', NULL, 'https://www.mainfreight.com/track?{TRACKID}', 0); From b9461322d9cc10370c56f7e120725d60a30d8bbc Mon Sep 17 00:00:00 2001 From: atm-benoit Date: Fri, 4 Dec 2020 15:37:00 +0100 Subject: [PATCH 075/137] FIX SUPPLIER PROPOSAL v12 bug add --- htdocs/supplier_proposal/card.php | 66 +++++++++++++++---------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 08479b95871..529c446df4d 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -554,8 +554,8 @@ if (empty($reshook)) } else { - $idprod = GETPOST('idprod', 'int'); - $price_ht = ''; + $idprod = GETPOST('idprod', 'int'); + $price_ht = GETPOST('price_ht'); $tva_tx = ''; } @@ -589,8 +589,8 @@ if (empty($reshook)) $error++; } if (!$error && ($qty >= 0)) { - $pu_ht = 0; - $pu_ttc = 0; + $pu_ht = price2num($price_ht, 'MU'); + $pu_ttc = price2num(GETPOST('price_ttc'), 'MU'); $price_min = 0; $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT'); @@ -658,41 +658,41 @@ if (empty($reshook)) $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr); $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr); - $pu_ht = $productsupplier->fourn_pu; if (empty($pu_ht)) $pu_ht = 0; // If pu is '' or null, we force to have a numeric value // If GETPOST('idprodfournprice') is a numeric, we can use it. If it is empty or if it is 'idprod_123', we should use -1 (not used) $fournprice = (is_numeric(GETPOST('idprodfournprice', 'alpha')) ? GETPOST('idprodfournprice', 'alpha') : -1); $buyingprice = 0; - + $pu_ht_devise = price2num($price_ht_devise, 'MU'); + $result = $object->addline( - $desc, - $pu_ht, - $qty, - $tva_tx, - $localtax1_tx, - $localtax2_tx, - $productsupplier->id, - $remise_percent, - $price_base_type, - $pu_ttc, - $tva_npr, - $type, - -1, - 0, - GETPOST('fk_parent_line'), - $fournprice, - $buyingprice, - $label, - $array_options, - $ref_supplier, - $productsupplier->fk_unit, - '', - 0, - $productsupplier->fourn_multicurrency_unitprice, - $date_start, - $date_end - ); + $desc, + $pu_ht, + $qty, + $tva_tx, + $localtax1_tx, + $localtax2_tx, + $productsupplier->id, + $remise_percent, + $price_base_type, + $pu_ttc, + $tva_npr, + $type, + -1, + 0, + GETPOST('fk_parent_line'), + $fournprice, + $buyingprice, + $label, + $array_options, + $ref_supplier, + $productsupplier->fk_unit, + '', + 0, + $pu_ht_devise, + $date_start, + $date_end + ); //var_dump($tva_tx);var_dump($productsupplier->fourn_pu);var_dump($price_base_type);exit; if ($result < 0) From ddf82f3e7a69d75cc414279eeed0250e560d525c Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 4 Dec 2020 14:45:26 +0000 Subject: [PATCH 076/137] Fixing style errors. --- htdocs/supplier_proposal/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 529c446df4d..708844b71c8 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -664,7 +664,7 @@ if (empty($reshook)) $fournprice = (is_numeric(GETPOST('idprodfournprice', 'alpha')) ? GETPOST('idprodfournprice', 'alpha') : -1); $buyingprice = 0; $pu_ht_devise = price2num($price_ht_devise, 'MU'); - + $result = $object->addline( $desc, $pu_ht, From d22646e6ae8df3f811d2b85b291940c662bd9ad5 Mon Sep 17 00:00:00 2001 From: atm-lena Date: Fri, 4 Dec 2020 16:06:10 +0100 Subject: [PATCH 077/137] pricetonum() - preg-replace() delete "-" negativ number --- 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 2a9052d0916..5094fad392a 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4724,7 +4724,7 @@ function price2num($amount, $rounding = '', $option = 0) if ($option != 1) { // If not a PHP number or unknown, we change or clean format //print 'PP'.$amount.' - '.$dec.' - '.$thousand.' - '.intval($amount).'
'; if (!is_numeric($amount)) { - $amount = preg_replace('/[a-zA-Z\/\\\*\(\)\<\>\-]/', '', $amount); + $amount = preg_replace('/[a-zA-Z\/\\\*\(\)\<\>]/', '', $amount); } if ($option == 2 && $thousand == '.' && preg_match('/\.(\d\d\d)$/', (string) $amount)) { // It means the . is used as a thousand separator and string come frominput data, so 1.123 is 1123 From 223205cf9db90f85a2763aebb7fc8697e9c960ce Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Fri, 4 Dec 2020 16:54:40 +0100 Subject: [PATCH 078/137] Fix volume calcution, depends on surface not surface_units surface_unit can be 0 for m2 --- 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 0e9841201de..7d1d326cabb 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -854,7 +854,7 @@ class Product extends CommonObject $this->surface = $this->length * $this->width; $this->surface_units = measuring_units_squared($this->length_units); } - if (empty($this->volume) && !empty($this->surface_units) && !empty($this->height) && $this->length_units == $this->height_units) { + if (empty($this->volume) && !empty($this->surface) && !empty($this->height) && $this->length_units == $this->height_units) { $this->volume = $this->surface * $this->height; $this->volume_units = measuring_units_cubed($this->height_units); } From 49db52134ba5e09c8cf022bc1cdbe763917c1f7e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Dec 2020 18:19:51 +0100 Subject: [PATCH 079/137] Fix for negative numbers --- test/phpunit/FunctionsLibTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 3d098131f21..a54b1a04674 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1267,9 +1267,9 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $this->assertEquals(1234, price2num('1.234', '', 2), 'Test 1.234 give 1234 with spanish language if user input'); $this->assertEquals(1.234, price2num('1,234', '', 2), 'Test 1,234 give 1234 with spanish language if user input'); $this->assertEquals(1234, price2num('1 234', '', 2), 'Test 1 234 give 1234 with spanish language if user input'); - $this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with spanish language'); - $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1234 with spanish language'); - $this->assertEquals(1234, price2num('1 234'), 'Test 1 234 give 1234 with spanish language'); + $this->assertEquals(-1.234, price2num('-1.234'), 'Test 1.234 give 1.234 with spanish language'); + $this->assertEquals(-1.234, price2num('-1,234'), 'Test 1,234 give 1234 with spanish language'); + $this->assertEquals(-1234, price2num('-1 234'), 'Test 1 234 give 1234 with spanish language'); $this->assertEquals(21500123, price2num('21.500.123'), 'Test 21.500.123 give 21500123 with spanish language'); $this->assertEquals(21500123, price2num('21500.123', 0, 2), 'Test 21500.123 give 21500123 with spanish language if user input'); $this->assertEquals(21500.123, price2num('21500.123'), 'Test 21500.123 give 21500123 with spanish language'); From 3770eef8dc4e3b75b2ee89e73c483851c85c8874 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Dec 2020 19:51:14 +0100 Subject: [PATCH 080/137] Fix can import all categories --- htdocs/core/modules/modCategorie.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index 0ea473ed95b..138de679f51 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -374,7 +374,7 @@ class modCategorie extends DolibarrModules 'ca.label'=>"Label*", 'ca.type'=>"Type*", 'ca.description'=>"Description", 'ca.fk_parent' => 'Parent' ); - $this->import_regex_array[$r] = array('ca.type'=>'^[0|1|2|3]'); + $this->import_regex_array[$r] = array('ca.type'=>'^(0|1|2|3|4|5|6|7|8|9|10|11)$'); $this->import_convertvalue_array[$r] = array( 'ca.fk_parent' => array( 'rule' => 'fetchidfromcodeandlabel', From d1c66059cd7ef147285b7c914a8fa1dd8ac87432 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 6 Dec 2020 19:01:09 +0100 Subject: [PATCH 081/137] Add missing tag order_ref and order_ref_customer on shipments for ODT generation. Conflicts: htdocs/core/class/commondocgenerator.class.php --- htdocs/core/class/commondocgenerator.class.php | 10 ++++++++-- .../doc/doc_generic_shipment_odt.modules.php | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 90cfd84cf69..aa8cb7a1301 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -690,8 +690,14 @@ abstract class CommonDocGenerator $array_shipment = $this->fill_substitutionarray_with_extrafields($object, $array_shipment, $extrafields, $array_key, $outputlangs); } - return $array_shipment; - } + // Add infor from $object->xxx where xxx has been loaded by fetch_origin() of shipment + if (!empty($object->commande) && is_object($object->commande)) { + $array_shipment['order_ref'] = $object->commande->ref; + $array_shipment['order_ref_customer'] = $object->commande->ref_customer; + } + + return $array_shipment; + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps diff --git a/htdocs/core/modules/expedition/doc/doc_generic_shipment_odt.modules.php b/htdocs/core/modules/expedition/doc/doc_generic_shipment_odt.modules.php index 8b255e146d5..dffe3197c7b 100644 --- a/htdocs/core/modules/expedition/doc/doc_generic_shipment_odt.modules.php +++ b/htdocs/core/modules/expedition/doc/doc_generic_shipment_odt.modules.php @@ -468,6 +468,7 @@ class doc_generic_shipment_odt extends ModelePdfExpedition // Replace tags of object + external modules $tmparray = $this->get_substitutionarray_shipment($object, $outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object); // Call the ODTSubstitution hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray); From 7ad70c7c218410575065b6fff36acfe9604ead0e Mon Sep 17 00:00:00 2001 From: Frans Bosman Date: Mon, 7 Dec 2020 14:33:44 +0100 Subject: [PATCH 082/137] Update product.class.php Added Hidden Option STOCK_DEFAULT_BATCH, in order to replace the default '000000' batchnumber for the existing stock when batchnumbers are enabled for a product. --- htdocs/product/class/product.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index ac931da8702..9abd1d82da5 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -934,6 +934,7 @@ class Product extends CommonObject if ($this->hasbatch() && !$this->oldcopy->hasbatch()) { //$valueforundefinedlot = 'Undefined'; // In previous version, 39 and lower $valueforundefinedlot = '000000'; + if ($conf->global->STOCK_DEFAULT_BATCH) $valueforundefinedlot = $conf->global->STOCK_DEFAULT_BATCH; dol_syslog("Flag batch of product id=".$this->id." is set to ON, so we will create missing records into product_batch"); From f871ade5452630ad12bab6608eb53e18fcdb870e Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Mon, 7 Dec 2020 15:15:41 +0100 Subject: [PATCH 083/137] FIX 12.0 - the stringent XSS prodection provided by 'alphanohtml' causes problems with some clients who used basic tags (bold, italic, underline) in product labels. Using 'restricthtml' instead could be a good compromise. --- htdocs/product/card.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 8b4654ba921..8659e5bcc23 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -201,7 +201,7 @@ if (empty($reshook)) { $error = 0; - if (!GETPOST('label', 'alphanohtml')) + if (!GETPOST('label', 'restricthtml')) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Label')), null, 'errors'); $action = "create"; @@ -225,7 +225,7 @@ if (empty($reshook)) $units = GETPOST('units', 'int'); $object->ref = $ref; - $object->label = GETPOST('label', 'alphanohtml'); + $object->label = GETPOST('label', 'restricthtml'); $object->price_base_type = GETPOST('price_base_type', 'aZ09'); if ($object->price_base_type == 'TTC') @@ -406,7 +406,7 @@ if (empty($reshook)) $object->oldcopy = clone $object; $object->ref = $ref; - $object->label = GETPOST('label', 'alphanohtml'); + $object->label = GETPOST('label', 'restricthtml'); $object->description = dol_htmlcleanlastbr(GETPOST('desc', 'none')); $object->url = GETPOST('url'); if (!empty($conf->global->MAIN_DISABLE_NOTES_TAB)) @@ -1005,7 +1005,7 @@ else print '
'; // Label - print ''; + print ''; // On sell print ''; // Label - print ''; + print ''; // On sell print ''; print ''; print '
'.$langs->trans('Ref').''.$langs->trans('Invoice').''.$langs->trans('RefSupplier').''.$langs->trans('Company').''.$langs->trans('ExpectedToPay').'
'.$langs->trans("Label").'
'.$langs->trans("Label").'
'.$langs->trans("Status").' ('.$langs->trans("Sell").')'; From 669205af1c05f879a59f57a2160b7515991d964b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Dec 2020 19:02:49 +0100 Subject: [PATCH 084/137] 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 9abd1d82da5..ccca1a85f47 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -934,7 +934,7 @@ class Product extends CommonObject if ($this->hasbatch() && !$this->oldcopy->hasbatch()) { //$valueforundefinedlot = 'Undefined'; // In previous version, 39 and lower $valueforundefinedlot = '000000'; - if ($conf->global->STOCK_DEFAULT_BATCH) $valueforundefinedlot = $conf->global->STOCK_DEFAULT_BATCH; + if (!empty($conf->global->STOCK_DEFAULT_BATCH)) $valueforundefinedlot = $conf->global->STOCK_DEFAULT_BATCH; dol_syslog("Flag batch of product id=".$this->id." is set to ON, so we will create missing records into product_batch"); From 7c77a0d84b1a5128037b6f31bd155b8be9fb3d67 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 7 Dec 2020 23:53:09 +0100 Subject: [PATCH 085/137] FIX : Export FEC - Remove line at zero --- .../class/accountancyexport.class.php | 85 ++++++++++--------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 11486bf76c9..a7183c70114 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -688,65 +688,70 @@ class AccountancyExport print $end_line; foreach ($objectLines as $line) { - $date_creation = dol_print_date($line->date_creation, '%Y%m%d'); - $date_document = dol_print_date($line->doc_date, '%Y%m%d'); - $date_validation = dol_print_date($line->date_validated, '%Y%m%d'); + if ($line->debit == 0 && $line->credit == 0) { + unset($array[$line]); + } else { + $date_creation = dol_print_date($line->date_creation, '%Y%m%d'); + $date_document = dol_print_date($line->doc_date, '%Y%m%d'); + $date_lettering = dol_print_date($line->date_lettering, '%Y%m%d'); + $date_validation = dol_print_date($line->date_validated, '%Y%m%d'); - // FEC:JournalCode - print $line->code_journal . $separator; + // FEC:JournalCode + print $line->code_journal . $separator; - // FEC:JournalLib - print $line->journal_label . $separator; + // FEC:JournalLib + print $line->journal_label . $separator; - // FEC:EcritureNum - print $line->piece_num . $separator; + // FEC:EcritureNum + print $line->piece_num . $separator; - // FEC:EcritureDate - print $date_document . $separator; + // FEC:EcritureDate + print $date_document . $separator; - // FEC:CompteNum - print $line->numero_compte . $separator; + // FEC:CompteNum + print $line->numero_compte . $separator; - // FEC:CompteLib - print dol_string_unaccent($line->label_compte) . $separator; + // FEC:CompteLib + print dol_string_unaccent($line->label_compte) . $separator; - // FEC:CompAuxNum - print $line->subledger_account . $separator; + // FEC:CompAuxNum + print $line->subledger_account . $separator; - // FEC:CompAuxLib - print dol_string_unaccent($line->subledger_label) . $separator; + // FEC:CompAuxLib + print dol_string_unaccent($line->subledger_label) . $separator; - // FEC:PieceRef - print $line->doc_ref . $separator; + // FEC:PieceRef + print $line->doc_ref . $separator; - // FEC:PieceDate - print dol_string_unaccent($date_creation) . $separator; + // FEC:PieceDate + print $date_creation . $separator; - // FEC:EcritureLib - print $line->label_operation . $separator; + // FEC:EcritureLib + print dol_string_unaccent($line->label_operation) . $separator; - // FEC:Debit - print price2fec($line->debit) . $separator; + // FEC:Debit + print price2fec($line->debit) . $separator; - // FEC:Credit - print price2fec($line->credit) . $separator; + // FEC:Credit + print price2fec($line->credit) . $separator; - // FEC:EcritureLet - print $line->lettering_code . $separator; + // FEC:EcritureLet + print $line->lettering_code . $separator; - // FEC:DateLet - print $line->date_lettering . $separator; + // FEC:DateLet + print $date_lettering . $separator; - // FEC:ValidDate - print $date_validation . $separator; + // FEC:ValidDate + print $date_validation . $separator; - // FEC:Montantdevise - print $line->multicurrency_amount . $separator; + // FEC:Montantdevise + print $line->multicurrency_amount . $separator; - // FEC:Idevise - print $line->multicurrency_code; + // FEC:Idevise + print $line->multicurrency_code; - print $end_line; + print $end_line; + } } } From 617c9f7ea93a30714c70238958a63cb1933c6592 Mon Sep 17 00:00:00 2001 From: Florian Mortgat Date: Tue, 8 Dec 2020 09:30:31 +0100 Subject: [PATCH 086/137] FIX: enable HTML in product labels depending on conf MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML --- htdocs/product/card.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 8659e5bcc23..d6f62b34769 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -86,6 +86,9 @@ $accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); $accountancy_code_buy_intra = GETPOST('accountancy_code_buy_intra', 'alpha'); $accountancy_code_buy_export = GETPOST('accountancy_code_buy_export', 'alpha'); +// by default 'alphanohtml' (better security); hidden conf MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML allows basic html +$label_security_check = empty($conf->global->MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML) ? 'alphanohtml' : 'restricthtml'; + if (!empty($user->socid)) $socid = $user->socid; $object = new Product($db); @@ -201,7 +204,7 @@ if (empty($reshook)) { $error = 0; - if (!GETPOST('label', 'restricthtml')) + if (!GETPOST('label', $label_security_check)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Label')), null, 'errors'); $action = "create"; @@ -225,7 +228,7 @@ if (empty($reshook)) $units = GETPOST('units', 'int'); $object->ref = $ref; - $object->label = GETPOST('label', 'restricthtml'); + $object->label = GETPOST('label', $label_security_check); $object->price_base_type = GETPOST('price_base_type', 'aZ09'); if ($object->price_base_type == 'TTC') @@ -406,7 +409,7 @@ if (empty($reshook)) $object->oldcopy = clone $object; $object->ref = $ref; - $object->label = GETPOST('label', 'restricthtml'); + $object->label = GETPOST('label', $label_security_check); $object->description = dol_htmlcleanlastbr(GETPOST('desc', 'none')); $object->url = GETPOST('url'); if (!empty($conf->global->MAIN_DISABLE_NOTES_TAB)) @@ -1005,7 +1008,7 @@ else print '
'.$langs->trans("Label").'
'.$langs->trans("Label").'
'.$langs->trans("Status").' ('.$langs->trans("Sell").')'; From 485fe0fc62a4d452c429de2d68e4883692114013 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 8 Dec 2020 17:51:26 +0100 Subject: [PATCH 087/137] FIX Can receipt of a product that required lot after disabling stock and lot module --- htdocs/expedition/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 289d317abb7..3e76b2bb12a 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -240,7 +240,7 @@ if (empty($reshook)) $stockLocation = "ent1".$i."_0"; $qty = "qtyl".$i; - if ($objectsrc->lines[$i]->product_tobatch) // If product need a batch number + if (!empty($conf->productbatch->enabled) && $objectsrc->lines[$i]->product_tobatch) // If product need a batch number { if (GETPOSTISSET($batch)) { From 75b8794d72d529e219434a1554805c4715f89228 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 8 Dec 2020 22:23:24 +0100 Subject: [PATCH 088/137] Fix column must be NULL --- htdocs/install/mysql/migration/11.0.0-12.0.0.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index fddfb8c8097..425e47d3251 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -341,6 +341,9 @@ ALTER TABLE llx_expedition ADD COLUMN billed smallint DEFAULT 0; ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_commande (fk_commande); ALTER TABLE llx_commande_fournisseurdet ADD INDEX idx_commande_fournisseurdet_fk_product (fk_product); + +-- VMYSQL4.3 ALTER TABLE llx_c_shipment_mode MODIFY COLUMN tracking varchar(255) NULL; + INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (9,'INPERSON', 'In person at your site', NULL, NULL, 0); INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (10,'FEDEX', 'Fedex', NULL, 'https://www.fedex.com/apps/fedextrack/index.html?tracknumbers={TRACKID}', 0); INSERT INTO llx_c_shipment_mode (rowid,code,libelle,description,tracking,active) VALUES (11,'TNT', 'TNT', NULL, 'https://www.tnt.com/express/fr_fr/site/outils-expedition/suivi.html?searchType=con&cons=={TRACKID}', 0); From 7360fcd03eff59eaa8bb4541ef23f5acf39237c0 Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Thu, 10 Dec 2020 13:11:55 +0100 Subject: [PATCH 089/137] FIX: Bad rigths to send contract --- htdocs/contrat/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index dbdba874dda..368e09d8ccd 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -6,7 +6,7 @@ * Copyright (C) 2010-2017 Juanjo Menent * Copyright (C) 2013 Christophe Battarel * Copyright (C) 2013-2014 Florian Henry - * Copyright (C) 2014-2018 Ferran Marcet + * Copyright (C) 2014-2020 Ferran Marcet * Copyright (C) 2014-2016 Marcos García * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2018-2020 Frédéric France @@ -2108,7 +2108,7 @@ else // Send if (empty($user->socid)) { if ($object->statut == 1) { - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->commande->order_advance->send)) { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->contrat->creer)) { print ''; } else print ''; From bcf4f65cc979fe29f6d27c6a2dfe5c8a0797e601 Mon Sep 17 00:00:00 2001 From: Stephane Lesage Date: Thu, 3 Dec 2020 19:45:36 +0100 Subject: [PATCH 090/137] Fix & sync import/export entity icons/labels translation --- htdocs/core/modules/modSociete.class.php | 4 +- htdocs/core/modules/modStock.class.php | 123 ++++++++++++-------- htdocs/exports/export.php | 46 ++++---- htdocs/imports/import.php | 139 +++++++++++++++++------ htdocs/langs/en_US/exports.lang | 1 + htdocs/langs/fr_FR/exports.lang | 1 + 6 files changed, 203 insertions(+), 111 deletions(-) diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index a88ddc355a4..b0346054323 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -478,7 +478,7 @@ class modSociete extends DolibarrModules 'classfile' => '/core/class/cstate.class.php', 'class' => 'Cstate', 'method' => 'fetch', - 'dict' => 'DictionaryState' + 'dict' => 'DictionaryStateCode' ), 's.fk_pays' => array( 'rule' => 'fetchidfromcodeid', @@ -630,7 +630,7 @@ class modSociete extends DolibarrModules 'classfile' => '/core/class/cstate.class.php', 'class' => 'Cstate', 'method' => 'fetch', - 'dict' => 'DictionaryState' + 'dict' => 'DictionaryStateCode' ), 's.fk_pays' => array( 'rule' => 'fetchidfromcodeid', diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php index 4dd1a740278..81cebc83ff5 100644 --- a/htdocs/core/modules/modStock.class.php +++ b/htdocs/core/modules/modStock.class.php @@ -188,28 +188,31 @@ class modStock extends DolibarrModules //-------- $r = 0; + // Export stock (without batch number) $r++; $this->export_code[$r] = $this->rights_class; - $this->export_label[$r] = "WarehousesAndProducts"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_label[$r] = "Stocks"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r] = "warehouse"; $this->export_permission[$r] = array(array("stock", "lire")); $this->export_fields_array[$r] = array( - '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', 'p.pmp'=>'PMPValue', 'p.cost_price'=>'CostPrice' + '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', 'p.pmp'=>'PMPValue', 'p.cost_price'=>'CostPrice', ); $this->export_TypeFields_array[$r] = array( - 'e.rowid'=>'List:entrepot:ref::stock', 'e.ref'=>'Text', 'e.lieu'=>'Text', 'e.address'=>'Text', 'e.zip'=>'Text', 'e.town'=>'Text', 'p.rowid'=>"List:product:label::product", - 'p.ref'=>"Text", 'p.fk_product_type'=>"Text", 'p.label'=>"Text", 'p.description'=>"Text", 'p.note'=>"Text", 'p.price'=>"Numeric", 'p.tva_tx'=>'Numeric', - 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean", 'p.duration'=>"Duree", 'p.datec'=>'Date', 'p.tms'=>'Date', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric', + 'e.rowid'=>'List:entrepot:ref::stock', 'e.ref'=>'Text', 'e.lieu'=>'Text', 'e.address'=>'Text', 'e.zip'=>'Text', 'e.town'=>'Text', + 'p.rowid'=>"List:product:label::product", 'p.ref'=>"Text", 'p.fk_product_type'=>"Text", 'p.label'=>"Text", 'p.description'=>"Text", 'p.note'=>"Text", + 'p.price'=>"Numeric", 'p.tva_tx'=>'Numeric', 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean", 'p.duration'=>"Duree", + 'p.datec'=>'Date', 'p.tms'=>'Date', 'p.pmp'=>'Numeric', 'p.cost_price'=>'Numeric', 'ps.reel'=>'Numeric' ); $this->export_entities_array[$r] = array( - 'e.rowid'=>'warehouse', 'e.ref'=>'warehouse', 'e.description'=>'warehouse', 'e.lieu'=>'warehouse', 'e.address'=>'warehouse', 'e.zip'=>'warehouse', - 'e.town'=>'warehouse', 'p.rowid'=>"product", 'p.ref'=>"product", 'p.fk_product_type'=>"product", 'p.label'=>"product", 'p.description'=>"product", - 'p.note'=>"product", 'p.price'=>"product", 'p.tva_tx'=>'product', 'p.tosell'=>"product", 'p.tobuy'=>"product", 'p.duration'=>"product", - 'p.datec'=>'product', 'p.tms'=>'product', 'p.pmp'=>'product', 'p.cost_price'=>'product', 'ps.reel'=>'stock' - ); + 'p.rowid'=>"product", 'p.ref'=>"product", 'p.fk_product_type'=>"product", 'p.label'=>"product", 'p.description'=>"product", 'p.note'=>"product", + 'p.price'=>"product", 'p.tva_tx'=>'product', 'p.tosell'=>"product", 'p.tobuy'=>"product", 'p.duration'=>"product", + 'p.datec'=>'product', 'p.tms'=>'product', 'p.pmp'=>'product', 'p.cost_price'=>'product', + 'ps.reel'=>'stock' + ); // We define here only fields that use another icon that the one defined into export_icon $this->export_aggregate_array[$r] = array('ps.reel'=>'SUM'); // TODO Not used yet $this->export_dependencies_array[$r] = array('stock'=>array('p.rowid', 'e.rowid')); // We must keep this until the aggregate_array is used. To have a unique key, if we ask a field of a child, to avoid the DISTINCT to discard them. $keyforselect = 'product'; $keyforelement = 'product'; $keyforaliasextra = 'extra'; @@ -220,73 +223,78 @@ class modStock extends DolibarrModules $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p LEFT JOIN '.MAIN_DB_PREFIX.'product_extrafields as extra ON extra.fk_object = p.rowid, '.MAIN_DB_PREFIX.'product_stock as ps, '.MAIN_DB_PREFIX.'entrepot as e'; $this->export_sql_end[$r] .= ' WHERE p.rowid = ps.fk_product AND ps.fk_entrepot = e.rowid'; $this->export_sql_end[$r] .= ' AND e.entity IN ('.getEntity('stock').')'; + + // Export stock including batch number if ($conf->productbatch->enabled) { - // Export of stock including lot number $langs->load("productbatch"); // This request is same than previous but without field ps.stock (real stock in warehouse) and with link to subtable productbatch $r++; $this->export_code[$r] = $this->rights_class.'_lot'; - $this->export_label[$r] = "WarehousesAndProductsBatchDetail"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_label[$r] = "StocksWithBatch"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r] = "warehouse"; $this->export_permission[$r] = array(array("stock", "lire")); $this->export_fields_array[$r] = array( - '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', 'pb.rowid'=>'Id', 'pb.batch'=>'Batch', 'pb.qty'=>'Qty', 'pl.eatby'=>'EatByDate', 'pl.sellby'=>'SellByDate' + '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', 'p.pmp'=>'PMPValue', 'p.cost_price'=>'CostPrice', + 'pb.rowid'=>'Id', 'pb.batch'=>'Batch', 'pb.qty'=>'Qty', + 'pl.eatby'=>'EatByDate', 'pl.sellby'=>'SellByDate' ); $this->export_TypeFields_array[$r] = array( 'e.rowid'=>'List:entrepot:ref::stock', 'e.ref'=>'Text', 'e.lieu'=>'Text', 'e.description'=>'Text', 'e.address'=>'Text', 'e.zip'=>'Text', 'e.town'=>'Text', 'p.rowid'=>"List:product:label::product", 'p.ref'=>"Text", 'p.fk_product_type'=>"Text", 'p.label'=>"Text", 'p.description'=>"Text", 'p.note'=>"Text", - 'p.price'=>"Numeric", 'p.tva_tx'=>'Numeric', 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean", 'p.duration'=>"Duree", 'p.datec'=>'Date', 'p.tms'=>'Date', - 'pb.batch'=>'Text', 'pb.qty'=>'Numeric', 'pl.eatby'=>'Date', 'pl.sellby'=>'Date' + 'p.price'=>"Numeric", 'p.tva_tx'=>'Numeric', 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean", 'p.duration'=>"Duree", + 'p.datec'=>'DateCreation', 'p.tms'=>'DateModification', 'p.pmp'=>'PMPValue', 'p.cost_price'=>'CostPrice', + 'pb.batch'=>'Text', 'pb.qty'=>'Numeric', + 'pl.eatby'=>'Date', 'pl.sellby'=>'Date' ); $this->export_entities_array[$r] = array( - 'e.rowid'=>'warehouse', 'e.ref'=>'warehouse', 'e.description'=>'warehouse', 'e.lieu'=>'warehouse', 'e.address'=>'warehouse', 'e.zip'=>'warehouse', - 'e.town'=>'warehouse', 'p.rowid'=>"product", 'p.ref'=>"product", 'p.fk_product_type'=>"product", 'p.label'=>"product", 'p.description'=>"product", - 'p.note'=>"product", 'p.price'=>"product", 'p.tva_tx'=>'product', 'p.tosell'=>"product", 'p.tobuy'=>"product", 'p.duration'=>"product", - 'p.datec'=>'product', 'p.tms'=>'product', 'pb.rowid'=>'stockbatch', 'pb.batch'=>'stockbatch', 'pb.qty'=>'stockbatch', 'pl.eatby'=>'batch', - 'pl.sellby'=>'batch' - ); + 'p.rowid'=>"product", 'p.ref'=>"product", 'p.fk_product_type'=>"product", 'p.label'=>"product", 'p.description'=>"product", 'p.note'=>"product", + 'p.price'=>"product", 'p.tva_tx'=>'product', 'p.tosell'=>"product", 'p.tobuy'=>"product", 'p.duration'=>"product", + 'p.datec'=>'product', 'p.tms'=>'product', 'p.pmp'=>'product', 'p.cost_price'=>'product', + 'pb.rowid'=>'batch', 'pb.batch'=>'batch', 'pb.qty'=>'batch', + 'pl.eatby'=>'batch', 'pl.sellby'=>'batch' + ); // We define here only fields that use another icon that the one defined into export_icon $this->export_aggregate_array[$r] = array('ps.reel'=>'SUM'); // TODO Not used yet $this->export_dependencies_array[$r] = array('stockbatch'=>array('pb.rowid'), 'batch'=>array('pb.rowid')); // We must keep this until the aggregate_array is used. To add unique key if we ask a field of a child to avoid the DISTINCT to discard them. $keyforselect = 'product_lot'; $keyforelement = 'batch'; $keyforaliasextra = 'extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM ('.MAIN_DB_PREFIX.'product as p, '.MAIN_DB_PREFIX.'product_stock as ps, '.MAIN_DB_PREFIX.'product_batch as pb)'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_lot as pl ON pl.fk_product = p.rowid AND pl.batch = pb.batch'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_lot_extrafields as extra ON extra.fk_object = pl.rowid,'; $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'entrepot as e'; $this->export_sql_end[$r] .= ' WHERE p.rowid = ps.fk_product AND ps.fk_entrepot = e.rowid AND ps.rowid = pb.fk_product_stock'; - $this->export_sql_end[$r] .= ' AND e.entity IN ('.getEntity('stock').')'; - } + $this->export_sql_end[$r] .= ' AND e.entity IN ('.getEntity('stock').')'; } - // Export of stock movement + // Export of stock movements $r++; $this->export_code[$r] = $this->rights_class.'_movement'; $this->export_label[$r] = "StockMovements"; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_icon[$r] = "movement"; $this->export_permission[$r] = array(array("stock", "lire")); $this->export_fields_array[$r] = array( - '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'=>'MovementLabel', - 'sm.inventorycode'=>'InventoryCode' + 'sm.rowid'=>'MovementId', 'sm.value'=>'Qty', 'sm.datem'=>'DateMovement', 'sm.label'=>'MovementLabel', 'sm.inventorycode'=>'InventoryCode', + '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' ); $this->export_TypeFields_array[$r] = array( + 'sm.rowid'=>'Numeric', 'sm.value'=>'Numeric', 'sm.datem'=>'Date', 'sm.batch'=>'Text', 'sm.label'=>'Text', 'sm.inventorycode'=>'Text', 'e.rowid'=>'List:entrepot:ref::stock', 'e.ref'=>'Text', 'e.description'=>'Text', 'e.lieu'=>'Text', 'e.address'=>'Text', 'e.zip'=>'Text', 'e.town'=>'Text', 'p.rowid'=>"List:product:label::product", 'p.ref'=>"Text", 'p.fk_product_type'=>"Text", 'p.label'=>"Text", 'p.description'=>"Text", 'p.note'=>"Text", - 'p.price'=>"Numeric", 'p.tva_tx'=>'Numeric', 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean", 'p.duration'=>"Duree", 'p.datec'=>'Date', 'p.tms'=>'Date', - 'sm.rowid'=>'Numeric', 'sm.value'=>'Numeric', 'sm.datem'=>'Date', 'sm.batch'=>'Text', 'sm.label'=>'Text', 'sm.inventorycode'=>'Text' + 'p.price'=>"Numeric", 'p.tva_tx'=>'Numeric', 'p.tosell'=>"Boolean", 'p.tobuy'=>"Boolean", 'p.duration'=>"Duree", 'p.datec'=>'Date', 'p.tms'=>'Date' ); $this->export_entities_array[$r] = array( - 'e.rowid'=>'warehouse', 'e.ref'=>'warehouse', 'e.description'=>'warehouse', 'e.lieu'=>'warehouse', 'e.address'=>'warehouse', 'e.zip'=>'warehouse', - 'e.town'=>'warehouse', 'p.rowid'=>"product", 'p.ref'=>"product", 'p.fk_product_type'=>"product", 'p.label'=>"product", 'p.description'=>"product", - 'p.note'=>"product", 'p.price'=>"product", 'p.tva_tx'=>'product', 'p.tosell'=>"product", 'p.tobuy'=>"product", 'p.duration'=>"product", 'p.datec'=>'product', - 'p.tms'=>'product', 'sm.rowid'=>'movement', 'sm.value'=>'movement', 'sm.datem'=>'movement', 'sm.label'=>'movement', 'sm.inventorycode'=>'movement' - ); + 'e.rowid'=>'warehouse', 'e.ref'=>'warehouse', 'e.description'=>'warehouse', 'e.lieu'=>'warehouse', 'e.address'=>'warehouse', 'e.zip'=>'warehouse', 'e.town'=>'warehouse', + 'p.rowid'=>"product", 'p.ref'=>"product", 'p.fk_product_type'=>"product", 'p.label'=>"product", 'p.description'=>"product", 'p.note'=>"product", + 'p.price'=>"product", 'p.tva_tx'=>'product', 'p.tosell'=>"product", 'p.tobuy'=>"product", 'p.duration'=>"product", 'p.datec'=>'product', 'p.tms'=>'product' + ); // We define here only fields that use another icon that the one defined into export_icon if ($conf->productbatch->enabled) { $this->export_fields_array[$r]['sm.batch'] = 'Batch'; @@ -295,6 +303,7 @@ class modStock extends DolibarrModules } $this->export_aggregate_array[$r] = array('sm.value'=>'SUM'); // TODO Not used yet $this->export_dependencies_array[$r] = array('movement'=>array('sm.rowid')); // We must keep this until the aggregate_array is used. To add unique key if we ask a field of a child to avoid the DISTINCT to discard them. + $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'product as p, '.MAIN_DB_PREFIX.'stock_mouvement as sm, '.MAIN_DB_PREFIX.'entrepot as e'; $this->export_sql_end[$r] .= ' WHERE p.rowid = sm.fk_product AND sm.fk_entrepot = e.rowid'; @@ -309,34 +318,48 @@ class modStock extends DolibarrModules $r++; $this->import_code[$r] = $this->rights_class.'_'.$r; $this->import_label[$r] = "Warehouses"; // Translation key - $this->import_icon[$r] = $this->picto; + $this->import_icon[$r] = "warehouse"; $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r] = array('e'=>MAIN_DB_PREFIX.'entrepot'); $this->import_tables_creator_array[$r] = array('e'=>'fk_user_author'); $this->import_fields_array[$r] = array('e.ref'=>"LocationSummary*", - 'e.description'=>"DescWareHouse", 'e.lieu'=>"LieuWareHouse", - 'e.address'=>"Address", 'e.zip'=>'Zip', 'e.fk_pays'=>'CountryCode', + 'e.description'=>"DescWareHouse", + 'e.lieu'=>"LieuWareHouse", + 'e.address'=>"Address", + 'e.zip'=>'Zip', + 'e.fk_departement'=>'StateCode', + 'e.fk_pays'=>'CountryCode', + 'e.phone'=>'Phone', + 'e.fax'=>'Fax', 'e.statut'=>'Status', 'e.fk_parent'=>'ParentWarehouse' ); $this->import_convertvalue_array[$r] = array( + 'e.fk_departement'=>array('rule'=>'fetchidfromcodeid', 'classfile'=>'/core/class/cstate.class.php', 'class'=>'Cstate', 'method'=>'fetch', 'dict'=>'DictionaryStateCode'), 'e.fk_pays'=>array('rule'=>'fetchidfromcodeid', 'classfile'=>'/core/class/ccountry.class.php', 'class'=>'Ccountry', 'method'=>'fetch', 'dict'=>'DictionaryCountry'), 'e.fk_parent'=>array('rule'=>'fetchidfromref', 'classfile'=>'/product/stock/class/entrepot.class.php', 'class'=>'Entrepot', 'method'=>'fetch', 'element'=>'ref') ); $this->import_regex_array[$r] = array('e.statut'=>'^[0|1]'); $this->import_examplevalues_array[$r] = array('e.ref'=>"ALM001", - 'e.description'=>"Central Warehouse", 'e.lieu'=>"Central", - 'e.address'=>"Route 66", 'e.zip'=>'28080', 'e.fk_pays'=>'US', + 'e.description'=>"Central Warehouse", + 'e.lieu'=>"Central", + 'e.address'=>"Route 66", + 'e.zip'=>'28080', + 'e.fk_departement'=>'matches field "code_departement" in table "'.MAIN_DB_PREFIX.'c_departements"', + 'e.fk_pays'=>'US/FR/DE etc. matches field "code" in table "'.MAIN_DB_PREFIX.'c_country"', + 'e.phone'=>'(+33)(0)123456789', + 'e.fax'=>'(+33)(0)123456790', 'e.statut'=>'1', - 'e.fk_parent'=>'' + 'e.fk_parent'=>'id or ref in this table' ); + $this->import_updatekeys_array[$r] = array('p.ref'=>'Ref'); // Import stocks $r++; $this->import_code[$r] = $this->rights_class.'_'.$r; $this->import_label[$r] = "Stocks"; // Translation key - $this->import_icon[$r] = $this->picto; + $this->import_icon[$r] = "stock"; $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r] = array('ps'=>MAIN_DB_PREFIX.'product_stock'); $this->import_fields_array[$r] = array('ps.fk_product'=>"Product*", 'ps.fk_entrepot'=>"Warehouse*", 'ps.reel'=>"Stock*"); @@ -346,7 +369,7 @@ class modStock extends DolibarrModules 'ps.fk_entrepot'=>array('rule'=>'fetchidfromref', 'classfile'=>'/product/stock/class/entrepot.class.php', 'class'=>'Entrepot', 'method'=>'fetch', 'element'=>'ref') ); $this->import_examplevalues_array[$r] = array( - 'ps.fk_product'=>"PREF123456", 'ps.fk_entrepot'=>"ALM001", 'ps.reel'=>"10" + 'ps.fk_product'=>"id or ref", 'ps.fk_entrepot'=>"id or ref", 'ps.reel'=>"10" ); $this->import_updatekeys_array[$r] = array('ps.fk_product'=>'Product', 'ps.fk_entrepot'=>"Warehouse"); $this->import_run_sql_after_array[$r] = array( // Because we may change data that are denormalized, we must update dernormalized data after. diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 6543747d1f7..541c43f1149 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -39,6 +39,7 @@ $langs->loadlangs(array('admin', 'exports', 'other', 'users', 'companies', 'proj //if (! $user->admin) // accessforbidden(); +// Map icons, array duplicated in import.php, was not synchronized, TODO put it somewhere only once $entitytoicon = array( 'invoice' => 'bill', 'invoice_line' => 'bill', @@ -54,13 +55,13 @@ $entitytoicon = array( 'payment' => 'payment', 'tax' => 'generic', 'tax_type' => 'generic', - 'stock' => 'generic', 'other' => 'generic', 'account' => 'account', 'product' => 'product', 'virtualproduct'=>'product', 'subproduct' => 'product', 'product_supplier_ref' => 'product', + 'stock' => 'stock', 'warehouse' => 'stock', 'batch' => 'stock', 'stockbatch' => 'stock', @@ -78,7 +79,7 @@ $entitytoicon = array( 'bomline' => 'bom' ); -// Translation code +// Translation code, array duplicated in import.php, was not synchronized, TODO put it somewhere only once $entitytolang = array( 'user' => 'User', 'company' => 'Company', @@ -459,15 +460,14 @@ if ($step == 1 || !$datatoexport) $sortedarrayofmodules = dol_sort_array($objexport->array_export_module, 'module_position', 'asc', 0, 0, 1); foreach ($sortedarrayofmodules as $key => $value) { + //var_dump($objexport->array_import_code[$key]); print '
'; - //print img_object($objexport->array_export_module[$key]->getName(),$export->array_export_module[$key]->picto).' '; - print $objexport->array_export_module[$key]->getName(); + print $objexport->array_export_module[$key]->getName(); print ''; - $icon = preg_replace('/:.*$/', '', $objexport->array_export_icon[$key]); - $label = $objexport->array_export_label[$key]; - //print $value.'-'.$icon.'-'.$label."
"; - print img_object($objexport->array_export_module[$key]->getName(), $icon).' '; - print $label; + $entity = preg_replace('/:.*$/', '', $objexport->array_export_icon[$key]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objexport->array_export_module[$key]->getName(), $entityicon).' '; + print $objexport->array_export_label[$key]; print '
'; if ($objexport->array_export_perms[$key]) { @@ -522,11 +522,10 @@ if ($step == 2 && $datatoexport) // Lot de donnees a exporter print '
'.$langs->trans("DatasetToExport").''; - $icon = preg_replace('/:.*$/', '', $objexport->array_export_icon[0]); - $label = $objexport->array_export_label[0]; - //print $value.'-'.$icon.'-'.$label."
"; - print img_object($objexport->array_export_module[0]->getName(), $icon).' '; - print $label; + $entity = preg_replace('/:.*$/', '', $objexport->array_export_icon[0]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objexport->array_export_module[0]->getName(), $entityicon).' '; + print $objexport->array_export_label[0]; print '
'; @@ -728,11 +727,10 @@ if ($step == 3 && $datatoexport) // Lot de donnees a exporter print ''.$langs->trans("DatasetToExport").''; print ''; - $icon = preg_replace('/:.*$/', '', $objexport->array_export_icon[0]); - $label = $objexport->array_export_label[0]; - //print $value.'-'.$icon.'-'.$label."
"; - print img_object($objexport->array_export_module[0]->getName(), $icon).' '; - print $label; + $entity = preg_replace('/:.*$/', '', $objexport->array_export_icon[0]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objexport->array_export_module[0]->getName(), $entityicon).' '; + print $objexport->array_export_label[0]; print ''; // Nbre champs exportes @@ -920,8 +918,9 @@ if ($step == 4 && $datatoexport) // Lot de donnees a exporter print ''.$langs->trans("DatasetToExport").''; print ''; - $icon = preg_replace('/:.*$/', '', $objexport->array_export_icon[0]); - print img_object($objexport->array_export_module[0]->getName(), $icon).' '; + $entity = preg_replace('/:.*$/', '', $objexport->array_export_icon[0]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objexport->array_export_module[0]->getName(), $entityicon).' '; print $objexport->array_export_label[0]; print ''; @@ -1190,8 +1189,9 @@ if ($step == 5 && $datatoexport) // Dataset to export print ''.$langs->trans("DatasetToExport").''; print ''; - $icon = preg_replace('/:.*$/', '', $objexport->array_export_icon[0]); - print img_object($objexport->array_export_module[0]->getName(), $icon).' '; + $entity = preg_replace('/:.*$/', '', $objexport->array_export_icon[0]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objexport->array_export_module[0]->getName(), $entityicon).' '; print $objexport->array_export_label[0]; print ''; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 0819ce0ac30..c6e2e282778 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -38,31 +38,93 @@ $langs->loadLangs(array('exports', 'compta', 'errors')); // Security check $result = restrictedArea($user, 'import'); +// Map icons, array duplicated in export.php, was not synchronized, TODO put it somewhere only once $entitytoicon = array( - 'invoice'=>'bill', 'invoice_line'=>'bill', - 'order'=>'order', 'order_line'=>'order', - 'intervention'=>'intervention', 'inter_line'=>'intervention', - 'member'=>'user', 'member_type'=>'group', 'subscription'=>'payment', - 'tax'=>'bill', 'tax_type'=>'generic', - 'account'=>'account', - 'payment'=>'payment', - 'product'=>'product', 'stock'=>'generic', 'warehouse'=>'stock', - 'category'=>'generic', - 'other'=>'generic' + 'invoice' => 'bill', + 'invoice_line' => 'bill', + 'order' => 'order', + 'order_line' => 'order', + 'propal' => 'propal', + 'propal_line' => 'propal', + 'intervention' => 'intervention', + 'inter_line' => 'intervention', + 'member' => 'user', + 'member_type' => 'group', + 'subscription' => 'payment', + 'payment' => 'payment', + 'tax' => 'bill', + 'tax_type' => 'generic', + 'other' => 'generic', + 'account' => 'account', + 'product' => 'product', + 'virtualproduct'=>'product', + 'subproduct' => 'product', + 'product_supplier_ref' => 'product', + 'stock' => 'stock', + 'warehouse' => 'stock', + 'batch' => 'stock', + 'stockbatch' => 'stock', + 'category' => 'category', + 'shipment' => 'sending', + 'shipment_line'=> 'sending', + 'reception'=> 'sending', + 'reception_line'=> 'sending', + 'expensereport'=> 'trip', + 'expensereport_line'=> 'trip', + 'holiday' => 'holiday', + 'contract_line' => 'contract', + 'translation' => 'generic', + 'bomm' => 'bom', + 'bomline' => 'bom' ); -$entitytolang = array( // Translation code - 'user'=>'User', - 'company'=>'Company', 'contact'=>'Contact', - 'invoice'=>'Bill', 'invoice_line'=>'InvoiceLine', - 'order'=>'Order', 'order_line'=>'OrderLine', - 'intervention'=>'Intervention', 'inter_line'=>'InterLine', - 'member'=>'Member', 'member_type'=>'MemberType', 'subscription'=>'Subscription', - 'tax'=>'SocialContribution', 'tax_type'=>'DictionarySocialContributions', - 'account'=>'BankTransactions', - 'payment'=>'Payment', - 'product'=>'Product', 'stock'=>'Stock', 'warehouse'=>'Warehouse', - 'category'=>'Category', - 'other'=>'Other' + +// Translation code, array duplicated in export.php, was not synchronized, TODO put it somewhere only once +$entitytolang = array( + 'user' => 'User', + 'company' => 'Company', + 'contact' => 'Contact', + 'invoice' => 'Bill', + 'invoice_line' => 'InvoiceLine', + 'order' => 'Order', + 'order_line' => 'OrderLine', + 'propal' => 'Proposal', + 'propal_line' => 'ProposalLine', + 'intervention' => 'Intervention', + 'inter_line' => 'InterLine', + 'member' => 'Member', + 'member_type' => 'MemberType', + 'subscription' => 'Subscription', + 'tax' => 'SocialContribution', + 'tax_type' => 'DictionarySocialContributions', + 'account' => 'BankTransactions', + 'payment' => 'Payment', + 'product' => 'Product', + 'virtualproduct' => 'AssociatedProducts', + 'subproduct' => 'SubProduct', + 'product_supplier_ref' => 'SupplierPrices', + 'service' => 'Service', + 'stock' => 'Stock', + 'movement' => 'StockMovement', + 'batch' => 'Batch', + 'stockbatch' => 'StockDetailPerBatch', + 'warehouse' => 'Warehouse', + 'category' => 'Category', + 'other' => 'Other', + 'trip' => 'TripsAndExpenses', + 'shipment' => 'Shipments', + 'shipment_line'=> 'ShipmentLine', + 'project' => 'Projects', + 'projecttask' => 'Tasks', + 'task_time' => 'TaskTimeSpent', + 'action' => 'Event', + 'expensereport'=> 'ExpenseReport', + 'expensereport_line'=> 'ExpenseReportLine', + 'holiday' => 'TitreRequestCP', + 'contract' => 'Contract', + 'contract_line'=> 'ContractLine', + 'translation' => 'Translation', + 'bom' => 'BOM', + 'bomline' => 'BOMLine' ); $datatoimport = GETPOST('datatoimport'); @@ -365,7 +427,9 @@ if ($step == 1 || !$datatoimport) if (in_array($objimport->array_import_code[$key], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) $titleofmodule = $langs->trans("ProductOrService"); print $titleofmodule; print ''; - print img_object($objimport->array_import_module[$key]->getName(), $objimport->array_import_icon[$key]).' '; + $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[$key]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objimport->array_import_module[$key]->getName(), $entityicon).' '; print $objimport->array_import_label[$key]; print ''; if ($objimport->array_import_perms[$key]) @@ -422,17 +486,17 @@ if ($step == 2 && $datatoimport) // Lot de donnees a importer print ''.$langs->trans("DatasetToImport").''; print ''; - print img_object($objimport->array_import_module[0]->getName(), $objimport->array_import_icon[0]).' '; + $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objimport->array_import_module[0]->getName(), $entityicon).' '; print $objimport->array_import_label[0]; print ''; print ''; - print ''; dol_fiche_end(); - print '
'; print ''; print ''; @@ -512,17 +576,17 @@ if ($step == 3 && $datatoimport) // Lot de donnees a importer print ''.$langs->trans("DatasetToImport").''; print ''; - print img_object($objimport->array_import_module[0]->getName(), $objimport->array_import_icon[0]).' '; + $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objimport->array_import_module[0]->getName(), $entityicon).' '; print $objimport->array_import_label[0]; print ''; print ''; print ''; - print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', ''); - print '
'; print '
'; print ''; @@ -797,14 +861,15 @@ if ($step == 4 && $datatoimport) // Lot de donnees a importer print ''; print ''; print '
'.$langs->trans("DatasetToImport").''; - print img_object($objimport->array_import_module[0]->getName(), $objimport->array_import_icon[0]).' '; + $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objimport->array_import_module[0]->getName(), $entityicon).' '; print $objimport->array_import_label[0]; print '
'; print '
'; - print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', ''); print '
'; @@ -1273,14 +1338,15 @@ if ($step == 5 && $datatoimport) // Lot de donnees a importer print ''.$langs->trans("DatasetToImport").''; print ''; - print img_object($objimport->array_import_module[0]->getName(), $objimport->array_import_icon[0]).' '; + $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objimport->array_import_module[0]->getName(), $entityicon).' '; print $objimport->array_import_label[0]; print ''; print ''; print ''; - print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', ''); print '
'; @@ -1716,14 +1782,15 @@ if ($step == 6 && $datatoimport) // Lot de donnees a importer print ''.$langs->trans("DatasetToImport").''; print ''; - print img_object($objimport->array_import_module[0]->getName(), $objimport->array_import_icon[0]).' '; + $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]); + $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); + print img_object($objimport->array_import_module[0]->getName(), $entityicon).' '; print $objimport->array_import_label[0]; print ''; print ''; print ''; - print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', ''); print '
'; diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang index 3549e3f8b23..a0eb7161ef2 100644 --- a/htdocs/langs/en_US/exports.lang +++ b/htdocs/langs/en_US/exports.lang @@ -133,3 +133,4 @@ KeysToUseForUpdates=Key (column) to use for updating existing data NbInsert=Number of inserted lines: %s NbUpdate=Number of updated lines: %s MultipleRecordFoundWithTheseFilters=Multiple records have been found with these filters: %s +StocksWithBatch=Stocks and location (warehouse) of products with batch/serial number diff --git a/htdocs/langs/fr_FR/exports.lang b/htdocs/langs/fr_FR/exports.lang index 3055d51e2ad..3de20e83d20 100644 --- a/htdocs/langs/fr_FR/exports.lang +++ b/htdocs/langs/fr_FR/exports.lang @@ -133,3 +133,4 @@ KeysToUseForUpdates=Clé à utiliser pour mettre à jour les données NbInsert=Nombre de lignes insérées: %s NbUpdate=Nombre de lignes mises à jour: %s MultipleRecordFoundWithTheseFilters=Plusieurs enregistrements ont été trouvés avec ces filtres: %s +StocksWithBatch=Stocks et emplacements (entrepôts) des produits avec numéros de lots/séries \ No newline at end of file From 4fcd3fe49332baab0e424225ad10b76b47ebcbac Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 11 Dec 2020 15:11:51 +0100 Subject: [PATCH 091/137] =?UTF-8?q?Fix=20disallow=20--=20string=20into=20f?= =?UTF-8?q?ilename=20for=20security=20purpose.=20Vulnerability=20reported?= =?UTF-8?q?=20by=20Y=C4=B1lmaz=20De=C4=9Firmenci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- htdocs/admin/tools/export_files.php | 2 +- htdocs/core/lib/functions.lib.php | 5 +++-- test/phpunit/SecurityTest.php | 25 ++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php index de10759c92d..587750d129e 100644 --- a/htdocs/admin/tools/export_files.php +++ b/htdocs/admin/tools/export_files.php @@ -34,7 +34,7 @@ $action = GETPOST('action', 'alpha'); $what = GETPOST('what', 'alpha'); $export_type = GETPOST('export_type', 'alpha'); $file = trim(GETPOST('zipfilename_template', 'alpha')); -$compression = GETPOST('compression'); +$compression = GETPOST('compression', 'aZ09'); $file = dol_sanitizeFileName($file); $file = preg_replace('/(\.zip|\.tar|\.tgz|\.gz|\.tar\.gz|\.bz2)$/i', '', $file); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 5094fad392a..37791d1e72d 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -866,8 +866,9 @@ function dol_sanitizeFileName($str, $newstr = '_', $unaccent = 1) // List of special chars for filenames in windows are defined on page https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file // Char '>' '<' '|' '$' and ';' are special chars for shells. // Char '/' and '\' are file delimiters. - $filesystem_forbidden_chars = array('<', '>', '/', '\\', '?', '*', '|', '"', ':', '°', '$', ';'); - return dol_string_nospecial($unaccent ?dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); + // -- car can be used into filename to inject special paramaters like --use-compress-program to make command with file as parameter making remote execution of command + $filesystem_forbidden_chars = array('<', '>', '/', '\\', '?', '*', '|', '"', ':', '°', '$', ';', '--'); + return dol_string_nospecial($unaccent ? dol_string_unaccent($str) : $str, $newstr, $filesystem_forbidden_chars); } /** diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 5a248006498..6d2a3cf3cd8 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -244,7 +244,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase $login=checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, 'admin'); + $this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed'); $login=checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authetntication method print __METHOD__." login=".$login."\n"; @@ -326,4 +326,27 @@ class SecurityTest extends PHPUnit\Framework\TestCase $result=restrictedArea($user, 'societe'); $this->assertEquals(1, $result); } + + /** + * testDolSanitizeFileName + * + * @return void + */ + public function testDolSanitizeFileName() + { + global $conf,$user,$langs,$db; + $conf=$this->savconf; + $user=$this->savuser; + $langs=$this->savlangs; + $db=$this->savdb; + + //$dummyuser=new User($db); + //$result=restrictedArea($dummyuser,'societe'); + + $result=dol_sanitizeFileName('bad file | evilaction'); + $this->assertEquals('bad file _ evilaction', $result); + + $result=dol_sanitizeFileName('bad file --evilparam'); + $this->assertEquals('bad file _evilparam', $result); + } } From 25923446018657c05a2f027987463550bbc603bf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 12 Dec 2020 17:27:27 +0100 Subject: [PATCH 092/137] Fix missing price2num --- htdocs/commande/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index f59038aceae..36f9705aabc 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -670,8 +670,8 @@ if (empty($reshook)) $tva_tx = ''; } - $qty = GETPOST('qty'.$predef); - $remise_percent = (GETPOST('remise_percent'.$predef) != '' ? GETPOST('remise_percent'.$predef) : 0); + $qty = price2num(GETPOST('qty'.$predef, 'alpha')); + $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha')) : 0); // Extrafields $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line); From 57b3b3db3a9f03885d55658be64ef6f19b451077 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 12 Dec 2020 19:18:45 +0100 Subject: [PATCH 093/137] Prepare 12.0.4 --- ChangeLog | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/ChangeLog b/ChangeLog index e7abb3f7cd6..83db59d2e64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,102 @@ English Dolibarr ChangeLog -------------------------------------------------------------- + +***** ChangeLog for 12.0.4 compared to 12.0.3 ***** +FIX: make formConfirm an addreplace-type hook +FIX: regex to remove 'action' parameter: taking feedback from PR#15213 into account +FIX: remove 'action' parameter from redirect URL when reordering lines on a document +FIX: error when displaying lines on order after adding a line if both MAIN_MULTILANGS and MAIN_DISABLE_PDF_AUTOUPDATE are activated +FIX: on survey creation, entity is always set to 1 ⇒ set it to $conf->entity +FIX: set entity to $conf->entity (instead of 1 by default) when creating a survey; otherwise the survey cannot be listed from the entity it was created on unless it is the main entity +FIX: the stringent XSS protection provided by 'alphanohtml' causes problems with some clients who used basic tags (bold, italic, underline) in product labels. Using 'restricthtml' instead could be a good compromise. +FIX: third party of object is not always fetched when initiating the e-mail presend action (e.g. from an order) +FIX: when the cronjob 'params' field is empty, the cron method is called with one empty string param instead of no params at all +FIX: XSS protection too stringent -> replace 'alphanohtml' with 'restricthtml' +FIX: #13067 including opening balance in calculation of displayed balance +FIX: #14326 +FIX: #14649 +FIX: #14901 +FIX: #14927 Change ContratLigne property type to product_type +FIX: #14979 +FIX: #15074 +FIX: #15111 Fix special characters output in PDF +FIX: #15161 MO translation conflict +FIX: #15163 +FIX: #15199 +FIX: #15208 +FIX: #15303 +FIX: #15365 export of extrafields for user and resources +FIX: #15374 : "New" doesn't clear total amounts +FIX: #15501 +FIX: #15572 +FIX: #15590 +FIX: #15618 +FIX: supplier proposals as linked objects of events are not correctly fetched +FIX: when users create an event from a supplier proposal, the "linked objects" section says "Deleted" +FIX: Accountancy - Some ajustments on length of the account (general & auxiliary) +FIX: admin conf selected +FIX: also check if there is a method $object->fetch_thirdparty() before calling it +FIX: autofocus on first setup +FIX: Bad rigths to send contract +FIX: Better error message with IMAP when connection fails +FIX: Can create user but not update user with activedirectory +FIX: Can receipt of a product that required lot after disabling stock and +FIX: Can't create shipment for virtual product. Add +FIX: cant empty action comm desc +FIX: CA report by product/service : subcategory filter +FIX: Clean orphan records in llx_ecm_files into repair script. +FIX: default accountancy values and posted values +FIX: Deletion of expensereport + other generated object not complete. +FIX: disabled users must not be available in sales representative list on societe edit mode +FIX: Dol print error : conf usage thirdparty propagate extrafields to +FIX: Don't display inactive users in birthday box and company card +FIX: empty value is needed on filter list +FIX: enable HTML in product labels depending on conf MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML +FIX: error 500 on cash closure +FIX: excess comma +FIX: Export FEC - Remove line at zero +FIX: extrafield required error after submit +FIX: filter on project list +FIX: force payment mode to withdraw +FIX: formating of prices with foreign languages +FIX: handling $heightforinfotot when he's superior to a page height +FIX: if no PDF default model in admin for expense report, do not create a PDF +FIX: invoice payment terms edition: error management +FIX: list of fields in list of recurring invoices was empty +FIX: load default linked options for linked sellist extra fields +FIX: Loan - Return on list when you cancel create form or delete a loan +FIX: Missing lang trans +FIX: no empty value in required extrafield +FIX: Param joinfiles not sanitized +FIX: Payment by BankTransfer +FIX: pdf_getlinetotalwithtax must show total incl tax +FIX: Problem on supplier payment card +FIX: product auto volume calculation +FIX: product customer prices: missing triggers in CRUD class +FIX: Request on purchase orders in timeout even on very small databases +FIX: set paid on total discount of a product in cash desk +FIX: several warning with the barcode use in ODT templates +FIX: SHIP MODE install v12 bug insert +FIX: stripe for connect mode +FIX: subcat filter +FIX: supplier invoice: automatically calculate payment term when modifying payment condition +FIX: SUPPLIER PROPOSAL v12 bug add +FIX: table making extrafield input too small on advance target mailing +FIX: table making extrafield too small advtagertmailing +FIX: Unable to edit extrafields in expense report +FIX: update margins rates on object line edit +FIX: uses price2numjs +FIX: various payments: bad data handling for subledger account + useless db commit/rollback +FIX: virtual products: displayed value is by unit +FIX: virtual products: supplier discount was not applied in component list +FIX: warning for purchase order delivery late. +FIX: Warning on late purchase order delivery +FIX: WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING must not consider services while STOCK_SUPPORTS_SERVICES is empty +FIX: wrong tab +FIX: Yogosha report 4425 (backport) +FIX: Yogosha report 4434 (backport) + ***** ChangeLog for 12.0.3 compared to 12.0.2 ***** FIX: 10.0 - when the mime file name is different from the filesystem name, the attachment name should be the mime filename FIX: 11.0 - expenses lines overlapping the total amounts frame From 4fc57d096ee589084eaff950f94872aa666d05c1 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Sat, 12 Dec 2020 20:37:00 +0100 Subject: [PATCH 094/137] Fix #15556 --- htdocs/projet/list.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 2f58c782c24..5c36044dcd1 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -788,8 +788,8 @@ while ($i < min($num, $limit)) $userstatic->statut = $val['statut']; $userstatic->entity = $val['entity']; $userstatic->photo = $val['photo']; - //print $userstatic->getNomUrl(1, '', 0, 0, 12); - print $userstatic->getNomUrl(-2); + print $userstatic->getNomUrl(1, '', 0, 0, 12); + //print $userstatic->getNomUrl(-2); $j++; if ($j < $nbofsalesrepresentative) print ' '; } From 35b3d4f40a8c6b59d30274cb81b0662f68b56666 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sun, 13 Dec 2020 14:11:04 +0100 Subject: [PATCH 095/137] FIX: Export FEC - Force Carriage Return Line Feed --- htdocs/accountancy/class/accountancyexport.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index a7183c70114..f0e428ea00e 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -665,7 +665,7 @@ class AccountancyExport public function exportFEC($objectLines) { $separator = "\t"; - $end_line = "\n"; + $end_line = "\r\n"; print "JournalCode" . $separator; print "JournalLib" . $separator; From 5f9b53004ba56fa7a11c76323f74f993bc810515 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 14 Dec 2020 17:40:40 +0100 Subject: [PATCH 096/137] Fix warning --- htdocs/core/lib/functions.lib.php | 5 ++++- htdocs/core/modules/facture/doc/pdf_crabe.modules.php | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 37791d1e72d..023ade28052 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6626,6 +6626,7 @@ function complete_substitutions_array(&$substitutionarray, $outputlangs, $object $substitfiles = dol_dir_list($dir, 'files', 0, 'functions_'); foreach ($substitfiles as $substitfile) { + $reg = array(); if (preg_match('/functions_(.*)\.lib\.php/i', $substitfile['name'], $reg)) { $module = $reg[1]; @@ -6635,7 +6636,9 @@ function complete_substitutions_array(&$substitutionarray, $outputlangs, $object require_once $dir.$substitfile['name']; // Call the user's function, and only if it is defined $function_name = $module."_".$callfunc; - if (function_exists($function_name)) $function_name($substitutionarray, $outputlangs, $object, $parameters); + if (function_exists($function_name)) { + $function_name($substitutionarray, $outputlangs, $object, $parameters); + } } } } diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 771325da38a..a5ef291da9f 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -468,6 +468,7 @@ class pdf_crabe extends ModelePDFFactures $substitutionarray = pdf_getSubstitutionArray($outputlangs, null, $object); complete_substitutions_array($substitutionarray, $outputlangs, $object); + $notetoshow = make_substitutions($notetoshow, $substitutionarray, $outputlangs); $notetoshow = convertBackOfficeMediasLinksToPublicLinks($notetoshow); From 943f1022c01da67fe383134efb6f5d33092dc1da Mon Sep 17 00:00:00 2001 From: zuiko Date: Tue, 15 Dec 2020 09:26:27 +0100 Subject: [PATCH 097/137] Update fournisseurs.php Product: purchase price tab, the supplier price table with its list of products is not "responsive", as a result, the right-clickable areas, including the "Add purchase price" button, disappear to the right of the screens that are not full HD which forces the user to drag his window with the mouse. The solution is to change the CSS class of the table to adopt the CSS class of the equivalent table of the selling price tab, which is "responsive" to it. We therefore replace : print ''; by : print '
'; Knowing that the class is used in 24 files, there might be other places where this class poses the same ergonomic problem. I don't know enough Dolibarr to generalize the correction ... --- htdocs/product/fournisseurs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 3e43937e697..b6f09346385 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -877,7 +877,7 @@ SCRIPT; // Suppliers list title print '
'; - print '
'; + print '
'; $param = "&id=".$object->id; From 7a93c11ae0e2473918397646bdccbe09ab7256cd Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 15 Dec 2020 22:01:33 +0100 Subject: [PATCH 098/137] FIX : dupliacete customer or supplier code must be error dipslayed with new code proposed --- htdocs/societe/card.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index b8af6777daa..56793184f65 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -634,11 +634,16 @@ if (empty($reshook)) } else { - if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') // TODO Sometime errors on duplicate on profid and not on code, so we must manage this case + if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS' || ($result==-3 && in_array('ErrorCustomerCodeAlreadyUsed', $object->errors))) // TODO Sometime errors on duplicate on profid and not on code, so we must manage this case + { + $duplicate_code_error = true; + $object->code_client = null; + } + + if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS' || ($result==-3 && in_array('ErrorSupplierCodeAlreadyUsed',$object->errors))) // TODO Sometime errors on duplicate on profid and not on code, so we must manage this case { $duplicate_code_error = true; $object->code_fournisseur = null; - $object->code_client = null; } setEventMessages($object->error, $object->errors, 'errors'); From b80bd8d1f8af4ced9e3c978ed41f5dbc605169b0 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 15 Dec 2020 22:03:15 +0100 Subject: [PATCH 099/137] FIX : dupliacete customer or supplier code must be error dipslayed with new code proposed --- htdocs/societe/card.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 56793184f65..93e0196f1ae 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -634,18 +634,22 @@ if (empty($reshook)) } else { - if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS' || ($result==-3 && in_array('ErrorCustomerCodeAlreadyUsed', $object->errors))) // TODO Sometime errors on duplicate on profid and not on code, so we must manage this case + if ($result==-3 && in_array('ErrorCustomerCodeAlreadyUsed', $object->errors)) { $duplicate_code_error = true; $object->code_client = null; } - if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS' || ($result==-3 && in_array('ErrorSupplierCodeAlreadyUsed',$object->errors))) // TODO Sometime errors on duplicate on profid and not on code, so we must manage this case + if ($result==-3 && in_array('ErrorSupplierCodeAlreadyUsed',$object->errors)) { $duplicate_code_error = true; $object->code_fournisseur = null; } + if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $duplicate_code_error = true; + } + setEventMessages($object->error, $object->errors, 'errors'); $error++; } From 9ca2e98a662a16bf57fb51f62729c1e6e4bca443 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 15 Dec 2020 21:12:52 +0000 Subject: [PATCH 100/137] Fixing style errors. --- htdocs/societe/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 93e0196f1ae..d79a5c1a9e0 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -640,7 +640,7 @@ if (empty($reshook)) $object->code_client = null; } - if ($result==-3 && in_array('ErrorSupplierCodeAlreadyUsed',$object->errors)) + if ($result==-3 && in_array('ErrorSupplierCodeAlreadyUsed', $object->errors)) { $duplicate_code_error = true; $object->code_fournisseur = null; From cb2c1f3ecef1537f40617b4c2796b2a5a7c5f923 Mon Sep 17 00:00:00 2001 From: atm-lena Date: Wed, 16 Dec 2020 10:54:32 +0100 Subject: [PATCH 101/137] FIX Facture Situation Out : status condition --- htdocs/compta/facture/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index fb5f7a6ac98..aa07de4867e 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2534,7 +2534,7 @@ if (empty($reshook)) { $object->fetch($id, '', '', '', true); - if ($object->statut == Facture::STATUS_VALIDATED + if (in_array($object->statut, array(Facture::STATUS_CLOSED, Facture::STATUS_VALIDATED)) && $object->type == Facture::TYPE_SITUATION && $usercancreate && !$objectidnext @@ -3872,7 +3872,7 @@ elseif ($id > 0 || !empty($ref)) $label = $langs->trans("ConfirmOuting"); $formquestion = array(); // remove situation from cycle - if ($object->statut == Facture::STATUS_VALIDATED + if (in_array($object->statut, array(Facture::STATUS_CLOSED, Facture::STATUS_VALIDATED)) && $usercancreate && !$objectidnext && $object->is_last_in_cycle() @@ -5387,7 +5387,7 @@ elseif ($id > 0 || !empty($ref)) } // Remove situation from cycle - if ($object->statut > Facture::STATUS_DRAFT + if (in_array($object->statut, array(Facture::STATUS_CLOSED, Facture::STATUS_VALIDATED)) && $object->type == Facture::TYPE_SITUATION && $usercancreate && !$objectidnext From 10ac74162e71e9463883feb46293e74c18ad4e17 Mon Sep 17 00:00:00 2001 From: Haldarys <49756127+Haldarys@users.noreply.github.com> Date: Thu, 17 Dec 2020 10:19:21 +0100 Subject: [PATCH 102/137] Fix PRELEVEMENT_ADDDAYS check If we used a positive value in PRELEVEMENT_ADDDAYS it couldn't submit the changes to database --- htdocs/admin/prelevement.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index 144ec744d41..2f942410787 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -92,11 +92,10 @@ if ($action == "set") if (! $res > 0) $error++; } - if (GETPOST("PRELEVEMENT_ADDDAYS") || GETPOST("PRELEVEMENT_ADDDAYS")=="") - { - $res = dolibarr_set_const($db, "PRELEVEMENT_ADDDAYS", GETPOST("PRELEVEMENT_ADDDAYS"), 'chaine', 0, '', $conf->entity); - if (! $res > 0) $error++; - } elseif (! $error) + $res = dolibarr_set_const($db, "PRELEVEMENT_ADDDAYS", GETPOST("PRELEVEMENT_ADDDAYS"), 'chaine', 0, '', $conf->entity); + if (! $res > 0) $error++; + + if (! $error) { $db->commit(); setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); From 36d6b472ce90480130bcece86d3ba7448c9fb855 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 17 Dec 2020 13:52:03 +0100 Subject: [PATCH 103/137] Update prelevement.php --- htdocs/admin/prelevement.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index 2f942410787..4fba501b305 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -250,9 +250,10 @@ print ''; //ADDDAYS print ''; print ''; print ''; + print '
'.$langs->trans("ADDDAYS").''; -if (! $conf->global->PRELEVEMENT_ADDDAYS) $conf->global->PRELEVEMENT_ADDDAYS=0; +if (empty($conf->global->PRELEVEMENT_ADDDAYS)) $conf->global->PRELEVEMENT_ADDDAYS=0; print '
'; print '
'; From 27542ed8ed6f19924106e01789a67ec37738c6a0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 17 Dec 2020 13:53:09 +0100 Subject: [PATCH 104/137] Update prelevement.php --- htdocs/admin/prelevement.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index 4fba501b305..122ec26f1c6 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -74,34 +74,31 @@ if ($action == "set") else $error++; $res = dolibarr_set_const($db, "PRELEVEMENT_ICS", GETPOST("PRELEVEMENT_ICS"), 'chaine', 0, '', $conf->entity); - if (! $res > 0) $error++; + if (! ($res > 0)) $error++; if (GETPOST("PRELEVEMENT_USER") > 0) { $res = dolibarr_set_const($db, "PRELEVEMENT_USER", GETPOST("PRELEVEMENT_USER"), 'chaine', 0, '', $conf->entity); - if (! $res > 0) $error++; + if (! ($res > 0)) $error++; } if (GETPOST("PRELEVEMENT_END_TO_END") || GETPOST("PRELEVEMENT_END_TO_END")=="") { $res = dolibarr_set_const($db, "PRELEVEMENT_END_TO_END", GETPOST("PRELEVEMENT_END_TO_END"), 'chaine', 0, '', $conf->entity); - if (! $res > 0) $error++; + if (! ($res > 0)) $error++; } if (GETPOST("PRELEVEMENT_USTRD") || GETPOST("PRELEVEMENT_USTRD")=="") { $res = dolibarr_set_const($db, "PRELEVEMENT_USTRD", GETPOST("PRELEVEMENT_USTRD"), 'chaine', 0, '', $conf->entity); - if (! $res > 0) $error++; + if (! ($res > 0)) $error++; } $res = dolibarr_set_const($db, "PRELEVEMENT_ADDDAYS", GETPOST("PRELEVEMENT_ADDDAYS"), 'chaine', 0, '', $conf->entity); - if (! $res > 0) $error++; + if (! ($res > 0)) $error++; - if (! $error) - { + if (! $error) { $db->commit(); setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); - } - else - { + } else { $db->rollback(); setEventMessages($langs->trans("Error"), null, 'errors'); } From 73dfa7d44a115b153b4b421e23ba6ae5da2c769d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 17 Dec 2020 14:37:02 +0100 Subject: [PATCH 105/137] Try a better fix for #15770 --- htdocs/product/price.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/price.php b/htdocs/product/price.php index 12029ea7cdc..dd56aa42318 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -1457,11 +1457,11 @@ if ((empty($conf->global->PRODUIT_CUSTOMER_PRICES) || $action == 'showlog_defaul // Il doit au moins y avoir la ligne de prix initial. // On l'ajoute donc pour remettre a niveau (pb vieilles versions) - //$object->updatePrice($object->price, $object->price_base_type, $user, $object->tva_tx, $object->price_min); + // We emulate the change of the price from interface with the same value than the one into table llx_product if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - $object->updatePrice($object->multiprices[1], $object->multiprices_base_type[1], $user, (empty($object->multiprices_tva_tx[1]) ? 0 : $object->multiprices_tva_tx[1]), $object->multiprices_min[1], 1); + $object->updatePrice(($object->multiprices_base_type[1] == 'TTC' ? $object->multiprices_ttc[1] : $object->multiprices[1]), $object->multiprices_base_type[1], $user, (empty($object->multiprices_tva_tx[1]) ? 0 : $object->multiprices_tva_tx[1]), ($object->multiprices_base_type[1] == 'TTC' ? $object->multiprices_min_ttc[1] : $object->multiprices_min[1]), 1); } else { - $object->updatePrice($object->price, $object->price_base_type, $user, $object->tva_tx, $object->price_min); + $object->updatePrice(($object->price_base_type == 'TTC' ? $object->price_ttc : $object->price), $object->price_base_type, $user, $object->tva_tx, ($object->price_base_type == 'TTC' ? $object->price_min_ttc : $object->price_min)); } $result = $db->query($sql); From f79dec80e61704026eada93a76b566c602b1777c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 17 Dec 2020 16:45:56 +0100 Subject: [PATCH 106/137] Fix phpcs --- htdocs/admin/prelevement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index f3f0bc8f430..16384e9599f 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -94,7 +94,7 @@ if ($action == "set") $res = dolibarr_set_const($db, "PRELEVEMENT_ADDDAYS", GETPOST("PRELEVEMENT_ADDDAYS"), 'chaine', 0, '', $conf->entity); if (! ($res > 0)) $error++; - + if (! $error) { $db->commit(); setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); From b5db5f7474fc8f7fff3e044236cf05beb28f747f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 17 Dec 2020 21:11:44 +0100 Subject: [PATCH 107/137] Better responsive --- htdocs/theme/eldy/global.inc.php | 18 ++++++++++++++++++ htdocs/theme/md/dropdown.inc.php | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 3bd0e560ce5..e5db84f9719 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -6471,6 +6471,24 @@ div.tabsElem a.tab { } } +@media only screen and (max-width: 320px) +{ + .dropdown dd ul { + max-width: 270px; /* must always be 50 slower than width */ + } +} +@media only screen and (max-width: 300px) +{ + .dropdown dd ul { + max-width: 250px; + } +} +@media only screen and (max-width: 280px) +{ + .dropdown dd ul { + max-width: 230px; + } +} Date: Thu, 17 Dec 2020 21:41:39 +0100 Subject: [PATCH 108/137] Better fix select2 bug https://github.com/select2/select2/issues/5832 --- dev/dolibarr_changes.txt | 2 +- htdocs/includes/jquery/plugins/select2/dist/css/select2.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index cdb0999e53f..ecd25ce692b 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -320,7 +320,7 @@ SELECT2 Edit CSS to restore line removed between 4.0.5 and 4.0.6. It generates this bug: https://github.com/select2/select2/issues/5832 .select2-hidden-accessible { - margin: -1px !important; /* line to restore */ + margin: -10000px !important; /* line to restore */ } diff --git a/htdocs/includes/jquery/plugins/select2/dist/css/select2.css b/htdocs/includes/jquery/plugins/select2/dist/css/select2.css index c4c42ea3cc6..eb341de9d83 100644 --- a/htdocs/includes/jquery/plugins/select2/dist/css/select2.css +++ b/htdocs/includes/jquery/plugins/select2/dist/css/select2.css @@ -121,7 +121,7 @@ -webkit-clip-path: inset(50%) !important; clip-path: inset(50%) !important; height: 1px !important; - margin: -1px !important; + margin: -10000px !important; overflow: hidden !important; padding: 0 !important; position: absolute !important; From f10c69680c370f4ff6c580074188d8f045e4872a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 17 Dec 2020 21:42:10 +0100 Subject: [PATCH 109/137] Ajax combo at a better place (after select) --- htdocs/core/class/html.form.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 450ed7364ca..cd808157045 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -6191,12 +6191,6 @@ class Form $resql = $this->db->query($sql); if ($resql) { - if (!$forcecombo) - { - include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; - $out .= ajax_combobox($htmlname, null, $conf->global->$confkeyforautocompletemode); - } - // Construct $out and $outarray $out .= ''."\n"; + + if (!$forcecombo) + { + include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + $out .= ajax_combobox($htmlname, null, $conf->global->$confkeyforautocompletemode); + } } else { From 22b224744282b23bffdf2c7f1ec3006fbcd74d36 Mon Sep 17 00:00:00 2001 From: ptibogxiv Date: Sat, 19 Dec 2020 13:41:49 +0100 Subject: [PATCH 110/137] Update sms.php --- htdocs/admin/sms.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/sms.php b/htdocs/admin/sms.php index 09cc0debfd5..d06b99691f5 100644 --- a/htdocs/admin/sms.php +++ b/htdocs/admin/sms.php @@ -310,7 +310,7 @@ else $formsms->withfromreadonly = 0; $formsms->withsubstit = 0; $formsms->withfrom = 1; - $formsms->withto = (isset($_POST['sendto']) ? $_POST['sendto'] : $user->user_mobile ? $user->user_mobile : 1); + $formsms->withto = (isset($_POST['sendto']) ? $_POST['sendto'] : ($user->user_mobile ? $user->user_mobile : 1)); $formsms->withbody = (isset($_POST['message']) ? (empty($_POST['message']) ? 1 : $_POST['message']) : $langs->trans("ThisIsATestMessage")); $formsms->withbodyreadonly = 0; $formsms->withcancel = 1; From 8c87050703903b8fe6577e75cddc43bc6c259735 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 20 Dec 2020 13:54:02 +0100 Subject: [PATCH 111/137] FIX Check of customer/vendor code fails in some cases --- htdocs/comm/card.php | 5 ++- htdocs/core/lib/functions2.lib.php | 39 ++++++++----------- .../societe/mod_codeclient_elephant.php | 6 +-- htdocs/fourn/card.php | 6 ++- htdocs/margin/tabs/thirdpartyMargins.php | 10 ++++- htdocs/societe/card.php | 10 ++++- htdocs/societe/class/societe.class.php | 2 + htdocs/societe/consumption.php | 10 ++++- htdocs/societe/document.php | 10 ++++- htdocs/societe/note.php | 10 ++++- htdocs/societe/notify/card.php | 10 ++++- htdocs/societe/paymentmodes.php | 10 ++++- htdocs/societe/price.php | 8 +++- htdocs/societe/project.php | 10 ++++- htdocs/societe/societecontact.php | 10 ++++- htdocs/societe/website.php | 8 +++- htdocs/ticket/list.php | 10 ++--- 17 files changed, 120 insertions(+), 54 deletions(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index d48c897d6bb..8b1ab0f4ac8 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -269,7 +269,10 @@ if ($object->id > 0) print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; print ''; diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 1ccc4a2d1fb..c00e0f7f825 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -773,6 +773,7 @@ function get_next_value($db, $mask, $table, $field, $where = '', $objsoc = '', $ if (dol_strlen($maskcounter) < 3 && empty($conf->global->MAIN_COUNTER_WITH_LESS_3_DIGITS)) return 'ErrorCounterMustHaveMoreThan3Digits'; // Extract value for third party mask counter + $regClientRef = array(); if (preg_match('/\{(c+)(0*)\}/i', $mask, $regClientRef)) { $maskrefclient = $regClientRef[1].$regClientRef[2]; @@ -806,6 +807,7 @@ function get_next_value($db, $mask, $table, $field, $where = '', $objsoc = '', $ } // Extract value for user + $regType = array(); if (preg_match('/\{(u+)\}/i', $mask, $regType)) { $lastname = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; @@ -970,12 +972,10 @@ function get_next_value($db, $mask, $table, $field, $where = '', $objsoc = '', $ //print "masktri=".$masktri." maskcounter=".$maskcounter." maskraz=".$maskraz." maskoffset=".$maskoffset."
\n"; // Define $sqlstring - if (function_exists('mb_strrpos')) - { + if (function_exists('mb_strrpos')) { $posnumstart = mb_strrpos($maskwithnocode, $maskcounter, 'UTF-8'); } - else - { + else { $posnumstart = strrpos($maskwithnocode, $maskcounter); } // Pos of counter in final string (from 0 to ...) if ($posnumstart < 0) return 'ErrorBadMaskFailedToLocatePosOfSequence'; @@ -1218,6 +1218,7 @@ function check_value($mask, $value) $hasglobalcounter = false; // Extract value for mask counter, mask raz and mask offset + $reg = array(); if (preg_match('/\{(0+)([@\+][0-9]+)?([@\+][0-9]+)?\}/i', $mask, $reg)) { $masktri = $reg[1].(isset($reg[2]) ? $reg[2] : '').(isset($reg[3]) ? $reg[3] : ''); @@ -1236,6 +1237,7 @@ function check_value($mask, $value) if (dol_strlen($maskcounter) < 3) return 'ErrorCounterMustHaveMoreThan3Digits'; // Extract value for third party mask counter + $regClientRef = array(); if (preg_match('/\{(c+)(0*)\}/i', $mask, $regClientRef)) { $maskrefclient = $regClientRef[1].$regClientRef[2]; @@ -1288,31 +1290,24 @@ function check_value($mask, $value) // Define reg if ($maskraz > 1 && !preg_match('/^(.*)\{(y+)\}\{(m+)\}/i', $maskwithonlyymcode, $reg)) return 'ErrorCantUseRazInStartedYearIfNoYearMonthInMask'; if ($maskraz <= 1 && !preg_match('/^(.*)\{(y+)\}/i', $maskwithonlyymcode, $reg)) return 'ErrorCantUseRazIfNoYearInMask'; - //print "x".$maskwithonlyymcode." ".$maskraz; } - //print "masktri=".$masktri." maskcounter=".$maskcounter." maskraz=".$maskraz." maskoffset=".$maskoffset."
\n"; + //print "masktri=".$masktri." maskcounter=".$maskcounter." maskwithonlyymcode=".$maskwithonlyymcode." maskwithnocode=".$maskwithnocode." maskraz=".$maskraz." maskoffset=".$maskoffset."
\n"; - // Check we have a number in ($posnumstart+1).', '.dol_strlen($maskcounter) - // + if (function_exists('mb_strrpos')) { + $posnumstart = mb_strrpos($maskwithnocode, $maskcounter, 'UTF-8'); + } + else { + $posnumstart = strrpos($maskwithnocode, $maskcounter); + } // Pos of counter in final string (from 0 to ...) + if ($posnumstart < 0) return 'ErrorBadMaskFailedToLocatePosOfSequence'; + + // Check we have a number in $value at position ($posnumstart+1).', '.dol_strlen($maskcounter) + // TODO // Check length $len = dol_strlen($maskwithnocode); if (dol_strlen($value) != $len) $result = -1; - // Define $maskLike - /* seems not used - $maskLike = dol_string_nospecial($mask); - $maskLike = str_replace("%","_",$maskLike); - // Replace protected special codes with matching number of _ as wild card caracter - $maskLike = str_replace(dol_string_nospecial('{yyyy}'),'____',$maskLike); - $maskLike = str_replace(dol_string_nospecial('{yy}'),'__',$maskLike); - $maskLike = str_replace(dol_string_nospecial('{y}'),'_',$maskLike); - $maskLike = str_replace(dol_string_nospecial('{mm}'),'__',$maskLike); - $maskLike = str_replace(dol_string_nospecial('{dd}'),'__',$maskLike); - $maskLike = str_replace(dol_string_nospecial('{'.$masktri.'}'),str_pad("",dol_strlen($maskcounter),"_"),$maskLike); - if ($maskrefclient) $maskLike = str_replace(dol_string_nospecial('{'.$maskrefclient.'}'),str_pad("",strlen($maskrefclient),"_"),$maskLike); - */ - dol_syslog("functions2::check_value result=".$result, LOG_DEBUG); return $result; } diff --git a/htdocs/core/modules/societe/mod_codeclient_elephant.php b/htdocs/core/modules/societe/mod_codeclient_elephant.php index 22ec06c8aa6..c7a2d600ede 100644 --- a/htdocs/core/modules/societe/mod_codeclient_elephant.php +++ b/htdocs/core/modules/societe/mod_codeclient_elephant.php @@ -267,7 +267,8 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode * -2 ErrorCustomerCodeRequired * -3 ErrorCustomerCodeAlreadyUsed * -4 ErrorPrefixRequired - * -5 Other (see this->error) + * -5 NotConfigured - Setup empty so any value may be ok or not + * -6 Other (see this->error) */ public function verif($db, &$code, $soc, $type) { @@ -297,12 +298,11 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode $this->error = 'NotConfigured'; return -5; } - $result = check_value($mask, $code); if (is_string($result)) { $this->error = $result; - return -5; + return -6; } } diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index b467fdbd366..9d94c6847b7 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -180,7 +180,11 @@ if ($object->id > 0) print ''; print ''.$langs->trans("SupplierCode").''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + var_dump($tmpcheck); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; print ''; diff --git a/htdocs/margin/tabs/thirdpartyMargins.php b/htdocs/margin/tabs/thirdpartyMargins.php index ecb8a3ce764..047edc8cfe2 100644 --- a/htdocs/margin/tabs/thirdpartyMargins.php +++ b/htdocs/margin/tabs/thirdpartyMargins.php @@ -101,7 +101,10 @@ if ($socid > 0) print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; } @@ -110,7 +113,10 @@ if ($socid > 0) print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; } diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index d79a5c1a9e0..ea121acc4c7 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -2330,7 +2330,10 @@ else print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; print ''; } @@ -2341,7 +2344,10 @@ else print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; print ''; } diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index ee91363dba1..35b52243804 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -3018,6 +3018,8 @@ class Societe extends CommonObject * -2 ErrorCustomerCodeRequired * -3 ErrorCustomerCodeAlreadyUsed * -4 ErrorPrefixRequired + * -5 NotConfigured - Setup empty so any value may be ok or not + * -6 Other (see this->error) */ public function check_codeclient() { diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index 0ce28356d90..e9514365c0f 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -130,7 +130,10 @@ if ($object->client) print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; $sql = "SELECT count(*) as nb from ".MAIN_DB_PREFIX."facture where fk_soc = ".$socid; $resql = $db->query($sql); @@ -153,7 +156,10 @@ if ($object->fournisseur) print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; $sql = "SELECT count(*) as nb from ".MAIN_DB_PREFIX."commande_fournisseur where fk_soc = ".$socid; $resql = $db->query($sql); diff --git a/htdocs/societe/document.php b/htdocs/societe/document.php index d082ae6baa5..05c6cbd2378 100644 --- a/htdocs/societe/document.php +++ b/htdocs/societe/document.php @@ -136,7 +136,10 @@ if ($object->id) print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; } @@ -145,7 +148,10 @@ if ($object->id) print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; } diff --git a/htdocs/societe/note.php b/htdocs/societe/note.php index 2e3e3ec4532..63f9ab3b1c6 100644 --- a/htdocs/societe/note.php +++ b/htdocs/societe/note.php @@ -99,7 +99,10 @@ if ($object->id > 0) print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; } @@ -108,7 +111,10 @@ if ($object->id > 0) print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; } diff --git a/htdocs/societe/notify/card.php b/htdocs/societe/notify/card.php index 191f9c4bb2c..52969ef4008 100644 --- a/htdocs/societe/notify/card.php +++ b/htdocs/societe/notify/card.php @@ -174,7 +174,10 @@ if ($result > 0) print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; } @@ -183,7 +186,10 @@ if ($result > 0) print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; } diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 5894c3245a9..a215b254a55 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -847,7 +847,10 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; $sql = "SELECT count(*) as nb from ".MAIN_DB_PREFIX."facture where fk_soc = ".$socid; $resql = $db->query($sql); @@ -899,7 +902,10 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; $sql = "SELECT count(*) as nb from ".MAIN_DB_PREFIX."facture where fk_soc = ".$socid; $resql = $db->query($sql); diff --git a/htdocs/societe/price.php b/htdocs/societe/price.php index df8e966d0ce..7571ae314ef 100644 --- a/htdocs/societe/price.php +++ b/htdocs/societe/price.php @@ -212,8 +212,10 @@ if ($object->client) { print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() != 0) + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; } @@ -221,8 +223,10 @@ if ($object->fournisseur) { print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() != 0) + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; } diff --git a/htdocs/societe/project.php b/htdocs/societe/project.php index 1c2604e0e44..94b453e87d9 100644 --- a/htdocs/societe/project.php +++ b/htdocs/societe/project.php @@ -99,7 +99,10 @@ if ($socid) print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; } @@ -108,7 +111,10 @@ if ($socid) print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; } diff --git a/htdocs/societe/societecontact.php b/htdocs/societe/societecontact.php index 5ff86ff0064..fdba8d6a461 100644 --- a/htdocs/societe/societecontact.php +++ b/htdocs/societe/societecontact.php @@ -193,7 +193,10 @@ if ($id > 0 || !empty($ref)) print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() <> 0) print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; } @@ -202,7 +205,10 @@ if ($id > 0 || !empty($ref)) print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() <> 0) print ' ('.$langs->trans("WrongSupplierCode").')'; + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; } print ''; diff --git a/htdocs/societe/website.php b/htdocs/societe/website.php index e7ebae374e2..109e65c5b04 100644 --- a/htdocs/societe/website.php +++ b/htdocs/societe/website.php @@ -213,8 +213,10 @@ if ($object->client) { print ''; print $langs->trans('CustomerCode').''; print $object->code_client; - if ($object->check_codeclient() != 0) + $tmpcheck = $object->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { print ' ('.$langs->trans("WrongCustomerCode").')'; + } print ''; } @@ -222,8 +224,10 @@ if ($object->fournisseur) { print ''; print $langs->trans('SupplierCode').''; print $object->code_fournisseur; - if ($object->check_codefournisseur() != 0) + $tmpcheck = $object->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { print ' ('.$langs->trans("WrongSupplierCode").')'; + } print ''; } diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 40beb75b5e9..8e3b73346b7 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -441,10 +441,10 @@ if ($socid && !$projectid && !$project_ref && $user->rights->societe->lire) { print ''; print $langs->trans('CustomerCode').''; print $socstat->code_client; - if ($socstat->check_codeclient() != 0) { - print ' ('.$langs->trans("WrongCustomerCode").')'; + $tmpcheck = $socstat->check_codeclient(); + if ($tmpcheck != 0 && $tmpcheck != -5) { + print ' ('.$langs->trans("WrongCustomerCode").')'; } - print ''; print ''; } @@ -453,10 +453,10 @@ if ($socid && !$projectid && !$project_ref && $user->rights->societe->lire) { print ''; print $langs->trans('SupplierCode').''; print $socstat->code_fournisseur; - if ($socstat->check_codefournisseur() != 0) { + $tmpcheck = $socstat->check_codefournisseur(); + if ($tmpcheck != 0 && $tmpcheck != -5) { print ' ('.$langs->trans("WrongSupplierCode").')'; } - print ''; print ''; } From 33f8c53ccabccfb0b549c22e3102cc7e93d97653 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 20 Dec 2020 14:03:10 +0100 Subject: [PATCH 112/137] Fix var_dump --- htdocs/fourn/card.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 9d94c6847b7..8b07fea2204 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -181,7 +181,6 @@ if ($object->id > 0) print ''.$langs->trans("SupplierCode").''; print $object->code_fournisseur; $tmpcheck = $object->check_codefournisseur(); - var_dump($tmpcheck); if ($tmpcheck != 0 && $tmpcheck != -5) { print ' ('.$langs->trans("WrongSupplierCode").')'; } From f273273129526bb0ecaccf2a42932a96166fa449 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 22 Dec 2020 06:57:55 +0100 Subject: [PATCH 113/137] FIX: Accountancy - Retire entire opening balance feature --- htdocs/accountancy/bookkeeping/balance.php | 46 +++++++++++++++------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 29e56cd4233..961a012f396 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -77,7 +77,7 @@ $form = new Form($db); if (empty($search_date_start) && !GETPOSTISSET('formfilteraction')) { $sql = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear "; - $sql .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."'"; + $sql .= " WHERE date_start < '".$db->idate(dol_now())."' AND date_end > '".$db->idate(dol_now())."'"; $sql .= $db->plimit(1); $res = $db->query($sql); if ($res->num_rows > 0) { @@ -237,7 +237,7 @@ if ($action != 'export_csv') print ''; print ''; - print ''; 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("OpeningBalance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder); + // print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'class="right"', $sortfield, $sortorder); @@ -265,10 +265,13 @@ if ($action != 'export_csv') $total_credit = 0; $sous_total_debit = 0; $sous_total_credit = 0; - $total_opening_balance = 0; - $sous_total_opening_balance = 0; + // $total_opening_balance = 0; + // $sous_total_opening_balance = 0; $displayed_account = ""; + // TODO Debug - In French accounting, this functionality is dangerous, it takes all the entries and adds all the accounts + // without time and class limits (Class 6 and 7 accounts ???) and does not take into account the "a-nouveau" journal. + /* $sql = "SELECT t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance"; $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as t"; $sql .= " WHERE t.entity = ".$conf->entity; // Never do sharing into accounting features @@ -282,6 +285,7 @@ if ($action != 'export_csv') $arr = $resql->fetch_array(); $opening_balances["'".$arr['numero_compte']."'"] = $arr['opening_balance']; } + */ foreach ($object->lines as $line) { @@ -290,8 +294,8 @@ if ($action != 'export_csv') $total_credit += $line->credit; $description = $object->get_compte_desc($line->numero_compte); // Search description of the account $root_account_description = $object->get_compte_racine($line->numero_compte); - $opening_balance = isset($opening_balances["'".$line->numero_compte."'"]) ? $opening_balances["'".$line->numero_compte."'"] : 0; - $total_opening_balance += $opening_balance; + // $opening_balance = isset($opening_balances["'".$line->numero_compte."'"]) ? $opening_balances["'".$line->numero_compte."'"] : 0; + // $total_opening_balance += $opening_balance; if (empty($description)) { $link = ''.img_edit_add().''; } @@ -302,30 +306,34 @@ if ($action != 'export_csv') { // Display a sub-total per account if ($displayed_account != "") { - print ''; + print ''; + // print ''; + print ''; + print ''; + print ''; print "\n"; print ''; } // Show first line of a break print ''; - print ''; + print ''; print ''; $displayed_account = $root_account_description; $sous_total_debit = 0; $sous_total_credit = 0; - $sous_total_opening_balance = 0; + // $sous_total_opening_balance = 0; } // $object->get_compte_racine($line->numero_compte); print ''; print ''; - print ''; + // print ''; print ''; print ''; - print ''; + print ''; print ''; print "\n"; @@ -333,14 +341,22 @@ if ($action != 'export_csv') // Records the sub-total $sous_total_debit += $line->debit; $sous_total_credit += $line->credit; - $sous_total_opening_balance += $opening_balance; + // $sous_total_opening_balance += $opening_balance; } - print ''; + print ''; + // print ''; + print ''; + print ''; + print ''; print "\n"; print ''; - print ''; + print ''; + // print ''; + print ''; + print ''; + print ''; print "\n"; print ''; From 77c335c5f36a45fb6343c9b38d2cacb4ca3e6e23 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 23 Dec 2020 09:19:56 +0100 Subject: [PATCH 114/137] fix colspan balance accountanty --- htdocs/accountancy/bookkeeping/balance.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 29e56cd4233..94a927d676c 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -302,7 +302,7 @@ if ($action != 'export_csv') { // Display a sub-total per account if ($displayed_account != "") { - print ''; + print ''; print "\n"; print ''; } From 8658f903fa633174050e80efcdd49c06ef476493 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 23 Dec 2020 15:00:25 +0100 Subject: [PATCH 115/137] FIX Must delete extrafields before main table on product deletion. --- htdocs/product/class/product.class.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index ccca1a85f47..0ec669afad8 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1241,6 +1241,16 @@ class Product extends CommonObject } } + // Remove extrafields + if (!$error) + { + $result = $this->deleteExtraFields(); + if ($result < 0) { + $error++; + dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); + } + } + // Delete product if (!$error) { $sqlz = "DELETE FROM ".MAIN_DB_PREFIX."product"; @@ -1268,16 +1278,6 @@ class Product extends CommonObject } } - // Remove extrafields - if (!$error) - { - $result = $this->deleteExtraFields(); - if ($result < 0) { - $error++; - dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR); - } - } - if (!$error) { $this->db->commit(); return 1; From 7d1d58822589fde6947531260c1e850c08c08e3f Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 23 Dec 2020 23:48:45 +0100 Subject: [PATCH 116/137] fix service right problem for mass action --- htdocs/product/list.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index d2f212df8da..50001d25026 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -240,6 +240,9 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +$rightskey = 'produit'; +if ($type == Product::TYPE_SERVICE) $rightskey = 'service'; + if (empty($reshook)) { // Selection of new fields @@ -275,8 +278,8 @@ if (empty($reshook)) if ((string) $search_type == '1') { $objectlabel = 'Services'; } if ((string) $search_type == '0') { $objectlabel = 'Products'; } - $permissiontoread = $user->rights->produit->lire; - $permissiontodelete = $user->rights->produit->supprimer; + $permissiontoread = $user->rights->{$rightskey}->lire; + $permissiontodelete = $user->rights->{$rightskey}->supprimer; $uploaddir = $conf->product->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } @@ -507,8 +510,6 @@ if ($resql) //'builddoc'=>$langs->trans("PDFMerge"), //'presend'=>$langs->trans("SendByMail"), ); - $rightskey = 'produit'; - if ($type == Product::TYPE_SERVICE) $rightskey = 'service'; if ($user->rights->{$rightskey}->supprimer) $arrayofmassactions['predelete'] = "".$langs->trans("Delete"); if (in_array($massaction, array('presend', 'predelete'))) $arrayofmassactions = array(); $massactionbutton = $form->selectMassAction('', $arrayofmassactions); From 60d8fb47199261c92c3ab416674bd70fdcc2157d Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 24 Dec 2020 00:48:48 +0100 Subject: [PATCH 117/137] fic porject mass action right --- htdocs/projet/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 5c36044dcd1..9bb383e9803 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -436,7 +436,7 @@ $arrayofmassactions = array( ); //if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); if ($user->rights->projet->creer) $arrayofmassactions['close'] = $langs->trans("Close"); -if ($user->rights->societe->supprimer) $arrayofmassactions['predelete'] = ''.$langs->trans("Delete"); +if ($user->rights->projet->supprimer) $arrayofmassactions['predelete'] = ''.$langs->trans("Delete"); if (in_array($massaction, array('presend', 'predelete'))) $arrayofmassactions = array(); $massactionbutton = $form->selectMassAction('', $arrayofmassactions); From 360a85cbbc76b26634578081254f68ea02150e0b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Dec 2020 12:32:34 +0100 Subject: [PATCH 118/137] FIX add autofix of count of email target when data is corrupted --- htdocs/comm/mailing/cibles.php | 38 ++++++++++++++++++--- htdocs/comm/mailing/class/mailing.class.php | 34 ++++++++++++++++++ 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index d8d9873b88b..8bfa82260b9 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -481,11 +481,27 @@ if ($object->fetch($id) >= 0) $sql .= " mc.source_url, mc.source_id, mc.source_type, mc.error_text"; $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc"; $sql .= " WHERE mc.fk_mailing=".$object->id; - if ($search_lastname) $sql .= natural_search("mc.lastname", $search_lastname); - if ($search_firstname) $sql .= natural_search("mc.firstname", $search_firstname); - if ($search_email) $sql .= natural_search("mc.email", $search_email); - if ($search_other) $sql .= natural_search("mc.other", $search_other); - if ($search_dest_status != '' && $search_dest_status >= -1) $sql .= " AND mc.statut=".$db->escape($search_dest_status)." "; + $asearchcriteriahasbeenset = 0; + if ($search_lastname) { + $sql .= natural_search("mc.lastname", $search_lastname); + $asearchcriteriahasbeenset++; + } + if ($search_firstname) { + $sql .= natural_search("mc.firstname", $search_firstname); + $asearchcriteriahasbeenset++; + } + if ($search_email) { + $sql .= natural_search("mc.email", $search_email); + $asearchcriteriahasbeenset++; + } + if ($search_other) { + $sql .= natural_search("mc.other", $search_other); + $asearchcriteriahasbeenset++; + } + if ($search_dest_status != '' && $search_dest_status >= -1) { + $sql .= " AND mc.statut=".$db->escape($search_dest_status)." "; + $asearchcriteriahasbeenset++; + } $sql .= $db->order($sortfield, $sortorder); // Count total nb of records @@ -499,6 +515,18 @@ if ($object->fetch($id) >= 0) $page = 0; $offset = 0; } + + // Fix/update nbemail on emailing record if it differs (may happen if user edit lines from database directly) + if (empty($asearchcriteriahasbeenset)) { + if ($nbtotalofrecords != $object->email) { + dol_syslog("We found a difference in nb of record in target table and the property ->nbemail, we fix ->nbemail"); + //print "nbemail=".$object->nbemail." nbtotalofrecords=".$nbtotalofrecords; + $resultrefresh = $object->refreshNbOfTargets(); + if ($resultrefresh < 0) { + dol_print_error($db, $object->error, $object->errors); + } + } + } } //$nbtotalofrecords=$object->nbemail; // nbemail is a denormalized field storing nb of targets diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php index 56a115a2fea..75efe1f07b2 100644 --- a/htdocs/comm/mailing/class/mailing.class.php +++ b/htdocs/comm/mailing/class/mailing.class.php @@ -461,6 +461,8 @@ class Mailing extends CommonObject $resql = $this->db->query($sql); if ($resql) { + $this->refreshNbOfTargets(); + return 1; } else @@ -532,6 +534,38 @@ class Mailing extends CommonObject return 0; } + /** + * Refresh denormalized value ->nbemail into emailing record + * Note: There is also the method update_nb into modules_mailings that is used for this. + * + * @return int <0 if KO, >0 if OK + */ + public function refreshNbOfTargets() + { + $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."mailing_cibles"; + $sql .= " WHERE fk_mailing = ".$this->id; + + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + if ($obj) { + $nbforupdate = $obj->nb; + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'mailing SET nbemail = '.((int) $nbforupdate); + $sql .= ' WHERE rowid = '.$this->id; + + $resqlupdate = $this->db->query($sql); + if (! $resqlupdate) { + $this->error = $this->db->lasterror(); + return -1; + } + } + } else { + $this->error = $this->db->lasterror(); + return -1; + } + return 1; + } /** * Return a link to the object card (with optionally the picto) From 739695c442e40960dc5435c7033853419d7de3f0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Dec 2020 12:49:17 +0100 Subject: [PATCH 119/137] Fix delay to wait between email for emailing refused float. --- htdocs/admin/mailing.php | 2 +- htdocs/comm/mailing/card.php | 2 +- scripts/emailings/mailing-send.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/admin/mailing.php b/htdocs/admin/mailing.php index 921a4a6338c..6e3341dcd8f 100644 --- a/htdocs/admin/mailing.php +++ b/htdocs/admin/mailing.php @@ -125,7 +125,7 @@ print ''; print ''; diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index e3cb5a9ad97..80692c1384d 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -346,7 +346,7 @@ if (empty($reshook)) if (!empty($conf->global->MAILING_DELAY)) { dol_syslog("Wait a delay of MAILING_DELAY=".$conf->global->MAILING_DELAY); - sleep($conf->global->MAILING_DELAY); + usleep((float) $conf->global->MAILING_DELAY * 1000000); } //test if CHECK READ change statut prospect contact diff --git a/scripts/emailings/mailing-send.php b/scripts/emailings/mailing-send.php index bc7efec7dba..0118697e5ec 100755 --- a/scripts/emailings/mailing-send.php +++ b/scripts/emailings/mailing-send.php @@ -318,7 +318,7 @@ if ($resql) { } if (!empty($conf->global->MAILING_DELAY)) { - sleep($conf->global->MAILING_DELAY); + usleep((float) $conf->global->MAILING_DELAY * 1000000); } } } else { From 3abceadb86445c021bac43139d5295f8f74adaf6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 24 Dec 2020 13:02:45 +0100 Subject: [PATCH 120/137] Add info --- scripts/emailings/mailing-send.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/emailings/mailing-send.php b/scripts/emailings/mailing-send.php index 0118697e5ec..5f93600f1be 100755 --- a/scripts/emailings/mailing-send.php +++ b/scripts/emailings/mailing-send.php @@ -60,6 +60,10 @@ $error = 0; @set_time_limit(0); print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n"; +if (!empty($conf->global->MAILING_DELAY)) { + print 'A delay of '.((float) $conf->global->MAILING_DELAY * 1000000).' millisecond has been set between each email'."\n"; +} + if ($conf->global->MAILING_LIMIT_SENDBYCLI == '-1') {} $user = new User($db); From 26791714cee70a00bc05243c49645c0d47ee4cff Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Mon, 28 Dec 2020 03:07:33 +0100 Subject: [PATCH 121/137] Fix : Introduce constant ACCOUNTANCY_SHOW_OPENING_BALANCE --- htdocs/accountancy/bookkeeping/balance.php | 76 +++++++++++++--------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 961a012f396..b71c633b1e5 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -237,7 +237,8 @@ if ($action != 'export_csv') print '
'; + print ''; print $langs->trans('From'); print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, ''); print ' '; @@ -254,7 +254,7 @@ if ($action != 'export_csv') print '
'.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_credit - $sous_total_debit)).'
'.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_credit - $sous_total_debit)).' 
'.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').''.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').'
'.length_accountg($line->numero_compte).''.$description.''.price($opening_balance).''.price($opening_balance).''.price($line->debit).''.price($line->credit).''.price($opening_balance + $line->debit - $line->credit).''.price(/*$opening_balance +*/ $line->debit - $line->credit).''.$link; print '
'.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit, 'MT')).'
'.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num(/*$sous_total_opening_balance +*/ $sous_total_debit - $sous_total_credit, 'MT')).' 
'.$langs->trans("AccountBalance").':'.price($total_opening_balance).''.price($total_debit).''.price($total_credit).''.price(price2num($total_opening_balance + $total_debit - $total_credit, 'MT')).'
'.$langs->trans("AccountBalance").':'.price($total_opening_balance).''.price($total_debit).''.price($total_credit).''.price(price2num(/*$total_opening_balance +*/ $total_debit - $total_credit, 'MT')).' 
'.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_credit - $sous_total_debit)).'
'.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_credit - $sous_total_debit)).' 
'; print $langs->trans("MailingDelay").''; -print ''; +print ''; print '
'; print ''; - print ''; 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("OpeningBalance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder); + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'class="right"', $sortfield, $sortorder); @@ -265,27 +266,29 @@ if ($action != 'export_csv') $total_credit = 0; $sous_total_debit = 0; $sous_total_credit = 0; - // $total_opening_balance = 0; - // $sous_total_opening_balance = 0; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { + $total_opening_balance = 0; + $sous_total_opening_balance = 0; + } $displayed_account = ""; // TODO Debug - In French accounting, this functionality is dangerous, it takes all the entries and adds all the accounts // without time and class limits (Class 6 and 7 accounts ???) and does not take into account the "a-nouveau" journal. - /* - $sql = "SELECT t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance"; - $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as t"; - $sql .= " WHERE t.entity = ".$conf->entity; // Never do sharing into accounting features - $sql .= " AND t.doc_date < '".$db->idate($search_date_start)."'"; - $sql .= " GROUP BY t.numero_compte"; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { + $sql = "SELECT t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as t"; + $sql .= " WHERE t.entity = " . $conf->entity; // Never do sharing into accounting features + $sql .= " AND t.doc_date < '" . $db->idate($search_date_start) . "'"; + $sql .= " GROUP BY t.numero_compte"; - $resql = $db->query($sql); - $nrows = $resql->num_rows; - $opening_balances = array(); - for ($i = 0; $i < $nrows; $i++) { - $arr = $resql->fetch_array(); - $opening_balances["'".$arr['numero_compte']."'"] = $arr['opening_balance']; + $resql = $db->query($sql); + $nrows = $resql->num_rows; + $opening_balances = array(); + for ($i = 0; $i < $nrows; $i++) { + $arr = $resql->fetch_array(); + $opening_balances["'" . $arr['numero_compte'] . "'"] = $arr['opening_balance']; + } } - */ foreach ($object->lines as $line) { @@ -294,8 +297,10 @@ if ($action != 'export_csv') $total_credit += $line->credit; $description = $object->get_compte_desc($line->numero_compte); // Search description of the account $root_account_description = $object->get_compte_racine($line->numero_compte); - // $opening_balance = isset($opening_balances["'".$line->numero_compte."'"]) ? $opening_balances["'".$line->numero_compte."'"] : 0; - // $total_opening_balance += $opening_balance; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { + $opening_balance = isset($opening_balances["'".$line->numero_compte."'"]) ? $opening_balances["'".$line->numero_compte."'"] : 0; + $total_opening_balance += $opening_balance; + } if (empty($description)) { $link = ''.img_edit_add().''; } @@ -307,7 +312,7 @@ if ($action != 'export_csv') // Display a sub-total per account if ($displayed_account != "") { print ''; - // print ''; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) print ''; print ''; print ''; print ''; @@ -317,23 +322,28 @@ if ($action != 'export_csv') // Show first line of a break print ''; - print ''; + $colspan = (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE) ? 7 : 6); + print ''; print ''; $displayed_account = $root_account_description; $sous_total_debit = 0; $sous_total_credit = 0; - // $sous_total_opening_balance = 0; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) $sous_total_opening_balance = 0; } // $object->get_compte_racine($line->numero_compte); print ''; print ''; - // print ''; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) print ''; print ''; print ''; - print ''; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { + print ''; + } else { + print ''; + } print ''; print "\n"; @@ -341,22 +351,30 @@ if ($action != 'export_csv') // Records the sub-total $sous_total_debit += $line->debit; $sous_total_credit += $line->credit; - // $sous_total_opening_balance += $opening_balance; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) $sous_total_opening_balance += $opening_balance; } print ''; - // print ''; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) print ''; print ''; print ''; - print ''; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { + print ''; + } else { + print ''; + } print "\n"; print ''; print ''; - // print ''; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) print ''; print ''; print ''; - print ''; + if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { + print ''; + } else { + print ''; + } print "\n"; print ''; From c3326a0963dccb3224d30c841ca4509d1483fc2c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 29 Dec 2020 04:30:37 +0100 Subject: [PATCH 122/137] FIX Creation of thirdparty when setup is empty --- htdocs/societe/class/societe.class.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 35b52243804..3842a8cd2a9 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -940,7 +940,7 @@ class Societe extends CommonObject if ($this->client) { $rescode = $this->check_codeclient(); - if ($rescode <> 0) + if ($rescode != 0 && $rescode != -5) { if ($rescode == -1) { @@ -965,7 +965,7 @@ class Societe extends CommonObject if ($this->fournisseur) { $rescode = $this->check_codefournisseur(); - if ($rescode <> 0) + if ($rescode != 0 && $rescode != -5) { if ($rescode == -1) { @@ -979,7 +979,7 @@ class Societe extends CommonObject { $this->errors[] = 'ErrorSupplierCodeAlreadyUsed'; } - elseif ($rescode == -5) + elseif ($rescode == -4) { $this->errors[] = 'ErrorPrefixRequired'; } @@ -3057,6 +3057,8 @@ class Societe extends CommonObject * -2 ErrorCustomerCodeRequired * -3 ErrorCustomerCodeAlreadyUsed * -4 ErrorPrefixRequired + * -5 NotConfigured - Setup empty so any value may be ok or not + * -6 Other (see this->error) */ public function check_codefournisseur() { From 0e2b7d8b3c9fc50d01239cdd01929e5e2ed141d9 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 30 Dec 2020 07:23:26 +0100 Subject: [PATCH 123/137] Remove typo --- htdocs/compta/bank/various_payment/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index ddad89e22fc..0e3c80a6ef8 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -392,7 +392,7 @@ if ($action == 'create') // Subledger account if (!empty($conf->accounting->enabled)) { - print ''; + print ''; print ''."\n"; // Timezone $txt = $langs->trans("OSTZ").' (variable system TZ): '.(!empty($_ENV["TZ"]) ? $_ENV["TZ"] : $langs->trans("NotDefined")).'
'."\n"; -$txt .= $langs->trans("PHPTZ").' (php.ini date.timezone): '.(ini_get("date.timezone") ?ini_get("date.timezone") : $langs->trans("NotDefined")).''."
\n"; // date.timezone must be in valued defined in http://fr3.php.net/manual/en/timezones.europe.php +$txt .= $langs->trans("PHPTZ").' (date_default_timezone_get() / php.ini date.timezone): '.(getServerTimeZoneString()." / ".(ini_get("date.timezone") ? ini_get("date.timezone") : $langs->trans("NotDefined")))."
\n"; // date.timezone must be in valued defined in http://fr3.php.net/manual/en/timezones.europe.php $txt .= $langs->trans("Dolibarr constant MAIN_SERVER_TZ").': '.(empty($conf->global->MAIN_SERVER_TZ) ? $langs->trans("NotDefined") : $conf->global->MAIN_SERVER_TZ); print ''; - print ''; + print ''; $label = ($langs->trans("PaymentType".$objp->payment_code) != ("PaymentType".$objp->payment_code)) ? $langs->trans("PaymentType".$objp->payment_code) : $objp->payment_label; print ''; if (!empty($conf->banque->enabled)) diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 7a759dde543..4583f0376ae 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -1201,7 +1201,16 @@ class Paiement extends CommonObject $result = ''; $label = ''.$langs->trans("ShowPayment").'
'; $label .= ''.$langs->trans("Ref").': '.$this->ref; - if ($this->datepaye ? $this->datepaye : $this->date) $label .= '
'.$langs->trans("Date").': '.dol_print_date($this->datepaye ? $this->datepaye : $this->date, 'dayhour'); + $dateofpayment = ($this->datepaye ? $this->datepaye : $this->date); + if ($dateofpayment) { + $label .= '
'.$langs->trans("Date").': '; + $tmparray = dol_getdate($dateofpayment); + if ($tmparray['seconds'] == 0 && $tmparray['minutes'] == 0 && ($tmparray['hours'] == 0 || $tmparray['hours'] == 12)) { // We set hours to 0:00 or 12:00 because we don't know it + $label .= dol_print_date($dateofpayment, 'day'); + } else { // Hours was set to real date of payment (special case for POS for example) + $label .= dol_print_date($dateofpayment, 'dayhour', 'tzuser'); + } + } if ($mode == 'withlistofinvoices') { $arraybill = $this->getBillsArray(); diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 1022308c308..0909f1b3cca 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -158,7 +158,7 @@ if ($action == 'valid' && $user->rights->facture->creer) if ($invoice->total_ttc < 0) { $invoice->type = $invoice::TYPE_CREDIT_NOTE; $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture WHERE "; - $sql .= "fk_soc = '".$invoice->socid."' "; + $sql .= "fk_soc = ".((int) $invoice->socid)." "; $sql .= "AND type <> ".Facture::TYPE_CREDIT_NOTE." "; $sql .= "AND fk_statut >= ".$invoice::STATUS_VALIDATED." "; $sql .= "ORDER BY rowid DESC"; @@ -763,13 +763,13 @@ $( document ).ready(function() { if ($resql) { while ($obj = $db->fetch_object($resql)) { echo '$("#customerandsales").append(\''; - echo 'jdate($obj->datec), '%H:%M'))).'" onclick="place=\\\''; + echo 'jdate($obj->datec), '%H:%M', 'tzuser'))).'" onclick="place=\\\''; $num_sale = str_replace(")", "", str_replace("(PROV-POS".$_SESSION["takeposterminal"]."-", "", $obj->ref)); echo $num_sale; if (str_replace("-", "", $num_sale) > $max_sale) $max_sale = str_replace("-", "", $num_sale); echo '\\\';Refresh();">'; if ($placeid == $obj->rowid) echo ""; - echo dol_print_date($db->jdate($obj->datec), '%H:%M'); + echo dol_print_date($db->jdate($obj->datec), '%H:%M', 'tzuser'); if ($placeid == $obj->rowid) echo ""; echo '\');'; } From a8d15fafd22707600afb54339ca1b6aef03914ad Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 2 Jan 2021 14:17:54 +0100 Subject: [PATCH 129/137] Fix missing span --- htdocs/admin/limits.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/limits.php b/htdocs/admin/limits.php index caf2192a9a3..ed3578522d4 100644 --- a/htdocs/admin/limits.php +++ b/htdocs/admin/limits.php @@ -293,7 +293,7 @@ if (empty($mysoc->country_code)) print ''.$langs->trans("UnitPriceOfProduct").": ".price2num($s, 'MU'); print " x ".$langs->trans("Quantity").": ".$qty; print " - ".$langs->trans("VAT").": ".$vat.'%'; - print '   ->   '.$langs->trans("TotalPriceAfterRounding").": ".$tmparray[0].' / '.$tmparray[1].' / '.$tmparray[2]."
\n"; + print '   ->   '.$langs->trans("TotalPriceAfterRounding").": ".$tmparray[0].' / '.$tmparray[1].' / '.$tmparray[2]."
\n"; $s = 10 / 3; $qty = 2; $vat = 10; $tmparray = calcul_price_total($qty, price2num($s, 'MU'), 0, $vat, -1, -1, 0, 'HT', 0, 0, $mysoc, $localtax_array); From d46eb08083a5239a0e9196d968e3b2b4bb556363 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 2 Jan 2021 15:36:19 +0100 Subject: [PATCH 130/137] More log and use id to refresh/reload an invoice. --- htdocs/takepos/index.php | 5 +++-- htdocs/takepos/invoice.php | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 4bfeaa57b75..51b6334a2c9 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -155,6 +155,7 @@ var pageactions=0; var place=""; var editaction="qty"; var editnumber=""; +var invoiceid=0; /* var app = this; @@ -448,8 +449,8 @@ function TakeposOrderNotes() { } function Refresh() { - console.log("Refresh by reloading place="+place); - $("#poslines").load("invoice.php?place="+place, function() { + console.log("Refresh by reloading place="+place+" invoiceid="+invoiceid); + $("#poslines").load("invoice.php?place="+place+"&invoiceid="+invoiceid, function() { //$('#poslines').scrollTop($('#poslines')[0].scrollHeight); }); } diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 0909f1b3cca..f31bb90bfcd 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -742,7 +742,7 @@ function DolibarrTakeposPrinting(id) { $( document ).ready(function() { - console.log("Set customer info and sales in header"); + console.log("Set customer info and sales in header placeid= status=statut; ?>"); trans("Customer"); @@ -757,7 +757,14 @@ $( document ).ready(function() { global->TAKEPOS_CAN_EDIT_IF_ALREADY_VALIDATED)) { + // By default, only invoices with a ref not already defined can in list of open invoice we can edit. + $sql .= " WHERE ref LIKE '(PROV-POS".$_SESSION["takeposterminal"]."-0%'"; + } else { + // If TAKEPOS_CAN_EDIT_IF_ALREADY_VALIDATED set, we show also draft invoice that already has a reference defined + $sql .= " WHERE pos_source = ".$_SESSION["takeposterminal"]; + $sql .= " AND module_source = 'takepos'"; + } $sql .= $db->order('datec', 'ASC'); $resql = $db->query($sql); if ($resql) { @@ -767,7 +774,9 @@ $( document ).ready(function() { $num_sale = str_replace(")", "", str_replace("(PROV-POS".$_SESSION["takeposterminal"]."-", "", $obj->ref)); echo $num_sale; if (str_replace("-", "", $num_sale) > $max_sale) $max_sale = str_replace("-", "", $num_sale); - echo '\\\';Refresh();">'; + echo '\\\'; invoiceid=\\\''; + echo $obj->rowid; + echo '\\\'; Refresh();">'; if ($placeid == $obj->rowid) echo ""; echo dol_print_date($db->jdate($obj->datec), '%H:%M', 'tzuser'); if ($placeid == $obj->rowid) echo ""; @@ -775,7 +784,7 @@ $( document ).ready(function() { } echo '$("#customerandsales").append(\'\');'; + echo '\\\'; invoiceid=0; Refresh();">\');'; } else { dol_print_error($db); } From fd4dab495f010fc170c94ab3e6d5a47be7e7f605 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 2 Jan 2021 16:51:34 +0100 Subject: [PATCH 131/137] FIX Bad cleaning of VAT rate when numbers are into code --- htdocs/comm/propal/class/propal.class.php | 5 ++++- htdocs/commande/class/commande.class.php | 4 +++- htdocs/compta/facture/class/facture-rec.class.php | 11 ++++++++--- htdocs/compta/facture/class/facture.class.php | 4 +++- htdocs/contrat/class/contrat.class.php | 1 - htdocs/fichinter/class/fichinterrec.class.php | 4 +++- htdocs/fourn/class/fournisseur.commande.class.php | 4 +++- .../class/supplier_proposal.class.php | 11 ++++++++--- 8 files changed, 32 insertions(+), 12 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 144374ab47c..9d6b6c201c5 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -602,6 +602,7 @@ class Propal extends CommonObject // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $txtva, $reg)) { $vat_src_code = $reg[1]; @@ -779,7 +780,9 @@ class Propal extends CommonObject $qty = price2num($qty); $pu = price2num($pu); $pu_ht_devise = price2num($pu_ht_devise); - $txtva = price2num($txtva); + if (!preg_match('/\((.*)\)/', $txtva)) { + $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + } $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); $pa_ht = price2num($pa_ht); diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 5402d31ba7d..49f8005980f 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3120,7 +3120,9 @@ class Commande extends CommonOrder $pu = price2num($pu); $pa_ht = price2num($pa_ht); $pu_ht_devise = price2num($pu_ht_devise); - $txtva = price2num($txtva); + if (!preg_match('/\((.*)\)/', $txtva)) { + $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + } $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index c5bd8a987ac..85ecb3f969d 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -849,7 +849,9 @@ class FactureRec extends CommonInvoice $qty = price2num($qty); $pu_ht = price2num($pu_ht); $pu_ttc = price2num($pu_ttc); - $txtva = price2num($txtva); + if (!preg_match('/\((.*)\)/', $txtva)) { + $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + } $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); if (empty($txtva)) $txtva = 0; @@ -1031,8 +1033,10 @@ class FactureRec extends CommonInvoice $pu_ht = price2num($pu_ht); $pu_ttc = price2num($pu_ttc); $pu_ht_devise = price2num($pu_ht_devise); - $txtva = price2num($txtva); - $txlocaltax1 = price2num($txlocaltax1); + if (!preg_match('/\((.*)\)/', $txtva)) { + $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + } + $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); if (empty($txlocaltax1)) $txlocaltax1 = 0; if (empty($txlocaltax2)) $txlocaltax2 = 0; @@ -1059,6 +1063,7 @@ class FactureRec extends CommonInvoice // Clean vat code $vat_src_code = ''; + $reg = array(); if (preg_match('/\((.*)\)/', $txtva, $reg)) { $vat_src_code = $reg[1]; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 4bfc36a3e78..392817b0368 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3311,7 +3311,9 @@ class Facture extends CommonInvoice $pu = price2num($pu); $pu_ht_devise = price2num($pu_ht_devise); $pa_ht = price2num($pa_ht); - $txtva = price2num($txtva); + if (!preg_match('/\((.*)\)/', $txtva)) { + $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + } $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index e38c24565dd..13f0ba644d0 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -1502,7 +1502,6 @@ class Contrat extends CommonObject $vat_src_code = $reg[1]; $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. } - $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index 5b3dfb3a2fc..2d678514182 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -473,7 +473,9 @@ class FichinterRec extends Fichinter if (!$info_bits) $info_bits = 0; $pu_ht = price2num($pu_ht); $pu_ttc = price2num($pu_ttc); - $txtva = price2num($txtva); + if (!preg_match('/\((.*)\)/', $txtva)) { + $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + } if ($price_base_type == 'HT') { $pu = $pu_ht; diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index af283d8cdf0..123b1eb0046 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2633,7 +2633,9 @@ class CommandeFournisseur extends CommonOrder if (!$qty) $qty = 1; $pu = price2num($pu); $pu_ht_devise = price2num($pu_ht_devise); - $txtva = price2num($txtva); + if (!preg_match('/\((.*)\)/', $txtva)) { + $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + } $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 33c80f9b6b1..9822c171cd8 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -423,10 +423,13 @@ class SupplierProposal extends CommonObject $qty = price2num($qty); $pu_ht = price2num($pu_ht); $pu_ttc = price2num($pu_ttc); - $txtva = price2num($txtva); + if (!preg_match('/\((.*)\)/', $txtva)) { + $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + } $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); - $pa_ht = price2num($pa_ht); + + $pa_ht = price2num($pa_ht); if ($price_base_type == 'HT') { $pu = $pu_ht; @@ -682,7 +685,9 @@ class SupplierProposal extends CommonObject $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu = price2num($pu); - $txtva = price2num($txtva); + if (!preg_match('/\((.*)\)/', $txtva)) { + $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' + } $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); $pa_ht = price2num($pa_ht); From f462f68056dcc1dd443244854e8f15bdd3f24a88 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 3 Jan 2021 15:10:33 +0100 Subject: [PATCH 132/137] Code comment --- htdocs/core/db/DoliDB.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index 837946ce706..8f2a9dc315e 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -89,7 +89,7 @@ abstract class DoliDB implements Database */ public function idate($param) { - // TODO GMT $param should be gmt, so we should add tzouptut to 'gmt' + // TODO $param should be gmt, so we should add tzouptut to 'gmt' instead of default 'tzserver' return dol_print_date($param, "%Y-%m-%d %H:%M:%S"); } @@ -285,7 +285,7 @@ abstract class DoliDB implements Database */ public function jdate($string, $gm = false) { - // TODO GMT must set param gm to true by default + // TODO $string should be converted into a GMT timestamp, so param gm should be set to true by default instead of false if ($string == 0 || $string == "0000-00-00 00:00:00") return ''; $string = preg_replace('/([^0-9])/i', '', $string); $tmp = $string.'000000'; From 8ad5dc81de8268eea6ed4e299a5fe4088712abc4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 3 Jan 2021 15:13:29 +0100 Subject: [PATCH 133/137] GETPOST --- htdocs/comm/action/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 0709a2571ad..fcb33bd544a 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -445,8 +445,8 @@ if (empty($reshook) && $action == 'update') $object->fetch_userassigned(); $object->oldcopy = clone $object; - $datep = dol_mktime($fulldayevent ? '00' : $aphour, $fulldayevent ? '00' : $apmin, 0, $_POST["apmonth"], $_POST["apday"], $_POST["apyear"]); - $datef = dol_mktime($fulldayevent ? '23' : $p2hour, $fulldayevent ? '59' : $p2min, $fulldayevent ? '59' : '0', $_POST["p2month"], $_POST["p2day"], $_POST["p2year"]); + $datep = dol_mktime($fulldayevent ? '00' : $aphour, $fulldayevent ? '00' : $apmin, 0, GETPOST("apmonth", 'int'), GETPOST("apday", 'int'), GETPOST("apyear", 'int')); + $datef = dol_mktime($fulldayevent ? '23' : $p2hour, $fulldayevent ? '59' : $p2min, $fulldayevent ? '59' : '0', GETPOST("p2month", 'int'), GETPOST("p2day", 'int'), GETPOST("p2year", 'int')); $object->type_id = dol_getIdFromCode($db, GETPOST("actioncode", 'aZ09'), 'c_actioncomm'); $object->label = GETPOST("label", "alphanohtml"); From e190b010d3aae2aa6c501d37003f6a921a36a924 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sun, 3 Jan 2021 16:05:04 +0100 Subject: [PATCH 134/137] Fix dict contact type element list --- htdocs/core/lib/admin.lib.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 7b3d66f9003..1bae8d0224f 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1382,7 +1382,14 @@ function complete_elementList_with_modules(&$elementList) if (!empty($objMod->module_parts['contactelement'])) { - $elementList[$objMod->name] = $langs->trans($objMod->name); + if(is_array($objMod->module_parts['contactelement'])) { + foreach ($objMod->module_parts['contactelement'] as $elem => $title) { + $elementList[$elem] = $langs->trans($title); + } + } + else { + $elementList[$objMod->name] = $langs->trans($objMod->name); + } } $j++; From d892d8c3c792f1bc29db570b02f17c629b5d9ea4 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Mon, 4 Jan 2021 10:59:45 +0100 Subject: [PATCH 135/137] FIX: Bad dates filtering in the ticket list causes sql error --- htdocs/ticket/list.php | 63 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 8e3b73346b7..90cd1fd1ec9 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -2,7 +2,7 @@ /* Copyright (C) 2013-2018 Jean-François FERRY * Copyright (C) 2016 Christophe Battarel * Copyright (C) 2018 Regis Houssin - * Copyright (C) 2019 Juanjo Menent + * Copyright (C) 2019-2021 Juanjo Menent * Copyright (C) 2019-2020 Laurent Destailleur * * This program is free software; you can redistribute it and/or modify @@ -57,6 +57,14 @@ $project_ref = GETPOST('project_ref', 'alpha'); $search_societe = GETPOST('search_societe', 'alpha'); $search_fk_project = GETPOST('search_fk_project', 'int') ?GETPOST('search_fk_project', 'int') : GETPOST('projectid', 'int'); $search_fk_status = GETPOST('search_fk_statut', 'array'); +$search_date_start = dol_mktime(0, 0, 0, GETPOST('search_date_startmonth', 'int'), GETPOST('search_date_startday', 'int'), GETPOST('search_date_startyear', 'int')); +$search_date_end = dol_mktime(23, 59, 59, GETPOST('search_date_endmonth', 'int'), GETPOST('search_date_endday', 'int'), GETPOST('search_date_endyear', 'int')); +$search_dateread_start = dol_mktime(0, 0, 0, GETPOST('search_dateread_startmonth', 'int'), GETPOST('search_dateread_startday', 'int'), GETPOST('search_dateread_startyear', 'int')); +$search_dateread_end = dol_mktime(23, 59, 59, GETPOST('search_dateread_endmonth', 'int'), GETPOST('search_dateread_endday', 'int'), GETPOST('search_dateread_endyear', 'int')); +$search_dateclose_start = dol_mktime(0, 0, 0, GETPOST('search_dateclose_startmonth', 'int'), GETPOST('search_dateclose_startday', 'int'), GETPOST('search_dateclose_startyear', 'int')); +$search_dateclose_end = dol_mktime(23, 59, 59, GETPOST('search_dateclose_endmonth', 'int'), GETPOST('search_dateclose_endday', 'int'), GETPOST('search_dateclose_endyear', 'int')); + + $mode = GETPOST('mode', 'alpha'); // Load variable for pagination @@ -178,6 +186,12 @@ if (empty($reshook)) } $toselect = ''; $search_array_options = array(); + $search_date_start = ''; + $search_date_end = ''; + $search_dateread_start = ''; + $search_dateread_end = ''; + $search_dateclose_start = ''; + $search_dateclose_end = ''; } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) @@ -356,6 +370,14 @@ foreach ($search as $key => $val) if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all); if ($search_societe) $sql .= natural_search('s.nom', $search_societe); if ($search_fk_project) $sql .= natural_search('fk_project', $search_fk_project, 2); +if ($search_date_start) $sql .= " AND t.datec >= '".$db->idate($search_date_start)."'"; +if ($search_date_end) $sql .= " AND t.datec <= '".$db->idate($search_date_end)."'"; +if ($search_dateread_start) $sql .= " AND t.date_read >= '".$db->idate($search_dateread_start)."'"; +if ($search_dateread_end) $sql .= " AND t.date_read <= '".$db->idate($search_dateread_end)."'"; +if ($search_dateclose_start) $sql .= " AND t.date_close >= '".$db->idate($search_dateclose_start)."'"; +if ($search_dateclose_end) $sql .= " AND t.date_close <= '".$db->idate($search_dateclose_end)."'"; + + if (!$user->socid && ($mode == "mine" || (!$user->admin && $conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY))) { $sql .= " AND (t.fk_user_assign = ".$user->id; if (empty($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY)) $sql .= " OR t.fk_user_create = ".$user->id; @@ -549,6 +571,13 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; if ($socid) $param .= '&socid='.urlencode($socid); if ($projectid) $param .= '&projectid='.urlencode($projectid); +if ($search_date_start) $param .= '&search_date_start='.urlencode($search_date_start); +if ($search_date_end) $param .= '&search_date_end='.urlencode($search_date_end); +if ($search_dateread_start) $param .= '&search_dateread_start='.urlencode($search_dateread_start); +if ($search_dateread_end) $param .= '&search_dateread_end='.urlencode($search_dateread_end); +if ($search_dateclose_start) $param .= '&search_dateclose_start='.urlencode($search_dateclose_start); +if ($search_dateclose_end) $param .= '&search_dateclose_end='.urlencode($search_dateclose_end); + // List of mass actions available $arrayofmassactions = array( //'presend'=>$langs->trans("SendByMail"), @@ -667,6 +696,38 @@ foreach ($object->fields as $key => $val) { print '
'; } + elseif ($key == "datec" || $key == 'date_read' || $key == 'date_close'){ + print ''; + } else { print ''; } From bb22f2ccaf18b8f50abe25a9477ff1f8188a4320 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 4 Jan 2021 12:02:41 +0100 Subject: [PATCH 136/137] Update admin.lib.php --- htdocs/core/lib/admin.lib.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 1bae8d0224f..8fddc46cca3 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1380,14 +1380,12 @@ function complete_elementList_with_modules(&$elementList) $dirmod[$i] = $dir; //print "x".$modName." ".$orders[$i]."\n
"; - if (!empty($objMod->module_parts['contactelement'])) - { - if(is_array($objMod->module_parts['contactelement'])) { + if (!empty($objMod->module_parts['contactelement'])) { + if (is_array($objMod->module_parts['contactelement'])) { foreach ($objMod->module_parts['contactelement'] as $elem => $title) { $elementList[$elem] = $langs->trans($title); } - } - else { + } else { $elementList[$objMod->name] = $langs->trans($objMod->name); } } From ca6899c1386201c479fea276f44364e08d9e2d3b Mon Sep 17 00:00:00 2001 From: lvessiller Date: Tue, 5 Jan 2021 16:11:46 +0100 Subject: [PATCH 137/137] FIX right to show VAT rate in product list --- htdocs/product/list.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index cc12bc73349..2478e75057c 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -180,7 +180,7 @@ $arrayfields = array( 'p.sellprice'=>array('label'=>$langs->trans("SellingPrice"), 'checked'=>1, 'enabled'=>empty($conf->global->PRODUIT_MULTIPRICES)), 'p.minbuyprice'=>array('label'=>$langs->trans("BuyingPriceMinShort"), 'checked'=>1, 'enabled'=>(!empty($user->rights->fournisseur->lire))), 'p.numbuyprice'=>array('label'=>$langs->trans("BuyingPriceNumShort"), 'checked'=>0, 'enabled'=>(!empty($user->rights->fournisseur->lire))), - 'p.tva_tx'=>array('label'=>$langs->trans("VATRate"), 'checked'=>0, 'enabled'=>(!empty($user->rights->fournisseur->lire))), + 'p.tva_tx'=>array('label'=>$langs->trans("VATRate"), 'checked'=>0, 'enabled'=>empty($conf->global->PRODUIT_MULTIPRICES)), 'p.pmp'=>array('label'=>$langs->trans("PMPValueShort"), 'checked'=>0, 'enabled'=>(!empty($user->rights->fournisseur->lire))), 'p.seuil_stock_alerte'=>array('label'=>$langs->trans("StockLimit"), 'checked'=>0, 'enabled'=>(!empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')), 'p.desiredstock'=>array('label'=>$langs->trans("DesiredStock"), 'checked'=>1, 'enabled'=>(!empty($conf->stock->enabled) && $user->rights->stock->lire && $contextpage != 'service')), @@ -332,7 +332,7 @@ if ($search_label) $sql .= natural_search('p.label', $search_label); if ($search_barcode) $sql .= natural_search('p.barcode', $search_barcode); if (isset($search_tosell) && dol_strlen($search_tosell) > 0 && $search_tosell != -1) $sql .= " AND p.tosell = ".$db->escape($search_tosell); if (isset($search_tobuy) && dol_strlen($search_tobuy) > 0 && $search_tobuy != -1) $sql .= " AND p.tobuy = ".$db->escape($search_tobuy); -if ($search_vatrate) $sql .= natural_search('p.tva_tx', $search_vatrate); +if ($search_vatrate) $sql .= natural_search('p.tva_tx', $search_vatrate, 1); if (dol_strlen($canvas) > 0) $sql .= " AND p.canvas = '".$db->escape($canvas)."'"; if ($catid > 0) $sql .= " AND cp.fk_categorie = ".$catid; if ($catid == -2) $sql .= " AND cp.fk_categorie IS NULL"; @@ -774,7 +774,7 @@ if ($resql) print_liste_field_titre($arrayfields['p.numbuyprice']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right '); } if (!empty($arrayfields['p.tva_tx']['checked'])) { - print_liste_field_titre($arrayfields['p.tva_tx']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right '); + print_liste_field_titre($arrayfields['p.tva_tx']['label'], $_SERVER["PHP_SELF"], 'p.tva_tx', "", $param, '', $sortfield, $sortorder, 'right '); } if (!empty($arrayfields['p.pmp']['checked'])) { print_liste_field_titre($arrayfields['p.pmp']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
'; + $colspan = (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE) ? 6 : 5); + print ''; print $langs->trans('From'); print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, ''); print ' '; @@ -254,7 +255,7 @@ if ($action != 'export_csv') print '
'.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_credit - $sous_total_debit)).'
'.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').''.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').'
'.length_accountg($line->numero_compte).''.$description.''.price($opening_balance).''.price($opening_balance).''.price($line->debit).''.price($line->credit).''.price(/*$opening_balance +*/ $line->debit - $line->credit).''.price($opening_balance + $line->debit - $line->credit).''.price($line->debit - $line->credit).''.$link; print '
'.$langs->trans("SubTotal").':'.price($sous_total_opening_balance).''.price($sous_total_opening_balance).''.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num(/*$sous_total_opening_balance +*/ $sous_total_debit - $sous_total_credit, 'MT')).'' . price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit, 'MT')) . '' . price(price2num($sous_total_debit - $sous_total_credit, 'MT')) . ' 
'.$langs->trans("AccountBalance").':'.price($total_opening_balance).''.price($total_opening_balance).''.price($total_debit).''.price($total_credit).''.price(price2num(/*$total_opening_balance +*/ $total_debit - $total_credit, 'MT')).'' . price(price2num($total_opening_balance + $total_debit - $total_credit, 'MT')) . '' . price(price2num($total_debit - $total_credit, 'MT')) . ' 
'.$langs->trans("SubledgerAccount").'aaaa
'.$langs->trans("SubledgerAccount").''; if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { From a336e4509802386f15c50afa977b5bd521ca475a Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Wed, 30 Dec 2020 08:11:20 +0100 Subject: [PATCH 124/137] FIX: #15751 Miscellaneous payment type change to 0 after updating subledger --- htdocs/compta/bank/class/paymentvarious.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/bank/class/paymentvarious.class.php b/htdocs/compta/bank/class/paymentvarious.class.php index aec104028c0..348c24acd83 100644 --- a/htdocs/compta/bank/class/paymentvarious.class.php +++ b/htdocs/compta/bank/class/paymentvarious.class.php @@ -137,7 +137,7 @@ class PaymentVarious extends CommonObject $sql .= " datev='".$this->db->idate($this->datev)."',"; $sql .= " sens=".(int) $this->sens.","; $sql .= " amount=".price2num($this->amount).","; - $sql .= " fk_typepayment=".(int) $this->fk_typepayment.","; + $sql .= " fk_typepayment=".(int) $this->type_payment.","; $sql .= " num_payment='".$this->db->escape($this->num_payment)."',"; $sql .= " label='".$this->db->escape($this->label)."',"; $sql .= " note='".$this->db->escape($this->note)."',"; From 1ec763fc14f324ea1301fafefd00d3d72bf7b667 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 30 Dec 2020 21:22:54 +0100 Subject: [PATCH 125/137] FIX When creating a new POS sell, the creation date must be modified. --- htdocs/takepos/index.php | 7 ++++--- htdocs/takepos/invoice.php | 13 ++++--------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index d3fc6b7416a..4eeb9dcf9a7 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -448,7 +448,7 @@ function TakeposOrderNotes() { } function Refresh() { - console.log("Refresh"); + console.log("Refresh by reloading place="+place); $("#poslines").load("invoice.php?place="+place, function() { //$('#poslines').scrollTop($('#poslines')[0].scrollHeight); }); @@ -456,9 +456,10 @@ function Refresh() { function New() { // If we go here,it means $conf->global->TAKEPOS_BAR_RESTAURANT is not defined - console.log("New with place = , js place="+place); - invoiceid = $("#invoiceid").val(); + + console.log("New with place = , js place="+place+", invoiceid="+invoiceid); + $.getJSON('/takepos/ajax/ajax.php?action=getInvoice&id='+invoiceid, function(data) { var r; diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 493202376a9..0bc6087409d 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -395,16 +395,9 @@ if ($action == "deleteline") { } } +// Action to delete or discard an invoice if ($action == "delete") { // $placeid is the invoice id (it differs from place) and is defined if the place is set and the ref of invoice is '(PROV-POS'.$_SESSION["takeposterminal"].'-'.$place.')', so the fetch at begining of page works. - - /*$reg = array(); - if (preg_match('/^(\d+)-(\d+)$/', $place, $reg)) { - - $place = $reg[1]; - var_dump($place); - }*/ - if ($placeid > 0) { $result = $invoice->fetch($placeid); @@ -422,7 +415,9 @@ if ($action == "delete") { } } - $sql = "UPDATE ".MAIN_DB_PREFIX."facture set fk_soc=".$conf->global->{'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"]}; + $sql = "UPDATE ".MAIN_DB_PREFIX."facture"; + $sql .= " SET fk_soc=".$conf->global->{'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"]}.", "; + $sql .= " datec = '".$db->idate(dol_now())."'"; $sql .= " WHERE ref='(PROV-POS".$_SESSION["takeposterminal"]."-".$place.")'"; $resql1 = $db->query($sql); From 79da04780248280be09cb0e5ed19d345db4efca1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 30 Dec 2020 21:43:04 +0100 Subject: [PATCH 126/137] FIX Dates of sales start in TakePOS Conflicts: htdocs/langs/en_US/cashdesk.lang --- htdocs/langs/en_US/cashdesk.lang | 5 +++-- htdocs/takepos/index.php | 2 +- htdocs/takepos/invoice.php | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index ce5cdaf4ba6..a93571d4768 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -99,8 +99,9 @@ CashDeskRefNumberingModules=Numbering module for POS sales CashDeskGenericMaskCodes6 =
{TN} tag is used to add the terminal number TakeposGroupSameProduct=Group same products lines StartAParallelSale=Start a new parallel sale -ControlCashOpening=Control cash box at opening pos -CloseCashFence=Close cash fence +SaleStartedAt=Sale started at %s +ControlCashOpening=Control cash popup at opening POS +CloseCashFence=Close cash desk control CashReport=Cash report MainPrinterToUse=Main printer to use OrderPrinterToUse=Order printer to use diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index 4eeb9dcf9a7..4bfeaa57b75 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -778,7 +778,7 @@ if (empty($conf->global->TAKEPOS_HIDE_HEAD_BAR)) {
  => price(1234.56)'.price(1234.56).'
'.$langs->trans("CurrentTimeZone").''; // Timezone server PHP $a = getServerTimeZoneInt('now'); From 65edc377c3515cbea7a40d27e4d69d9e8773e39e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 30 Dec 2020 22:53:21 +0100 Subject: [PATCH 128/137] FIX Visible date of payment --- htdocs/compta/facture/card.php | 10 +++++++++- htdocs/compta/paiement/class/paiement.class.php | 11 ++++++++++- htdocs/takepos/invoice.php | 6 +++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index aa07de4867e..0970aff1b45 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -4848,7 +4848,15 @@ elseif ($id > 0 || !empty($ref)) print '
'; print $paymentstatic->getNomUrl(1); print ''.dol_print_date($db->jdate($objp->dp), 'dayhour').''; + $dateofpayment = $db->jdate($objp->dp); + $tmparray = dol_getdate($dateofpayment); + if ($tmparray['seconds'] == 0 && $tmparray['minutes'] == 0 && ($tmparray['hours'] == 0 || $tmparray['hours'] == 12)) { // We set hours to 0:00 or 12:00 because we don't know it + print dol_print_date($dateofpayment, 'day'); + } else { // Hours was set to real date of payment (special case for POS for example) + print dol_print_date($dateofpayment, 'dayhour', 'tzuser'); + } + print ''.$label.' '.$objp->num_payment.''; + print '
'; + print $langs->trans('From').' '; + + switch ($key){ + case 'datec': + print $form->selectDate($search_date_start ?: -1, 'search_date_start', 0, 0, 1); + break; + case 'date_read': + print $form->selectDate($search_dateread_start ?: -1, 'search_dateread_start', 0, 0, 1); + break; + case 'date_close': + print $form->selectDate($search_dateclose_start ?: -1, 'search_dateclose_start', 0, 0, 1); + } + + print '
'; + print '
'; + print $langs->trans('to').' '; + switch ($key){ + case 'datec': + print $form->selectDate($search_date_end ?: -1, 'search_date_end', 0, 0, 1); + break; + case 'date_read': + print $form->selectDate($search_dateread_end ?: -1, 'search_dateread_end', 0, 0, 1); + break; + case 'date_close': + print $form->selectDate($search_dateclose_end ?: -1, 'search_dateclose_end', 0, 0, 1); + } + print '
'; + print '