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