From a9727760cfd19fde9d0f301d1d6e39c2490e8240 Mon Sep 17 00:00:00 2001 From: Jyhere Date: Mon, 12 May 2025 19:39:31 +0200 Subject: [PATCH 1/6] NEW: add hooks on societe consumption page (#34112) * NEW: add hooks on societe consumption page Add all necessary hooks to modify query and add more columns on the societe consumption page * FIX : redefine $parameters array between each hook call * FIX: php cs errors --- htdocs/societe/consumption.php | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index e3570e90aa1..fe6dee6e28e 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -385,12 +385,13 @@ if ($type_element == 'contract') { // Order $thirdTypeSelect = 'customer'; } -$parameters = array(); $totalnboflines = 0; -$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook if (!empty($sql_select)) { $sql = $sql_select; + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; $sql .= ' d.description as description,'; if ($type_element != 'fichinter' && $type_element != 'contract' && $type_element != 'supplier_proposal' && $type_element != 'shipment' && $type_element != 'reception') { $sql .= ' d.label, d.fk_product as product_id, d.fk_product as fk_product, d.info_bits, d.date_start, d.date_end, d.qty, d.qty as prod_qty, d.total_ht as total_ht, '; @@ -418,6 +419,9 @@ if (!empty($sql_select)) { if ($type_element != 'fichinter') { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON d.fk_product = p.rowid '; } + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; $sql .= $where; $sql .= dolSqlDateFilter($dateprint, 0, $month, $year); if ($sref) { @@ -434,6 +438,15 @@ if (!empty($sql_select)) { } $sql .= ")"; } + + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; + + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; + $sql .= $db->order($sortfield, $sortorder); $resql = $db->query($sql); @@ -518,6 +531,9 @@ if ($sql_select) { print ''; print ''; print ''; + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; print ''; $searchpicto = $form->showFilterAndCheckAddButtons(0); print $searchpicto; @@ -537,6 +553,9 @@ if ($sql_select) { print_liste_field_titre('Quantity', $_SERVER['PHP_SELF'], 'prod_qty', '', $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre('TotalHT', $_SERVER['PHP_SELF'], 'total_ht', '', $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre('UnitPrice', $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'right '); + $parameters = array('param'=>$param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; print "\n"; $i = 0; @@ -740,7 +759,9 @@ if ($sql_select) { $total_ht += (float) $objp->total_ht; print ''.price($objp->total_ht / (empty($objp->prod_qty) ? 1 : $objp->prod_qty)).''; - + $parameters = array('obj' => $objp); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; print "\n"; $i++; } @@ -755,6 +776,9 @@ if ($sql_select) { print ''.$total_qty.''; print ''.price($total_ht).''; print ''.price(price2num($total_ht / (empty($total_qty) ? 1 : $total_qty), 'MU')).''; + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListTotal', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; print ""; print ''; From 991e6f383ac18e074dbe864d8c26a77d71b7c9cb Mon Sep 17 00:00:00 2001 From: Lucas Marcouiller <45882981+Hystepik@users.noreply.github.com> Date: Mon, 12 May 2025 19:41:46 +0200 Subject: [PATCH 2/6] Fix ai feature to edit/set extrafield with ai following step 3 (#34111) * Fix ai feature to edit/set extrafield with ai following step 3 * fix formlayoutai page * fix CI --- htdocs/core/ajax/updateextrafield.php | 2 +- htdocs/core/class/html.formai.class.php | 2 +- htdocs/core/tpl/extrafields_view.tpl.php | 47 ++++++++++++++++-------- htdocs/core/tpl/formlayoutai.tpl.php | 7 +--- 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/htdocs/core/ajax/updateextrafield.php b/htdocs/core/ajax/updateextrafield.php index e42424126fe..f7dffb2954d 100644 --- a/htdocs/core/ajax/updateextrafield.php +++ b/htdocs/core/ajax/updateextrafield.php @@ -59,7 +59,7 @@ include '../../main.inc.php'; $objectType = GETPOST('objectType', 'aZ09'); $objectId = GETPOST('objectId', 'aZ09'); $field = GETPOST('field', 'aZ09'); -$value = GETPOST('value', 'aZ09'); +$value = GETPOST('value', 'alpha'); $module = getElementProperties($objectType)['module']; $element_ref = ''; diff --git a/htdocs/core/class/html.formai.class.php b/htdocs/core/class/html.formai.class.php index fd0304141c4..246dea54cca 100644 --- a/htdocs/core/class/html.formai.class.php +++ b/htdocs/core/class/html.formai.class.php @@ -411,7 +411,7 @@ class FormAI extends Form console.log('Add response into field \'#'+htmlname+'\': '+response); jQuery('#'+htmlname).val(response); // If #htmlcontent is a input name or textarea - jQuery('#'+htmlname).html(response); // If #htmlContent is a div + jQuery('#'+htmlname).html(response).trigger('change'); // If #htmlContent is a div and trigger event change for extrafield update //jQuery('#'+htmlname+'preview').val(response); if (CKEDITOR.instances) { diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index 25bee4baf24..ac3d92ba0aa 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -229,23 +229,38 @@ if (empty($reshook) && !empty($object->table_element) && isset($extrafields->att $fieldid = 'socid'; } - print ''.img_edit().''; - } - if (isModEnabled("ai") && $action == 'edit_extras' && GETPOST('attribute') == $tmpkeyextra && !empty($extrafields->attributes[$object->table_element]["aiprompt"][$tmpkeyextra])) { - $showlinktoai = "extrafieldfiller"; - $showlinktoailabel = $langs->trans("FillExtrafieldWithAi"); - $htmlname = "options_".$tmpkeyextra; - $onlyenhancements = "textgenerationextrafield"; - $morecss = "editfielda"; - $aiprompt = $extrafields->attributes[$object->table_element]["aiprompt"][$tmpkeyextra]; - $out = ""; - - // Fill $out - include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php'; print ''; - print ''; - print $out; - print ''; + if (isModEnabled("ai") && !empty($extrafields->attributes[$object->table_element]["aiprompt"][$tmpkeyextra])) { + $showlinktoai = "extrafieldfiller_".$tmpkeyextra; + $showlinktoailabel = $langs->trans("FillExtrafieldWithAi"); + $htmlname = !empty($object->id) ? $object->element.'_extras_'.$tmpkeyextra.'_'.$object->id : "options_".$tmpkeyextra; + $onlyenhancements = "textgenerationextrafield"; + $morecss = "editfielda"; + $aiprompt = $extrafields->attributes[$object->table_element]["aiprompt"][$tmpkeyextra]; + $out = ""; + + // Fill $out + include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php'; + print $out; + print ''; + } + print ''.img_edit().''; + print''; } print ''; print ''; diff --git a/htdocs/core/tpl/formlayoutai.tpl.php b/htdocs/core/tpl/formlayoutai.tpl.php index cc4896a567e..5b422875afe 100644 --- a/htdocs/core/tpl/formlayoutai.tpl.php +++ b/htdocs/core/tpl/formlayoutai.tpl.php @@ -41,15 +41,10 @@ if (empty($conf) || !is_object($conf)) { exit(1); } - if (empty($langs)) { print 'Parameter langs not defined.'; exit(1); } -if (empty($object)) { - print 'Parameter object not defined.'; - exit(1); -} if (empty($htmlname)) { print 'Parameter htmlname not defined.'; exit(1); @@ -163,7 +158,7 @@ if ($showlinktoai) { if (empty($onlyenhancements)) { $onlyenhancements = ''; } - if (!empty($aiprompt)) { + if (!empty($aiprompt) && !empty($object)) { $formai->setSubstitFromObject($object, $langs); $aiprompt = make_substitutions($aiprompt, $formai->substit); } From b791e20407421a859722242e3d7434bfb4a2da4c Mon Sep 17 00:00:00 2001 From: Arthur Lenoble <71173990+ArthurDLTR@users.noreply.github.com> Date: Mon, 12 May 2025 19:44:19 +0200 Subject: [PATCH 3/6] Add constant to show stock in products combo (#34107) Same constant added to use the same constant in both calls of the function select_produits_fournisseur_list() --- htdocs/product/ajax/products.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/ajax/products.php b/htdocs/product/ajax/products.php index 85e9a6fcfc5..c491243ed0e 100644 --- a/htdocs/product/ajax/products.php +++ b/htdocs/product/ajax/products.php @@ -335,7 +335,7 @@ if ($action == 'fetch' && !empty($id)) { if (empty($mode) || $mode == 1) { // mode=1: customer $arrayresult = $form->select_produits_list(0, $htmlname, $type, getDolGlobalInt('PRODUIT_LIMIT_SIZE', 1000), $price_level, $searchkey, $status, $finished, $outjson, $socid, '1', 0, '', $hidepriceinlabel, $warehouseStatus, $status_purchase, $warehouseId); } elseif ($mode == 2) { // mode=2: supplier - $arrayresult = $form->select_produits_fournisseurs_list($socid, "", $htmlname, $type, "", $searchkey, $status, $outjson, getDolGlobalInt('PRODUIT_LIMIT_SIZE', 1000), $alsoproductwithnosupplierprice); + $arrayresult = $form->select_produits_fournisseurs_list($socid, "", $htmlname, $type, "", $searchkey, $status, $outjson, getDolGlobalInt('PRODUIT_LIMIT_SIZE', 1000), $alsoproductwithnosupplierprice, '', getDolGlobalInt('SUPPLIER_SHOW_STOCK_IN_PRODUCTS_COMBO')); } $db->close(); From 1192ce57911e7bb3a5741ce44d5a51881d7168de Mon Sep 17 00:00:00 2001 From: Delthair <41671350+Delthair@users.noreply.github.com> Date: Mon, 12 May 2025 19:45:21 +0200 Subject: [PATCH 4/6] #33951 Non-blocking minimum sale price in the proposals (#34104) #33951 Non-blocking minimum sale price in the proposals the price base type was not in the $price_base_type variable and therefore none of the checks were done so it was possible to have a price below the min price --- htdocs/comm/propal/card.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 050fe09f444..5d8cee7215f 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1924,6 +1924,7 @@ if (empty($reshook)) { $res = $product->fetch($productid); $type = $product->type; + $$price_base_type = $product->price_base_type; $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : ''); $price_min = $product->price_min; From 22298c1f8345dbb4e810600aa80ab3ad4c8f1b70 Mon Sep 17 00:00:00 2001 From: William Mead Date: Mon, 12 May 2025 20:06:38 +0200 Subject: [PATCH 5/6] NEW pagination data for interventions API get (#34113) * Added get interventions pagination data * Fixed PHPDoc --------- Co-authored-by: Laurent Destailleur --- .../class/api_interventions.class.php | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php index 51bcfeb64b9..f20d2ac0894 100644 --- a/htdocs/fichinter/class/api_interventions.class.php +++ b/htdocs/fichinter/class/api_interventions.class.php @@ -131,13 +131,14 @@ class Interventions extends DolibarrApi * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" * @param string $properties Restrict the data returned to these properties. Ignored if empty. Comma separated list of property names * @param string $contact_type {@choice '',thirdparty,internal,external} Type of contacts + * @param bool $pagination_data If this parameter is set to true the response will include pagination data. Default value is false. Page starts from 0* * @return array Array of order objects * @phan-return array * @phpstan-return array * * @throws RestException */ - public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '', $properties = '', $contact_type = '') + public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '', $properties = '', $contact_type = '', $pagination_data = false) { if (!DolibarrApiAccess::$user->hasRight('ficheinter', 'lire')) { throw new RestException(403); @@ -177,6 +178,9 @@ class Interventions extends DolibarrApi } } + //this query will return total interventions with the filters given + $sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql); + $sql .= $this->db->order($sortfield, $sortorder); if ($limit) { if ($page < 0) { @@ -209,6 +213,23 @@ class Interventions extends DolibarrApi throw new RestException(503, 'Error when retrieve intervention list : '.$this->db->lasterror()); } + //if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit) + if ($pagination_data) { + $totalsResult = $this->db->query($sqlTotals); + $total = $this->db->fetch_object($totalsResult)->total; + + $tmp = $obj_ret; + $obj_ret = []; + + $obj_ret['data'] = $tmp; + $obj_ret['pagination'] = [ + 'total' => (int) $total, + 'page' => $page, //count starts from 0 + 'page_count' => ceil((int) $total / $limit), + 'limit' => $limit + ]; + } + return $obj_ret; } From 77a5147f6cf35179b89ee7b04301eb7d838cc040 Mon Sep 17 00:00:00 2001 From: Arthur Lenoble <71173990+ArthurDLTR@users.noreply.github.com> Date: Mon, 12 May 2025 20:12:30 +0200 Subject: [PATCH 6/6] Option to show stock in products combo in supplier orders (#34106) Add the constant SUPPLIER_SHOW_STOCK_IN_PRODUCTS_COMBO to show the current stock of the product in the products combo in a supplier order like it's already possible in a customer order --- htdocs/core/class/html.form.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 7f14ae81e59..f6bf37f03dc 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -3754,7 +3754,7 @@ class Form print($hidelabel ? '' : $langs->trans("RefOrLabel") . ' : ') . ''; } else { - print $this->select_produits_fournisseurs_list($socid, $selected, $htmlname, $filtertype, $filtre, '', $status, 0, 0, $alsoproductwithnosupplierprice, $morecss, 0, $placeholder); + print $this->select_produits_fournisseurs_list($socid, $selected, $htmlname, $filtertype, $filtre, '', $status, 0, 0, $alsoproductwithnosupplierprice, $morecss, getDolGlobalInt('SUPPLIER_SHOW_STOCK_IN_PRODUCTS_COMBO'), $placeholder); } }