dolibarr 21.0.0-alpha
list.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2019 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2012-2016 Marcos García <marcosgdf@gmail.com>
6 * Copyright (C) 2013-2023 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2013-2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
8 * Copyright (C) 2013 Jean Heimburger <jean@tiaris.info>
9 * Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
10 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
11 * Copyright (C) 2013 Adolfo segura <adolfo.segura@gmail.com>
12 * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
13 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
14 * Copyright (C) 2020-2021 Open-DSI <support@open-dsi.fr>
15 * Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
16 * Copyright (C) 2020-2023 Alexandre Spangaro <aspangaro@easya.solutions>
17 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
18 * Copyright (C) 2024 Benjamin Falière <benjamin.faliere@altairis.fr>
19 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 3 of the License, or
24 * (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program. If not, see <https://www.gnu.org/licenses/>.
33 */
34
42// Load Dolibarr environment
43require '../main.inc.php';
44require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
45require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
46require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
47require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
48require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
49require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
50require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
51require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
52
53if (isModEnabled('workstation')) {
54 require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php';
55}
56if (isModEnabled('category')) {
57 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
58 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
59}
60
61// Load translation files required by the page
62$langs->loadLangs(array('products', 'stocks', 'suppliers', 'companies', 'margins'));
63if (isModEnabled('productbatch')) {
64 $langs->load("productbatch");
65}
66
67
68// Get parameters
69$action = GETPOST('action', 'aZ09');
70$massaction = GETPOST('massaction', 'alpha');
71$show_files = GETPOSTINT('show_files');
72$confirm = GETPOST('confirm', 'alpha');
73$toselect = GETPOST('toselect', 'array');
74$optioncss = GETPOST('optioncss', 'alpha');
75$mode = GETPOST('mode', 'alpha');
76
77$fourn_id = GETPOSTINT("fourn_id");
78
79// Search Criteria
80$search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
81$search_id = GETPOST("search_id", 'alpha');
82$search_ref = GETPOST("search_ref", 'alpha');
83$search_ref_supplier = GETPOST("search_ref_supplier", 'alpha');
84$search_barcode = GETPOST("search_barcode", 'alpha');
85$search_label = GETPOST("search_label", 'alpha');
86$search_default_workstation = GETPOST("search_default_workstation", 'alpha');
87$search_type = GETPOST("search_type", "int");
88$search_vatrate = GETPOST("search_vatrate", 'alpha');
89$searchCategoryProductOperator = 0;
90if (GETPOSTISSET('formfilteraction')) {
91 $searchCategoryProductOperator = GETPOSTINT('search_category_product_operator');
92} elseif (getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT')) {
93 $searchCategoryProductOperator = getDolGlobalString('MAIN_SEARCH_CAT_OR_BY_DEFAULT');
94}
95$searchCategoryProductList = GETPOST('search_category_product_list', 'array');
96$catid = GETPOSTINT('catid');
97if (!empty($catid) && empty($searchCategoryProductList)) {
98 $searchCategoryProductList = array($catid);
99}
100$search_tosell = GETPOST("search_tosell");
101$search_tobuy = GETPOST("search_tobuy");
102$search_country = GETPOST("search_country", 'aZ09');
103$search_state = GETPOST("state_id", 'intcomma');
104$search_tobatch = GETPOST("search_tobatch");
105$search_accountancy_code_sell = GETPOST("search_accountancy_code_sell", 'alpha');
106$search_accountancy_code_sell_intra = GETPOST("search_accountancy_code_sell_intra", 'alpha');
107$search_accountancy_code_sell_export = GETPOST("search_accountancy_code_sell_export", 'alpha');
108$search_accountancy_code_buy = GETPOST("search_accountancy_code_buy", 'alpha');
109$search_accountancy_code_buy_intra = GETPOST("search_accountancy_code_buy_intra", 'alpha');
110$search_accountancy_code_buy_export = GETPOST("search_accountancy_code_buy_export", 'alpha');
111$search_import_key = GETPOST("search_import_key", 'alpha');
112$search_finished = GETPOST("search_finished");
113$search_units = GETPOST('search_units', 'alpha');
114$type = GETPOST("type", 'alpha');
115
116// Show/hide child product variants
117$show_childproducts = 0;
118if (isModEnabled('variants')) {
119 $show_childproducts = GETPOST('search_show_childproducts');
120}
121
122$diroutputmassaction = $conf->product->dir_output.'/temp/massgeneration/'.$user->id;
123
124// Load variable for pagination
125$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
126$sortfield = GETPOST('sortfield', 'aZ09comma');
127$sortorder = GETPOST('sortorder', 'aZ09comma');
128$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
129if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
130 // If $page is not defined, or '' or -1 or if we click on clear filters
131 $page = 0;
132}
133$offset = $limit * $page;
134$pageprev = $page - 1;
135$pagenext = $page + 1;
136if (!$sortfield) {
137 $sortfield = "p.ref";
138}
139if (!$sortorder) {
140 $sortorder = "ASC";
141}
142
143// Initialize context for list
144$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'productservicelist';
145if ((string) $type == '1') {
146 $contextpage = 'servicelist';
147 if ($search_type == '') {
148 $search_type = '1';
149 }
150}
151if ((string) $type == '0') {
152 $contextpage = 'productlist';
153 if ($search_type == '') {
154 $search_type = '0';
155 }
156}
157
158// Initialize a technical object to manage hooks. Note that conf->hooks_modules contains array of hooks
159$object = new Product($db);
160$hookmanager->initHooks(array('productservicelist'));
161$extrafields = new ExtraFields($db);
162$form = new Form($db);
163$formcompany = new FormCompany($db);
164$formproduct = new FormProduct($db);
165
166// fetch optionals attributes and labels
167$extrafields->fetch_name_optionals_label($object->table_element);
168$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
169
170if (empty($action)) {
171 $action = 'list';
172}
173
174// Get object canvas (By default, this is not defined, so standard usage of dolibarr)
175$canvas = GETPOST("canvas");
176$objcanvas = null;
177if (!empty($canvas)) {
178 require_once DOL_DOCUMENT_ROOT.'/core/class/canvas.class.php';
179 $objcanvas = new Canvas($db, $action);
180 $objcanvas->getCanvas('product', 'list', $canvas);
181}
182
183// Define virtualdiffersfromphysical
184$virtualdiffersfromphysical = 0;
185if (getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT')
186 || getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER')
187 || getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT_CLOSE')
188 || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION')
189 || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')
190 || isModEnabled('mrp')) {
191 $virtualdiffersfromphysical = 1; // According to increase/decrease stock options, virtual and physical stock may differs.
192}
193
194// List of fields to search into when doing a "search in all"
195$fieldstosearchall = array(
196 'p.ref' => "Ref",
197 'p.label' => "ProductLabel",
198 'p.description' => "Description",
199 "p.note" => "Note",
200 'pfp.ref_fourn' => 'RefSupplier'
201);
202// multilang
203if (getDolGlobalInt('MAIN_MULTILANGS')) {
204 $fieldstosearchall['pl.label'] = 'ProductLabelTranslated';
205 $fieldstosearchall['pl.description'] = 'ProductDescriptionTranslated';
206 $fieldstosearchall['pl.note'] = 'ProductNoteTranslated';
207}
208if (isModEnabled('barcode')) {
209 $fieldstosearchall['p.barcode'] = 'Gencod';
210 $fieldstosearchall['pfp.barcode'] = 'GencodBuyPrice';
211}
212// Personalized search criteria. Example: getDolGlobalString('PRODUCT_QUICKSEARCH_ON_FIELDS') = 'p.ref=ProductRef;p.label=ProductLabel;p.description=Description;p.note=Note;'
213if (getDolGlobalString('PRODUCT_QUICKSEARCH_ON_FIELDS')) {
214 $fieldstosearchall = dolExplodeIntoArray(getDolGlobalString('PRODUCT_QUICKSEARCH_ON_FIELDS'));
215}
216
217if (!getDolGlobalString('PRODUIT_MULTIPRICES')) {
218 $titlesellprice = $langs->trans("SellingPrice");
219 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
220 $titlesellprice = $form->textwithpicto($langs->trans("SellingPrice"), $langs->trans("DefaultPriceRealPriceMayDependOnCustomer"));
221 }
222}
223
224$isInEEC = isInEEC($mysoc);
225
226$alias_product_perentity = !getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED') ? "p" : "ppe";
227
228$arraypricelevel = array();
229// Definition of array of fields for columns
230$arrayfields = array(
231 'p.rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -2, 'noteditable' => 1, 'notnull' => 1, 'index' => 1, 'position' => 1, 'comment' => 'Id', 'css' => 'left'),
232 'p.ref' => array('label' => 'ProductRef', 'checked' => 1, 'position' => 10),
233 //'pfp.ref_fourn'=>array('label'=>$langs->trans("RefSupplier"), 'checked'=>1, 'enabled'=>(isModEnabled('barcode'))),
234 'thumbnail' => array('label' => 'Photo', 'checked' => 0, 'position' => 10),
235 'p.description' => array('label' => 'Description', 'checked' => 0, 'position' => 10),
236 'p.label' => array('label' => "Label", 'checked' => 1, 'position' => 10),
237 'p.fk_product_type' => array('label' => "Type", 'checked' => 0, 'enabled' => (isModEnabled("product") && isModEnabled("service")), 'position' => 11),
238 'p.barcode' => array('label' => "Gencod", 'checked' => 1, 'enabled' => (isModEnabled('barcode')), 'position' => 12),
239 'p.duration' => array('label' => "Duration", 'checked' => ($contextpage != 'productlist'), 'enabled' => (isModEnabled("service") && (string) $type == '1'), 'position' => 13),
240 'pac.fk_product_parent' => array('label' => "ParentProductOfVariant", 'checked' => -1, 'enabled' => (isModEnabled('variants')), 'position' => 14),
241 'p.finished' => array('label' => "Nature", 'checked' => 0, 'enabled' => (isModEnabled("product") && $type != '1'), 'position' => 19),
242 'p.weight' => array('label' => 'Weight', 'checked' => 0, 'enabled' => (isModEnabled("product") && $type != '1'), 'position' => 20),
243 'p.weight_units' => array('label' => 'WeightUnits', 'checked' => 0, 'enabled' => (isModEnabled("product") && $type != '1'), 'position' => 21),
244 'p.length' => array('label' => 'Length', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_SIZE') && $type != '1'), 'position' => 22),
245 'p.length_units' => array('label' => 'LengthUnits', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_SIZE') && $type != '1'), 'position' => 23),
246 'p.width' => array('label' => 'Width', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_SIZE') && $type != '1'), 'position' => 24),
247 'p.width_units' => array('label' => 'WidthUnits', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_SIZE') && $type != '1'), 'position' => 25),
248 'p.height' => array('label' => 'Height', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_SIZE') && $type != '1'), 'position' => 26),
249 'p.height_units' => array('label' => 'HeightUnits', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_SIZE') && $type != '1'), 'position' => 27),
250 'p.surface' => array('label' => 'Surface', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_SURFACE') && $type != '1'), 'position' => 28),
251 'p.surface_units' => array('label' => 'SurfaceUnits', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_SURFACE') && $type != '1'), 'position' => 29),
252 'p.volume' => array('label' => 'Volume', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_VOLUME') && $type != '1'), 'position' => 30),
253 'p.volume_units' => array('label' => 'VolumeUnits', 'checked' => 0, 'enabled' => (isModEnabled("product") && !getDolGlobalString('PRODUCT_DISABLE_VOLUME') && $type != '1'), 'position' => 31),
254 'cu.label' => array('label' => "DefaultUnitToShow", 'checked' => 0, 'enabled' => (isModEnabled("product") && getDolGlobalString('PRODUCT_USE_UNITS')), 'position' => 32),
255 'p.fk_default_workstation' => array('label' => 'DefaultWorkstation', 'checked' => 0, 'enabled' => isModEnabled('workstation') && $type == 1, 'position' => 33),
256 'p.sellprice' => array('label' => "SellingPrice", 'checked' => 1, 'enabled' => !getDolGlobalString('PRODUIT_MULTIPRICES'), 'position' => 40),
257 'p.tva_tx' => array('label' => "VATRate", 'checked' => 0, 'enabled' => !getDolGlobalString('PRODUIT_MULTIPRICES'), 'position' => 41),
258 'p.minbuyprice' => array('label' => "BuyingPriceMinShort", 'checked' => 1, 'enabled' => ($user->hasRight('fournisseur', 'lire')), 'position' => 42),
259 'p.numbuyprice' => array('label' => "BuyingPriceNumShort", 'checked' => 0, 'enabled' => ($user->hasRight('fournisseur', 'lire')), 'position' => 43),
260 'p.pmp' => array('label' => "PMPValueShort", 'checked' => 0, 'enabled' => ($user->hasRight('fournisseur', 'lire')), 'position' => 44),
261 'p.cost_price' => array('label' => "CostPrice", 'checked' => 0, 'enabled' => ($user->hasRight('fournisseur', 'lire')), 'position' => 45),
262 'p.seuil_stock_alerte' => array('label' => "StockLimit", 'checked' => 0, 'enabled' => (isModEnabled('stock') && $user->hasRight('stock', 'lire') && ($contextpage != 'servicelist' || getDolGlobalString('STOCK_SUPPORTS_SERVICES'))), 'position' => 50),
263 'p.desiredstock' => array('label' => "DesiredStock", 'checked' => 1, 'enabled' => (isModEnabled('stock') && $user->hasRight('stock', 'lire') && ($contextpage != 'servicelist' || getDolGlobalString('STOCK_SUPPORTS_SERVICES'))), 'position' => 51),
264 'p.stock' => array('label' => "PhysicalStock", 'checked' => 1, 'enabled' => (isModEnabled('stock') && $user->hasRight('stock', 'lire') && ($contextpage != 'servicelist' || getDolGlobalString('STOCK_SUPPORTS_SERVICES'))), 'position' => 52),
265 'stock_virtual' => array('label' => "VirtualStock", 'checked' => 1, 'enabled' => (isModEnabled('stock') && $user->hasRight('stock', 'lire') && ($contextpage != 'servicelist' || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) && $virtualdiffersfromphysical), 'position' => 53),
266 'p.tobatch' => array('label' => "ManageLotSerial", 'checked' => 0, 'enabled' => (isModEnabled('productbatch')), 'position' => 60),
267 'p.fk_country' => array('label' => "Country", 'checked' => 0, 'position' => 100),
268 'p.fk_state' => array('label' => "State", 'checked' => 0, 'position' => 101),
269 $alias_product_perentity . '.accountancy_code_sell' => array('label' => "ProductAccountancySellCode", 'checked' => 0, 'enabled' => !getDolGlobalString('PRODUCT_DISABLE_ACCOUNTING'), 'position' => 400),
270 $alias_product_perentity . '.accountancy_code_sell_intra' => array('label' => "ProductAccountancySellIntraCode", 'checked' => 0, 'enabled' => $isInEEC && !getDolGlobalString('PRODUCT_DISABLE_ACCOUNTING'), 'position' => 401),
271 $alias_product_perentity . '.accountancy_code_sell_export' => array('label' => "ProductAccountancySellExportCode", 'checked' => 0, 'enabled' => !getDolGlobalString('PRODUCT_DISABLE_ACCOUNTING'), 'position' => 402),
272 $alias_product_perentity . '.accountancy_code_buy' => array('label' => "ProductAccountancyBuyCode", 'checked' => 0, 'enabled' => !getDolGlobalString('PRODUCT_DISABLE_ACCOUNTING'), 'position' => 403),
273 $alias_product_perentity . '.accountancy_code_buy_intra' => array('label' => "ProductAccountancyBuyIntraCode", 'checked' => 0, 'enabled' => $isInEEC && !getDolGlobalString('PRODUCT_DISABLE_ACCOUNTING'), 'position' => 404),
274 $alias_product_perentity . '.accountancy_code_buy_export' => array('label' => "ProductAccountancyBuyExportCode", 'checked' => 0, 'enabled' => !getDolGlobalString('PRODUCT_DISABLE_ACCOUNTING'), 'position' => 405),
275 'p.datec' => array('label' => "DateCreation", 'checked' => 0, 'position' => 500),
276 'p.tms' => array('label' => "DateModificationShort", 'checked' => 0, 'position' => 500),
277 'p.tosell' => array('label' => $langs->transnoentitiesnoconv("Status").' ('.$langs->transnoentitiesnoconv("Sell").')', 'checked' => 1, 'position' => 1000),
278 'p.tobuy' => array('label' => $langs->transnoentitiesnoconv("Status").' ('.$langs->transnoentitiesnoconv("Buy").')', 'checked' => 1, 'position' => 1000),
279 'p.import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'index' => 0, 'checked' => -1, 'position' => 1100),
280);
281/*foreach ($object->fields as $key => $val) {
282 // If $val['visible']==0, then we never show the field
283 if (!empty($val['visible'])) {
284 $visible = dol_eval($val['visible'], 1, 1, '1');
285 $arrayfields['p.'.$key] = array(
286 'label'=>$val['label'],
287 'checked'=>(($visible < 0) ? 0 : 1),
288 'enabled'=>(abs($visible) != 3 && (bool) dol_eval($val['enabled'], 1)),
289 'position'=>$val['position']
290 );
291 }
292}*/
293
294
295// MultiPrices
296if (getDolGlobalString('PRODUIT_MULTIPRICES')) {
297 $produit_multiprices_limit = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT');
298 for ($i = 1; $i <= $produit_multiprices_limit; $i++) {
299 $keyforlabel = 'PRODUIT_MULTIPRICES_LABEL'.$i;
300 if (getDolGlobalString($keyforlabel)) {
301 $labelp = $i.' - '.$langs->transnoentitiesnoconv(getDolGlobalString($keyforlabel));
302 } else {
303 $labelp = $langs->transnoentitiesnoconv("SellingPrice")." ".$i;
304 }
305 $arrayfields['p.sellprice'.$i] = array('label' => $labelp, 'checked' => ($i == 1 ? 1 : 0), 'enabled' => getDolGlobalString('PRODUIT_MULTIPRICES'), 'position' => (float) ('40.'.sprintf('%03d', $i)));
306 $arraypricelevel[$i] = array($i);
307 }
308}
309
310//var_dump($arraypricelevel);
311// Extra fields
312include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
313
314$object->fields = dol_sort_array($object->fields, 'position');
315$arrayfields = dol_sort_array($arrayfields, 'position');
316'@phan-var-force array<string,array{label:string,checked?:int<0,1>,position?:int,help?:string}> $arrayfields'; // dol_sort_array looses type for Phan
317
318// Security check
319if ($search_type == '0') {
320 $result = restrictedArea($user, 'produit', '', '', '', '', '', 0);
321} elseif ($search_type == '1') {
322 $result = restrictedArea($user, 'service', '', '', '', '', '', 0);
323} else {
324 $result = restrictedArea($user, 'produit|service', '', '', '', '', '', 0);
325}
326
327
328/*
329 * Actions
330 */
331
332if (GETPOST('cancel', 'alpha')) {
333 $action = 'list';
334 $massaction = '';
335}
336if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
337 $massaction = '';
338}
339$parameters = array('arrayfields' => &$arrayfields);
340$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
341if ($reshook < 0) {
342 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
343}
344
345$rightskey = 'produit';
346if ($type == Product::TYPE_SERVICE) {
347 $rightskey = 'service';
348}
349
350if (empty($reshook)) {
351 // Selection of new fields
352 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
353
354 // Purge search criteria
355 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
356 $search_all = "";
357 $search_id = '';
358 $search_ref = "";
359 $search_ref_supplier = "";
360 $search_label = "";
361 $search_default_workstation = "";
362 $search_barcode = "";
363 $searchCategoryProductOperator = 0;
364 $searchCategoryProductList = array();
365 $search_tosell = "";
366 $search_tobuy = "";
367 $search_tobatch = '';
368 $search_country = "";
369 $search_state = "";
370 $search_vatrate = "";
371 $search_finished = '';
372 //$search_type=''; // There is 2 types of list: a list of product and a list of services. No list with both. So when we clear search criteria, we must keep the filter on type.
373
374 $show_childproducts = '';
375 $search_import_key = '';
376 $search_accountancy_code_sell = '';
377 $search_accountancy_code_sell_intra = '';
378 $search_accountancy_code_sell_export = '';
379 $search_accountancy_code_buy = '';
380 $search_accountancy_code_buy_intra = '';
381 $search_accountancy_code_buy_export = '';
382 $search_array_options = array();
383 $search_units = '';
384 }
385
386 // Mass actions
387 $objectclass = 'Product';
388 if ((string) $search_type == '1') {
389 $objectlabel = 'Services';
390 }
391 if ((string) $search_type == '0') {
392 $objectlabel = 'Products';
393 }
394
395 $permissiontoread = $user->hasRight($rightskey, 'lire');
396 $permissiontodelete = $user->hasRight($rightskey, 'supprimer');
397 $permissiontoadd = $user->hasRight($rightskey, 'creer');
398 $uploaddir = $conf->product->dir_output;
399 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
400
401 if (!$error && $massaction == 'switchonsalestatus' && $permissiontoadd) {
402 $product = new Product($db);
403 foreach ($toselect as $toselectid) {
404 $result = $product->fetch($toselectid);
405 if ($result > 0 && $product->id > 0) {
406 if ($product->setStatut($product->status ? 0 : 1, null, 'product', 'PRODUCT_MODIFY', 'tosell') < 0) {
407 setEventMessages($product->error, $product->errors, 'errors');
408 }
409 }
410 }
411 }
412 if (!$error && $massaction == 'switchonpurchasestatus' && $permissiontoadd) {
413 $product = new Product($db);
414 foreach ($toselect as $toselectid) {
415 $result = $product->fetch($toselectid);
416 if ($result > 0 && $product->id > 0) {
417 if ($product->setStatut($product->status_buy ? 0 : 1, null, 'product', 'PRODUCT_MODIFY', 'tobuy') < 0) {
418 setEventMessages($product->error, $product->errors, 'errors');
419 }
420 }
421 }
422 }
423}
424
425
426/*
427 * View
428 */
429
430$product_static = new Product($db);
431if (isModEnabled('workstation')) {
432 $workstation_static = new Workstation($db);
433}
434$product_fourn = new ProductFournisseur($db);
435
436$title = $langs->trans("ProductsAndServices");
437
438if ($search_type != '' && $search_type != '-1') {
439 if ($search_type == 1) {
440 $title = $langs->trans("Services");
441 } else {
442 $title = $langs->trans("Products");
443 }
444}
445
446// Build and execute select
447// --------------------------------------------------------------------
448$sql = 'SELECT p.rowid, p.ref, p.description, p.label, p.fk_product_type, p.barcode, p.price, p.tva_tx, p.price_ttc, p.price_base_type, p.entity,';
449$sql .= ' p.fk_product_type, p.duration, p.finished, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock,';
450$sql .= ' p.tobatch, ';
451if (isModEnabled('workstation')) {
452 $sql .= ' p.fk_default_workstation, ws.status as status_workstation, ws.ref as ref_workstation, ';
453}
454if (!getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
455 $sql .= " p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.accountancy_code_buy_intra, p.accountancy_code_buy_export,";
456} else {
457 $sql .= " ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export, ppe.accountancy_code_buy, ppe.accountancy_code_buy_intra, ppe.accountancy_code_buy_export,";
458}
459$sql .= ' p.datec as date_creation, p.tms as date_modification, p.pmp, p.stock, p.cost_price,';
460$sql .= ' p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units,';
461$sql .= ' p.fk_country, p.fk_state,';
462$sql .= ' p.import_key,';
463if (getDolGlobalString('PRODUCT_USE_UNITS')) {
464 $sql .= ' p.fk_unit, cu.label as cu_label,';
465}
466$sql .= ' MIN(pfp.unitprice) as bestpurchaseprice';
467if (isModEnabled('variants')) {
468 $sql .= ', pac.rowid as prod_comb_id';
469 $sql .= ', pac.fk_product_parent';
470}
471// Add fields from extrafields
472if (!empty($extrafields->attributes[$object->table_element]['label'])) {
473 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
474 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
475 }
476}
477// Add fields from hooks
478$parameters = array();
479$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
480$sql .= $hookmanager->resPrint;
481$sql = preg_replace('/,\s*$/', '', $sql);
482
483$sqlfields = $sql; // $sql fields to remove for count total
484
485$sql .= ' FROM '.MAIN_DB_PREFIX.'product as p';
486if (isModEnabled('workstation')) {
487 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "workstation_workstation as ws ON (p.fk_default_workstation = ws.rowid)";
488}
489if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
490 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
491}
492if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
493 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_extrafields as ef on (p.rowid = ef.fk_object)";
494}
495$linktopfp = " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product";
496$sql .= $linktopfp;
497// multilang
498if (getDolGlobalInt('MAIN_MULTILANGS')) {
499 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_lang as pl ON pl.fk_product = p.rowid AND pl.lang = '".$db->escape($langs->getDefaultLang())."'";
500}
501if (isModEnabled('variants')) {
502 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid";
503}
504if (getDolGlobalString('PRODUCT_USE_UNITS')) {
505 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_units cu ON cu.rowid = p.fk_unit";
506}
507
508// Add table from hooks
509$parameters = array();
510$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
511$sql .= $hookmanager->resPrint;
512
513$sql .= ' WHERE p.entity IN ('.getEntity('product').')';
514if ($search_all) {
515 // Clean $fieldstosearchall
516 $newfieldstosearchall = $fieldstosearchall;
517 unset($newfieldstosearchall['pfp.ref_fourn']);
518 unset($newfieldstosearchall['pfp.barcode']);
519
520 $sql .= ' AND (';
521 $sql .= natural_search(array_keys($newfieldstosearchall), $search_all, 0, 1);
522 // Search also into a supplier reference 'pfp.ref_fourn'="RefSupplier"
523 $sql .= ' OR EXISTS (SELECT rowid FROM '.MAIN_DB_PREFIX.'product_fournisseur_price as pfp WHERE pfp.fk_product = p.rowid';
524 $sql .= ' AND ('.natural_search('pfp.ref_fourn', $search_all, 0, 1);
525 if (isModEnabled('barcode')) {
526 // Search also into a supplier barcode 'pfp.barcode'='GencodBuyPrice';
527 $sql .= ' OR '.natural_search('pfp.barcode', $search_all, 0, 1);
528 }
529 $sql .= ')))';
530}
531// if the type is not 1, we show all products (type = 0,2,3)
532if (dol_strlen($search_type) && $search_type != '-1') {
533 if ($search_type == 1) {
534 $sql .= " AND p.fk_product_type = 1";
535 } else {
536 $sql .= " AND p.fk_product_type <> 1";
537 }
538}
539
540if (isModEnabled('variants') && !$show_childproducts) {
541 $sql .= " AND pac.rowid IS NULL";
542}
543
544if ($search_id) {
545 $sql .= natural_search('p.rowid', $search_id, 1);
546}
547if ($search_ref) {
548 $sql .= natural_search('p.ref', $search_ref);
549}
550if ($search_label) {
551 $sql .= natural_search('p.label', $search_label);
552}
553if ($search_default_workstation) {
554 $sql .= natural_search('ws.ref', $search_default_workstation);
555}
556if ($search_barcode) {
557 $sql .= natural_search('p.barcode', $search_barcode);
558}
559if ($search_import_key) {
560 $sql .= natural_search('p.import_key', $search_import_key);
561}
562if (isset($search_tosell) && dol_strlen($search_tosell) > 0 && $search_tosell != -1) {
563 $sql .= " AND p.tosell = ".((int) $search_tosell);
564}
565if (isset($search_tobuy) && dol_strlen($search_tobuy) > 0 && $search_tobuy != -1) {
566 $sql .= " AND p.tobuy = ".((int) $search_tobuy);
567}
568if (isset($search_tobatch) && dol_strlen($search_tobatch) > 0 && $search_tobatch != -1) {
569 $sql .= " AND p.tobatch = ".((int) $search_tobatch);
570}
571if ($search_vatrate) {
572 $sql .= natural_search('p.tva_tx', $search_vatrate, 1);
573}
574if (dol_strlen($canvas) > 0) {
575 $sql .= " AND p.canvas = '".$db->escape($canvas)."'";
576}
577// Search for tag/category ($searchCategoryProductList is an array of ID)
578if (!empty($searchCategoryProductList)) {
579 $searchCategoryProductSqlList = array();
580 $listofcategoryid = '';
581 foreach ($searchCategoryProductList as $searchCategoryProduct) {
582 if (intval($searchCategoryProduct) == -2) {
583 $searchCategoryProductSqlList[] = "NOT EXISTS (SELECT ck.fk_product FROM ".MAIN_DB_PREFIX."categorie_product as ck WHERE p.rowid = ck.fk_product)";
584 } elseif (intval($searchCategoryProduct) > 0) {
585 if ($searchCategoryProductOperator == 0) {
586 $searchCategoryProductSqlList[] = " EXISTS (SELECT ck.fk_product FROM ".MAIN_DB_PREFIX."categorie_product as ck WHERE p.rowid = ck.fk_product AND ck.fk_categorie = ".((int) $searchCategoryProduct).")";
587 } else {
588 $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryProduct);
589 }
590 }
591 }
592 if ($listofcategoryid) {
593 $searchCategoryProductSqlList[] = " EXISTS (SELECT ck.fk_product FROM ".MAIN_DB_PREFIX."categorie_product as ck WHERE p.rowid = ck.fk_product AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))";
594 }
595 if ($searchCategoryProductOperator == 1) {
596 if (!empty($searchCategoryProductSqlList)) {
597 $sql .= " AND (".implode(' OR ', $searchCategoryProductSqlList).")";
598 }
599 } else {
600 if (!empty($searchCategoryProductSqlList)) {
601 $sql .= " AND (".implode(' AND ', $searchCategoryProductSqlList).")";
602 }
603 }
604}
605if ($fourn_id > 0) {
606 $sql .= " AND pfp.fk_soc = ".((int) $fourn_id);
607}
608if ($search_country) {
609 $sql .= " AND p.fk_country = ".((int) $search_country);
610}
611if ($search_state) {
612 $sql .= " AND p.fk_state = ".((int) $search_state);
613}
614if ($search_finished >= 0 && $search_finished !== '') {
615 $sql .= " AND p.finished = ".((int) $search_finished);
616}
617if ($search_accountancy_code_sell) {
618 $sql .= natural_search($alias_product_perentity . '.accountancy_code_sell', clean_account($search_accountancy_code_sell));
619}
620if ($search_accountancy_code_sell_intra) {
621 $sql .= natural_search($alias_product_perentity . '.accountancy_code_sell_intra', clean_account($search_accountancy_code_sell_intra));
622}
623if ($search_accountancy_code_sell_export) {
624 $sql .= natural_search($alias_product_perentity . '.accountancy_code_sell_export', clean_account($search_accountancy_code_sell_export));
625}
626if ($search_accountancy_code_buy) {
627 $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy', clean_account($search_accountancy_code_buy));
628}
629if ($search_accountancy_code_buy_intra) {
630 $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy_intra', clean_account($search_accountancy_code_buy_intra));
631}
632if ($search_accountancy_code_buy_export) {
633 $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy_export', clean_account($search_accountancy_code_buy_export));
634}
635if (getDolGlobalString('PRODUCT_USE_UNITS') && $search_units) {
636 $sql .= natural_search('cu.rowid', $search_units);
637}
638// Add where from extra fields
639include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
640// Add where from hooks
641$parameters = array();
642$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
643$sql .= $hookmanager->resPrint;
644$sql .= " GROUP BY p.rowid, p.ref, p.description, p.label, p.barcode, p.price, p.tva_tx, p.price_ttc, p.price_base_type,";
645$sql .= " p.fk_product_type, p.duration, p.finished, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock,";
646$sql .= ' p.datec, p.tms, p.entity, p.tobatch, p.pmp, p.cost_price, p.stock,';
647if (!getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
648 $sql .= " p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.accountancy_code_buy_intra, p.accountancy_code_buy_export,";
649} else {
650 $sql .= " ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export, ppe.accountancy_code_buy, ppe.accountancy_code_buy_intra, ppe.accountancy_code_buy_export,";
651}
652$sql .= ' p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units,';
653$sql .= ' p.fk_country, p.fk_state,';
654$sql .= ' p.import_key';
655if (getDolGlobalString('PRODUCT_USE_UNITS')) {
656 $sql .= ', p.fk_unit, cu.label';
657}
658if (isModEnabled('workstation')) {
659 $sql .= ', p.fk_default_workstation, ws.status, ws.ref';
660}
661if (isModEnabled('variants')) {
662 $sql .= ', pac.rowid';
663 $sql .= ', pac.fk_product_parent';
664}
665// Add fields from extrafields
666if (!empty($extrafields->attributes[$object->table_element]['label'])) {
667 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
668 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key : '');
669 }
670}
671// Add groupby from hooks
672$parameters = array();
673$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
674$sql .= $hookmanager->resPrint;
675//if (GETPOST("toolowstock")) $sql.= " HAVING SUM(s.reel) < p.seuil_stock_alerte"; // Not used yet
676
677$nbtotalofrecords = '';
678if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
679 /* The fast and low memory method to get and count full list converts the sql into a sql count */
680 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
681 $sqlforcount = preg_replace('/'.preg_quote($linktopfp, '/').'/', '', $sqlforcount);
682 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
683
684 $resql = $db->query($sqlforcount);
685 if ($resql) {
686 $objforcount = $db->fetch_object($resql);
687 $nbtotalofrecords = $objforcount->nbtotalofrecords;
688 } else {
689 dol_print_error($db);
690 }
691
692 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
693 $page = 0;
694 $offset = 0;
695 }
696 $db->free($resql);
697}
698
699// Complete request and execute it with limit
700$sql .= $db->order($sortfield, $sortorder);
701if ($limit) {
702 $sql .= $db->plimit($limit + 1, $offset);
703}
704
705$resql = $db->query($sql);
706if (!$resql) {
707 dol_print_error($db);
708 exit;
709}
710
711$num = $db->num_rows($resql);
712
713
714// Direct jump if only one record found
715if ($num == 1 && getDolGlobalString('MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE') && $search_all) {
716 $obj = $db->fetch_object($resql);
717 $id = $obj->rowid;
718 header("Location: ".DOL_URL_ROOT.'/product/card.php?id='.$id);
719 exit;
720}
721
722
723// Output page
724// --------------------------------------------------------------------
725
726$helpurl = '';
727if ($search_type != '') {
728 if ($search_type == 0) {
729 $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:M&oacute;dulo_Productos';
730 } elseif ($search_type == 1) {
731 $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios';
732 }
733}
734
735$paramsCat = '';
736foreach ($searchCategoryProductList as $searchCategoryProduct) {
737 $paramsCat .= "&search_category_product_list[]=".urlencode($searchCategoryProduct);
738}
739
740//llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, 'classforhorizontalscrolloftabs');
741llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, 'bodyforlist mod-product page-list');
742
743$arrayofselected = is_array($toselect) ? $toselect : array();
744
745// Displays product removal confirmation
746if (GETPOST('delprod')) {
747 setEventMessages($langs->trans("ProductDeleted", GETPOST('delprod')), null, 'mesgs');
748}
749
750$param = '';
751if (!empty($mode)) {
752 $param .= '&mode='.urlencode($mode);
753}
754if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
755 $param .= '&contextpage='.urlencode($contextpage);
756}
757if ($limit > 0 && $limit != $conf->liste_limit) {
758 $param .= '&limit='.((int) $limit);
759}
760if ($optioncss != '') {
761 $param .= '&optioncss='.urlencode($optioncss);
762}
763if ($search_all) {
764 $param .= "&search_all=".urlencode($search_all);
765}
766if ($searchCategoryProductOperator == 1) {
767 $param .= "&search_category_product_operator=".urlencode((string) ($searchCategoryProductOperator));
768}
769foreach ($searchCategoryProductList as $searchCategoryProduct) {
770 $param .= "&search_category_product_list[]=".urlencode($searchCategoryProduct);
771}
772if ($search_ref) {
773 $param .= "&search_ref=".urlencode($search_ref);
774}
775if ($search_ref_supplier) {
776 $param .= "&search_ref_supplier=".urlencode($search_ref_supplier);
777}
778if ($search_barcode) {
779 $param .= ($search_barcode ? "&search_barcode=".urlencode($search_barcode) : "");
780}
781if ($search_import_key) {
782 $param .= "&search_import_key=".urlencode($search_import_key);
783}
784if ($search_label) {
785 $param .= "&search_label=".urlencode($search_label);
786}
787if ($search_default_workstation) {
788 $param .= "&search_default_workstation=".urlencode($search_default_workstation);
789}
790if ($search_tosell != '') {
791 $param .= "&search_tosell=".urlencode($search_tosell);
792}
793if ($search_tobuy != '') {
794 $param .= "&search_tobuy=".urlencode($search_tobuy);
795}
796if ($search_tobatch) {
797 $param .= "&search_tobatch=".urlencode($search_tobatch);
798}
799if ($search_country != '') {
800 $param .= "&search_country=".urlencode((string) ($search_country));
801}
802if ($search_state != '') {
803 $param .= "&search_state=".urlencode((string) ($search_state));
804}
805if ($search_vatrate) {
806 $param .= "&search_vatrate=".urlencode($search_vatrate);
807}
808if ($fourn_id > 0) {
809 $param .= "&fourn_id=".urlencode((string) ($fourn_id));
810}
811if ($show_childproducts) {
812 $param .= ($show_childproducts ? "&search_show_childproducts=".urlencode($show_childproducts) : "");
813}
814if ($type != '') {
815 $param .= '&type='.urlencode((string) ($type));
816}
817if ($search_type != '') {
818 $param .= '&search_type='.urlencode($search_type);
819}
820if ($search_accountancy_code_sell) {
821 $param .= "&search_accountancy_code_sell=".urlencode($search_accountancy_code_sell);
822}
823if ($search_accountancy_code_sell_intra) {
824 $param .= "&search_accountancy_code_sell_intra=".urlencode($search_accountancy_code_sell_intra);
825}
826if ($search_accountancy_code_sell_export) {
827 $param .= "&search_accountancy_code_sell_export=".urlencode($search_accountancy_code_sell_export);
828}
829if ($search_accountancy_code_buy) {
830 $param .= "&search_accountancy_code_buy=".urlencode($search_accountancy_code_buy);
831}
832if ($search_accountancy_code_buy_intra) {
833 $param .= "&search_accountancy_code_buy_intra=".urlencode($search_accountancy_code_buy_intra);
834}
835if ($search_accountancy_code_buy_export) {
836 $param .= "&search_accountancy_code_buy_export=".urlencode($search_accountancy_code_buy_export);
837}
838if ($search_finished) {
839 $param .= "&search_finished=".urlencode($search_finished);
840}
841// Add $param from extra fields
842include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
843
844// Add $param from hooks
845$parameters = array('param' => &$param);
846$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
847$param .= $hookmanager->resPrint;
848
849// List of mass actions available
850$arrayofmassactions = array(
851 'generate_doc' => img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
852 'edit_extrafields' => img_picto('', 'edit', 'class="pictofixedwidth"').$langs->trans("ModifyValueExtrafields"),
853 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
854 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
855);
856if ($user->hasRight($rightskey, 'creer')) {
857 $arrayofmassactions['preupdateprice'] = img_picto('', 'edit', 'class="pictofixedwidth"').$langs->trans("UpdatePrice");
858 $arrayofmassactions['switchonsalestatus'] = img_picto('', 'stop-circle', 'class="pictofixedwidth"').$langs->trans("SwitchOnSaleStatus");
859 $arrayofmassactions['switchonpurchasestatus'] = img_picto('', 'stop-circle', 'class="pictofixedwidth"').$langs->trans("SwitchOnPurchaseStatus");
860}
861if (isModEnabled('category') && $user->hasRight($rightskey, 'creer')) {
862 $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
863}
864if (in_array($massaction, array('presend', 'predelete','preaffecttag', 'edit_extrafields', 'preupdateprice'))) {
865 $arrayofmassactions = array();
866}
867if ($user->hasRight($rightskey, 'supprimer')) {
868 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
869}
870$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
871
872$newcardbutton = '';
873$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss' => 'reposition'));
874$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss' => 'reposition'));
875
876if ($type === "") {
877 $perm = ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer'));
878} elseif ($type == Product::TYPE_SERVICE) {
879 $perm = $user->hasRight('service', 'creer');
880} elseif ($type == Product::TYPE_PRODUCT) {
881 $perm = $user->hasRight('produit', 'creer');
882}
883$oldtype = $type;
884$params = array();
885if ($type === "") {
886 $params['forcenohideoftext'] = 1;
887}
888$newcardbutton .= dolGetButtonTitleSeparator();
889if ((isModEnabled('product') && $type === "") || $type == Product::TYPE_PRODUCT) {
890 $label = 'NewProduct';
891 $newcardbutton .= dolGetButtonTitle($langs->trans($label), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/product/card.php?action=create&type=0', '', $perm, $params);
892}
893if ((isModEnabled('service') && $type === "") || $type == Product::TYPE_SERVICE) {
894 $label = 'NewService';
895 $newcardbutton .= dolGetButtonTitle($langs->trans($label), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/product/card.php?action=create&type=1', '', $perm, $params);
896}
897
898print '<form id="searchFormList" action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire">';
899if ($optioncss != '') {
900 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
901}
902print '<input type="hidden" name="token" value="'.newToken().'">';
903print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
904print '<input type="hidden" name="action" value="list">';
905print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
906print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
907//print '<input type="hidden" name="page" value="'.$page.'">';
908print '<input type="hidden" name="type" value="'.$type.'">';
909print '<input type="hidden" name="page_y" value="">';
910print '<input type="hidden" name="mode" value="'.$mode.'">';
911
912if (empty($arrayfields['p.fk_product_type']['checked'])) {
913 print '<input type="hidden" name="search_type" value="'.dol_escape_htmltag($search_type).'">';
914}
915
916$picto = 'product';
917if ($type == 1) {
918 $picto = 'service';
919}
920
921print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
922
923$topicmail = "Information";
924$modelmail = "product";
925$objecttmp = new Product($db);
926$trackid = 'prod'.$object->id;
927include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
928
929if (!empty($catid)) {
930 print "<div id='ways'>";
931 $c = new Categorie($db);
932 $ways = $c->print_all_ways(' &gt; ', 'product/list.php');
933 print " &gt; ".$ways[0]."<br>\n";
934 print "</div><br>";
935}
936
937if ($search_all) {
938 $setupstring = '';
939 foreach ($fieldstosearchall as $key => $val) {
940 $fieldstosearchall[$key] = $langs->trans($val);
941 $setupstring .= $key."=".$val.";";
942 }
943 print '<!-- Search done like if PRODUCT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
944 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).implode(', ', $fieldstosearchall).'</div>'."\n";
945}
946
947// Filter on categories
948$moreforfilter = '';
949if (isModEnabled('category') && $user->hasRight('categorie', 'read')) {
950 $formcategory = new FormCategory($db);
951 $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_PRODUCT, $searchCategoryProductList, 'minwidth300', $searchCategoryProductOperator ? $searchCategoryProductOperator : 0);
952}
953
954// Show/hide child variant products
955if (isModEnabled('variants')) {
956 $moreforfilter .= '<div class="divsearchfield">';
957 $moreforfilter .= '<input type="checkbox" id="search_show_childproducts" name="search_show_childproducts"'.($show_childproducts ? 'checked="checked"' : '').'>';
958 $moreforfilter .= ' <label for="search_show_childproducts">'.$langs->trans('ShowChildProducts').'</label>';
959 $moreforfilter .= '</div>';
960}
961
962$parameters = array();
963$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
964if (empty($reshook)) {
965 $moreforfilter .= $hookmanager->resPrint;
966} else {
967 $moreforfilter = $hookmanager->resPrint;
968}
969
970if (!empty($moreforfilter)) {
971 print '<div class="liste_titre liste_titre_bydiv centpercent">';
972 print $moreforfilter;
973 print '</div>';
974}
975
976$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
977$htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields with user setup
978$selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
979$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
980
981print '<div class="div-table-responsive">';
982print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
983
984// Fields title search
985// --------------------------------------------------------------------
986print '<tr class="liste_titre_filter">';
987// Action column
988if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
989 print '<td class="liste_titre center maxwidthsearch">';
990 $searchpicto = $form->showFilterButtons('left');
991 print $searchpicto;
992 print '</td>';
993}
994if (!empty($arrayfields['p.rowid']['checked'])) {
995 print '<td class="liste_titre left">';
996 print '<input class="flat" type="text" name="search_id" size="4" value="'.dol_escape_htmltag($search_id).'">';
997 print '</td>';
998}
999if (!empty($arrayfields['p.ref']['checked'])) {
1000 print '<td class="liste_titre left">';
1001 print '<input class="flat" type="text" name="search_ref" size="8" value="'.dol_escape_htmltag($search_ref).'">';
1002 print '</td>';
1003}
1004if (!empty($arrayfields['pfp.ref_fourn']['checked'])) {
1005 print '<td class="liste_titre left">';
1006 print '<input class="flat" type="text" name="search_ref_supplier" size="8" value="'.dol_escape_htmltag($search_ref_supplier).'">';
1007 print '</td>';
1008}
1009// Thumbnail
1010if (!empty($arrayfields['thumbnail']['checked'])) {
1011 print '<td class="liste_titre center">';
1012 print '</td>';
1013}
1014if (!empty($arrayfields['p.label']['checked'])) {
1015 print '<td class="liste_titre left">';
1016 print '<input class="flat width100" type="text" name="search_label" value="'.dol_escape_htmltag($search_label).'">';
1017 print '</td>';
1018}
1019// Type
1020if (!empty($arrayfields['p.fk_product_type']['checked'])) {
1021 print '<td class="liste_titre center">';
1022 $array = array('-1' => '&nbsp;', '0' => $langs->trans('Product'), '1' => $langs->trans('Service'));
1023 print $form->selectarray('search_type', $array, $search_type);
1024 print '</td>';
1025}
1026// Description
1027if (!empty($arrayfields['p.description']['checked'])) {
1028 print '<td class="liste_titre left">';
1029 print '</td>';
1030}
1031// Barcode
1032if (!empty($arrayfields['p.barcode']['checked'])) {
1033 print '<td class="liste_titre">';
1034 print '<input class="flat" type="text" name="search_barcode" size="6" value="'.dol_escape_htmltag($search_barcode).'">';
1035 print '</td>';
1036}
1037// Duration
1038if (!empty($arrayfields['p.duration']['checked'])) {
1039 print '<td class="liste_titre">';
1040 print '</td>';
1041}
1042// Parent
1043if (!empty($arrayfields['pac.fk_product_parent']['checked'])) {
1044 print '<td class="liste_titre">';
1045 print '</td>';
1046}
1047// Finished
1048if (!empty($arrayfields['p.finished']['checked'])) {
1049 print '<td class="liste_titre">';
1050 print $formproduct->selectProductNature('search_finished', $search_finished);
1051 print '</td>';
1052}
1053// Weight
1054if (!empty($arrayfields['p.weight']['checked'])) {
1055 print '<td class="liste_titre">';
1056 print '</td>';
1057}
1058// Weight units
1059if (!empty($arrayfields['p.weight_units']['checked'])) {
1060 print '<td class="liste_titre">';
1061 print '</td>';
1062}
1063// Length
1064if (!empty($arrayfields['p.length']['checked'])) {
1065 print '<td class="liste_titre">';
1066 print '</td>';
1067}
1068// Length units
1069if (!empty($arrayfields['p.length_units']['checked'])) {
1070 print '<td class="liste_titre">';
1071 print '</td>';
1072}
1073// Width
1074if (!empty($arrayfields['p.width']['checked'])) {
1075 print '<td class="liste_titre">';
1076 print '</td>';
1077}
1078// Width units
1079if (!empty($arrayfields['p.width_units']['checked'])) {
1080 print '<td class="liste_titre">';
1081 print '</td>';
1082}
1083// Height
1084if (!empty($arrayfields['p.height']['checked'])) {
1085 print '<td class="liste_titre">';
1086 print '</td>';
1087}
1088// Height units
1089if (!empty($arrayfields['p.height_units']['checked'])) {
1090 print '<td class="liste_titre">';
1091 print '</td>';
1092}
1093// Surface
1094if (!empty($arrayfields['p.surface']['checked'])) {
1095 print '<td class="liste_titre">';
1096 print '</td>';
1097}
1098// Surface units
1099if (!empty($arrayfields['p.surface_units']['checked'])) {
1100 print '<td class="liste_titre">';
1101 print '</td>';
1102}
1103// Volume
1104if (!empty($arrayfields['p.volume']['checked'])) {
1105 print '<td class="liste_titre">';
1106 print '</td>';
1107}
1108// Volume units
1109if (!empty($arrayfields['p.volume_units']['checked'])) {
1110 print '<td class="liste_titre">';
1111 print '</td>';
1112}
1113
1114// Unit
1115if (!empty($arrayfields['cu.label']['checked'])) {
1116 print '<td class="liste_titre">';
1117 print $form->selectUnits($search_units, 'search_units', 1);
1118 print '</td>';
1119}
1120
1121// Default workstation
1122if (!empty($arrayfields['p.fk_default_workstation']['checked'])) {
1123 print '<td class="liste_titre">';
1124 print '<input class="flat width75" type="text" name="search_default_workstation" value="'.dol_escape_htmltag($search_default_workstation).'">';
1125 print '</td>';
1126}
1127
1128// Sell price
1129if (!empty($arrayfields['p.sellprice']['checked'])) {
1130 print '<td class="liste_titre right">';
1131 print '</td>';
1132}
1133
1134// Multiprice
1135if (getDolGlobalString('PRODUIT_MULTIPRICES')) {
1136 foreach ($arraypricelevel as $key => $value) {
1137 if (!empty($arrayfields['p.sellprice'.$key]['checked'])) {
1138 print '<td class="liste_titre right">';
1139 print '</td>';
1140 }
1141 }
1142}
1143
1144// Minimum buying Price
1145if (!empty($arrayfields['p.minbuyprice']['checked'])) {
1146 print '<td class="liste_titre">';
1147 print '&nbsp;';
1148 print '</td>';
1149}
1150// Number buying Price
1151if (!empty($arrayfields['p.numbuyprice']['checked'])) {
1152 print '<td class="liste_titre">';
1153 print '&nbsp;';
1154 print '</td>';
1155}
1156// VAT or Sell Tax Rate
1157if (!empty($arrayfields['p.tva_tx']['checked'])) {
1158 print '<td class="liste_titre right">';
1159 print '<input class="right flat maxwidth50" placeholder="%" type="text" name="search_vatrate" size="1" value="'.dol_escape_htmltag($search_vatrate).'">';
1160 print '</td>';
1161}
1162// WAP
1163if (!empty($arrayfields['p.pmp']['checked'])) {
1164 print '<td class="liste_titre">';
1165 print '&nbsp;';
1166 print '</td>';
1167}
1168// cost_price
1169if (!empty($arrayfields['p.cost_price']['checked'])) {
1170 print '<td class="liste_titre">';
1171 print '&nbsp;';
1172 print '</td>';
1173}
1174// Limit for alert
1175if (!empty($arrayfields['p.seuil_stock_alerte']['checked'])) {
1176 print '<td class="liste_titre">';
1177 print '&nbsp;';
1178 print '</td>';
1179}
1180// Desired stock
1181if (!empty($arrayfields['p.desiredstock']['checked'])) {
1182 print '<td class="liste_titre">';
1183 print '&nbsp;';
1184 print '</td>';
1185}
1186// Stock
1187if (!empty($arrayfields['p.stock']['checked'])) {
1188 print '<td class="liste_titre">&nbsp;</td>';
1189}
1190// Stock
1191if (!empty($arrayfields['stock_virtual']['checked'])) {
1192 print '<td class="liste_titre">&nbsp;</td>';
1193}
1194// To batch
1195if (!empty($arrayfields['p.tobatch']['checked'])) {
1196 print '<td class="liste_titre center">';
1197 $statutarray = array(
1198 '-1' => '',
1199 '0' => $langs->trans("ProductStatusNotOnBatchShort"),
1200 '1' => $langs->trans("ProductStatusOnBatchShort"),
1201 '2' => $langs->trans("ProductStatusOnSerialShort")
1202 );
1203 print $form->selectarray('search_tobatch', $statutarray, $search_tobatch);
1204 print '</td>';
1205}
1206// Country
1207if (!empty($arrayfields['p.fk_country']['checked'])) {
1208 print '<td class="liste_titre center">';
1209 print $form->select_country($search_country, 'search_country', '', 0);
1210 print '</td>';
1211}
1212// State
1213if (!empty($arrayfields['p.fk_state']['checked'])) {
1214 print '<td class="liste_titre center">';
1215 print $formcompany->select_state($search_state, $search_country);
1216 print '</td>';
1217}
1218// Accountancy code sell
1219if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell']['checked'])) {
1220 print '<td class="liste_titre"><input class="flat maxwidth75" type="text" name="search_accountancy_code_sell" value="'.dol_escape_htmltag($search_accountancy_code_sell).'"></td>';
1221}
1222if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_intra']['checked'])) {
1223 print '<td class="liste_titre"><input class="flat maxwidth75" type="text" name="search_accountancy_code_sell_intra" value="'.dol_escape_htmltag($search_accountancy_code_sell_intra).'"></td>';
1224}
1225if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_export']['checked'])) {
1226 print '<td class="liste_titre"><input class="flat maxwidth75" type="text" name="search_accountancy_code_sell_export" value="'.dol_escape_htmltag($search_accountancy_code_sell_export).'"></td>';
1227}
1228// Accountancy code buy
1229if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy']['checked'])) {
1230 print '<td class="liste_titre"><input class="flat maxwidth75" type="text" name="search_accountancy_code_buy" value="'.dol_escape_htmltag($search_accountancy_code_buy).'"></td>';
1231}
1232if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_intra']['checked'])) {
1233 print '<td class="liste_titre"><input class="flat maxwidth75" type="text" name="search_accountancy_code_buy_intra" value="'.dol_escape_htmltag($search_accountancy_code_buy_intra).'"></td>';
1234}
1235if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_export']['checked'])) {
1236 print '<td class="liste_titre"><input class="flat maxwidth75" type="text" name="search_accountancy_code_buy_export" value="'.dol_escape_htmltag($search_accountancy_code_buy_export).'"></td>';
1237}
1238// Extra fields
1239include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
1240// Fields from hook
1241$parameters = array('arrayfields' => $arrayfields);
1242$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1243print $hookmanager->resPrint;
1244// Date creation
1245if (!empty($arrayfields['p.datec']['checked'])) {
1246 print '<td class="liste_titre">';
1247 print '</td>';
1248}
1249// Date modification
1250if (!empty($arrayfields['p.tms']['checked'])) {
1251 print '<td class="liste_titre">';
1252 print '</td>';
1253}
1254if (!empty($arrayfields['p.import_key']['checked'])) {
1255 print '<td class="liste_titre center">';
1256 print '<input class="flat maxwidth75" type="text" name="search_import_key" value="'.dol_escape_htmltag($search_import_key).'">';
1257 print '</td>';
1258}
1259if (!empty($arrayfields['p.tosell']['checked'])) {
1260 print '<td class="liste_titre center parentonrightofpage">';
1261 print $form->selectarray('search_tosell', array('0' => $langs->trans('ProductStatusNotOnSellShort'), '1' => $langs->trans('ProductStatusOnSellShort')), $search_tosell, 1, 0, 0, '', 0, 0, 0, '', 'search_status width100 onrightofpage');
1262 print '</td>';
1263}
1264if (!empty($arrayfields['p.tobuy']['checked'])) {
1265 print '<td class="liste_titre center parentonrightofpage">';
1266 print $form->selectarray('search_tobuy', array('0' => $langs->trans('ProductStatusNotOnBuyShort'), '1' => $langs->trans('ProductStatusOnBuyShort')), $search_tobuy, 1, 0, 0, '', 0, 0, 0, '', 'search_status width100 onrightofpage');
1267 print '</td>';
1268}
1269// Action column
1270if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1271 print '<td class="liste_titre center maxwidthsearch">';
1272 $searchpicto = $form->showFilterButtons();
1273 print $searchpicto;
1274 print '</td>';
1275}
1276print '</tr>'."\n";
1277
1278$totalarray = array();
1279$totalarray['nbfield'] = 0;
1280
1281// Fields title label
1282// --------------------------------------------------------------------
1283print '<tr class="liste_titre">';
1284// Action column
1285if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1286 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1287 $totalarray['nbfield']++;
1288}
1289if (!empty($arrayfields['p.rowid']['checked'])) {
1290 print_liste_field_titre($arrayfields['p.rowid']['label'], $_SERVER["PHP_SELF"], "p.rowid", "", $param, "", $sortfield, $sortorder);
1291 $totalarray['nbfield']++;
1292}
1293if (!empty($arrayfields['p.ref']['checked'])) {
1294 print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, "", $sortfield, $sortorder);
1295 $totalarray['nbfield']++;
1296}
1297if (!empty($arrayfields['pfp.ref_fourn']['checked'])) {
1298 print_liste_field_titre($arrayfields['pfp.ref_fourn']['label'], $_SERVER["PHP_SELF"], "pfp.ref_fourn", "", $param, "", $sortfield, $sortorder);
1299 $totalarray['nbfield']++;
1300}
1301if (!empty($arrayfields['thumbnail']['checked'])) {
1302 print_liste_field_titre($arrayfields['thumbnail']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ');
1303 $totalarray['nbfield']++;
1304}
1305if (!empty($arrayfields['p.label']['checked'])) {
1306 print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"], "p.label", "", $param, "", $sortfield, $sortorder);
1307 $totalarray['nbfield']++;
1308}
1309if (!empty($arrayfields['p.fk_product_type']['checked'])) {
1310 // @phan-suppress-next-line PhanTypeInvalidDimOffset
1311 print_liste_field_titre($arrayfields['p.fk_product_type']['label'], $_SERVER["PHP_SELF"], "p.fk_product_type", "", $param, "", $sortfield, $sortorder, 'center ');
1312 $totalarray['nbfield']++;
1313}
1314if (!empty($arrayfields['p.description']['checked'])) {
1315 print_liste_field_titre($arrayfields['p.description']['label'], $_SERVER["PHP_SELF"], "p.description", "", $param, "", $sortfield, $sortorder);
1316 $totalarray['nbfield']++;
1317}
1318if (!empty($arrayfields['p.barcode']['checked'])) {
1319 print_liste_field_titre($arrayfields['p.barcode']['label'], $_SERVER["PHP_SELF"], "p.barcode", "", $param, "", $sortfield, $sortorder);
1320 $totalarray['nbfield']++;
1321}
1322if (!empty($arrayfields['p.duration']['checked'])) {
1323 print_liste_field_titre($arrayfields['p.duration']['label'], $_SERVER["PHP_SELF"], "p.duration", "", $param, '', $sortfield, $sortorder, 'center ');
1324 $totalarray['nbfield']++;
1325}
1326if (!empty($arrayfields['pac.fk_product_parent']['checked'])) {
1327 print_liste_field_titre($arrayfields['pac.fk_product_parent']['label'], $_SERVER["PHP_SELF"], "pac.fk_product_parent", "", $param, '', $sortfield, $sortorder, '', empty($arrayfields['pac.fk_product_parent']['help']) ? '' : $arrayfields['pac.fk_product_parent']['help']);
1328 $totalarray['nbfield']++;
1329}
1330if (!empty($arrayfields['p.finished']['checked'])) {
1331 print_liste_field_titre($arrayfields['p.finished']['label'], $_SERVER["PHP_SELF"], "p.finished", "", $param, '', $sortfield, $sortorder, 'center ');
1332 $totalarray['nbfield']++;
1333}
1334if (!empty($arrayfields['p.weight']['checked'])) {
1335 print_liste_field_titre($arrayfields['p.weight']['label'], $_SERVER['PHP_SELF'], 'p.weight', '', $param, '', $sortfield, $sortorder, 'center ');
1336 $totalarray['nbfield']++;
1337}
1338if (!empty($arrayfields['p.weight_units']['checked'])) {
1339 print_liste_field_titre($arrayfields['p.weight_units']['label'], $_SERVER['PHP_SELF'], 'p.weight_units', '', $param, '', $sortfield, $sortorder, 'center ');
1340 $totalarray['nbfield']++;
1341}
1342if (!empty($arrayfields['p.length']['checked'])) {
1343 print_liste_field_titre($arrayfields['p.length']['label'], $_SERVER['PHP_SELF'], 'p.length', '', $param, '', $sortfield, $sortorder, 'center ');
1344 $totalarray['nbfield']++;
1345}
1346if (!empty($arrayfields['p.length_units']['checked'])) {
1347 print_liste_field_titre($arrayfields['p.length_units']['label'], $_SERVER['PHP_SELF'], 'p.length_units', '', $param, '', $sortfield, $sortorder, 'center ');
1348 $totalarray['nbfield']++;
1349}
1350if (!empty($arrayfields['p.width']['checked'])) {
1351 print_liste_field_titre($arrayfields['p.width']['label'], $_SERVER['PHP_SELF'], 'p.width', '', $param, '', $sortfield, $sortorder, 'center ');
1352 $totalarray['nbfield']++;
1353}
1354if (!empty($arrayfields['p.width_units']['checked'])) {
1355 print_liste_field_titre($arrayfields['p.width_units']['label'], $_SERVER['PHP_SELF'], 'p.width_units', '', $param, '', $sortfield, $sortorder, 'center ');
1356 $totalarray['nbfield']++;
1357}
1358if (!empty($arrayfields['p.height']['checked'])) {
1359 print_liste_field_titre($arrayfields['p.height']['label'], $_SERVER['PHP_SELF'], 'p.height', '', $param, '', $sortfield, $sortorder, 'center ');
1360 $totalarray['nbfield']++;
1361}
1362if (!empty($arrayfields['p.height_units']['checked'])) {
1363 print_liste_field_titre($arrayfields['p.height_units']['label'], $_SERVER['PHP_SELF'], 'p.height_units', '', $param, '', $sortfield, $sortorder, 'center ');
1364 $totalarray['nbfield']++;
1365}
1366if (!empty($arrayfields['p.surface']['checked'])) {
1367 print_liste_field_titre($arrayfields['p.surface']['label'], $_SERVER['PHP_SELF'], "p.surface", '', $param, '', $sortfield, $sortorder, 'center ');
1368 $totalarray['nbfield']++;
1369}
1370if (!empty($arrayfields['p.surface_units']['checked'])) {
1371 print_liste_field_titre($arrayfields['p.surface_units']['label'], $_SERVER['PHP_SELF'], 'p.surface_units', '', $param, '', $sortfield, $sortorder, 'center ');
1372 $totalarray['nbfield']++;
1373}
1374if (!empty($arrayfields['p.volume']['checked'])) {
1375 print_liste_field_titre($arrayfields['p.volume']['label'], $_SERVER['PHP_SELF'], 'p.volume', '', $param, '', $sortfield, $sortorder, 'center ');
1376 $totalarray['nbfield']++;
1377}
1378if (!empty($arrayfields['p.volume_units']['checked'])) {
1379 print_liste_field_titre($arrayfields['p.volume_units']['label'], $_SERVER['PHP_SELF'], 'p.volume_units', '', $param, '', $sortfield, $sortorder, 'center ');
1380 $totalarray['nbfield']++;
1381}
1382if (!empty($arrayfields['cu.label']['checked'])) {
1383 print_liste_field_titre($arrayfields['cu.label']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'center ');
1384 $totalarray['nbfield']++;
1385}
1386if (!empty($arrayfields['p.fk_default_workstation']['checked'])) {
1387 print_liste_field_titre($arrayfields['p.fk_default_workstation']['label'], $_SERVER['PHP_SELF'], 'ws.ref', '', $param, '', $sortfield, $sortorder);
1388 $totalarray['nbfield']++;
1389}
1390if (!empty($arrayfields['p.sellprice']['checked'])) {
1391 print_liste_field_titre($arrayfields['p.sellprice']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1392 $totalarray['nbfield']++;
1393}
1394
1395// Multiprices
1396if (getDolGlobalString('PRODUIT_MULTIPRICES')) {
1397 foreach ($arraypricelevel as $key => $value) {
1398 if (!empty($arrayfields['p.sellprice'.$key]['checked'])) {
1399 print_liste_field_titre($arrayfields['p.sellprice'.$key]['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1400 $totalarray['nbfield']++;
1401 }
1402 }
1403}
1404
1405if (!empty($arrayfields['p.minbuyprice']['checked'])) {
1406 print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1407 $totalarray['nbfield']++;
1408}
1409if (!empty($arrayfields['p.numbuyprice']['checked'])) {
1410 print_liste_field_titre($arrayfields['p.numbuyprice']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1411 $totalarray['nbfield']++;
1412}
1413if (!empty($arrayfields['p.tva_tx']['checked'])) {
1414 print_liste_field_titre($arrayfields['p.tva_tx']['label'], $_SERVER["PHP_SELF"], 'p.tva_tx', "", $param, '', $sortfield, $sortorder, 'right ');
1415 $totalarray['nbfield']++;
1416}
1417if (!empty($arrayfields['p.pmp']['checked'])) {
1418 print_liste_field_titre($arrayfields['p.pmp']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1419 $totalarray['nbfield']++;
1420}
1421if (!empty($arrayfields['p.cost_price']['checked'])) {
1422 print_liste_field_titre($arrayfields['p.cost_price']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1423 $totalarray['nbfield']++;
1424}
1425if (!empty($arrayfields['p.seuil_stock_alerte']['checked'])) {
1426 print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"], "p.seuil_stock_alerte", "", $param, '', $sortfield, $sortorder, 'right ');
1427 $totalarray['nbfield']++;
1428}
1429if (!empty($arrayfields['p.desiredstock']['checked'])) {
1430 print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"], "p.desiredstock", "", $param, '', $sortfield, $sortorder, 'right ');
1431 $totalarray['nbfield']++;
1432}
1433if (!empty($arrayfields['p.stock']['checked'])) {
1434 print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"], "p.stock", "", $param, '', $sortfield, $sortorder, 'right ');
1435 $totalarray['nbfield']++;
1436}
1437if (!empty($arrayfields['stock_virtual']['checked'])) {
1438 print_liste_field_titre($arrayfields['stock_virtual']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ', 'VirtualStockDesc');
1439 $totalarray['nbfield']++;
1440}
1441if (!empty($arrayfields['p.tobatch']['checked'])) {
1442 print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"], "p.tobatch", "", $param, '', $sortfield, $sortorder, 'center ');
1443 $totalarray['nbfield']++;
1444}
1445if (!empty($arrayfields['p.fk_country']['checked'])) {
1446 print_liste_field_titre($arrayfields['p.fk_country']['label'], $_SERVER["PHP_SELF"], "p.fk_country", "", $param, '', $sortfield, $sortorder);
1447 $totalarray['nbfield']++;
1448}
1449if (!empty($arrayfields['p.fk_state']['checked'])) {
1450 print_liste_field_titre($arrayfields['p.fk_state']['label'], $_SERVER["PHP_SELF"], "p.fk_state", "", $param, '', $sortfield, $sortorder);
1451 $totalarray['nbfield']++;
1452}
1453if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell']['checked'])) {
1454 print_liste_field_titre($arrayfields[$alias_product_perentity . '.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"], $alias_product_perentity . ".accountancy_code_sell", "", $param, '', $sortfield, $sortorder);
1455 $totalarray['nbfield']++;
1456}
1457if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_intra']['checked'])) {
1458 print_liste_field_titre($arrayfields[$alias_product_perentity . '.accountancy_code_sell_intra']['label'], $_SERVER["PHP_SELF"], $alias_product_perentity . ".accountancy_code_sell_intra", "", $param, '', $sortfield, $sortorder);
1459 $totalarray['nbfield']++;
1460}
1461if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_export']['checked'])) {
1462 print_liste_field_titre($arrayfields[$alias_product_perentity . '.accountancy_code_sell_export']['label'], $_SERVER["PHP_SELF"], $alias_product_perentity . ".accountancy_code_sell_export", "", $param, '', $sortfield, $sortorder);
1463 $totalarray['nbfield']++;
1464}
1465if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy']['checked'])) {
1466 print_liste_field_titre($arrayfields[$alias_product_perentity . '.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"], $alias_product_perentity . ".accountancy_code_buy", "", $param, '', $sortfield, $sortorder);
1467 $totalarray['nbfield']++;
1468}
1469if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_intra']['checked'])) {
1470 print_liste_field_titre($arrayfields[$alias_product_perentity . '.accountancy_code_buy_intra']['label'], $_SERVER["PHP_SELF"], $alias_product_perentity . ".accountancy_code_buy_intra", "", $param, '', $sortfield, $sortorder);
1471 $totalarray['nbfield']++;
1472}
1473if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_export']['checked'])) {
1474 print_liste_field_titre($arrayfields[$alias_product_perentity . '.accountancy_code_buy_export']['label'], $_SERVER["PHP_SELF"], $alias_product_perentity . ".accountancy_code_buy_export", "", $param, '', $sortfield, $sortorder);
1475 $totalarray['nbfield']++;
1476}
1477// Extra fields
1478include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1479// Hook fields
1480$parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray);
1481$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1482print $hookmanager->resPrint;
1483if (!empty($arrayfields['p.datec']['checked'])) {
1484 print_liste_field_titre($arrayfields['p.datec']['label'], $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1485 $totalarray['nbfield']++;
1486}
1487if (!empty($arrayfields['p.tms']['checked'])) {
1488 print_liste_field_titre($arrayfields['p.tms']['label'], $_SERVER["PHP_SELF"], "p.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1489 $totalarray['nbfield']++;
1490}
1491if (!empty($arrayfields['p.import_key']['checked'])) {
1492 print_liste_field_titre($arrayfields['p.import_key']['label'], $_SERVER["PHP_SELF"], "p.import_key", "", $param, '', $sortfield, $sortorder, 'center ');
1493 $totalarray['nbfield']++;
1494}
1495if (!empty($arrayfields['p.tosell']['checked'])) {
1496 print_liste_field_titre($arrayfields['p.tosell']['label'], $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center ');
1497 $totalarray['nbfield']++;
1498}
1499if (!empty($arrayfields['p.tobuy']['checked'])) {
1500 print_liste_field_titre($arrayfields['p.tobuy']['label'], $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'center ');
1501 $totalarray['nbfield']++;
1502}
1503// Action column
1504if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1505 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1506 $totalarray['nbfield']++;
1507}
1508print '</tr>'."\n";
1509
1510
1511// Loop on record
1512// --------------------------------------------------------------------
1513$i = 0;
1514$savnbfield = $totalarray['nbfield'];
1515$totalarray = array();
1516$totalarray['nbfield'] = 0;
1517$imaxinloop = ($limit ? min($num, $limit) : $num);
1518while ($i < $imaxinloop) {
1519 $obj = $db->fetch_object($resql);
1520 if (empty($obj)) {
1521 break; // Should not happen
1522 }
1523
1524 // Multilangs
1525 if (getDolGlobalInt('MAIN_MULTILANGS')) { // If multilang is enabled
1526 $sql = "SELECT label";
1527 $sql .= " FROM ".MAIN_DB_PREFIX."product_lang";
1528 $sql .= " WHERE fk_product = ".((int) $obj->rowid);
1529 $sql .= " AND lang = '".$db->escape($langs->getDefaultLang())."'";
1530 $sql .= " LIMIT 1";
1531
1532 $result = $db->query($sql);
1533 if ($result) {
1534 $objtp = $db->fetch_object($result);
1535 if (!empty($objtp->label)) {
1536 $obj->label = $objtp->label;
1537 }
1538 }
1539 }
1540
1541 $parameters = array('staticdata' => $obj);
1542 // Note that $action and $object may have been modified by hook
1543 // do product_static fetch in hook if wanted or anything else
1544 $reshook = $hookmanager->executeHooks('loadStaticObject', $parameters, $product_static, $action);
1545 if (empty($reshook)) {
1546 $product_static->id = $obj->rowid;
1547 $product_static->ref = $obj->ref;
1548 $product_static->description = $obj->description;
1549 $product_static->ref_fourn = empty($obj->ref_supplier) ? '' : $obj->ref_supplier; // deprecated
1550 $product_static->ref_supplier = empty($obj->ref_supplier) ? '' : $obj->ref_supplier;
1551 $product_static->label = $obj->label;
1552 $product_static->barcode = $obj->barcode;
1553 $product_static->finished = $obj->finished;
1554 $product_static->type = $obj->fk_product_type;
1555 $product_static->status_buy = $obj->tobuy;
1556 $product_static->status = $obj->tosell;
1557 $product_static->status_batch = $obj->tobatch;
1558 $product_static->entity = $obj->entity;
1559 $product_static->pmp = $obj->pmp;
1560 $product_static->accountancy_code_sell = $obj->accountancy_code_sell;
1561 $product_static->accountancy_code_sell_export = $obj->accountancy_code_sell_export;
1562 $product_static->accountancy_code_sell_intra = $obj->accountancy_code_sell_intra;
1563 $product_static->accountancy_code_buy = $obj->accountancy_code_buy;
1564 $product_static->accountancy_code_buy_intra = $obj->accountancy_code_buy_intra;
1565 $product_static->accountancy_code_buy_export = $obj->accountancy_code_buy_export;
1566 $product_static->length = $obj->length;
1567 $product_static->length_units = $obj->length_units;
1568 $product_static->width = $obj->width;
1569 $product_static->width_units = $obj->width_units;
1570 $product_static->height = $obj->height;
1571 $product_static->height_units = $obj->height_units;
1572 $product_static->weight = $obj->weight;
1573 $product_static->weight_units = $obj->weight_units;
1574 $product_static->volume = $obj->volume;
1575 $product_static->volume_units = $obj->volume_units;
1576 $product_static->surface = $obj->surface;
1577 $product_static->surface_units = $obj->surface_units;
1578 if (getDolGlobalString('PRODUCT_USE_UNITS')) {
1579 $product_static->fk_unit = $obj->fk_unit;
1580 }
1581 $product_static->import_key = $obj->import_key;
1582
1583 // STOCK_DISABLE_OPTIM_LOAD can be set to force load_stock whatever is permissions on stock.
1584 if ((isModEnabled('stock') && $user->hasRight('stock', 'lire') && $search_type != 1) || getDolGlobalString('STOCK_DISABLE_OPTIM_LOAD')) { // To optimize call of load_stock
1585 if ($product_static->type != 1 || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) { // Not a service
1586 $option = 'nobatch';
1587 if (empty($arrayfields['stock_virtual']['checked'])) {
1588 $option .= ',novirtual';
1589 }
1590 $product_static->load_stock($option); // Load stock_reel + stock_warehouse. This can also call load_virtual_stock()
1591 }
1592 }
1593 }
1594
1595 $product_static->price = $obj->price;
1596
1597 $object = $product_static;
1598
1599 $usercancreadprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS') ? $user->hasRight('product', 'product_advance', 'read_prices') : $user->hasRight('product', 'lire');
1600 if ($product_static->isService()) {
1601 $usercancreadprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS') ? $user->hasRight('service', 'service_advance', 'read_prices') : $user->hasRight('service', 'lire');
1602 }
1603
1604 if ($mode == 'kanban') {
1605 if ($i == 0) {
1606 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
1607 print '<div class="box-flex-container kanban">';
1608 }
1609
1610 // Output Kanban
1611 $selected = -1;
1612 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1613 $selected = 0;
1614 if (in_array($object->id, $arrayofselected)) {
1615 $selected = 1;
1616 }
1617 }
1618 print $object->getKanbanView('', array('selected' => $selected));
1619 if ($i == ($imaxinloop - 1)) {
1620 print '</div>';
1621 print '</td></tr>';
1622 }
1623 } else {
1624 // Show line of result
1625 $j = 0;
1626 print '<tr data-rowid="'.$object->id.'" class="oddeven">';
1627
1628 // Action column
1629 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1630 print '<td class="nowrap center">';
1631 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1632 $selected = 0;
1633 if (in_array($object->id, $arrayofselected)) {
1634 $selected = 1;
1635 }
1636 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
1637 }
1638 print '</td>';
1639 if (!$i) {
1640 $totalarray['nbfield']++;
1641 }
1642 }
1643 // Rowid
1644 if (!empty($arrayfields['p.rowid']['checked'])) {
1645 print '<td class="nowraponall">';
1646 print $product_static->id;
1647 print "</td>\n";
1648 if (!$i) {
1649 $totalarray['nbfield']++;
1650 }
1651 }
1652
1653 // Ref
1654 if (!empty($arrayfields['p.ref']['checked'])) {
1655 print '<td class="tdoverflowmax250">';
1656 print $product_static->getNomUrl(1);
1657 print "</td>\n";
1658 if (!$i) {
1659 $totalarray['nbfield']++;
1660 }
1661 }
1662
1663 // Ref supplier
1664 if (!empty($arrayfields['pfp.ref_fourn']['checked'])) {
1665 print '<td class="tdoverflowmax200">';
1666 print $product_static->getNomUrl(1);
1667 print "</td>\n";
1668 if (!$i) {
1669 $totalarray['nbfield']++;
1670 }
1671 }
1672
1673 // Thumbnail
1674 if (!empty($arrayfields['thumbnail']['checked'])) {
1675 $product_thumbnail_html = '';
1676 if (!empty($product_static->entity)) {
1677 $product_thumbnail = $product_static->show_photos('product', $conf->product->multidir_output[$product_static->entity], 1, 1, 0, 0, 0, 80);
1678 if ($product_static->nbphoto > 0) {
1679 $product_thumbnail_html = $product_thumbnail;
1680 }
1681 }
1682
1683 print '<td class="center">' . $product_thumbnail_html . '</td>';
1684 if (!$i) {
1685 $totalarray['nbfield']++;
1686 }
1687 }
1688
1689 // Label
1690 if (!empty($arrayfields['p.label']['checked'])) {
1691 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($product_static->label).'">'.$product_static->label.'</td>';
1692 if (!$i) {
1693 $totalarray['nbfield']++;
1694 }
1695 }
1696
1697 // Type
1698 if (!empty($arrayfields['p.fk_product_type']['checked'])) {
1699 print '<td class="center">';
1700 $s = '';
1701 if ($product_static->type == 0) {
1702 $s .= img_picto($langs->trans("Product"), 'product', 'class="paddingleftonly paddingrightonly colorgrey"');
1703 } else {
1704 $s .= img_picto($langs->trans("Service"), 'service', 'class="paddingleftonly paddingrightonly colorgrey"');
1705 }
1706 print $s;
1707 print '</td>';
1708 if (!$i) {
1709 $totalarray['nbfield']++;
1710 }
1711 }
1712
1713 // Description
1714 if (!empty($arrayfields['p.description']['checked'])) {
1715 print '<td class="left">';
1716 // Since description can be very large (several pages of HTML-
1717 // code) we limit to the first two rows
1718 print dolGetFirstLineOfText($product_static->description, 2);
1719 print '</td>';
1720 if (!$i) {
1721 $totalarray['nbfield']++;
1722 }
1723 }
1724
1725 // Barcode
1726 if (!empty($arrayfields['p.barcode']['checked'])) {
1727 print '<td class="tdoverflowmax125" title="'.dol_escape_htmltag($product_static->barcode).'">'.dol_escape_htmltag($product_static->barcode).'</td>';
1728 if (!$i) {
1729 $totalarray['nbfield']++;
1730 }
1731 }
1732
1733 // Duration
1734 if (!empty($arrayfields['p.duration']['checked'])) {
1735 print '<td class="center nowraponall">';
1736
1737 if (preg_match('/([^a-z]+)[a-z]$/i', $obj->duration)) {
1738 $duration_value = substr($obj->duration, 0, dol_strlen($obj->duration) - 1);
1739 $duration_unit = substr($obj->duration, -1);
1740
1741 if ((float) $duration_value > 1) {
1742 $dur = array("i" => $langs->trans("Minutes"), "h" => $langs->trans("Hours"), "d" => $langs->trans("Days"), "w" => $langs->trans("Weeks"), "m" => $langs->trans("Months"), "y" => $langs->trans("Years"));
1743 } elseif ((float) $duration_value > 0) {
1744 $dur = array("i" => $langs->trans("Minute"), "h" => $langs->trans("Hour"), "d" => $langs->trans("Day"), "w" => $langs->trans("Week"), "m" => $langs->trans("Month"), "y" => $langs->trans("Year"));
1745 }
1746 print $duration_value;
1747 print((!empty($duration_unit) && isset($dur[$duration_unit]) && $duration_value != '') ? ' '.$langs->trans($dur[$duration_unit]) : '');
1748 } elseif (!preg_match('/^[a-z]$/i', $obj->duration)) { // If duration is a simple char (like 's' of 'm'), we do not show value
1749 print $obj->duration;
1750 }
1751
1752 print '</td>';
1753 if (!$i) {
1754 $totalarray['nbfield']++;
1755 }
1756 }
1757
1758 if (!empty($arrayfields['pac.fk_product_parent']['checked'])) {
1759 print '<td class="nowraponall">';
1760 if ($obj->fk_product_parent > 0) {
1761 if (!empty($conf->cache['product'][$obj->fk_product_parent])) {
1762 $product_parent_static = $conf->cache['product'][$obj->fk_product_parent];
1763 } else {
1764 $product_parent_static = new Product($db);
1765 $product_parent_static->fetch($obj->fk_product_parent);
1766 $conf->cache['product'][$obj->fk_product_parent] = $product_parent_static;
1767 }
1768 print $product_parent_static->getNomUrl(1);
1769 }
1770 print '</td>';
1771 if (!$i) {
1772 $totalarray['nbfield']++;
1773 }
1774 }
1775 // Finished
1776 if (!empty($arrayfields['p.finished']['checked'])) {
1777 print '<td class="center">';
1778 print $product_static->getLibFinished();
1779 print '</td>';
1780 if (!$i) {
1781 $totalarray['nbfield']++;
1782 }
1783 }
1784 // Weight
1785 if (!empty($arrayfields['p.weight']['checked'])) {
1786 print '<td class="center">';
1787 print $product_static->weight;
1788 print '</td>';
1789 if (!$i) {
1790 $totalarray['nbfield']++;
1791 }
1792 }
1793 // Weight units
1794 if (!empty($arrayfields['p.weight_units']['checked'])) {
1795 print '<td class="center">';
1796 if ($product_static->weight != '') {
1797 print measuringUnitString(0, 'weight', $product_static->weight_units);
1798 }
1799 print '</td>';
1800 if (!$i) {
1801 $totalarray['nbfield']++;
1802 }
1803 }
1804 // Length
1805 if (!empty($arrayfields['p.length']['checked'])) {
1806 print '<td class="center">';
1807 print $product_static->length;
1808 print '</td>';
1809 if (!$i) {
1810 $totalarray['nbfield']++;
1811 }
1812 }
1813 // Length units
1814 if (!empty($arrayfields['p.length_units']['checked'])) {
1815 print '<td class="center">';
1816 if ($product_static->length != '') {
1817 print measuringUnitString(0, 'size', $product_static->length_units);
1818 }
1819 print '</td>';
1820 if (!$i) {
1821 $totalarray['nbfield']++;
1822 }
1823 }
1824 // Width
1825 if (!empty($arrayfields['p.width']['checked'])) {
1826 print '<td align="center">';
1827 print $product_static->width;
1828 print '</td>';
1829 if (!$i) {
1830 $totalarray['nbfield']++;
1831 }
1832 }
1833 // Width units
1834 if (!empty($arrayfields['p.width_units']['checked'])) {
1835 print '<td class="center">';
1836 if ($product_static->width != '') {
1837 print measuringUnitString(0, 'size', $product_static->width_units);
1838 }
1839 print '</td>';
1840 if (!$i) {
1841 $totalarray['nbfield']++;
1842 }
1843 }
1844 // Height
1845 if (!empty($arrayfields['p.height']['checked'])) {
1846 print '<td align="center">';
1847 print $product_static->height;
1848 print '</td>';
1849 if (!$i) {
1850 $totalarray['nbfield']++;
1851 }
1852 }
1853 // Height units
1854 if (!empty($arrayfields['p.height_units']['checked'])) {
1855 print '<td class="center">';
1856 if ($product_static->height != '') {
1857 print measuringUnitString(0, 'size', $product_static->height_units);
1858 }
1859 print '</td>';
1860 if (!$i) {
1861 $totalarray['nbfield']++;
1862 }
1863 }
1864 // Surface
1865 if (!empty($arrayfields['p.surface']['checked'])) {
1866 print '<td class="center">';
1867 print $product_static->surface;
1868 print '</td>';
1869 if (!$i) {
1870 $totalarray['nbfield']++;
1871 }
1872 }
1873 // Surface units
1874 if (!empty($arrayfields['p.surface_units']['checked'])) {
1875 print '<td class="center">';
1876 if ($product_static->surface != '') {
1877 print measuringUnitString(0, 'surface', $product_static->surface_units);
1878 }
1879 print '</td>';
1880 if (!$i) {
1881 $totalarray['nbfield']++;
1882 }
1883 }
1884 // Volume
1885 if (!empty($arrayfields['p.volume']['checked'])) {
1886 print '<td class="center">';
1887 print $product_static->volume;
1888 print '</td>';
1889 if (!$i) {
1890 $totalarray['nbfield']++;
1891 }
1892 }
1893 // Volume units
1894 if (!empty($arrayfields['p.volume_units']['checked'])) {
1895 print '<td class="center">';
1896 if ($product_static->volume != '') {
1897 print measuringUnitString(0, 'volume', $product_static->volume_units);
1898 }
1899 print '</td>';
1900 if (!$i) {
1901 $totalarray['nbfield']++;
1902 }
1903 }
1904 // Unit
1905 if (!empty($arrayfields['cu.label']['checked'])) {
1906 print '<td align="center">';
1907 if (!empty($obj->cu_label)) {
1908 print $langs->trans($obj->cu_label);
1909 }
1910 print '</td>';
1911 if (!$i) {
1912 $totalarray['nbfield']++;
1913 }
1914 }
1915
1916 // Default Workstation
1917 if (!empty($arrayfields['p.fk_default_workstation']['checked'])) {
1918 print '<td align="left">';
1919 if (isModEnabled('workstation') && !empty($obj->fk_default_workstation)) {
1920 $workstation_static->id = $obj->fk_default_workstation;
1921 $workstation_static->ref = $obj->ref_workstation;
1922 $workstation_static->status = $obj->status_workstation;
1923
1924 print $workstation_static->getNomUrl(1);
1925 }
1926 print '</td>';
1927 if (!$i) {
1928 $totalarray['nbfield']++;
1929 }
1930 }
1931
1932 // Sell price
1933 if (!empty($arrayfields['p.sellprice']['checked'])) {
1934 print '<td class="right nowraponall">';
1935 if ($product_static->status && $usercancreadprice) {
1936 if ($obj->price_base_type == 'TTC') {
1937 print '<span class="amount">'.price($obj->price_ttc).' '.$langs->trans("TTC").'</span>';
1938 } else {
1939 print '<span class="amount">'.price($obj->price).' '.$langs->trans("HT").'</span>';
1940 }
1941 }
1942 print '</td>';
1943 if (!$i) {
1944 $totalarray['nbfield']++;
1945 }
1946 }
1947
1948 // Multiprices
1949 if (getDolGlobalString('PRODUIT_MULTIPRICES')) {
1950 if (! isset($productpricescache)) {
1951 $productpricescache = array();
1952 }
1953 if (! isset($productpricescache[$obj->rowid])) {
1954 $productpricescache[$obj->rowid] = array();
1955 }
1956
1957 if ($product_static->status && $usercancreadprice) {
1958 // Make 1 request for all price levels (without filter on price_level) and saved result into an cache array
1959 // then reuse the cache array if we need prices for other price levels
1960 $sqlp = "SELECT p.rowid, p.fk_product, p.price, p.price_ttc, p.price_level, p.date_price, p.price_base_type";
1961 $sqlp .= " FROM ".MAIN_DB_PREFIX."product_price as p";
1962 $sqlp .= " WHERE fk_product = ".((int) $obj->rowid);
1963 $sqlp .= " ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC";
1964 $resultp = $db->query($sqlp);
1965 if ($resultp) {
1966 $nump = $db->num_rows($resultp);
1967 $j = 0;
1968 while ($j < $nump) {
1969 $objp = $db->fetch_object($resultp);
1970
1971 if (empty($productpricescache[$obj->rowid][$objp->price_level])) {
1972 $productpricescache[$obj->rowid][$objp->price_level]['price'] = $objp->price;
1973 $productpricescache[$obj->rowid][$objp->price_level]['price_ttc'] = $objp->price_ttc;
1974 $productpricescache[$obj->rowid][$objp->price_level]['price_base_type'] = $objp->price_base_type;
1975 }
1976
1977 $j++;
1978 }
1979
1980 $db->free($resultp);
1981 } else {
1982 dol_print_error($db);
1983 }
1984 }
1985
1986 foreach ($arraypricelevel as $key => $value) {
1987 if (!empty($arrayfields['p.sellprice'.$key]['checked'])) {
1988 print '<td class="right nowraponall">';
1989 if (!empty($productpricescache[$obj->rowid]) && isset($productpricescache[$obj->rowid][$key]['price_base_type'])) {
1990 if ($productpricescache[$obj->rowid][$key]['price_base_type'] == 'TTC') {
1991 print '<span class="amount">'.price($productpricescache[$obj->rowid][$key]['price_ttc']).' '.$langs->trans("TTC").'</span>';
1992 } else {
1993 print '<span class="amount">'.price($productpricescache[$obj->rowid][$key]['price']).' '.$langs->trans("HT").'</span>';
1994 }
1995 }
1996 print '</td>';
1997 if (!$i) {
1998 $totalarray['nbfield']++;
1999 }
2000 }
2001 }
2002 }
2003
2004 // Better buy price
2005 if (!empty($arrayfields['p.minbuyprice']['checked'])) {
2006 print '<td class="right nowraponall">';
2007 if ($product_static->status_buy && $obj->bestpurchaseprice != '' && $usercancreadprice) {
2008 if ($product_fourn->find_min_price_product_fournisseur($obj->rowid) > 0) {
2009 if ($product_fourn->product_fourn_price_id > 0) {
2010 if ((isModEnabled("fournisseur") && $user->hasRight('fournisseur', 'lire') && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD')) || (isModEnabled("supplier_order") && $user->hasRight('supplier_order', 'lire')) || (isModEnabled("supplier_invoice") && $user->hasRight('supplier_invoice', 'lire'))) {
2011 $htmltext = $product_fourn->display_price_product_fournisseur(1, 1, 0, 1);
2012 print '<span class="amount">'.$form->textwithpicto(price($product_fourn->fourn_unitprice * (1 - $product_fourn->fourn_remise_percent / 100) - $product_fourn->fourn_remise).' '.$langs->trans("HT"), $htmltext).'</span>';
2013 } else {
2014 print '<span class="amount">'.price($product_fourn->fourn_unitprice).' '.$langs->trans("HT").'</span>';
2015 }
2016 }
2017 }
2018 }
2019 print '</td>';
2020 if (!$i) {
2021 $totalarray['nbfield']++;
2022 }
2023 }
2024
2025 // Number of buy prices
2026 if (!empty($arrayfields['p.numbuyprice']['checked'])) {
2027 print '<td class="right">';
2028 if ($product_static->status_buy && $usercancreadprice) {
2029 if (count($productFournList = $product_fourn->list_product_fournisseur_price($obj->rowid)) > 0) {
2030 $htmltext = $product_fourn->display_price_product_fournisseur(1, 1, 0, 1, $productFournList);
2031 print $form->textwithpicto(count($productFournList), $htmltext);
2032 }
2033 }
2034 print '</td>';
2035 if (!$i) {
2036 $totalarray['nbfield']++;
2037 }
2038 }
2039
2040 // VAT or Sell Tax Rate
2041 if (!empty($arrayfields['p.tva_tx']['checked'])) {
2042 print '<td class="right">';
2043 print vatrate($obj->tva_tx, true);
2044 print '</td>';
2045 if (!$i) {
2046 $totalarray['nbfield']++;
2047 }
2048 }
2049
2050 // WAP
2051 if (!empty($arrayfields['p.pmp']['checked'])) {
2052 print '<td class="nowrap right">';
2053 if ($usercancreadprice) {
2054 print '<span class="amount">'.price($product_static->pmp, 1, $langs)."</span>";
2055 }
2056 print '</td>';
2057 if (!$i) {
2058 $totalarray['nbfield']++;
2059 }
2060 }
2061 // Cost price
2062 if (!empty($arrayfields['p.cost_price']['checked'])) {
2063 print '<td class="nowrap right">';
2064 //print $obj->cost_price;
2065 if ($usercancreadprice) {
2066 print '<span class="amount">'.price($obj->cost_price).' '.$langs->trans("HT").'</span>';
2067 }
2068 print '</td>';
2069 if (!$i) {
2070 $totalarray['nbfield']++;
2071 }
2072 }
2073
2074 // Limit alert
2075 if (!empty($arrayfields['p.seuil_stock_alerte']['checked'])) {
2076 print '<td class="right">';
2077 if ($product_static->type != 1) {
2078 print $obj->seuil_stock_alerte;
2079 }
2080 print '</td>';
2081 if (!$i) {
2082 $totalarray['nbfield']++;
2083 }
2084 }
2085 // Desired stock
2086 if (!empty($arrayfields['p.desiredstock']['checked'])) {
2087 print '<td class="right">';
2088 if ($product_static->type != 1) {
2089 print $obj->desiredstock;
2090 }
2091 print '</td>';
2092 if (!$i) {
2093 $totalarray['nbfield']++;
2094 }
2095 }
2096 // Stock real
2097 if (!empty($arrayfields['p.stock']['checked'])) {
2098 print '<td class="right">';
2099 if ($product_static->type != 1) {
2100 if ($obj->seuil_stock_alerte != '' && $product_static->stock_reel < (float) $obj->seuil_stock_alerte) {
2101 print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
2102 }
2103 if ($usercancreadprice) {
2104 if ($product_static->stock_reel < 0) {
2105 print '<span class="warning">';
2106 }
2107 print price(price2num($product_static->stock_reel, 'MS'), 0, $langs, 1, 0);
2108 if ($product_static->stock_reel < 0) {
2109 print '</span>';
2110 }
2111 }
2112 }
2113 print '</td>';
2114 if (!$i) {
2115 $totalarray['nbfield']++;
2116 }
2117 }
2118 // Stock virtual
2119 if (!empty($arrayfields['stock_virtual']['checked'])) {
2120 print '<td class="right">';
2121 if ($product_static->type != 1) {
2122 if ($obj->seuil_stock_alerte != '' && $product_static->stock_theorique < (float) $obj->seuil_stock_alerte) {
2123 print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
2124 }
2125 if ($usercancreadprice) {
2126 if ($product_static->stock_theorique < 0) {
2127 print '<span class="warning">';
2128 }
2129 print price(price2num($product_static->stock_theorique, 'MS'), 0, $langs, 1, 0);
2130 if ($product_static->stock_theorique < 0) {
2131 print '</span>';
2132 }
2133 }
2134 }
2135 print '</td>';
2136 if (!$i) {
2137 $totalarray['nbfield']++;
2138 }
2139 }
2140 // Lot/Serial
2141 if (!empty($arrayfields['p.tobatch']['checked'])) {
2142 print '<td class="center">';
2143 print $product_static->getLibStatut(1, 2);
2144 print '</td>';
2145 if (!$i) {
2146 $totalarray['nbfield']++;
2147 }
2148 }
2149 // Country
2150 if (!empty($arrayfields['p.fk_country']['checked'])) {
2151 print '<td>'.getCountry($obj->fk_country, '', $db).'</td>';
2152 if (!$i) {
2153 $totalarray['nbfield']++;
2154 }
2155 }
2156 // State
2157 if (!empty($arrayfields['p.fk_state']['checked'])) {
2158 print '<td>';
2159 if (!empty($obj->fk_state)) {
2160 print getState($obj->fk_state, '0', $db);
2161 }
2162 print '</td>';
2163 if (!$i) {
2164 $totalarray['nbfield']++;
2165 }
2166 }
2167 // Accountancy code sell
2168 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell']['checked'])) {
2169 print '<td>'.length_accountg($product_static->accountancy_code_sell).'</td>';
2170 if (!$i) {
2171 $totalarray['nbfield']++;
2172 }
2173 }
2174 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_intra']['checked'])) {
2175 print '<td>'.length_accountg($product_static->accountancy_code_sell_intra).'</td>';
2176 if (!$i) {
2177 $totalarray['nbfield']++;
2178 }
2179 }
2180 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_export']['checked'])) {
2181 print '<td>'.length_accountg($product_static->accountancy_code_sell_export).'</td>';
2182 if (!$i) {
2183 $totalarray['nbfield']++;
2184 }
2185 }
2186 // Accountancy code buy
2187 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy']['checked'])) {
2188 print '<td>'.length_accountg($product_static->accountancy_code_buy).'</td>';
2189 if (!$i) {
2190 $totalarray['nbfield']++;
2191 }
2192 }
2193 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_intra']['checked'])) {
2194 print '<td>'.length_accountg($product_static->accountancy_code_buy_intra).'</td>';
2195 if (!$i) {
2196 $totalarray['nbfield']++;
2197 }
2198 }
2199 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_export']['checked'])) {
2200 print '<td>'.length_accountg($product_static->accountancy_code_buy_export).'</td>';
2201 if (!$i) {
2202 $totalarray['nbfield']++;
2203 }
2204 }
2205 // Extra fields
2206 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
2207 // Fields from hook
2208 $parameters = array('arrayfields' => $arrayfields, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
2209 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2210 print $hookmanager->resPrint;
2211 // Date creation
2212 if (!empty($arrayfields['p.datec']['checked'])) {
2213 print '<td class="center nowraponall">';
2214 print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
2215 print '</td>';
2216 if (!$i) {
2217 $totalarray['nbfield']++;
2218 }
2219 }
2220 // Date modification
2221 if (!empty($arrayfields['p.tms']['checked'])) {
2222 print '<td class="center nowraponall">';
2223 print dol_print_date($db->jdate($obj->date_modification), 'dayhour', 'tzuser');
2224 print '</td>';
2225 if (!$i) {
2226 $totalarray['nbfield']++;
2227 }
2228 }
2229
2230 // Import ID
2231 if (!empty($arrayfields['p.import_key']['checked'])) {
2232 print '<td class="center nowrap">';
2233 print dol_escape_htmltag($product_static->import_key);
2234 print '</td>';
2235 if (!$i) {
2236 $totalarray['nbfield']++;
2237 }
2238 }
2239
2240 // Status (to sell)
2241 if (!empty($arrayfields['p.tosell']['checked'])) {
2242 print '<td class="center nowrap">';
2243 if (!empty($conf->use_javascript_ajax) && $user->hasRight("produit", "creer") && getDolGlobalString('MAIN_DIRECT_STATUS_UPDATE')) {
2244 print ajax_object_onoff($product_static, 'status', 'tosell', 'ProductStatusOnSell', 'ProductStatusNotOnSell');
2245 } else {
2246 print $product_static->LibStatut($product_static->status, 5, 0);
2247 }
2248 print '</td>';
2249 if (!$i) {
2250 $totalarray['nbfield']++;
2251 }
2252 }
2253 // Status (to buy)
2254 if (!empty($arrayfields['p.tobuy']['checked'])) {
2255 print '<td class="center nowrap">';
2256 if (!empty($conf->use_javascript_ajax) && $user->hasRight("produit", "creer") && getDolGlobalString('MAIN_DIRECT_STATUS_UPDATE')) {
2257 print ajax_object_onoff($product_static, 'status_buy', 'tobuy', 'ProductStatusOnBuy', 'ProductStatusNotOnBuy');
2258 } else {
2259 print $product_static->LibStatut($product_static->status_buy, 5, 1);
2260 }
2261 print '</td>';
2262 if (!$i) {
2263 $totalarray['nbfield']++;
2264 }
2265 }
2266
2267 // Action column
2268 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2269 print '<td class="nowrap center">';
2270 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
2271 $selected = 0;
2272 if (in_array($object->id, $arrayofselected)) {
2273 $selected = 1;
2274 }
2275 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
2276 }
2277 print '</td>';
2278 if (!$i) {
2279 $totalarray['nbfield']++;
2280 }
2281 }
2282
2283 print '</tr>'."\n";
2284 }
2285
2286 $i++;
2287}
2288
2289// If no record found
2290if ($num == 0) {
2291 $colspan = 1;
2292 foreach ($arrayfields as $key => $val) {
2293 if (!empty($val['checked'])) {
2294 $colspan++;
2295 }
2296 }
2297 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
2298}
2299
2300$db->free($resql);
2301
2302print '</table>'."\n";
2303print '</div>'."\n";
2304
2305print '</form>'."\n";
2306
2307// End of page
2308llxFooter();
2309$db->close();
$id
Definition account.php:39
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
clean_account($account)
Return accounting account without zero on the right.
ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input=array(), $morecss='', $htmlname='', $forcenojs=0, $moreparam='')
On/off button to change a property status of an object This uses the ajax service objectonoff....
Definition ajax.lib.php:733
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:70
Class to manage canvas.
Class to manage categories.
Class to manage standard extra fields.
Class to manage forms for categories.
Class to build HTML component for third parties management Only common components are here.
Class to manage generation of HTML components Only common components must be here.
Class with static methods for building HTML components related to products Only components common to ...
Class to manage predefined suppliers products.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class for Workstation.
getState($id, $withcode='0', $dbtouse=null, $withregion=0, $outputlangs=null, $entconv=1)
Return state translated from an id.
isInEEC($object)
Return if a country of an object is inside the EEC (European Economic Community)
llxFooter()
Footer empty.
Definition document.php:107
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
dolExplodeIntoArray($string, $delimiter=';', $kv='=')
Split a string with 2 keys into key array.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dolGetFirstLineOfText($text, $nboflines=1, $charset='UTF-8')
Return first line of text.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
measuringUnitString($unit, $measuring_style='', $scale='', $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.