From e7a5d263555b77a720b3eeb304df7e98ddb6dfce Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 23 Dec 2019 14:25:54 +0100 Subject: [PATCH 01/37] FIX remove backward compatibility projectid and uses object id instead --- htdocs/projet/element.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 97e99c93370..fe8a27ec6f8 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -83,17 +83,16 @@ if (! isset($_POST['datesrfc']) && ! isset($_POST['datesday']) && ! empty($conf- //$dates=dol_time_plus_duree($datee, -1, 'y'); $dates=dol_get_first_day($tmp['year'], 1); } -if ($id == '' && $projectid == '' && $ref == '') +if ($id == '' && $ref == '') { - dol_print_error('', 'Bad parameter'); - exit; + setEventMessage($langs->trans('ErrorBadParameters'), 'errors'); + header('Location: list.php'); + exit(); } $mine = $_REQUEST['mode']=='mine' ? 1 : 0; //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects -$projectid=$id; // For backward compatibility - $object = new Project($db); include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once @@ -102,7 +101,7 @@ if(! empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($ob // Security check $socid=$object->socid; //if ($user->societe_id > 0) $socid = $user->societe_id; // For external user, no check is done on company because readability is managed by public status of project and assignement. -$result = restrictedArea($user, 'projet', $projectid, 'projet&project'); +$result = restrictedArea($user, 'projet', $object->id, 'projet&project'); $hookmanager->initHooks(array('projectOverview')); @@ -513,7 +512,7 @@ elseif ($action == "unlink") { $tablename = GETPOST("tablename", "aZ09"); - $projectField = GETPOST("projectfield", "aZ09"); + $projectField = GETPOST('projectfield', 'aZ09') ? GETPOST('projectfield', 'aZ09') : 'fk_projet'; $elementselectid = GETPOST("elementselect", "int"); $result = $object->remove_element($tablename, $elementselectid, $projectField); @@ -532,7 +531,7 @@ $showdatefilter=0; if (! $showdatefilter) { print '
'; - print '
'; + print ''; print ''; print ''; print ''; @@ -755,7 +754,7 @@ foreach ($listofreferent as $key => $value) if (empty($conf->global->PROJECT_LINK_ON_OVERWIEW_DISABLED) && $idtofilterthirdparty && !in_array($tablename, $exclude_select_element)) { $selectList=$formproject->select_element($tablename, $idtofilterthirdparty, 'minwidth300', -2, !empty($project_field)?$project_field:'fk_projet'); - if (! $selectList || ($selectList<0)) + if ($selectList<0) { setEventMessages($formproject->error, $formproject->errors, 'errors'); } @@ -763,7 +762,7 @@ foreach ($listofreferent as $key => $value) { // Define form with the combo list of elements to link $addform.='
'; - $addform.=''; + $addform.=''; $addform.=''; $addform.=''; $addform.=''; @@ -890,7 +889,7 @@ foreach ($listofreferent as $key => $value) { if (empty($conf->global->PROJECT_DISABLE_UNLINK_FROM_OVERVIEW) || $user->admin) // PROJECT_DISABLE_UNLINK_FROM_OVERVIEW is empty by defaut, so this test true { - print ''; + print ''; print img_picto($langs->trans('Unlink'), 'unlink'); print ''; } From e03222b83109f2f56daf7b98398138c4900261d9 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 23 Dec 2019 14:38:01 +0100 Subject: [PATCH 02/37] FIX var transkey not defined in input hidden --- htdocs/admin/dict.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index e92cc80a08e..747a621e860 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -1985,9 +1985,9 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') if (in_array($fieldlist[$field], array('libelle', 'label', 'tracking'))) $class='quatrevingtpercent'; print ''; $transfound=0; + $transkey=''; if (in_array($fieldlist[$field], array('label','libelle'))) { - $transkey=''; // Special case for labels if ($tabname == MAIN_DB_PREFIX.'c_civility') { $transkey="Civility".strtoupper($obj->code); From b0edd464948af16d11adbd5ed311bf15cc55b958 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 23 Dec 2019 15:07:26 +0100 Subject: [PATCH 03/37] FIX add product qty in shipment already sent --- htdocs/product/class/product.class.php | 21 +++++++++++++++------ htdocs/product/stock/product.php | 9 ++++++++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index d00cba86e6a..c61d778a9f9 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2633,12 +2633,13 @@ class Product extends CommonObject /** * Charge tableau des stats expedition client pour le produit/service * - * @param int $socid Id societe pour filtrer sur une societe - * @param string $filtrestatut Id statut pour filtrer sur un statut - * @param int $forVirtualStock Ignore rights filter for virtual stock calculation. - * @return array Tableau des stats + * @param int $socid Id societe pour filtrer sur une societe + * @param string $filtrestatut Id statut pour filtrer sur un statut + * @param int $forVirtualStock Ignore rights filter for virtual stock calculation. + * @param string $filterShipmentStatus [=''] Ids shipment status separated by comma + * @return int <0 if KO, >0 if OK (Tableau des stats) */ - public function load_stats_sending($socid = 0, $filtrestatut = '', $forVirtualStock = 0) + public function load_stats_sending($socid = 0, $filtrestatut = '', $forVirtualStock = 0, $filterShipmentStatus = '') { // phpcs:enable global $conf,$user; @@ -2668,6 +2669,7 @@ class Product extends CommonObject if ($filtrestatut <> '') { $sql.= " AND c.fk_statut in (".$filtrestatut.")"; } + if (!empty($filterShipmentStatus)) $sql.= " AND e.fk_statut IN (" . $filterShipmentStatus . ")"; $result = $this->db->query($sql); if ($result ) { @@ -4461,7 +4463,14 @@ class Product extends CommonObject } if (! empty($conf->expedition->enabled)) { - $result=$this->load_stats_sending(0, '1,2', 1); + require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php'; + $filterShipmentStatus = ''; + if (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)) { + $filterShipmentStatus = Expedition::STATUS_VALIDATED . ',' . Expedition::STATUS_CLOSED; + } elseif (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) { + $filterShipmentStatus = Expedition::STATUS_CLOSED; + } + $result = $this->load_stats_sending(0, '1,2', 1, $filterShipmentStatus); if ($result < 0) dol_print_error($this->db, $this->error); $stock_sending_client=$this->stats_expedition['qty']; } diff --git a/htdocs/product/stock/product.php b/htdocs/product/stock/product.php index 944b3ce96cd..89e60ed07ed 100644 --- a/htdocs/product/stock/product.php +++ b/htdocs/product/stock/product.php @@ -666,8 +666,15 @@ if ($id > 0 || $ref) // Number of product from customer order already sent (partial shipping) if (!empty($conf->expedition->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/expedition/class/expedition.class.php'; + $filterShipmentStatus = ''; + if (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT)) { + $filterShipmentStatus = Expedition::STATUS_VALIDATED . ',' . Expedition::STATUS_CLOSED; + } elseif (!empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) { + $filterShipmentStatus = Expedition::STATUS_CLOSED; + } if ($found) $helpondiff .= '
'; else $found = 1; - $result = $object->load_stats_sending(0, '2', 1); + $result = $object->load_stats_sending(0, '2', 1, $filterShipmentStatus); $helpondiff .= $langs->trans("ProductQtyInShipmentAlreadySent") . ': ' . $object->stats_expedition['qty']; } From 99e63ad5073e0805a36fdc8e0342374c6da68a55 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 23 Dec 2019 15:18:45 +0100 Subject: [PATCH 04/37] FIX uses GETPOSTISSET instead of GETPOST for projectfield --- htdocs/projet/element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index fe8a27ec6f8..d60a71d5999 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -512,7 +512,7 @@ elseif ($action == "unlink") { $tablename = GETPOST("tablename", "aZ09"); - $projectField = GETPOST('projectfield', 'aZ09') ? GETPOST('projectfield', 'aZ09') : 'fk_projet'; + $projectField = GETPOSTISSET('projectfield') ? GETPOST('projectfield', 'aZ09') : 'fk_projet'; $elementselectid = GETPOST("elementselect", "int"); $result = $object->remove_element($tablename, $elementselectid, $projectField); From 720146c45f071364ef6d547a44880276fa6768b6 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 23 Dec 2019 15:37:12 +0100 Subject: [PATCH 05/37] FIX class Facture undefined in displaying margin information --- htdocs/core/class/html.formmargin.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/class/html.formmargin.class.php b/htdocs/core/class/html.formmargin.class.php index 6b7ba7348ff..579b8fe5208 100644 --- a/htdocs/core/class/html.formmargin.class.php +++ b/htdocs/core/class/html.formmargin.class.php @@ -63,6 +63,8 @@ class FormMargin { global $conf, $db; + require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + // Default returned array $marginInfos = array( 'pa_products' => 0, From 792096ad08ae495ffd81d57bc1b987fb5c227baf Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Mon, 23 Dec 2019 16:00:35 +0100 Subject: [PATCH 06/37] FIX url new for task time spent in project element tab --- htdocs/projet/element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 97e99c93370..06d14f18042 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -436,7 +436,7 @@ $listofreferent=array( 'table'=>'projet_task', 'datefieldname'=>'task_date', 'disableamount'=>0, - 'urlnew'=>DOL_URL_ROOT.'/projet/tasks/time.php?id='.$id, + 'urlnew'=>DOL_URL_ROOT.'/projet/tasks/time.php?withproject=1&action=createtime&projectid='.$id, 'buttonnew'=>'AddTimeSpent', 'testnew'=>$user->rights->projet->creer, 'test'=>($conf->projet->enabled && $user->rights->projet->lire && empty($conf->global->PROJECT_HIDE_TASKS))), From 5521d13a1186a5f0c5a60da96f1f7c528a2c3db3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 23 Dec 2019 22:12:50 +0100 Subject: [PATCH 07/37] Prepare 10.0.5 --- htdocs/filefunc.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 7c71221ba3c..c0697df392b 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', '10.0.4'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION', '10.0.5'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO', chr(128)); From 07b40f043e3992cab80e545d9cc0afdd3a0df1b4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 23 Dec 2019 22:44:34 +0100 Subject: [PATCH 08/37] Prepare 10.0.5 --- ChangeLog | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/ChangeLog b/ChangeLog index 99e70e960c9..b1b64681abb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,33 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 10.0.5 compared to 10.0.4 ***** +FIX: 10.0: add URL param "restore_last_search_values=1" to all backlinks pointing to lists +FIX: 10.0: do not display single-letter values (indicating duration unit without value) in product list +FIX: #12473 +FIX: #12481 : fix ticket creation from thirdparty, mission $socid var +FIX: #12482 +FIX: #12644 +FIX: #12665 Mass invoice validation with stock management +FIX: #12688 +FIX: #12745 +FIX: add and modify category translate form with posted values on errors +FIX: add URL param "restore_last_search_values=1" to all backlinks that point to a list +FIX: CommandeFournisseurLigne update function must not be able to return other value than 1 if success +FIX: contact card state address selected after filling address +FIX: dol_string_nohtmltag when there is html with windows EOL "
\r\n" +FIX: filter language is an array +FIX: first col at wrong position in Export 2007 (new) +FIX: getrights() request +FIX: Invoice Situation integration into Margin +FIX: missing nl2br conversion +FIX: not fee in payout list +FIX: product_fourn_price_id was assigned too late for logPrice() function +FIX: Reduce number of request for list of products +FIX: set due date in object in create invoice +FIX: units traductions for selectUnits() function +FIX: when we need to bill several orders, order lines unit is not on bill lines +NEW: 9.0: allow users to use the mysqldump '--quick' option ***** ChangeLog for 10.0.4 compared to 10.0.3 ***** FIX: The pdf templates were using the large logo making PDF too large (and edition of proposal, order, invoice VERY slow) From 44400b786654a363bea4a9bf5c3414e6248fb8db Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Tue, 24 Dec 2019 07:22:25 +0100 Subject: [PATCH 09/37] FIX : Some issues on salary payment --- htdocs/compta/salaries/card.php | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/htdocs/compta/salaries/card.php b/htdocs/compta/salaries/card.php index 392b90b7bb6..5371e773828 100644 --- a/htdocs/compta/salaries/card.php +++ b/htdocs/compta/salaries/card.php @@ -44,6 +44,12 @@ $id=GETPOST("id", 'int'); $action=GETPOST('action', 'aZ09'); $cancel= GETPOST('cancel', 'aZ09'); $projectid = (GETPOST('projectid', 'int') ? GETPOST('projectid', 'int') : GETPOST('fk_project', 'int')); +$accountid = GETPOST('accountid', 'int') > 0 ? GETPOST('accountid', 'int') : 0; + +$datep = dol_mktime(12, 0, 0, GETPOST("datepmonth", 'int'), GETPOST("datepday", 'int'), GETPOST("datepyear", 'int')); +$datev = dol_mktime(12, 0, 0, GETPOST("datevmonth", 'int'), GETPOST("datevday", 'int'), GETPOST("datevyear", 'int')); +$datesp = dol_mktime(12, 0, 0, GETPOST("datespmonth", 'int'), GETPOST("datespday", 'int'), GETPOST("datespyear", 'int')); +$dateep = dol_mktime(12, 0, 0, GETPOST("dateepmonth", 'int'), GETPOST("dateepday", 'int'), GETPOST("dateepyear", 'int')); // Security check $socid = GETPOST("socid", "int"); @@ -71,34 +77,30 @@ if ($cancel) if ($action == 'classin' && $user->rights->banque->modifier) { $object->fetch($id); - $object->setProject(GETPOST('projectid')); + $object->setProject($projectid); } if ($action == 'add' && empty($cancel)) { $error=0; - $datep=dol_mktime(12, 0, 0, GETPOST("datepmonth", 'int'), GETPOST("datepday", 'int'), GETPOST("datepyear", 'int')); - $datev=dol_mktime(12, 0, 0, GETPOST("datevmonth", 'int'), GETPOST("datevday", 'int'), GETPOST("datevyear", 'int')); - $datesp=dol_mktime(12, 0, 0, GETPOST("datespmonth", 'int'), GETPOST("datespday", 'int'), GETPOST("datespyear", 'int')); - $dateep=dol_mktime(12, 0, 0, GETPOST("dateepmonth", 'int'), GETPOST("dateepday", 'int'), GETPOST("dateepyear", 'int')); if (empty($datev)) $datev=$datep; $type_payment = dol_getIdFromCode($db, GETPOST("paymenttype", 'alpha'), 'c_paiement', 'code', 'id', 1); - $object->accountid=GETPOST("accountid") > 0 ? GETPOST("accountid", "int") : 0; - $object->fk_user=GETPOST("fk_user") > 0 ? GETPOST("fk_user", "int") : 0; + $object->accountid=GETPOST("accountid", "int") > 0 ? GETPOST("accountid", "int") : 0; + $object->fk_user=GETPOST("fk_user", "int") > 0 ? GETPOST("fk_user", "int") : 0; $object->datev=$datev; $object->datep=$datep; - $object->amount=price2num(GETPOST("amount")); - $object->label=GETPOST("label"); + $object->amount=price2num(GETPOST("amount", "alpha")); + $object->label=GETPOST("label", "alphanohtml"); $object->datesp=$datesp; $object->dateep=$dateep; - $object->note=GETPOST("note"); + $object->note=GETPOST("note", "none"); $object->type_payment=($type_payment > 0 ? $type_payment : 0); - $object->num_payment=GETPOST("num_payment"); + $object->num_payment=GETPOST("num_payment", "alphanohtml"); $object->fk_user_author=$user->id; - $object->fk_project= GETPOST('fk_project', 'int'); + $object->fk_project= $projectid; // Set user current salary as ref salaray for the payment $fuser=new User($db); @@ -303,7 +305,7 @@ if ($action == 'create') print ''.$langs->trans("Project").''; - $numproject=$formproject->select_projects(-1, $projectid, 'fk_project', 0, 0, 1, 1); + $formproject->select_projects(-1, $projectid, 'fk_project', 0, 0, 1, 1); print ''; } @@ -313,14 +315,14 @@ if ($action == 'create') { print ''; print $form->editfieldkey('BankAccount', 'selectaccountid', '', $object, 0, 'string', '', 1).''; - $form->select_comptes($_POST["accountid"], "accountid", 0, '', 1); // Affiche liste des comptes courant + $form->select_comptes($accountid, "accountid", 0, '', 1); // Affiche liste des comptes courant print ''; } // Type payment print ''; print $form->editfieldkey('PaymentMode', 'selectpaymenttype', '', $object, 0, 'string', '', 1).''; - $form->select_types_paiements(GETPOST("paymenttype"), "paymenttype", '', 2); + $form->select_types_paiements(GETPOST("paymenttype", "aZ09"), "paymenttype", '', 2); print ''; // Number From c8dfc3d9fc85515de1b40105f0fef6180a97681c Mon Sep 17 00:00:00 2001 From: Marc de Lima Lucio Date: Tue, 24 Dec 2019 16:09:29 +0100 Subject: [PATCH 10/37] FIX: error 500 when getting margin info for objects other than invoices --- htdocs/core/class/html.formmargin.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formmargin.class.php b/htdocs/core/class/html.formmargin.class.php index 6b7ba7348ff..8485afecec9 100644 --- a/htdocs/core/class/html.formmargin.class.php +++ b/htdocs/core/class/html.formmargin.class.php @@ -98,7 +98,7 @@ class FormMargin $pv = $line->total_ht; $pa_ht = ($pv < 0 ? - $line->pa_ht : $line->pa_ht); // We choosed to have line->pa_ht always positive in database, so we guess the correct sign - if ($object->type == Facture::TYPE_SITUATION) { + if ($object->element == 'facture' && $object->type == Facture::TYPE_SITUATION) { $pa = $line->qty * $pa_ht * ($line->situation_percent / 100); } else { $pa = $line->qty * $pa_ht; From 9a7307eea8f7d6899c6bc854faafcc0dec6c3beb Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 26 Dec 2019 12:01:09 +0100 Subject: [PATCH 11/37] FIX Missing language key for MAIN_MAXTABS_IN_CARD --- htdocs/langs/en_US/main.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 54eeac4085e..a9c79e747a3 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -982,3 +982,4 @@ PaymentInformation=Payment information ValidFrom=Valid from ValidUntil=Valid until NoRecordedUsers=No users +More=More From 9c4d7044a3144b760c74f53546257fb983d0ccd5 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Thu, 26 Dec 2019 16:18:26 +0100 Subject: [PATCH 12/37] FIX sql bad request in product buying price extrafields --- htdocs/product/fournisseurs.php | 132 ++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 56 deletions(-) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index bd93ef60a26..0abb57d8951 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -265,32 +265,31 @@ if (empty($reshook)) $extralabels = $extrafields->fetch_name_optionals_label("product_fournisseur_price"); $extrafield_values = $extrafields->getOptionalsFromPost("product_fournisseur_price"); + if (!empty($extrafield_values)) { + $resql = $db->query("SELECT fk_object FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields WHERE fk_object = " . $object->product_fourn_price_id); + // Insert a new extrafields row, if none exists + if ($db->num_rows($resql) != 1) { + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields (fk_object, "; + foreach ($extrafield_values as $key => $value) { + $sql .= str_replace('options_', '', $key) . ', '; + } + $sql = substr($sql, 0, strlen($sql) - 2) . ") VALUES (" . $object->product_fourn_price_id . ", "; + foreach ($extrafield_values as $key => $value) { + $sql .= '"' . $value . '", '; + } + $sql = substr($sql, 0, strlen($sql) - 2) . ')'; + } // else update the existing one + else { + $sql = "UPDATE " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields SET "; + foreach ($extrafield_values as $key => $value) { + $sql .= str_replace('options_', '', $key) . ' = "' . $value . '", '; + } + $sql = substr($sql, 0, strlen($sql) - 2) . ' WHERE fk_object = ' . $object->product_fourn_price_id; + } - $sql = ""; - $resql = $db->query("SELECT * FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields WHERE fk_object = ".$object->product_fourn_price_id); - // Insert a new extrafields row, if none exists - if ($db->num_rows($resql) != 1) { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields (fk_object, "; - foreach ($extrafield_values as $key => $value) { - $sql .= str_replace('options_', '', $key).', '; - } - $sql = substr($sql, 0, strlen($sql) - 2).") VALUES (".$object->product_fourn_price_id.", "; - foreach ($extrafield_values as $key => $value) { - $sql .= '"'.$value.'", '; - } - $sql = substr($sql, 0, strlen($sql) - 2).')'; - } - // else update the existing one - else { - $sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields SET "; - foreach ($extrafield_values as $key => $value) { - $sql .= str_replace('options_', '', $key).' = "'.$value.'", '; - } - $sql = substr($sql, 0, strlen($sql) - 2).' WHERE fk_object = '.$object->product_fourn_price_id; - } - - // Execute the sql command from above - $db->query($sql); + // Execute the sql command from above + $db->query($sql); + } $newprice = price2num(GETPOST("price", "alpha")); @@ -765,25 +764,36 @@ SCRIPT; print ''; } + // Extrafields $extrafields->fetch_name_optionals_label("product_fournisseur_price"); $extralabels = $extrafields->attributes["product_fournisseur_price"]['label']; - // Extrafields - $resql = $db->query("SELECT * FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields WHERE fk_object = ".$rowid); + $extrafield_values = $extrafields->getOptionalsFromPost("product_fournisseur_price"); if (!empty($extralabels)) { - if ($db->num_rows($resql) != 1) { - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) { - print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'.$langs->trans($value).''.$extrafields->showInputField($key, '', '', '', '', '', 0, 'product_fournisseur_price').''; - } - } - } else { - $resql = $db->fetch_object($resql); - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) { - print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'.$langs->trans($value).''.$extrafields->showInputField($key, $resql->{$key}, '', '', '', '', 0, 'product_fournisseur_price').''; - } - } - } + if (empty($rowid)) { + foreach ($extralabels as $key => $value) { + if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) { + print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'.$langs->trans($value).''.$extrafields->showInputField($key, GETPOSTISSET('options_' . $key) ? $extrafield_values['options_' . $key] : '', '', '', '', '', 0, 'product_fournisseur_price').''; + } + } + } else { + $sql = "SELECT"; + $sql .= " fk_object"; + foreach ($extralabels as $key => $value) { + $sql .= ", " . $key; + } + $sql .= " FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields"; + $sql .= " WHERE fk_object = " . $rowid; + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + foreach ($extralabels as $key => $value) { + if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) { + print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'.$langs->trans($value).''.$extrafields->showInputField($key, GETPOSTISSET('options_' . $key) ? $extrafield_values['options_' . $key] : $obj->{$key}, '', '', '', '', 0, 'product_fournisseur_price').''; + } + } + $db->free($resql); + } + } } if (is_object($hookmanager)) @@ -1008,22 +1018,32 @@ SCRIPT; print ''; // Extrafields - $resql = $db->query("SELECT * FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields WHERE fk_object = ".$productfourn->product_fourn_price_id); if (!empty($extralabels)) { - if ($db->num_rows($resql) != 1) { - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { - print ""; - } - } - } else { - $resql = $db->fetch_object($resql); - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { - print ''.$extrafields->showOutputField($key, $resql->{$key}).""; - } - } - } + $sql = "SELECT"; + $sql .= " fk_object"; + foreach ($extralabels as $key => $value) { + $sql .= ", " . $key; + } + $sql .= " FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields"; + $sql .= " WHERE fk_object = " . $productfourn->product_fourn_price_id; + $resql = $db->query($sql); + if ($resql) { + if ($db->num_rows($resql) != 1) { + foreach ($extralabels as $key => $value) { + if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { + print ""; + } + } + } else { + $obj = $db->fetch_object($resql); + foreach ($extralabels as $key => $value) { + if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { + print ''.$extrafields->showOutputField($key, $obj->{$key}).""; + } + } + } + $db->free($resql); + } } if (is_object($hookmanager)) From a804208b32b0e76d3374018f9a3aae222ffd656a Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 27 Dec 2019 20:54:47 +0100 Subject: [PATCH 13/37] Fix missing language key --- htdocs/langs/en_US/boxes.lang | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang index b1ab8e41fbc..1e2252d54b2 100644 --- a/htdocs/langs/en_US/boxes.lang +++ b/htdocs/langs/en_US/boxes.lang @@ -84,4 +84,5 @@ ForProposals=Proposals LastXMonthRolling=The latest %s month rolling ChooseBoxToAdd=Add widget to your dashboard BoxAdded=Widget was added in your dashboard -BoxTitleUserBirthdaysOfMonth=Birthdays of this month \ No newline at end of file +BoxTitleUserBirthdaysOfMonth=Birthdays of this month +BoxBirthdays=Birthdays of this month From c9cc6cbbeab0d449e22f183e3a8f1ec030b7dd13 Mon Sep 17 00:00:00 2001 From: TuxGasy Date: Sun, 29 Dec 2019 23:15:49 +0100 Subject: [PATCH 14/37] Fix decimal value on update object --- htdocs/core/actions_addupdatedelete.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 1d5dd28b21a..068a487c448 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -113,8 +113,8 @@ if ($action == 'update' && ! empty($permissiontoadd)) $value = dol_mktime(12, 0, 0, GETPOST($key.'month'), GETPOST($key.'day'), GETPOST($key.'year')); } elseif ($object->fields[$key]['type']=='datetime') { $value = dol_mktime(GETPOST($key.'hour'), GETPOST($key.'min'), 0, GETPOST($key.'month'), GETPOST($key.'day'), GETPOST($key.'year')); - } elseif ($object->fields[$key]['type']=='price') { - $value = price2num(GETPOST($key)); + } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { + $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } else { $value = GETPOST($key, 'alpha'); } From 71a29981187851cbc484db35f91554e8df1a2b51 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 30 Dec 2019 15:36:09 +0100 Subject: [PATCH 15/37] FIX wrong var name and avoid warning --- htdocs/product/admin/product_tools.php | 2 +- htdocs/product/class/product.class.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/product/admin/product_tools.php b/htdocs/product/admin/product_tools.php index cfbedbcb7f1..d68b395d5ad 100644 --- a/htdocs/product/admin/product_tools.php +++ b/htdocs/product/admin/product_tools.php @@ -135,7 +135,7 @@ if ($action == 'convert') $newlevel=$level; //print "$objectstatic->id $newprice, $price_base_type, $newvat, $newminprice, $newlevel, $newnpr
\n"; - $retm=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatratclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode); + $retm=$objectstatic->updatePrice($newprice, $price_base_type, $user, $newvatrateclean, $newminprice, $newlevel, $newnpr, 0, 0, $localtaxes_type, $newdefaultvatcode); if ($retm < 0) { $error++; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index d00cba86e6a..e59b52be803 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1859,6 +1859,9 @@ class Product extends CommonObject if (empty($newnpr)) { $newnpr=0; } + if (empty($newminprice)) { + $newminprice=0; + } // Check parameters if ($newvat == '') { From 5cc0d26eae777a1e51ceb714021a60ec79e0fd4b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 Dec 2019 17:26:02 +0100 Subject: [PATCH 16/37] Revert "FIX class Facture undefined in displaying margin information" --- htdocs/core/class/html.formmargin.class.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/core/class/html.formmargin.class.php b/htdocs/core/class/html.formmargin.class.php index 64048c5cfdc..8485afecec9 100644 --- a/htdocs/core/class/html.formmargin.class.php +++ b/htdocs/core/class/html.formmargin.class.php @@ -63,8 +63,6 @@ class FormMargin { global $conf, $db; - require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; - // Default returned array $marginInfos = array( 'pa_products' => 0, From 08d0d63a0461592238f7bbf15ab2f1c862ca2593 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 Dec 2019 17:30:27 +0100 Subject: [PATCH 17/37] FIX #12760 #12763 #12755 #12765 #12751 --- htdocs/core/class/html.formmargin.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.formmargin.class.php b/htdocs/core/class/html.formmargin.class.php index 64048c5cfdc..7c169916b60 100644 --- a/htdocs/core/class/html.formmargin.class.php +++ b/htdocs/core/class/html.formmargin.class.php @@ -1,5 +1,5 @@ +/* Copyright (c) 2015-2019 Laurent Destailleur * * 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 @@ -100,7 +100,7 @@ class FormMargin $pv = $line->total_ht; $pa_ht = ($pv < 0 ? - $line->pa_ht : $line->pa_ht); // We choosed to have line->pa_ht always positive in database, so we guess the correct sign - if ($object->element == 'facture' && $object->type == Facture::TYPE_SITUATION) { + if ($object->element == 'facture' && $object->type == $object::TYPE_SITUATION) { $pa = $line->qty * $pa_ht * ($line->situation_percent / 100); } else { $pa = $line->qty * $pa_ht; From d2efe1d4272289af6e73d38974035b57370e61cf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 31 Dec 2019 17:52:28 +0100 Subject: [PATCH 18/37] Fix SQL injection on type parameter in list of events --- htdocs/comm/action/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index dc00a4dd091..5233c58f079 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -301,7 +301,7 @@ if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND (a.fk_soc I if ($socid > 0) $sql.= " AND s.rowid = ".$socid; // We must filter on assignement table if ($filtert > 0 || $usergroup > 0) $sql.= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'"; -if ($type) $sql.= " AND c.id = ".$type; +if ($type) $sql.= " AND c.id = ".(int) $type; if ($status == '0') { $sql.= " AND a.percent = 0"; } if ($status == '-1') { $sql.= " AND a.percent = -1"; } // Not applicable if ($status == '50') { $sql.= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started From e005416189841b0e9aeb831253c746adcce10d24 Mon Sep 17 00:00:00 2001 From: andreubisquerra Date: Wed, 1 Jan 2020 21:19:23 +0100 Subject: [PATCH 19/37] If press enter add automatically the product. Widely used with barcodes. --- htdocs/takepos/takepos.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/takepos/takepos.php b/htdocs/takepos/takepos.php index ba9f2318508..b059885d64a 100644 --- a/htdocs/takepos/takepos.php +++ b/htdocs/takepos/takepos.php @@ -426,6 +426,7 @@ function New() { function Search2() { console.log("Search2 Call ajax search to replace products"); + if(window.event.keyCode == 13) ClickProduct(0); pageproducts=0; jQuery(".wrapper2 .catwatermark").hide(); $.getJSON('/takepos/ajax/ajax.php?action=search&term='+$('#search').val(), function(data) { From fff805e7eccb0e3c82f1085d0ab97f6533e4d20b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 Jan 2020 15:10:46 +0100 Subject: [PATCH 20/37] Look and feel v11 --- htdocs/societe/paymentmodes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 9bf2a40f069..04717aa01be 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -1769,7 +1769,7 @@ if ($socid && $action == 'editcard' && $user->rights->societe->creer) // Create BAN if ($socid && $action == 'create' && $user->rights->societe->creer) { - dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), -1, 'company'); + dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; From d398917294b1e567c7971654f78d92b28c5e963a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 Jan 2020 15:47:31 +0100 Subject: [PATCH 21/37] Prepare final version --- 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 401a2c01380..5c854d0ecb1 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', '11.0.0-beta'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION', '11.0.0'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO', chr(128)); From 2c20b25a298f623cb5dbcd4ca11a39bb39818482 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 Jan 2020 18:02:53 +0100 Subject: [PATCH 22/37] Suggest another value than "bad customer" to close an invoice paid --- htdocs/compta/facture/card.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 3f3bffc6cd2..aefe642970a 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -3747,18 +3747,24 @@ elseif ($id > 0 || !empty($ref)) $i++; $close[$i]['code'] = 'badcustomer'; $i++; + $close[$i]['code'] = 'other'; + $i++; // Help $i = 0; $close[$i]['label'] = $langs->trans("HelpEscompte").'

'.$langs->trans("ConfirmClassifyPaidPartiallyReasonDiscountVatDesc"); $i++; $close[$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); $i++; + $close[$i]['label'] = $langs->trans("Other"); + $i++; // Texte $i = 0; $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonDiscount", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1); $i++; $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1); $i++; + $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("Other"), $close[$i]['label'], 1); + $i++; // arrayreasons[code]=reason foreach ($close as $key => $val) { $arrayreasons[$close [$key]['code']] = $close[$key]['reason']; From d93de4b931aa0d474ffc8b6ff6c4ac669fab939d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 Jan 2020 20:08:43 +0100 Subject: [PATCH 23/37] FIX Import of customer prices per segment was not possible --- htdocs/install/mysql/migration/10.0.0-11.0.0.sql | 2 ++ htdocs/install/mysql/tables/llx_product_price.sql | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql index b73593c3dfd..e5d996be713 100644 --- a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql +++ b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql @@ -59,6 +59,8 @@ ALTER TABLE llx_emailcollector_emailcollectoraction ADD COLUMN position integer -- For v11 +ALTER TABLE llx_product_price MODIFY COLUMN tva_tx double(6,3) DEFAULT 0 NOT NULL; + ALTER TABLE llx_facturedet MODIFY COLUMN situation_percent real DEFAULT 100; UPDATE llx_facturedet SET situation_percent = 100 WHERE situation_percent IS NULL AND fk_prev_id IS NULL; diff --git a/htdocs/install/mysql/tables/llx_product_price.sql b/htdocs/install/mysql/tables/llx_product_price.sql index 11b2ac972cf..75a5355afe7 100644 --- a/htdocs/install/mysql/tables/llx_product_price.sql +++ b/htdocs/install/mysql/tables/llx_product_price.sql @@ -35,7 +35,7 @@ create table llx_product_price price_min_ttc double(24,8) default NULL, price_base_type varchar(3) DEFAULT 'HT', default_vat_code varchar(10), -- Same code than into table llx_c_tva (but no constraints). Should be used in priority to find default vat, npr, localtaxes for product. - tva_tx double(6,3) NOT NULL, + tva_tx double(6,3) DEFAULT 0 NOT NULL, -- Used only when option PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL is on (not supported) recuperableonly integer NOT NULL DEFAULT '0', localtax1_tx double(6,3) DEFAULT 0, localtax1_type varchar(10) NOT NULL DEFAULT '0', From 298f6d06836f2b7a1ea459c2cbdc2a57a4dd4132 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 Jan 2020 20:36:35 +0100 Subject: [PATCH 24/37] Look and feel v11 --- .../class/companypaymentmode.class.php | 60 +++++++------------ 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/htdocs/societe/class/companypaymentmode.class.php b/htdocs/societe/class/companypaymentmode.class.php index aa0c083f4f7..5fe072cc826 100644 --- a/htdocs/societe/class/companypaymentmode.class.php +++ b/htdocs/societe/class/companypaymentmode.class.php @@ -58,6 +58,10 @@ class CompanyPaymentMode extends CommonObject public $picto = 'generic'; + const STATUS_ENABLED = 1; + const STATUS_CANCELED = 0; + + /** * 'type' if the field format. * 'label' the translation key. @@ -475,9 +479,9 @@ class CompanyPaymentMode extends CommonObject } /** - * Retourne le libelle du status d'un user (actif, inactif) + * Return label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto * @return string Label of status */ public function getLibStatut($mode = 0) @@ -493,47 +497,29 @@ class CompanyPaymentMode extends CommonObject * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto * @return string Label of status */ - public static function LibStatut($status, $mode = 0) + public function LibStatut($status, $mode = 0) { - // phpcs:enable - global $langs; + // phpcs:enable + if (empty($this->labelStatus) || empty($this->labelStatusShort)) + { + global $langs; + //$langs->load("mymodule"); + $this->labelStatus[self::STATUS_ENABLED] = $langs->trans('Enabled'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatusShort[self::STATUS_ENABLED] = $langs->trans('Enabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); + } - if ($mode == 0 || $mode == 1) - { - if ($status == 1) return $langs->trans('Enabled'); - elseif ($status == 0) return $langs->trans('Disabled'); - } - elseif ($mode == 2) - { - if ($status == 1) return img_picto($langs->trans('Enabled'), 'statut4').' '.$langs->trans('Enabled'); - elseif ($status == 0) return img_picto($langs->trans('Disabled'), 'statut5').' '.$langs->trans('Disabled'); - } - elseif ($mode == 3) - { - if ($status == 1) return img_picto($langs->trans('Enabled'), 'statut4'); - elseif ($status == 0) return img_picto($langs->trans('Disabled'), 'statut5'); - } - elseif ($mode == 4) - { - if ($status == 1) return img_picto($langs->trans('Enabled'), 'statut4').' '.$langs->trans('Enabled'); - elseif ($status == 0) return img_picto($langs->trans('Disabled'), 'statut5').' '.$langs->trans('Disabled'); - } - elseif ($mode == 5) - { - if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'), 'statut4'); - elseif ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'), 'statut5'); - } - elseif ($mode == 6) - { - if ($status == 1) return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'), 'statut4'); - elseif ($status == 0) return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'), 'statut5'); - } + $statusType = 'status5'; + if ($status == self::STATUS_ENABLED) $statusType = 'status4'; + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); } /** - * Charge les informations d'ordre info dans l'objet commande + * Load the info information in the object * - * @param int $id Id of order + * @param int $id Id of object * @return void */ public function info($id) From d95e37aa72298818f232cb0c9e996f2af21cb90a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 Jan 2020 20:43:16 +0100 Subject: [PATCH 25/37] Look and feel v11 --- htdocs/societe/paymentmodes.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 04717aa01be..41bda75b2b5 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -1615,15 +1615,15 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' // Edit BAN if ($socid && $action == 'edit' && $user->rights->societe->creer) { - dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), -1, 'company'); + dol_fiche_head($head, 'rib', $langs->trans("ThirdParty"), 0, 'company'); $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom'); - print '
'; - print '
'; + + print '
'; print ''; print ''; @@ -1683,11 +1683,13 @@ if ($socid && $action == 'edit' && $user->rights->societe->creer) print ""; print '
'.$langs->trans("LabelRIB").'
'; + print '
'; if ($conf->prelevement->enabled) { print '
'; + print '
'; print ''; if (empty($companybankaccount->rum)) $companybankaccount->rum = $prelevement->buildRumNumber($object->code_client, $companybankaccount->datec, $companybankaccount->id); @@ -1705,9 +1707,9 @@ if ($socid && $action == 'edit' && $user->rights->societe->creer) print ''; print '
'; + print '
'; } - print '
'; dol_fiche_end(); From 68d7195964ac599d829f63e47d7c09efd21c2b2c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 Jan 2020 22:05:35 +0100 Subject: [PATCH 26/37] MRP --- .../mysql/data/llx_c_action_trigger.sql | 8 +- .../install/mysql/migration/10.0.0-11.0.0.sql | 9 +- htdocs/langs/en_US/agenda.lang | 6 +- htdocs/langs/en_US/main.lang | 2 +- htdocs/langs/en_US/mrp.lang | 4 +- htdocs/mrp/mo_production.php | 264 ++++++++++-------- 6 files changed, 160 insertions(+), 133 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_action_trigger.sql b/htdocs/install/mysql/data/llx_c_action_trigger.sql index 85360478500..dee1200389c 100644 --- a/htdocs/install/mysql/data/llx_c_action_trigger.sql +++ b/htdocs/install/mysql/data/llx_c_action_trigger.sql @@ -124,10 +124,10 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BOM_CLOSE','BOM disabled','Executed when a BOM is disabled','bom',652); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BOM_REOPEN','BOM reopen','Executed when a BOM is re-open','bom',653); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BOM_DELETE','BOM deleted','Executed when a BOM deleted','bom',654); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MO_VALIDATE','MO validated','Executed when a MO is validated','bom',660); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MO_PRODUCED','MO produced','Executed when a MO is produced','bom',661); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MO_DELETE','MO deleted','Executed when a MO is deleted','bom',662); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MO_CANCEL','MO canceled','Executed when a MO is canceled','bom',663); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_VALIDATE','MO validated','Executed when a MO is validated','bom',660); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_PRODUCED','MO produced','Executed when a MO is produced','bom',661); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_DELETE','MO deleted','Executed when a MO is deleted','bom',662); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_CANCEL','MO canceled','Executed when a MO is canceled','bom',663); -- actions not enabled by default : they are excluded when we enable the module Agenda (except TASK_...) insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_CREATE','Task created','Executed when a project task is created','project',150); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('TASK_MODIFY','Task modified','Executed when a project task is modified','project',151); diff --git a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql index e5d996be713..50014e2da05 100644 --- a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql +++ b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql @@ -522,10 +522,11 @@ insert into llx_c_action_trigger (code,label,description,elementtype,rang) value insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BOM_REOPEN','BOM reopen','Executed when a BOM is re-open','bom',653); insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('BOM_DELETE','BOM deleted','Executed when a BOM deleted','bom',654); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MO_VALIDATE','MO validated','Executed when a MO is validated','bom',660); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MO_PRODUCED','MO produced','Executed when a MO is produced','bom',661); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MO_DELETE','MO deleted','Executed when a MO is deleted','bom',662); -insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MO_CANCEL','MO canceled','Executed when a MO is canceled','bom',663); +DELETE FROM llx_c_action_trigger where code LIKE 'MO_%'; +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_VALIDATE','MO validated','Executed when a MO is validated','bom',660); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_PRODUCED','MO produced','Executed when a MO is produced','bom',661); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_DELETE','MO deleted','Executed when a MO is deleted','bom',662); +insert into llx_c_action_trigger (code,label,description,elementtype,rang) values ('MRP_MO_CANCEL','MO canceled','Executed when a MO is canceled','bom',663); ALTER TABLE llx_comment ADD COLUMN fk_user_modif integer DEFAULT NULL; diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index 9f141d15220..6e5415067f1 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -110,9 +110,9 @@ BOM_UNVALIDATEInDolibarr=BOM unvalidated BOM_CLOSEInDolibarr=BOM disabled BOM_REOPENInDolibarr=BOM reopen BOM_DELETEInDolibarr=BOM deleted -MO_VALIDATEInDolibarr=MO validated -MO_PRODUCEDInDolibarr=MO produced -MO_DELETEInDolibarr=MO deleted +MRP_MO_VALIDATEInDolibarr=MO validated +MRP_MO_PRODUCEDInDolibarr=MO produced +MRP_MO_DELETEInDolibarr=MO deleted ##### End agenda events ##### AgendaModelModule=Document templates for event DateActionStart=Start date diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index fa9f48ee4c4..bc9abb9753d 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -741,7 +741,7 @@ NotSupported=Not supported RequiredField=Required field Result=Result ToTest=Test -ValidateBefore=Card must be validated before using this feature +ValidateBefore=Item must be validated before using this feature Visibility=Visibility Totalizable=Totalizable TotalizableDesc=This field is totalizable in list diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang index e5bcb1e5318..a414920ff83 100644 --- a/htdocs/langs/en_US/mrp.lang +++ b/htdocs/langs/en_US/mrp.lang @@ -58,4 +58,6 @@ ConsumeAndProduceAll=Consume and Produce All Manufactured=Manufactured TheProductXIsAlreadyTheProductToProduce=The product to add is already the product to produce. ForAQuantityOf1=For a quantity to produce of 1 -ConfirmValidateMo=Are you sure you want to validate this Manufacturing Order? \ No newline at end of file +ConfirmValidateMo=Are you sure you want to validate this Manufacturing Order? +ConfirmProductionDesc=By clicking on '%s', you will validate the consumption and/or production for the quantities set. This will also update the stock and record stock movements. +ProductionForRefAndDate=Production %s - %s diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 17f2cd44069..cc08486e27d 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -47,11 +47,12 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; dol_include_once('/mrp/class/mo.class.php'); dol_include_once('/mrp/lib/mrp_mo.lib.php'); // Load translation files required by the page -$langs->loadLangs(array("mrp", "other")); +$langs->loadLangs(array("mrp", "stocks", "other")); // Get parameters $id = GETPOST('id', 'int'); @@ -103,8 +104,6 @@ $permissiontoproduce = $permissiontoadd; /* * Actions - * - * Put here all code to do according to value of "action" parameter */ $parameters = array(); @@ -120,7 +119,7 @@ if (empty($reshook)) if (empty($backtopage) || ($cancel && empty($id))) { //var_dump($backurlforlist);exit; if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) $backtopage = $backurlforlist; - else $backtopage = DOL_URL_ROOT.'/mrp/mo_card.php?id='.($id > 0 ? $id : '__ID__'); + else $backtopage = DOL_URL_ROOT.'/mrp/mo_production.php?id='.($id > 0 ? $id : '__ID__'); } $triggermodname = 'MRP_MO_MODIFY'; // Name of trigger action code to execute when we modify record @@ -162,6 +161,7 @@ if (empty($reshook)) $form = new Form($db); $formfile = new FormFile($db); $formproject = new FormProjets($db); +$formproduct = new FormProduct($db); llxHeader('', $langs->trans('Mo'), ''); @@ -306,48 +306,85 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea dol_fiche_end(); - print '
'; - $parameters = array(); - // Note that $action and $object may be modified by hook - $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); - if (empty($reshook)) { - // Consume + if (! in_array($action, array('consume', 'produce', 'consumeandproduceall'))) + { + print '
'; - if ($object->status == Mo::STATUS_VALIDATED || $object->status == Mo::STATUS_INPROGRESS) { - if ($permissiontoproduce) { - print ''.$langs->trans('Consume').''; + $parameters = array(); + // Note that $action and $object may be modified by hook + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); + if (empty($reshook)) { + // Consume + + if ($object->status == Mo::STATUS_VALIDATED || $object->status == Mo::STATUS_INPROGRESS) { + if ($permissiontoproduce) { + print ''.$langs->trans('Consume').''; + } else { + print ''.$langs->trans('Consume').''; + } } else { - print ''.$langs->trans('Consume').''; + print ''.$langs->trans('Consume').''; + } + + // Produce + if ($object->status == Mo::STATUS_VALIDATED || $object->status == Mo::STATUS_INPROGRESS) { + if ($permissiontoproduce) { + print ''.$langs->trans('Produce').''; + } else { + print ''.$langs->trans('Produce').''; + } + } else { + print ''.$langs->trans('Produce').''; + } + + // ConsumeAndProduceAll + if ($object->status == Mo::STATUS_VALIDATED || $object->status == Mo::STATUS_INPROGRESS) { + if ($permissiontoproduce) { + print ''.$langs->trans('ConsumeAndProduceAll').''; + } else { + print ''.$langs->trans('ConsumeAndProduceAll').''; + } + } else { + print ''.$langs->trans('ConsumeAndProduceAll').''; } - } else { - print ''.$langs->trans('Consume').''; } - // Produce - if ($object->status == Mo::STATUS_VALIDATED || $object->status == Mo::STATUS_INPROGRESS) { - if ($permissiontoproduce) { - print ''.$langs->trans('Produce').''; - } else { - print ''.$langs->trans('Produce').''; - } - } else { - print ''.$langs->trans('Produce').''; - } - - // ConsumeAndProduceAll - if ($object->status == Mo::STATUS_VALIDATED || $object->status == Mo::STATUS_INPROGRESS) { - if ($permissiontoproduce) { - print ''.$langs->trans('ConsumeAndProduceAll').''; - } else { - print ''.$langs->trans('ConsumeAndProduceAll').''; - } - } else { - print ''.$langs->trans('ConsumeAndProduceAll').''; - } + print '
'; } - print '
'; + if (in_array($action, array('consume', 'produce', 'consumeandproduceall'))) + { + print ''; + print ''; + print ''; + print ''; + print ''; + + if ($action == 'consume') + { + print $langs->trans("FeatureNotYetAvailable"); + } + if ($action == 'produce') + { + print $langs->trans("FeatureNotYetAvailable"); + } + if ($action == 'consumeandproduceall') + { + $defaultstockmovementlabel = $langs->trans("ProductionForRefAndDate", $object->ref, dol_print_date(dol_now(), 'standard')); + $defaultstockmovementcode = $object->ref.'_'.dol_print_date(dol_now(), 'dayhourlog'); + + print '
'; + print ''.$langs->trans("ConfirmProductionDesc", $langs->transnoentitiesnoconv("Confirm")).'

'; + print $langs->trans("MovementLabel").':   '; + print $langs->trans("InventoryCode").':   '; + print ''; + print '   '; + print ''; + print '
'; + print '
'; + } + } /* @@ -360,17 +397,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea //$result = $object->getLinesArray(); $object->fetchLines(); - print ' - - - - - '; - - if (!empty($conf->use_javascript_ajax) && $object->status == 0) { - include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; - } - print '
'; print '
'; print '
'; @@ -384,27 +410,54 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''.$langs->trans("Product").''; print ''.$langs->trans("Qty").''; print ''.$langs->trans("QtyAlreadyConsumed").''; - /*print ''.$langs->trans("Date").''; - print ''.$langs->trans("Batch").'';*/ + print ''; + if ($conf->productbatch->enabled) { + print ''; + if ($action == 'consumeandproduceall') print $langs->trans("Batch"); + print ''; + } print ''; if (!empty($object->lines)) { foreach($object->lines as $line) { if ($line->role == 'toconsume') { - print ''; $tmpproduct = new Product($db); $tmpproduct->fetch($line->fk_product); + + print ''; print ''.$tmpproduct->getNomUrl(1).''; print ''.$line->qty.''; $alreadyconsumed = 0; print ''.$alreadyconsumed.''; - /*print ''.''; - print ''.'';*/ + print ''; // Warehouse + if ($conf->productbatch->enabled) { + print ''; // Lot + } print ''; - // Show detailed of already consumed + // Show detailed of already consumed with js code to collapse //$arrayoflines = $line->fetchLinesLinked('consumed'); + + if ($action == 'consumeandproduceall') { + print ''; + print ''.$langs->trans("ToConsume").''; + print ''; + print ''; + print ''; + if ($tmpproduct->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + print $formproduct->selectWarehouses('ifone', 'idwarehouse-'.$line->id, '', 1, 0, $line->fk_product, '', 1); + } + print ''; + if ($conf->productbatch->enabled) { + print ''; + if ($tmpproduct->status_batch) { + print ''; + } + print ''; + } + print ''; + } } } } @@ -443,8 +496,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''.$langs->trans("Product").''; print ''.$langs->trans("Qty").''; print ''.$langs->trans("QtyAlreadyProduced").''; - /*print ''.$langs->trans("Date").''; - print ''.$langs->trans("Batch").'';*/ + print ''; + if ($conf->productbatch->enabled) { + print ''; + if ($action == 'consumeandproduceall') print $langs->trans("Batch"); + print ''; + } print ''; if (!empty($object->lines)) @@ -456,14 +513,36 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $tmpproduct->fetch($line->fk_product); print ''.$tmpproduct->getNomUrl(1).''; print ''.$line->qty.''; - $alreadyconsumed = 0; - print ''.$alreadyconsumed.''; - /*print ''.''; - print ''.'';*/ + $alreadyproduced = 0; + print ''.$alreadyproduced.''; + print ''; // Warehouse + if ($conf->productbatch->enabled) { + print ''; // Lot + } print ''; - // Show detailed of already consumed - //$arrayoflines = $line->fetchLinesLinked('consumed'); + // Show detailed of already produced + //$arrayoflines = $line->fetchLinesLinked('produced'); + + if ($action == 'consumeandproduceall') { + print ''; + print ''.$langs->trans("ToProduce").''; + print ''; + print ''; + print ''; + if ($tmpproduct->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + print $formproduct->selectWarehouses('ifone', 'idwarehouse-'.$line->id, '', 1, 0, $line->fk_product, '', 1); + } + print ''; + if ($conf->productbatch->enabled) { + print ''; + if ($tmpproduct->status_batch) { + print ''; + } + print ''; + } + print ''; + } } } } @@ -473,66 +552,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print '
'; - - print "\n"; } - - // Buttons for actions - /* - if ($action != 'presend' && $action != 'editline') { - print '
'."\n"; - $parameters=array(); - $reshook=$hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - - if (empty($reshook)) - { - // Send - print '' . $langs->trans('SendMail') . ''."\n"; - - // Modify - if (! empty($user->rights->mrp->write)) - { - print ''.$langs->trans("Modify").''."\n"; - } - else - { - print ''.$langs->trans('Modify').''."\n"; - } - - // Clone - if (! empty($user->rights->mrp->write)) - { - print ''; - } - - // Delete (need delete permission, or if draft, just need create/modify permission) - if (! empty($user->rights->mrp->delete) || (! empty($object->fields['status']) && $object->status == $object::STATUS_DRAFT && ! empty($user->rights->mrp->write))) - { - print ''.$langs->trans('Delete').''."\n"; - } - else - { - print ''.$langs->trans('Delete').''."\n"; - } - } - print '
'."\n"; - }*/ - - - if ($action != 'presend') + if (in_array($action, array('consume', 'produce', 'consumeandproduceall'))) { - print '
'; - print ''; // ancre - - - - print '
'; - - - - print '
'; + print "\n"; } } From 67316c912542d77dba736938cf7f514d4b316de0 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 3 Jan 2020 14:38:25 +0100 Subject: [PATCH 27/37] FIX Loan card - Wrong language key used --- htdocs/loan/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 73d7a7eeaf0..0c5eda1d972 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -624,7 +624,7 @@ if ($id > 0) else { print ''; - print $langs->trans("LoanAccountancyCapitalCode"); + print $langs->trans("LoanAccountancyInsuranceCode"); print ''; if (! empty($conf->accounting->enabled)) From 93d87d581b3f4055c20066eb01b8f071a24f3060 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 3 Jan 2020 14:56:49 +0100 Subject: [PATCH 28/37] FIX typo on language key --- htdocs/langs/en_US/other.lang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 0ad4c5dfc83..5dd7422539a 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -56,7 +56,7 @@ Notify_BILL_SUPPLIER_PAYED=Vendor invoice paid Notify_BILL_SUPPLIER_SENTBYMAIL=Vendor invoice sent by mail Notify_BILL_SUPPLIER_CANCELED=Vendor invoice cancelled Notify_CONTRACT_VALIDATE=Contract validated -Notify_FICHEINTER_VALIDATE=Intervention validated +Notify_FICHINTER_VALIDATE=Intervention validated Notify_FICHINTER_ADD_CONTACT=Added contact to Intervention Notify_FICHINTER_SENTBYMAIL=Intervention sent by mail Notify_SHIPPING_VALIDATE=Shipping validated @@ -269,4 +269,4 @@ WEBSITE_KEYWORDS=Keywords LinesToImport=Lines to import MemoryUsage=Memory usage -RequestDuration=Duration of request \ No newline at end of file +RequestDuration=Duration of request From 15ad41ee6d553d67b699df2df96cb27cf316a90a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 3 Jan 2020 15:01:14 +0100 Subject: [PATCH 29/37] MRP --- htdocs/langs/en_US/errors.lang | 1 + htdocs/langs/en_US/mrp.lang | 6 +- htdocs/mrp/class/mo.class.php | 36 +++++++- htdocs/mrp/mo_card.php | 2 - htdocs/mrp/mo_production.php | 145 +++++++++++++++++++++++++++++---- 5 files changed, 166 insertions(+), 24 deletions(-) diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 53f9e57fceb..db7fa8330bf 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -223,6 +223,7 @@ ErrorSearchCriteriaTooSmall=Search criteria too small. ErrorObjectMustHaveStatusActiveToBeDisabled=Objects must have status 'Active' to be disabled ErrorObjectMustHaveStatusDraftOrDisabledToBeActivated=Objects must have status 'Draft' or 'Disabled' to be enabled ErrorNoFieldWithAttributeShowoncombobox=No fields has property 'showoncombobox' into definition of object '%s'. No way to show the combolist. +ErrorFieldRequiredForProduct=Field '%s' is required for product %s # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang index a414920ff83..e336dd2552d 100644 --- a/htdocs/langs/en_US/mrp.lang +++ b/htdocs/langs/en_US/mrp.lang @@ -44,8 +44,8 @@ StatusMOProduced=Produced QtyFrozen=Frozen Qty QuantityFrozen=Frozen Quantity QuantityConsumedInvariable=When this flag is set, the quantity consumed is always the value defined and is not relative to the quantity produced. -DisableStockChange=Disable stock change -DisableStockChangeHelp=When this flag is set, there is no stock change on this product, whatever is the quantity produced +DisableStockChange=Stock change disabled +DisableStockChangeHelp=When this flag is set, there is no stock change on this product, whatever is the quantity consumed BomAndBomLines=Bills Of Material and lines BOMLine=Line of BOM WarehouseForProduction=Warehouse for production @@ -61,3 +61,5 @@ ForAQuantityOf1=For a quantity to produce of 1 ConfirmValidateMo=Are you sure you want to validate this Manufacturing Order? ConfirmProductionDesc=By clicking on '%s', you will validate the consumption and/or production for the quantities set. This will also update the stock and record stock movements. ProductionForRefAndDate=Production %s - %s +AutoCloseMO=Close automatically the Manufacturing Order if quantities to consume and to produce are reached +NoStockChangeOnServices=No stock change on services \ No newline at end of file diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index cc51515eeb6..e5ac29616a7 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -505,7 +505,7 @@ class Mo extends CommonObject } /** - * Erase and update the line to produce + * Erase and update the line to produce. * * @param User $user User that modifies * @return int <0 if KO, >0 if OK @@ -557,7 +557,11 @@ class Mo extends CommonObject $moline = new MoLine($this->db); $moline->fk_mo = $this->id; - $moline->qty = round($line->qty * $this->qty / $bom->efficiency, 2); + if ($line->qty_frozen) { + $moline->qty = $line->qty; // Qty to consume does not depends on quantity to produce + } else { + $moline->qty = round($line->qty * $this->qty / $bom->efficiency, 2); + } if ($moline->qty <= 0) { $error++; $this->error = "BadValueForquantityToConsume"; @@ -980,10 +984,16 @@ class Mo extends CommonObject global $langs; //$langs->load("mrp"); $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated').' ('.$langs->trans("ToProduce").')'; $this->labelStatus[self::STATUS_INPROGRESS] = $langs->trans('InProgress'); $this->labelStatus[self::STATUS_PRODUCED] = $langs->trans('StatusMOProduced'); $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Canceled'); + + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated'); + $this->labelStatusShort[self::STATUS_INPROGRESS] = $langs->trans('InProgress'); + $this->labelStatusShort[self::STATUS_PRODUCED] = $langs->trans('StatusMOProduced'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Canceled'); } $statusType = 'status'.$status; @@ -992,7 +1002,7 @@ class Mo extends CommonObject if ($status == self::STATUS_PRODUCED) $statusType = 'status5'; if ($status == self::STATUS_CANCELED) $statusType = 'status6'; - return dolGetStatus($this->labelStatus[$status], $this->labelStatus[$status], '', $statusType, $mode); + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); } /** @@ -1448,6 +1458,24 @@ class MoLine extends CommonObjectLine } } + /** + * Get list of lines linked to current line for a defined role + * + * @param string $role Get lines linked to current line with the selected role ('consumed', 'produced', ...) + * @return array Array of lines + */ + public function fetchLinesLinked($role) { + $array = array(); + + $sql = 'SELECT rowid, qty '; + $sql .= $this->getFieldList(); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')'; + else $sql .= ' WHERE 1 = 1'; + + return $array; + } + /** * Update object into database * diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php index 671353ff961..68938f97a58 100644 --- a/htdocs/mrp/mo_card.php +++ b/htdocs/mrp/mo_card.php @@ -117,8 +117,6 @@ $upload_dir = $conf->mrp->multidir_output[isset($object->entity) ? $object->enti /* * Actions - * - * Put here all code to do according to value of "action" parameter */ $parameters = array(); diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index cc08486e27d..212a7040927 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -47,6 +47,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; dol_include_once('/mrp/class/mo.class.php'); dol_include_once('/mrp/lib/mrp_mo.lib.php'); @@ -149,6 +150,89 @@ if (empty($reshook)) { $object->setProject(GETPOST('projectid', 'int')); } + + if ($action == 'confirm_consumeandproduceall') { + $db->begin(); + + // Process line to consume + foreach($object->lines as $line) { + if ($line->role == 'toconsume') { + $tmpproduct = new Product($db); + $tmpproduct->fetch($line->fk_product); + + $i=1; + while (GETPOSTISSET('qty-'.$line->id.'-'.$i)) { + // Check warehouse is set if we should have to + if (GETPOST('idwarehouse-'.$line->id.'-'.$i)) { + if (! (GETPOST('idwarehouse-'.$line->id.'-'.$i) > 0)) { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref), null, 'errors'); + $error++; + } + if ($tmpproduct->status_batch && (! GETPOST('batch-'.$line->id.'-'.$i))) { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref), null, 'errors'); + $error++; + } + } + + if (! $error) { + + + + } + + $i++; + } + } + } + + // Process line to produce + foreach($object->lines as $line) { + if ($line->role == 'toproduce') { + $tmpproduct = new Product($db); + $tmpproduct->fetch($line->fk_product); + + $i=1; + while (GETPOSTISSET('qtytoproduce-'.$line->id.'-'.$i)) { + // Check warehouse is set if we should have to + if (GETPOST('idwarehousetoproduce-'.$line->id.'-'.$i)) { + if (! (GETPOST('idwarehousetoproduce-'.$line->id.'-'.$i) > 0)) { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref), null, 'errors'); + $error++; + } + if ($tmpproduct->status_batch && (! GETPOST('batchtoproduce-'.$line->id.'-'.$i))) { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref), null, 'errors'); + $error++; + } + } + + if (! $error) { + + + + } + + $i++; + } + } + } + + if (! $error) { + // Update status of MO + + } + + if ($error) { + $action = str_replace('confirm_', '', $action); + $db->rollback(); + } else { + $db->commit(); + } + + } } @@ -357,7 +441,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea { print '
'; print ''; - print ''; + print ''; print ''; print ''; @@ -375,9 +459,10 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $defaultstockmovementcode = $object->ref.'_'.dol_print_date(dol_now(), 'dayhourlog'); print '
'; - print ''.$langs->trans("ConfirmProductionDesc", $langs->transnoentitiesnoconv("Confirm")).'

'; + print ''.$langs->trans("ConfirmProductionDesc", $langs->transnoentitiesnoconv("Confirm")).'
'; print $langs->trans("MovementLabel").':   '; - print $langs->trans("InventoryCode").':   '; + print $langs->trans("InventoryCode").':

'; + print ' '.$langs->trans("AutoCloseMO").'
'; print ''; print '   '; print ''; @@ -425,10 +510,24 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $tmpproduct = new Product($db); $tmpproduct->fetch($line->fk_product); + $arrayoflines = $line->fetchLinesLinked('consumed'); + $alreadyconsumed = 0; + foreach($arrayoflines as $line2) { + $alreadyconsumed += $line2->qty; + } + print ''; print ''.$tmpproduct->getNomUrl(1).''; - print ''.$line->qty.''; - $alreadyconsumed = 0; + print ''; + $help = ''; + if ($line->qty_frozen) $help.=($help ? '
' : '').''.$langs->trans("QuantityFrozen").': '.yn(1).' ('.$langs->trans("QuantityConsumedInvariable").')'; + if ($line->disable_stock_change) $help.=($help ? '
' : '').''.$langs->trans("DisableStockChange").': '.yn(1).' ('.(($tmpproduct->type == Product::TYPE_SERVICE && empty($conf->global->STOCK_SUPPORTS_SERVICES)) ? $langs->trans("NoStockChangeOnServices") : $langs->trans("DisableStockChangeHelp")).')'; + if ($help) { + print $form->textwithpicto($line->qty, $help); + } else { + print $line->qty; + } + print ''; print ''.$alreadyconsumed.''; print ''; // Warehouse if ($conf->productbatch->enabled) { @@ -440,19 +539,28 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea //$arrayoflines = $line->fetchLinesLinked('consumed'); if ($action == 'consumeandproduceall') { + $i = 1; print ''; print ''.$langs->trans("ToConsume").''; - print ''; + print ''; print ''; print ''; if ($tmpproduct->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - print $formproduct->selectWarehouses('ifone', 'idwarehouse-'.$line->id, '', 1, 0, $line->fk_product, '', 1); + if (empty($line->disable_stock_change)) { + $preselected = (GETPOSTISSET('idwarehouse-'.$line->id.'-'.$i) ? GETPOST('idwarehouse-'.$line->id.'-'.$i) : 'ifone'); + print $formproduct->selectWarehouses($preselected, 'idwarehouse-'.$line->id.'-'.$i, '', 1, 0, $line->fk_product, '', 1); + } else { + print ''.$langs->trans("DisableStockChange").''; + } + } else { + print ''.$langs->trans("NoStockChangeOnServices").''; } print ''; if ($conf->productbatch->enabled) { print ''; if ($tmpproduct->status_batch) { - print ''; + $preselected = (GETPOSTISSET('batch-'.$line->id.'-'.$i) ? GETPOST('batch-'.$line->id.'-'.$i) : ''); + print ''; } print ''; } @@ -508,12 +616,18 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea { foreach($object->lines as $line) { if ($line->role == 'toproduce') { - print ''; $tmpproduct = new Product($db); $tmpproduct->fetch($line->fk_product); + + $arrayoflines = $line->fetchLinesLinked('produced'); + $alreadyproduced = 0; + foreach($arrayoflines as $line2) { + $alreadyproduced += $line2->qty; + } + + print ''; print ''.$tmpproduct->getNomUrl(1).''; print ''.$line->qty.''; - $alreadyproduced = 0; print ''.$alreadyproduced.''; print ''; // Warehouse if ($conf->productbatch->enabled) { @@ -521,23 +635,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } print ''; - // Show detailed of already produced - //$arrayoflines = $line->fetchLinesLinked('produced'); - if ($action == 'consumeandproduceall') { print ''; print ''.$langs->trans("ToProduce").''; - print ''; + print ''; print ''; print ''; if ($tmpproduct->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - print $formproduct->selectWarehouses('ifone', 'idwarehouse-'.$line->id, '', 1, 0, $line->fk_product, '', 1); + $preselected = (GETPOSTISSET('idwarehousetoproduce-'.$line->id.'-'.$i) ? GETPOST('idwarehousetoproduce-'.$line->id.'-'.$i) : ($object->fk_warehouse > 0 ? $object->fk_warehouse : 'ifone')); + print $formproduct->selectWarehouses($preselected, 'idwarehousetoproduce-'.$line->id.'-'.$i, '', 1, 0, $line->fk_product, '', 1); } print ''; if ($conf->productbatch->enabled) { print ''; if ($tmpproduct->status_batch) { - print ''; + $preselected = (GETPOSTISSET('batchtoproduce-'.$line->id.'-'.$i) ? GETPOST('batchtoproduce-'.$line->id.'-'.$i) : ''); + print ''; } print ''; } From f14aaf5e50d9daeb4538d10468c987df9ee01b79 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 3 Jan 2020 16:35:02 +0100 Subject: [PATCH 30/37] FIX Some problems on conciliation with others modules --- htdocs/compta/bank/releve.php | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index b93f381c555..845ba1a2172 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -37,12 +37,15 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/don/class/paymentdonation.class.php'; +require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php'; //show files require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("banks","categories","companies","bills","trips")); +$langs->loadLangs(array("banks","categories","companies","bills","trips","donations","loan")); $action=GETPOST('action', 'alpha'); $id=GETPOST('account', 'int'); @@ -363,7 +366,10 @@ $paymentsupplierstatic=new PaiementFourn($db); $paymentvatstatic=new TVA($db); $bankstatic=new Account($db); $banklinestatic=new AccountLine($db); -$remisestatic = new RemiseCheque($db); +$remisestatic=new RemiseCheque($db); +$paymentdonationstatic=new PaymentDonation($db); +$paymentloanstatic=new PaymentLoan($db); +$paymentvariousstatic=new PaymentVarious($db); // Must be before button action $param=''; @@ -668,6 +674,27 @@ else print ''; $newline=0; } + elseif ($links[$key]['type']=='payment_donation') + { + $paymentdonationstatic->id=$links[$key]['url_id']; + $paymentdonationstatic->ref=$langs->trans("Payment"); + print ' '.$paymentdonationstatic->getNomUrl(1); + $newline = 0; + } + elseif ($links[$key]['type']=='payment_loan') + { + $paymentloanstatic->id=$links[$key]['url_id']; + $paymentloanstatic->ref=$langs->trans("Payment"); + print ' '.$paymentloanstatic->getNomUrl(1); + $newline = 0; + } + elseif ($links[$key]['type']=='payment_various') + { + $paymentvariousstatic->id=$links[$key]['url_id']; + $paymentvariousstatic->ref=$langs->trans("Payment"); + print ' '.$paymentvariousstatic->getNomUrl(1); + $newline = 0; + } elseif ($links[$key]['type']=='banktransfert') { // Do not show link to transfer since there is no transfer card (avoid confusion). Can already be accessed from transaction detail. if ($objp->amount > 0) From 79458ac139e5bd88b1402e98c5b0413dd545ca1f Mon Sep 17 00:00:00 2001 From: Pierre Ardoin <32256817+mapiolca@users.noreply.github.com> Date: Fri, 3 Jan 2020 18:05:49 +0100 Subject: [PATCH 31/37] FIX an issue that shows all entities stock Before : If products are shared between several entities, the stock of each entity are to add in this page (reassort.php) Now : Each entity see only her stock and not other's stock. --- htdocs/product/reassort.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index 476fec36c2a..cbf461f4fe4 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -123,10 +123,12 @@ $sql.= ' SUM(s.reel) as stock_physique'; if (! empty($conf->global->PRODUCT_USE_UNITS)) $sql.= ', u.short_label as unit_short'; $sql.= ' FROM '.MAIN_DB_PREFIX.'product as p'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s on p.rowid = s.fk_product'; +$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'entrepot as e on s.fk_entrepot = e.rowid'; if (! empty($conf->global->PRODUCT_USE_UNITS)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_units as u on p.fk_unit = u.rowid'; // We'll need this table joined to the select in order to filter by categ if ($search_categ) $sql.= ", ".MAIN_DB_PREFIX."categorie_product as cp"; $sql.= " WHERE p.entity IN (".getEntity('product').")"; +$sql.= " AND e.entity IN (".getEntity('entrepot').")"; if ($search_categ) $sql.= " AND p.rowid = cp.fk_product"; // Join for the needed table to filter by categ if ($sall) $sql.=natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $sall); // if the type is not 1, we show all products (type = 0,2,3) From 8a5f3d48f41caaa65f4ca18da1fdd9dd1116be1f Mon Sep 17 00:00:00 2001 From: Pierre Tocquin Date: Fri, 3 Jan 2020 19:18:24 +0100 Subject: [PATCH 32/37] Update api_supplier_invoices.class.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correction test data 'date' lors de la création d'une facture fournisseur. `array_keys` remplacé par `array_key_exists` dans la clause `if`. Cette clause est correcte dans api_invoices.class.php. --- htdocs/fourn/class/api_supplier_invoices.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 416f7e11e94..f4918650dc7 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -200,7 +200,7 @@ class SupplierInvoices extends DolibarrApi foreach($request_data as $field => $value) { $this->invoice->$field = $value; } - if(! array_keys($request_data, 'date')) { + if(! array_key_exists('date', $request_data)) { $this->invoice->date = dol_now(); } /* We keep lines as an array From 6e9bb5d7dae602bcc11a634c8a91e3d18a68a0a6 Mon Sep 17 00:00:00 2001 From: VESSILLER Date: Thu, 26 Dec 2019 16:18:26 +0100 Subject: [PATCH 33/37] FIX sql bad request in product buying price extrafields --- htdocs/product/fournisseurs.php | 132 ++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 56 deletions(-) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index bd93ef60a26..0abb57d8951 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -265,32 +265,31 @@ if (empty($reshook)) $extralabels = $extrafields->fetch_name_optionals_label("product_fournisseur_price"); $extrafield_values = $extrafields->getOptionalsFromPost("product_fournisseur_price"); + if (!empty($extrafield_values)) { + $resql = $db->query("SELECT fk_object FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields WHERE fk_object = " . $object->product_fourn_price_id); + // Insert a new extrafields row, if none exists + if ($db->num_rows($resql) != 1) { + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields (fk_object, "; + foreach ($extrafield_values as $key => $value) { + $sql .= str_replace('options_', '', $key) . ', '; + } + $sql = substr($sql, 0, strlen($sql) - 2) . ") VALUES (" . $object->product_fourn_price_id . ", "; + foreach ($extrafield_values as $key => $value) { + $sql .= '"' . $value . '", '; + } + $sql = substr($sql, 0, strlen($sql) - 2) . ')'; + } // else update the existing one + else { + $sql = "UPDATE " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields SET "; + foreach ($extrafield_values as $key => $value) { + $sql .= str_replace('options_', '', $key) . ' = "' . $value . '", '; + } + $sql = substr($sql, 0, strlen($sql) - 2) . ' WHERE fk_object = ' . $object->product_fourn_price_id; + } - $sql = ""; - $resql = $db->query("SELECT * FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields WHERE fk_object = ".$object->product_fourn_price_id); - // Insert a new extrafields row, if none exists - if ($db->num_rows($resql) != 1) { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields (fk_object, "; - foreach ($extrafield_values as $key => $value) { - $sql .= str_replace('options_', '', $key).', '; - } - $sql = substr($sql, 0, strlen($sql) - 2).") VALUES (".$object->product_fourn_price_id.", "; - foreach ($extrafield_values as $key => $value) { - $sql .= '"'.$value.'", '; - } - $sql = substr($sql, 0, strlen($sql) - 2).')'; - } - // else update the existing one - else { - $sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields SET "; - foreach ($extrafield_values as $key => $value) { - $sql .= str_replace('options_', '', $key).' = "'.$value.'", '; - } - $sql = substr($sql, 0, strlen($sql) - 2).' WHERE fk_object = '.$object->product_fourn_price_id; - } - - // Execute the sql command from above - $db->query($sql); + // Execute the sql command from above + $db->query($sql); + } $newprice = price2num(GETPOST("price", "alpha")); @@ -765,25 +764,36 @@ SCRIPT; print ''; } + // Extrafields $extrafields->fetch_name_optionals_label("product_fournisseur_price"); $extralabels = $extrafields->attributes["product_fournisseur_price"]['label']; - // Extrafields - $resql = $db->query("SELECT * FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields WHERE fk_object = ".$rowid); + $extrafield_values = $extrafields->getOptionalsFromPost("product_fournisseur_price"); if (!empty($extralabels)) { - if ($db->num_rows($resql) != 1) { - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) { - print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'.$langs->trans($value).''.$extrafields->showInputField($key, '', '', '', '', '', 0, 'product_fournisseur_price').''; - } - } - } else { - $resql = $db->fetch_object($resql); - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) { - print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'.$langs->trans($value).''.$extrafields->showInputField($key, $resql->{$key}, '', '', '', '', 0, 'product_fournisseur_price').''; - } - } - } + if (empty($rowid)) { + foreach ($extralabels as $key => $value) { + if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) { + print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'.$langs->trans($value).''.$extrafields->showInputField($key, GETPOSTISSET('options_' . $key) ? $extrafield_values['options_' . $key] : '', '', '', '', '', 0, 'product_fournisseur_price').''; + } + } + } else { + $sql = "SELECT"; + $sql .= " fk_object"; + foreach ($extralabels as $key => $value) { + $sql .= ", " . $key; + } + $sql .= " FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields"; + $sql .= " WHERE fk_object = " . $rowid; + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + foreach ($extralabels as $key => $value) { + if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && ($extrafields->attributes["product_fournisseur_price"]['list'][$key] == 1 || $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 3 || ($action == "update_price" && $extrafields->attributes["product_fournisseur_price"]['list'][$key] == 4))) { + print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'.$langs->trans($value).''.$extrafields->showInputField($key, GETPOSTISSET('options_' . $key) ? $extrafield_values['options_' . $key] : $obj->{$key}, '', '', '', '', 0, 'product_fournisseur_price').''; + } + } + $db->free($resql); + } + } } if (is_object($hookmanager)) @@ -1008,22 +1018,32 @@ SCRIPT; print ''; // Extrafields - $resql = $db->query("SELECT * FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields WHERE fk_object = ".$productfourn->product_fourn_price_id); if (!empty($extralabels)) { - if ($db->num_rows($resql) != 1) { - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { - print ""; - } - } - } else { - $resql = $db->fetch_object($resql); - foreach ($extralabels as $key => $value) { - if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { - print ''.$extrafields->showOutputField($key, $resql->{$key}).""; - } - } - } + $sql = "SELECT"; + $sql .= " fk_object"; + foreach ($extralabels as $key => $value) { + $sql .= ", " . $key; + } + $sql .= " FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields"; + $sql .= " WHERE fk_object = " . $productfourn->product_fourn_price_id; + $resql = $db->query($sql); + if ($resql) { + if ($db->num_rows($resql) != 1) { + foreach ($extralabels as $key => $value) { + if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { + print ""; + } + } + } else { + $obj = $db->fetch_object($resql); + foreach ($extralabels as $key => $value) { + if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { + print ''.$extrafields->showOutputField($key, $obj->{$key}).""; + } + } + } + $db->free($resql); + } } if (is_object($hookmanager)) From 37f93077328b8567674d57f19cb35005bd7f78fd Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 3 Jan 2020 20:53:49 +0100 Subject: [PATCH 34/37] 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 c61d778a9f9..4a8390d80cd 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2634,7 +2634,7 @@ class Product extends CommonObject * Charge tableau des stats expedition client pour le produit/service * * @param int $socid Id societe pour filtrer sur une societe - * @param string $filtrestatut Id statut pour filtrer sur un statut + * @param string $filtrestatut [=''] Ids order status separated by comma * @param int $forVirtualStock Ignore rights filter for virtual stock calculation. * @param string $filterShipmentStatus [=''] Ids shipment status separated by comma * @return int <0 if KO, >0 if OK (Tableau des stats) From 991bb5a2eb78aeb186d09b289e2365aa167d5c18 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 3 Jan 2020 21:02:05 +0100 Subject: [PATCH 35/37] Update issue templates --- .github/ISSUE_TEMPLATE/custom.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/custom.md diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 00000000000..48d5f81fa42 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,10 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' + +--- + + From a84ff7089ccd196ff8057db0f880ee1c3281a511 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 3 Jan 2020 21:14:04 +0100 Subject: [PATCH 36/37] Fix static text that is never updated --- README-FR.md | 3 +++ README.md | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README-FR.md b/README-FR.md index 3d5473b14cc..95a42da1127 100644 --- a/README-FR.md +++ b/README-FR.md @@ -1,5 +1,8 @@ # DOLIBARR ERP & CRM +![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg) +![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg) + Dolibarr ERP & CRM est un logiciel moderne pour gérer votre activité (société, association, auto-entrepreneurs, artisans). Il est simple d'utilisation et modulaire, vous permettant de n'activez que les fonctions dont vous avez besoin (contacts, fournisseurs, factures, commandes, stocks, agenda, ...). diff --git a/README.md b/README.md index e7f1535d1e5..a0c4dfd59ad 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,7 @@ # DOLIBARR ERP & CRM ![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg) - -|7|8|9|10|develop| -|----------|----------|----------|----------|----------| -|![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/7.0.svg)|![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/8.0.svg)|![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/9.0.svg)|![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/10.0.svg)|![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg)| +![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg) Dolibarr ERP & CRM is a modern software package to manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…). From 7853427bb1cc50685aabe6d5b2cb019f397a39d6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 4 Jan 2020 14:21:38 +0100 Subject: [PATCH 37/37] FIX product with empty stock were not visible --- htdocs/product/reassort.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/product/reassort.php b/htdocs/product/reassort.php index cbf461f4fe4..6ee13633139 100644 --- a/htdocs/product/reassort.php +++ b/htdocs/product/reassort.php @@ -123,12 +123,11 @@ $sql.= ' SUM(s.reel) as stock_physique'; if (! empty($conf->global->PRODUCT_USE_UNITS)) $sql.= ', u.short_label as unit_short'; $sql.= ' FROM '.MAIN_DB_PREFIX.'product as p'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'product_stock as s on p.rowid = s.fk_product'; -$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'entrepot as e on s.fk_entrepot = e.rowid'; +$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'entrepot as e on s.fk_entrepot = e.rowid AND e.entity IN ('.getEntity('entrepot').')'; if (! empty($conf->global->PRODUCT_USE_UNITS)) $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_units as u on p.fk_unit = u.rowid'; // We'll need this table joined to the select in order to filter by categ if ($search_categ) $sql.= ", ".MAIN_DB_PREFIX."categorie_product as cp"; $sql.= " WHERE p.entity IN (".getEntity('product').")"; -$sql.= " AND e.entity IN (".getEntity('entrepot').")"; if ($search_categ) $sql.= " AND p.rowid = cp.fk_product"; // Join for the needed table to filter by categ if ($sall) $sql.=natural_search(array('p.ref', 'p.label', 'p.description', 'p.note'), $sall); // if the type is not 1, we show all products (type = 0,2,3)