From 721371a08cd50c0ca131c3fd2422fc9ed2c55076 Mon Sep 17 00:00:00 2001 From: ATM john Date: Mon, 6 Apr 2020 13:08:03 +0200 Subject: [PATCH 01/12] Fix warehouse list --- htdocs/product/stock/class/entrepot.class.php | 6 +- htdocs/product/stock/list.php | 188 +++++++++++++----- 2 files changed, 144 insertions(+), 50 deletions(-) diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index ab3dfde9bf0..6499cc0ce9d 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -108,12 +108,12 @@ class Entrepot extends CommonObject 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>30), 'description' =>array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-2, 'position'=>35), 'lieu' =>array('type'=>'varchar(64)', 'label'=>'LocationSummary', 'enabled'=>1, 'visible'=>-2, 'position'=>40, 'showoncombobox'=>1), - 'fk_parent' =>array('type'=>'integer', 'label'=>'ParentWarehouse', 'enabled'=>1, 'visible'=>-2, 'position'=>41), + 'fk_parent' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:1:statut=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ParentWarehouse', 'enabled'=>1, 'visible'=>-2, 'position'=>41), 'address' =>array('type'=>'varchar(255)', 'label'=>'Address', 'enabled'=>1, 'visible'=>-2, 'position'=>45), 'zip' =>array('type'=>'varchar(10)', 'label'=>'Zip', 'enabled'=>1, 'visible'=>-2, 'position'=>50), 'town' =>array('type'=>'varchar(50)', 'label'=>'Town', 'enabled'=>1, 'visible'=>-2, 'position'=>55), - 'fk_departement' =>array('type'=>'integer', 'label'=>'State', 'enabled'=>1, 'visible'=>0, 'position'=>60), - 'fk_pays' =>array('type'=>'integer', 'label'=>'Country', 'enabled'=>1, 'visible'=>-2, 'position'=>65), + 'fk_departement' =>array('type'=>'sellist:c_departements:label:rowid::active=1', 'label'=>'State', 'enabled'=>1, 'visible'=>0, 'position'=>60), + 'fk_pays' =>array('type'=>'sellist:c_country:label:rowid::active=1', 'label'=>'Country', 'enabled'=>1, 'visible'=>-2, 'position'=>65), //'fk_user_author' =>array('type'=>'integer', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-2, 'position'=>82), 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>500), 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>501), diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 22f86df95a8..91a335758c6 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -89,12 +89,12 @@ $fieldstosearchall = array( $arrayfields = array( 'stockqty'=>array('type'=>'float', 'label'=>'PhysicalStock', 'enabled'=>1, 'visible'=>-2, 'position'=>70), 'estimatedvalue'=>array('type'=>'float', 'label'=>'EstimatedStockValue', 'enabled'=>1, 'visible'=>-2, 'position'=>71), - 'sellvalue'=>array('type'=>'float', 'label'=>'EstimatedStockValueSell', 'enabled'=>1, 'visible'=>-2, 'position'=>72), + 'estimatedstockvaluesell'=>array('type'=>'float', 'label'=>'EstimatedStockValueSell', 'enabled'=>1, 'visible'=>-2, 'position'=>72), ); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field - if (!empty($val['visible'])) $arrayfields['t.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>($val['enabled'] && ($val['visible'] != 3)), 'position'=>$val['position']); + if (!empty($val['visible'])) $arrayfields['e.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>($val['enabled'] && ($val['visible'] != 3)), 'position'=>$val['position']); } // Extra fields if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) @@ -158,6 +158,7 @@ if (empty($reshook)) $form = new Form($db); $warehouse = new Entrepot($db); +$totalarray = array(); $now = dol_now(); $help_url = 'EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks'; @@ -168,10 +169,12 @@ $title = $langs->trans("ListOfWarehouses"); // -------------------------------------------------------------------- $sql = "SELECT e.rowid, e.ref, e.statut, e.lieu, e.address, e.zip, e.town, e.fk_pays, e.fk_parent,"; $sql .= " SUM(p.pmp * ps.reel) as estimatedvalue, SUM(p.price * ps.reel) as sellvalue, SUM(ps.reel) as stockqty"; +$sqlGroupBy = ''; // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key : ''); + $sqlGroupBy .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key : ''); } } // Add fields from hooks @@ -183,6 +186,8 @@ $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as e"; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (e.rowid = ef.fk_object)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_stock as ps ON e.rowid = ps.fk_entrepot"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON ps.fk_product = p.rowid"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as c_dep ON c_dep.rowid = e.fk_departement"; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as ccount ON ccount.rowid = e.fk_pays"; $sql .= " WHERE e.entity IN (".getEntity('stock').")"; if ($search_ref) $sql .= natural_search("e.ref", $search_ref); // ref if ($search_label) $sql .= natural_search("e.lieu", $search_label); // label @@ -194,7 +199,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; -$sql .= " GROUP BY e.rowid, e.ref, e.statut, e.lieu, e.address, e.zip, e.town, e.fk_pays, e.fk_parent"; +$sql .= " GROUP BY e.rowid, e.ref, e.statut, e.lieu, e.address, e.zip, e.town, e.fk_pays, e.fk_parent".$sqlGroupBy; $totalnboflines = 0; $result = $db->query($sql); if ($result) @@ -210,6 +215,9 @@ if ($result) $totalStock += $objp->stockqty; $line++; } + $totalarray['val']['stockqty'] = $totalStock; + $totalarray['val']['estimatedvalue'] = $total; + $totalarray['val']['estimatedstockvaluesell'] = $totalsell; } $sql .= $db->order($sortfield, $sortorder); @@ -337,17 +345,37 @@ print ''; -print ''; +foreach ($object->fields as $key => $val) +{ + if($key == 'statut'){ continue; } + $cssforfield = (empty($val['css']) ? '' : $val['css']); + if ($key == 'status') $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif (in_array($val['type'], array('timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') $cssforfield .= ($cssforfield ? ' ' : '').'right'; + if (!empty($arrayfields['e.'.$key]['checked'])) + { + print ''; + } +} -print ''; +if (!empty($arrayfields["stockqty"]['checked'])) { + print ''; +} -print ''; -print ''; -print ''; +if (!empty($arrayfields["estimatedvalue"]['checked'])) { + print ''; +} + +if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) { + print ''; +} // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -357,9 +385,11 @@ $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $obje print $hookmanager->resPrint; // Status -print ''; +if (!empty($arrayfields["e.statut"]['checked'])) { + print ''; +} // Action column print ''."\n"; // Fields title label // -------------------------------------------------------------------- print ''; -print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "e.ref", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre("LocationSummary", $_SERVER["PHP_SELF"], "e.lieu", "", $param, "", $sortfield, $sortorder); -print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stockqty", '', $param, '', $sortfield, $sortorder, 'right '); -print_liste_field_titre("EstimatedStockValue", $_SERVER["PHP_SELF"], "estimatedvalue", '', $param, '', $sortfield, $sortorder, 'right '); -print_liste_field_titre("EstimatedStockValueSell", $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right '); + +foreach ($object->fields as $key => $val) +{ + if($key == 'statut'){ continue; } + $cssforfield = (empty($val['css']) ? '' : $val['css']); + if ($key == 'status') $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif (in_array($val['type'], array('timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') $cssforfield .= ($cssforfield ? ' ' : '').'right'; + if (!empty($arrayfields['e.'.$key]['checked'])) + { + print getTitleFieldOfList($arrayfields['e.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 'e.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n"; + } +} + +if (!empty($arrayfields["stockqty"]['checked'])) { + print_liste_field_titre("PhysicalStock", $_SERVER["PHP_SELF"], "stockqty", '', $param, '', $sortfield, $sortorder, 'right '); +} + +if (!empty($arrayfields["estimatedvalue"]['checked'])) { + print_liste_field_titre("EstimatedStockValue", $_SERVER["PHP_SELF"], "estimatedvalue", '', $param, '', $sortfield, $sortorder, 'right '); +} + +if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) { + print_liste_field_titre("EstimatedStockValueSell", $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right '); +} + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; -print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "e.statut", '', $param, '', $sortfield, $sortorder, 'right '); + +if (!empty($arrayfields["e.statut"]['checked'])) { + print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "e.statut", '', $param, '', $sortfield, $sortorder, 'right '); +} + // Action column print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; print ''."\n"; @@ -390,12 +446,10 @@ print ''."\n"; // Loop on record // -------------------------------------------------------------------- $i = 0; -$totalarray = array(); if ($num) { $warehouse = new Entrepot($db); - $totalarray = array(); while ($i < min($num, $limit)) { $obj = $db->fetch_object($resql); @@ -408,35 +462,70 @@ if ($num) $warehouse->fk_parent = $obj->fk_parent; $warehouse->statut = $obj->statut; + foreach ($object->fields as $key => $val){ + $warehouse->{$key} = $obj->{$key}; + } + + // Show here line of result print ''; - print ''; - if (!$i) $totalarray['nbfield']++; - // Location - print ''; - if (!$i) $totalarray['nbfield']++; + + foreach ($warehouse->fields as $key => $val) + { + if($key == 'statut'){ continue; } + $cssforfield = (empty($val['css']) ? '' : $val['css']); + if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'center'; + elseif ($key == 'status') $cssforfield .= ($cssforfield ? ' ' : '').'center'; + + if (in_array($val['type'], array('timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + elseif ($key == 'ref') $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status') $cssforfield .= ($cssforfield ? ' ' : '').'right'; + + if (!empty($arrayfields['e.'.$key]['checked'])) + { + print ''; + if ($key == 'status') print $warehouse->getLibStatut(5); + else print $warehouse->showOutputField($val, $key, $warehouse->$key, ''); + print ''; + if (!$i) $totalarray['nbfield']++; + if (!empty($val['isameasure'])) + { + if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'e.'.$key; + $totalarray['val']['e.'.$key] += $warehouse->$key; + } + } + } // Stock qty - print ''; - if (!$i) $totalarray['nbfield']++; + if (!empty($arrayfields["stockqty"]['checked'])) { + print ''; + if (!$i) $totalarray['nbfield']++; + if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'stockqty'; + } // PMP value - print ''; - if (!$i) $totalarray['nbfield']++; + if (!empty($arrayfields["estimatedvalue"]['checked'])) { + print ''; + if (!$i) $totalarray['nbfield']++; + if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'estimatedvalue'; + } // Selling value - print ''; + if (!$i) $totalarray['nbfield']++; + if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'estimatedstockvaluesell'; } - print ''; - if (!$i) $totalarray['nbfield']++; // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; @@ -446,8 +535,10 @@ if ($num) print $hookmanager->resPrint; // Status - print ''; - if (!$i) $totalarray['nbfield']++; + if (!empty($arrayfields["e.statut"]['checked'])) { + print ''; + if (!$i) $totalarray['nbfield']++; + } // Action column print ''; + // Show total line + include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; + + /*print ''; print ''; print ''; print ''; @@ -482,7 +576,7 @@ if ($num) print ''; print ''; print ''; - print "\n"; + print "\n";*/ } } From 88297d5682db0ffda1e7267981afa99068f5b0da Mon Sep 17 00:00:00 2001 From: ATM john Date: Mon, 6 Apr 2020 13:20:42 +0200 Subject: [PATCH 02/12] fix key --- htdocs/product/stock/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 91a335758c6..b84ddf9aad2 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -485,7 +485,7 @@ if ($num) if (!empty($arrayfields['e.'.$key]['checked'])) { print ''; - if ($key == 'status') print $warehouse->getLibStatut(5); + if ($key == 'statut') print $warehouse->getLibStatut(5); else print $warehouse->showOutputField($val, $key, $warehouse->$key, ''); print ''; if (!$i) $totalarray['nbfield']++; From 0716951b6dfba263c4419381556fc706eb6533b0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Apr 2020 13:38:29 +0200 Subject: [PATCH 03/12] Fix logo --- htdocs/core/modules/modLabel.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modLabel.class.php b/htdocs/core/modules/modLabel.class.php index c6f2c5267b5..5f2cff13ae6 100644 --- a/htdocs/core/modules/modLabel.class.php +++ b/htdocs/core/modules/modLabel.class.php @@ -51,7 +51,7 @@ class modLabel extends DolibarrModules // Possible values for version are: 'development', 'experimental', 'dolibarr' or version $this->version = 'development'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); - $this->picto='label'; + $this->picto='generic'; // Data directories to create when module is enabled $this->dirs = array("/label/temp"); From 64f6542f96fcb2e198bee59a0e355be378918dc7 Mon Sep 17 00:00:00 2001 From: atm-quentin Date: Wed, 8 Apr 2020 15:59:10 +0200 Subject: [PATCH 04/12] FIX buyprice extrafield langfile and tooltip --- htdocs/product/fournisseurs.php | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index f6daf4cb77d..615e6cbde56 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -773,7 +773,12 @@ SCRIPT; 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).''; + if(!empty($extrafields->attributes["product_fournisseur_price"]['langfile'][$key])) $langs->load($extrafields->attributes["product_fournisseur_price"]['langfile'][$key]); + + print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'; + if (!empty($extrafields->attributes["product_fournisseur_price"]['help'][$key])) print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product_fournisseur_price"]['help'][$key])); + else print $langs->trans($value); + print ''; } } } else { @@ -789,7 +794,14 @@ SCRIPT; $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).''; + if(!empty($extrafields->attributes["product_fournisseur_price"]['langfile'][$key])) $langs->load($extrafields->attributes["product_fournisseur_price"]['langfile'][$key]); + + print 'attributes["product_fournisseur_price"]['required'][$key] ? ' class="fieldrequired"' : '').'>'; + if (!empty($extrafields->attributes["product_fournisseur_price"]['help'][$key])) print $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product_fournisseur_price"]['help'][$key])); + else print $langs->trans($value); + print ''; } } $db->free($resql); @@ -890,9 +902,13 @@ SCRIPT; $extralabels = $extrafields->attributes["product_fournisseur_price"]['label']; if (!empty($extralabels)) { foreach ($extralabels as $key => $value) { + // Show field if not hidden if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { - print_liste_field_titre($value, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right '); + if(!empty($extrafields->attributes["product_fournisseur_price"]['langfile'][$key])) $langs->load($extrafields->attributes["product_fournisseur_price"]['langfile'][$key]); + if (!empty($extrafields->attributes["product_fournisseur_price"]['help'][$key])) $extratitle = $form->textwithpicto($langs->trans($value), $langs->trans($extrafields->attributes["product_fournisseur_price"]['help'][$key])); + else $extratitle = $langs->trans($value); + print_liste_field_titre($extratitle, $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right '); } } } From 50b789456d2ea85bc79fe627490e79f827991d94 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 8 Apr 2020 14:03:16 +0000 Subject: [PATCH 05/12] Fixing style errors. --- htdocs/product/fournisseurs.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 615e6cbde56..4cf56b8a9d0 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -902,7 +902,6 @@ SCRIPT; $extralabels = $extrafields->attributes["product_fournisseur_price"]['label']; if (!empty($extralabels)) { foreach ($extralabels as $key => $value) { - // Show field if not hidden if (!empty($extrafields->attributes["product_fournisseur_price"]['list'][$key]) && $extrafields->attributes["product_fournisseur_price"]['list'][$key] != 3) { if(!empty($extrafields->attributes["product_fournisseur_price"]['langfile'][$key])) $langs->load($extrafields->attributes["product_fournisseur_price"]['langfile'][$key]); From 6cb780d125fdd268288f7c6a5a75a76d7dc6faf5 Mon Sep 17 00:00:00 2001 From: simicar29 Date: Wed, 8 Apr 2020 16:03:41 +0200 Subject: [PATCH 06/12] Avoid the doubledot issue in quoted-printable mail When sending HTML mail using swiftmailer, the content will be encoded using quoted-printable. We may then encounter the "double dot" issue (doubled dot at the beginning of the line). This can be problematic with broken links to pictures for example. This PR switches the encoding to base64. --- htdocs/core/class/CMailFile.class.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 6127a7d6044..8b6722b0977 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -814,6 +814,10 @@ class CMailFile if (!empty($conf->global->$keyforsmtppw)) $this->transport->setPassword($conf->global->$keyforsmtppw); //$smtps->_msgReplyTo = 'reply@web.com'; + // Switch content encoding to base64 - avoid the doubledot issue with quoted-printable + $contentEncoderBase64 = new Swift_Mime_ContentEncoder_Base64ContentEncoder(); + $this->message->setEncoder($contentEncoderBase64); + // Create the Mailer using your created Transport $this->mailer = new Swift_Mailer($this->transport); From e402e35d96932f427a601966e411c3fd79d22655 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Wed, 8 Apr 2020 14:09:04 +0000 Subject: [PATCH 07/12] Fixing style errors. --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 8b6722b0977..454673fe55b 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -817,7 +817,7 @@ class CMailFile // Switch content encoding to base64 - avoid the doubledot issue with quoted-printable $contentEncoderBase64 = new Swift_Mime_ContentEncoder_Base64ContentEncoder(); $this->message->setEncoder($contentEncoderBase64); - + // Create the Mailer using your created Transport $this->mailer = new Swift_Mailer($this->transport); From 63f0c07a0765c3aa119bb930758943349830fd73 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 8 Apr 2020 18:32:13 +0200 Subject: [PATCH 08/12] Add warning --- htdocs/comm/mailing/card.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index e4e4237db05..dda9efb2b95 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -345,6 +345,7 @@ if (empty($reshook)) if (!empty($conf->global->MAILING_DELAY)) { + dol_syslog("Wait a delay of MAILING_DELAY=".$conf->global->MAILING_DELAY); sleep($conf->global->MAILING_DELAY); } From caecb0152ff90692d028eb8fe2fdbfac6d99a4bc Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Thu, 9 Apr 2020 14:46:20 +0200 Subject: [PATCH 09/12] Fix set default warehouse list columns --- htdocs/product/stock/class/entrepot.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 6499cc0ce9d..03ba46a4068 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -103,11 +103,11 @@ class Entrepot extends CommonObject * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. */ public $fields=array( - 'rowid' =>array('type'=>'integer', 'label'=>'ID', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>10), - 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-2, 'showoncombobox'=>1, 'position'=>25), + 'rowid' =>array('type'=>'integer', 'label'=>'ID', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>10), + 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'showoncombobox'=>1, 'position'=>25), 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>30), 'description' =>array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-2, 'position'=>35), - 'lieu' =>array('type'=>'varchar(64)', 'label'=>'LocationSummary', 'enabled'=>1, 'visible'=>-2, 'position'=>40, 'showoncombobox'=>1), + 'lieu' =>array('type'=>'varchar(64)', 'label'=>'LocationSummary', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'showoncombobox'=>1), 'fk_parent' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:1:statut=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ParentWarehouse', 'enabled'=>1, 'visible'=>-2, 'position'=>41), 'address' =>array('type'=>'varchar(255)', 'label'=>'Address', 'enabled'=>1, 'visible'=>-2, 'position'=>45), 'zip' =>array('type'=>'varchar(10)', 'label'=>'Zip', 'enabled'=>1, 'visible'=>-2, 'position'=>50), @@ -119,7 +119,7 @@ class Entrepot extends CommonObject 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>501), //'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000), //'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'ModelPDF', 'enabled'=>1, 'visible'=>0, 'position'=>1010), - 'statut' =>array('type'=>'tinyint(4)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-2, 'position'=>200), + 'statut' =>array('type'=>'tinyint(4)', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'position'=>200), ); /** From c9ab61b521a958b8c530ac0c6f6a40cf25bbb2ae Mon Sep 17 00:00:00 2001 From: atm-lena Date: Thu, 9 Apr 2020 14:54:47 +0200 Subject: [PATCH 10/12] FIX - Add function "completeTabsHead" to hooks "addreplace" --- htdocs/core/class/hookmanager.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index 39493825377..fc2193b451a 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -207,7 +207,8 @@ class HookManager 'sendMailAfter', 'showLinkToObjectBlock', 'setContentSecurityPolicy', - 'setHtmlTitle' + 'setHtmlTitle', + 'completeTabsHead' ) )) $hooktype='addreplace'; From 0a8a8bafa0528f8dd32f9d44abbe24226e2c4fb7 Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Thu, 9 Apr 2020 15:40:36 +0200 Subject: [PATCH 11/12] FIX print pictures in shipment docs --- .../expedition/doc/pdf_espadon.modules.php | 20 ++++++++++++++----- .../expedition/doc/pdf_rouget.modules.php | 13 +++++++++--- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index 0d702adab60..c4262f71f19 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -171,7 +171,8 @@ class pdf_espadon extends ModelePdfExpedition $nblines = count($object->lines); // Loop on each lines to detect if there is at least one image to show - $realpatharray=array(); + $realpatharray=array(); + $this->atleastonephoto = false; if (! empty($conf->global->MAIN_GENERATE_SHIPMENT_WITH_PICTURE)) { $objphoto = new Product($this->db); @@ -183,8 +184,16 @@ class pdf_espadon extends ModelePdfExpedition $objphoto = new Product($this->db); $objphoto->fetch($object->lines[$i]->fk_product); - $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product') . $object->lines[$i]->fk_product ."/photos/"; - $dir = $conf->product->dir_output.'/'.$pdir; + if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { + $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product') . $object->lines[$i]->fk_product ."/photos/"; + $dir = $conf->product->dir_output.'/'.$pdir; + } + else + { + $pdir = get_exdir(0, 2, 0, 0, $objphoto, 'product') . dol_sanitizeFileName($objphoto->ref).'/'; + $dir = $conf->product->dir_output.'/'.$pdir; + } $realpath=''; @@ -206,7 +215,8 @@ class pdf_espadon extends ModelePdfExpedition $filename = $obj['photo']; } - $realpath = $dir.$filename; + $realpath = $dir.$filename; + $this->atleastonephoto = true; break; } @@ -1150,7 +1160,7 @@ class pdf_espadon extends ModelePdfExpedition 'border-left' => false, // remove left line separator ); - if (!empty($conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE) && !empty($this->atleastonephoto)) + if (!empty($conf->global->MAIN_GENERATE_SHIPMENT_WITH_PICTURE) && !empty($this->atleastonephoto)) { $this->cols['photo']['status'] = true; } diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php index ad0272f46a1..506e72ba1b0 100644 --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php @@ -214,9 +214,16 @@ class pdf_rouget extends ModelePdfExpedition $objphoto = new Product($this->db); $objphoto->fetch($object->lines[$i]->fk_product); - - $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product').$object->lines[$i]->fk_product."/photos/"; - $dir = $conf->product->dir_output.'/'.$pdir; + if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) + { + $pdir = get_exdir($object->lines[$i]->fk_product, 2, 0, 0, $objphoto, 'product') . $object->lines[$i]->fk_product ."/photos/"; + $dir = $conf->product->dir_output.'/'.$pdir; + } + else + { + $pdir = get_exdir(0, 2, 0, 0, $objphoto, 'product') . dol_sanitizeFileName($objphoto->ref).'/'; + $dir = $conf->product->dir_output.'/'.$pdir; + } $realpath = ''; From f7d1ce1e099b95d83046556c60d734c4a3f0539b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Apr 2020 00:25:30 +0200 Subject: [PATCH 12/12] FIX Can use decimal value in virtual products --- htdocs/product/composition/card.php | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/htdocs/product/composition/card.php b/htdocs/product/composition/card.php index cb95f10d79f..88945342af5 100644 --- a/htdocs/product/composition/card.php +++ b/htdocs/product/composition/card.php @@ -70,13 +70,15 @@ if ($cancel) $action =''; if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->service->creer)) { $error=0; - for ($i=0; $i<$_POST["max_prod"]; $i++) + var_dump(GETPOST("max_prod", 'int')); + for ($i=0; $i < GETPOST("max_prod", 'int'); $i++) { - if ($_POST["prod_qty_".$i] > 0) + $qty = price2num(GETPOST("prod_qty_".$i, 'alpha'), 'MS'); + if ($qty > 0) { - if ($object->add_sousproduit($id, $_POST["prod_id_".$i], $_POST["prod_qty_".$i], $_POST["prod_incdec_".$i]) > 0) + if ($object->add_sousproduit($id, GETPOST("prod_id_".$i, 'int'), $qty, GETPOST("prod_incdec_".$i, 'int')) > 0) { - //var_dump($id.' - '.$_POST["prod_id_".$i].' - '.$_POST["prod_qty_".$i]);exit; + //var_dump($i.' '.GETPOST("prod_id_".$i, 'int'), $qty, GETPOST("prod_incdec_".$i, 'int')); $action = 'edit'; } else @@ -94,7 +96,7 @@ if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->se } else { - if ($object->del_sousproduit($id, $_POST["prod_id_".$i]) > 0) + if ($object->del_sousproduit($id, GETPOST("prod_id_".$i, 'int')) > 0) { $action = 'edit'; } @@ -106,6 +108,7 @@ if ($action == 'add_prod' && ($user->rights->produit->creer || $user->rights->se } } } + if (! $error) { header("Location: ".$_SERVER["PHP_SELF"].'?id='.$object->id); @@ -540,7 +543,9 @@ if ($id > 0 || ! empty($ref)) if($num == 0) print ''; - while ($i < $num) + $MAX = 100; + + while ($i < min($num, $MAX)) { $objp = $db->fetch_object($resql); if($objp->rowid != $id) @@ -572,7 +577,8 @@ if ($id > 0 || ! empty($ref)) } } - print "\n".''; + print "\n"; + print ''; $productstatic->id=$objp->rowid; $productstatic->ref=$objp->ref; @@ -620,6 +626,14 @@ if ($id > 0 || ! empty($ref)) } $i++; } + if ($num > $MAX) { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } } else {
'; -print ''; -print ''; + if (is_array($val['arrayofkeyval'])) print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth75'); + elseif (strpos($val['type'], 'integer:') === 0 || strpos($val['type'], 'sellist:') === 0) { + print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth150', 1); + } + elseif (! preg_match('/^(date|timestamp)/', $val['type'])) print ''; + print ''; -print ''; -print ''; -print $form->selectarray('search_status', $warehouse->statuts, $search_status, 1, 0, 0, '', 1); -print ''; + print $form->selectarray('search_status', $warehouse->statuts, $search_status, 1, 0, 0, '', 1); + print ''; @@ -371,18 +401,44 @@ print '
'.$warehouse->getNomUrl(1).''.$obj->lieu.''.price2num($obj->stockqty, 5).'' . price2num($obj->stockqty, 5) . ''; - if (price2num($obj->estimatedvalue, 'MT')) print price(price2num($obj->estimatedvalue, 'MT'), 1); - else print ''; - print ''; + if (price2num($obj->estimatedvalue, 'MT')) print price(price2num($obj->estimatedvalue, 'MT'), 1); + else print ''; + print ''; - if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($obj->sellvalue, 'MT'), 1); - else - { - $htmltext = $langs->trans("OptionMULTIPRICESIsOn"); - print $form->textwithtooltip($langs->trans("Variable"), $htmltext); + if (!empty($arrayfields["estimatedstockvaluesell"]['checked'])) { + print ''; + if (empty($conf->global->PRODUIT_MULTIPRICES)) print price(price2num($obj->sellvalue, 'MT'), 1); + else { + $htmltext = $langs->trans("OptionMULTIPRICESIsOn"); + print $form->textwithtooltip($langs->trans("Variable"), $htmltext); + } + print ''.$warehouse->LibStatut($obj->statut, 5).'' . $warehouse->LibStatut($obj->statut, 5) . ''; @@ -468,7 +559,10 @@ if ($num) if ($totalnboflines - $offset <= $limit) { - print '
'.$langs->trans("Total").''.price2num($totalStock, 5).''.price(price2num($total, 'MT'), 1, $langs, 0, 0, -1, $conf->currency).'
'.$extrafields->showInputField($key, GETPOSTISSET('options_' . $key) ? $extrafield_values['options_' . $key] : '', '', '', '', '', 0, 'product_fournisseur_price').'
'.$extrafields->showInputField($key, GETPOSTISSET('options_' . $key) ? $extrafield_values['options_' . $key] : '', '', '', '', '', 0, 'product_fournisseur_price').'
'.$extrafields->showInputField($key, GETPOSTISSET('options_' . $key) ? $extrafield_values['options_' . $key] : $obj->{$key}, '', '', '', '', 0, 'product_fournisseur_price').'
'.$extrafields->showInputField($key, GETPOSTISSET('options_' . $key) ? $extrafield_values['options_' . $key] : $obj->{$key}, '', '', '', '', 0, 'product_fournisseur_price'); + + print '
'.$langs->trans("NoMatchFound").'
'.$langs->trans("More").'...