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// Add table from hooks
488$parameters = array();
489$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
490$sql .= $hookmanager->resPrint;
491
492$sql .= ' WHERE p.entity IN ('.getEntity('product').')';
493if ($sall) {
494 // Clean $fieldstosearchall
495 $newfieldstosearchall = $fieldstosearchall;
496 unset($newfieldstosearchall['pfp.ref_fourn']);
497 unset($newfieldstosearchall['pfp.barcode']);
498
499 $sql .= ' AND (';
500 $sql .= natural_search(array_keys($newfieldstosearchall), $sall, 0, 1);
501 // Search also into a supplier reference 'pfp.ref_fourn'="RefSupplier"
502 $sql .= ' OR EXISTS (SELECT rowid FROM '.MAIN_DB_PREFIX.'product_fournisseur_price as pfp WHERE pfp.fk_product = p.rowid';
503 $sql .= ' AND ('.natural_search('pfp.ref_fourn', $sall, 0, 1);
504 if (isModEnabled('barcode')) {
505 // Search also into a supplier barcode 'pfp.barcode'='GencodBuyPrice';
506 $sql .= ' OR '.natural_search('pfp.barcode', $sall, 0, 1);
507 }
508 $sql .= ')))';
509}
510// if the type is not 1, we show all products (type = 0,2,3)
511if (dol_strlen($search_type) && $search_type != '-1') {
512 if ($search_type == 1) {
513 $sql .= " AND p.fk_product_type = 1";
514 } else {
515 $sql .= " AND p.fk_product_type <> 1";
516 }
517}
518
519if (isModEnabled('variants') && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && !$show_childproducts)) {
520 $sql .= " AND pac.rowid IS NULL";
521}
522
523if ($search_id) {
524 $sql .= natural_search('p.rowid', $search_id, 1);
525}
526if ($search_ref) {
527 $sql .= natural_search('p.ref', $search_ref);
528}
529if ($search_label) {
530 $sql .= natural_search('p.label', $search_label);
531}
532if ($search_default_workstation) {
533 $sql .= natural_search('ws.ref', $search_default_workstation);
534}
535if ($search_barcode) {
536 $sql .= natural_search('p.barcode', $search_barcode);
537}
538if (isset($search_tosell) && dol_strlen($search_tosell) > 0 && $search_tosell != -1) {
539 $sql .= " AND p.tosell = ".((int) $search_tosell);
540}
541if (isset($search_tobuy) && dol_strlen($search_tobuy) > 0 && $search_tobuy != -1) {
542 $sql .= " AND p.tobuy = ".((int) $search_tobuy);
543}
544if (isset($search_tobatch) && dol_strlen($search_tobatch) > 0 && $search_tobatch != -1) {
545 $sql .= " AND p.tobatch = ".((int) $search_tobatch);
546}
547if ($search_vatrate) {
548 $sql .= natural_search('p.tva_tx', $search_vatrate, 1);
549}
550if (dol_strlen($canvas) > 0) {
551 $sql .= " AND p.canvas = '".$db->escape($canvas)."'";
552}
553// Search for tag/category ($searchCategoryProductList is an array of ID)
554if (!empty($searchCategoryProductList)) {
555 $searchCategoryProductSqlList = array();
556 $listofcategoryid = '';
557 foreach ($searchCategoryProductList as $searchCategoryProduct) {
558 if (intval($searchCategoryProduct) == -2) {
559 $searchCategoryProductSqlList[] = "NOT EXISTS (SELECT ck.fk_product FROM ".MAIN_DB_PREFIX."categorie_product as ck WHERE p.rowid = ck.fk_product)";
560 } elseif (intval($searchCategoryProduct) > 0) {
561 if ($searchCategoryProductOperator == 0) {
562 $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).")";
563 } else {
564 $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryProduct);
565 }
566 }
567 }
568 if ($listofcategoryid) {
569 $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)."))";
570 }
571 if ($searchCategoryProductOperator == 1) {
572 if (!empty($searchCategoryProductSqlList)) {
573 $sql .= " AND (".implode(' OR ', $searchCategoryProductSqlList).")";
574 }
575 } else {
576 if (!empty($searchCategoryProductSqlList)) {
577 $sql .= " AND (".implode(' AND ', $searchCategoryProductSqlList).")";
578 }
579 }
580}
581if ($fourn_id > 0) {
582 $sql .= " AND pfp.fk_soc = ".((int) $fourn_id);
583}
584if ($search_country) {
585 $sql .= " AND p.fk_country = ".((int) $search_country);
586}
587if ($search_state) {
588 $sql .= " AND p.fk_state = ".((int) $search_state);
589}
590if ($search_finished >= 0 && $search_finished !== '') {
591 $sql .= " AND p.finished = ".((int) $search_finished);
592}
593if ($search_accountancy_code_sell) {
594 $sql .= natural_search($alias_product_perentity . '.accountancy_code_sell', clean_account($search_accountancy_code_sell));
595}
596if ($search_accountancy_code_sell_intra) {
597 $sql .= natural_search($alias_product_perentity . '.accountancy_code_sell_intra', clean_account($search_accountancy_code_sell_intra));
598}
599if ($search_accountancy_code_sell_export) {
600 $sql .= natural_search($alias_product_perentity . '.accountancy_code_sell_export', clean_account($search_accountancy_code_sell_export));
601}
602if ($search_accountancy_code_buy) {
603 $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy', clean_account($search_accountancy_code_buy));
604}
605if ($search_accountancy_code_buy_intra) {
606 $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy_intra', clean_account($search_accountancy_code_buy_intra));
607}
608if ($search_accountancy_code_buy_export) {
609 $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy_export', clean_account($search_accountancy_code_buy_export));
610}
611if (!empty($conf->global->PRODUCT_USE_UNITS) && $search_units) {
612 $sql .= natural_search('cu.rowid', $search_units);
613}
614// Add where from extra fields
615include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
616// Add where from hooks
617$parameters = array();
618$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
619$sql .= $hookmanager->resPrint;
620$sql .= " GROUP BY p.rowid, p.ref, p.label, p.barcode, p.price, p.tva_tx, p.price_ttc, p.price_base_type,";
621$sql .= " p.fk_product_type, p.duration, p.finished, p.tosell, p.tobuy, p.seuil_stock_alerte, p.desiredstock,";
622$sql .= ' p.datec, p.tms, p.entity, p.tobatch, p.pmp, p.cost_price, p.stock,';
623if (empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
624 $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,";
625} else {
626 $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,";
627}
628$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';
629if (!empty($conf->global->PRODUCT_USE_UNITS)) {
630 $sql .= ', p.fk_unit, cu.label';
631}
632if (isModEnabled('workstation')) {
633 $sql .= ', p.fk_default_workstation, ws.status, ws.ref ';
634}
635
636if (isModEnabled('variants') && (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD) && !$show_childproducts)) {
637 $sql .= ', pac.rowid';
638}
639// Add fields from extrafields
640if (!empty($extrafields->attributes[$object->table_element]['label'])) {
641 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
642 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key : '');
643 }
644}
645// Add groupby from hooks
646$parameters = array();
647$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
648$sql .= $hookmanager->resPrint;
649//if (GETPOST("toolowstock")) $sql.= " HAVING SUM(s.reel) < p.seuil_stock_alerte"; // Not used yet
650
651$nbtotalofrecords = '';
652if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
653 /* The fast and low memory method to get and count full list converts the sql into a sql count */
654 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
655 $sqlforcount = preg_replace('/'.preg_quote($linktopfp, '/').'/', '', $sqlforcount);
656 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
657
658 $resql = $db->query($sqlforcount);
659 if ($resql) {
660 $objforcount = $db->fetch_object($resql);
661 $nbtotalofrecords = $objforcount->nbtotalofrecords;
662 } else {
663 dol_print_error($db);
664 }
665
666 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
667 $page = 0;
668 $offset = 0;
669 }
670 $db->free($resql);
671}
672
673// Complete request and execute it with limit
674$sql .= $db->order($sortfield, $sortorder);
675if ($limit) {
676 $sql .= $db->plimit($limit + 1, $offset);
677}
678
679$resql = $db->query($sql);
680if (!$resql) {
681 dol_print_error($db);
682 exit;
683}
684
685$num = $db->num_rows($resql);
686
687
688// Direct jump if only one record found
689if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $sall) {
690 $obj = $db->fetch_object($resql);
691 $id = $obj->rowid;
692 header("Location: ".DOL_URL_ROOT.'/product/card.php?id='.$id);
693 exit;
694}
695
696
697// Output page
698// --------------------------------------------------------------------
699
700$helpurl = '';
701if ($search_type != '') {
702 if ($search_type == 0) {
703 $helpurl = 'EN:Module_Products|FR:Module_Produits|ES:M&oacute;dulo_Productos';
704 } elseif ($search_type == 1) {
705 $helpurl = 'EN:Module_Services_En|FR:Module_Services|ES:M&oacute;dulo_Servicios';
706 }
707}
708
709$paramsCat = '';
710foreach ($searchCategoryProductList as $searchCategoryProduct) {
711 $paramsCat .= "&search_category_product_list[]=".urlencode($searchCategoryProduct);
712}
713
714//llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, 'classforhorizontalscrolloftabs');
715llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, '');
716
717$arrayofselected = is_array($toselect) ? $toselect : array();
718
719// Displays product removal confirmation
720if (GETPOST('delprod')) {
721 setEventMessages($langs->trans("ProductDeleted", GETPOST('delprod')), null, 'mesgs');
722}
723
724$param = '';
725if (!empty($mode)) {
726 $param .= '&mode='.urlencode($mode);
727}
728if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
729 $param .= '&contextpage='.urlencode($contextpage);
730}
731if ($limit > 0 && $limit != $conf->liste_limit) {
732 $param .= '&limit='.((int) $limit);
733}
734if ($optioncss != '') {
735 $param .= '&optioncss='.urlencode($optioncss);
736}
737if ($sall) {
738 $param .= "&sall=".urlencode($sall);
739}
740if ($searchCategoryProductOperator == 1) {
741 $param .= "&search_category_product_operator=".urlencode($searchCategoryProductOperator);
742}
743foreach ($searchCategoryProductList as $searchCategoryProduct) {
744 $param .= "&search_category_product_list[]=".urlencode($searchCategoryProduct);
745}
746if ($search_ref) {
747 $param .= "&search_ref=".urlencode($search_ref);
748}
749if ($search_ref_supplier) {
750 $param .= "&search_ref_supplier=".urlencode($search_ref_supplier);
751}
752if ($search_barcode) {
753 $param .= ($search_barcode ? "&search_barcode=".urlencode($search_barcode) : "");
754}
755if ($search_label) {
756 $param .= "&search_label=".urlencode($search_label);
757}
758if ($search_default_workstation) {
759 $param .= "&search_default_workstation=".urlencode($search_default_workstation);
760}
761if ($search_tosell != '') {
762 $param .= "&search_tosell=".urlencode($search_tosell);
763}
764if ($search_tobuy != '') {
765 $param .= "&search_tobuy=".urlencode($search_tobuy);
766}
767if ($search_tobatch) {
768 $param .= "&search_tobatch=".urlencode($search_tobatch);
769}
770if ($search_country != '') {
771 $param .= "&search_country=".urlencode($search_country);
772}
773if ($search_state != '') {
774 $param .= "&search_state=".urlencode($search_state);
775}
776if ($search_vatrate) {
777 $param .= "&search_vatrate=".urlencode($search_vatrate);
778}
779if ($fourn_id > 0) {
780 $param .= "&fourn_id=".urlencode($fourn_id);
781}
782if ($show_childproducts) {
783 $param .= ($show_childproducts ? "&search_show_childproducts=".urlencode($show_childproducts) : "");
784}
785if ($type != '') {
786 $param .= '&type='.urlencode($type);
787}
788if ($search_type != '') {
789 $param .= '&search_type='.urlencode($search_type);
790}
791if ($search_accountancy_code_sell) {
792 $param .= "&search_accountancy_code_sell=".urlencode($search_accountancy_code_sell);
793}
794if ($search_accountancy_code_sell_intra) {
795 $param .= "&search_accountancy_code_sell_intra=".urlencode($search_accountancy_code_sell_intra);
796}
797if ($search_accountancy_code_sell_export) {
798 $param .= "&search_accountancy_code_sell_export=".urlencode($search_accountancy_code_sell_export);
799}
800if ($search_accountancy_code_buy) {
801 $param .= "&search_accountancy_code_buy=".urlencode($search_accountancy_code_buy);
802}
803if ($search_accountancy_code_buy_intra) {
804 $param .= "&search_accountancy_code_buy_intra=".urlencode($search_accountancy_code_buy_intra);
805}
806if ($search_accountancy_code_buy_export) {
807 $param .= "&search_accountancy_code_buy_export=".urlencode($search_accountancy_code_buy_export);
808}
809if ($search_finished) {
810 $param .= "&search_finished=".urlencode($search_finished);
811}
812// Add $param from extra fields
813include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
814
815// List of mass actions available
816$arrayofmassactions = array(
817 'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
818 'edit_extrafields'=>img_picto('', 'edit', 'class="pictofixedwidth"').$langs->trans("ModifyValueExtrafields"),
819 //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
820 //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
821);
822
823if ($user->hasRight($rightskey, 'supprimer')) {
824 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
825}
826if ($user->hasRight($rightskey, 'creer')) {
827 $arrayofmassactions['switchonsalestatus'] = img_picto('', 'stop-circle', 'class="pictofixedwidth"').$langs->trans("SwitchOnSaleStatus");
828 $arrayofmassactions['switchonpurchasestatus'] = img_picto('', 'stop-circle', 'class="pictofixedwidth"').$langs->trans("SwitchOnPurchaseStatus");
829 $arrayofmassactions['preupdateprice'] = img_picto('', 'edit', 'class="pictofixedwidth"').$langs->trans("UpdatePrice");
830}
831if (isModEnabled('category') && $user->hasRight($rightskey, 'creer')) {
832 $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
833}
834if (in_array($massaction, array('presend', 'predelete','preaffecttag', 'edit_extrafields', 'preupdateprice'))) {
835 $arrayofmassactions = array();
836}
837$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
838
839$newcardbutton = '';
840$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'));
841$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'));
842
843if ($type === "") {
844 $perm = ($user->hasRight('produit', 'creer') || $user->hasRight('service', 'creer'));
845} elseif ($type == Product::TYPE_SERVICE) {
846 $perm = $user->hasRight('service', 'creer');
847} elseif ($type == Product::TYPE_PRODUCT) {
848 $perm = $user->hasRight('produit', 'creer');
849}
850 $oldtype = $type;
851 $params = array();
852if ($type === "") {
853 $params['forcenohideoftext'] = 1;
854}
855
856if ((isModEnabled('product') && $type === "") || $type == Product::TYPE_PRODUCT) {
857 $label = 'NewProduct';
858 $newcardbutton .= dolGetButtonTitle($langs->trans($label), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/product/card.php?action=create&type=0', '', $perm, $params);
859}
860if ((isModEnabled('service') && $type === "") || $type == Product::TYPE_SERVICE) {
861 $label = 'NewService';
862 $newcardbutton .= dolGetButtonTitle($langs->trans($label), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/product/card.php?action=create&type=1', '', $perm, $params);
863}
864
865print '<form id="searchFormList" action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire">';
866if ($optioncss != '') {
867 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
868}
869print '<input type="hidden" name="token" value="'.newToken().'">';
870print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
871print '<input type="hidden" name="action" value="list">';
872print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
873print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
874//print '<input type="hidden" name="page" value="'.$page.'">';
875print '<input type="hidden" name="type" value="'.$type.'">';
876print '<input type="hidden" name="page_y" value="">';
877print '<input type="hidden" name="mode" value="'.$mode.'">';
878
879if (empty($arrayfields['p.fk_product_type']['checked'])) {
880 print '<input type="hidden" name="search_type" value="'.dol_escape_htmltag($search_type).'">';
881}
882
883$picto = 'product';
884if ($type == 1) {
885 $picto = 'service';
886}
887
888print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
889
890$topicmail = "Information";
891$modelmail = "product";
892$objecttmp = new Product($db);
893$trackid = 'prod'.$object->id;
894include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
895
896if (!empty($catid)) {
897 print "<div id='ways'>";
898 $c = new Categorie($db);
899 $ways = $c->print_all_ways(' &gt; ', 'product/list.php');
900 print " &gt; ".$ways[0]."<br>\n";
901 print "</div><br>";
902}
903
904if ($sall) {
905 $setupstring = '';
906 foreach ($fieldstosearchall as $key => $val) {
907 $fieldstosearchall[$key] = $langs->trans($val);
908 $setupstring .= $key."=".$val.";";
909 }
910 print '<!-- Search done like if PRODUCT_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
911 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'</div>'."\n";
912}
913
914// Filter on categories
915$moreforfilter = '';
916if (isModEnabled('categorie') && $user->hasRight('categorie', 'read')) {
917 $formcategory = new FormCategory($db);
918 $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_PRODUCT, $searchCategoryProductList, 'minwidth300', $searchCategoryProductOperator ? $searchCategoryProductOperator : 0);
919}
920
921//Show/hide child products. Hidden by default
922if (isModEnabled('variants') && !empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
923 $moreforfilter .= '<div class="divsearchfield">';
924 $moreforfilter .= '<input type="checkbox" id="search_show_childproducts" name="search_show_childproducts"'.($show_childproducts ? 'checked="checked"' : '').'>';
925 $moreforfilter .= ' <label for="search_show_childproducts">'.$langs->trans('ShowChildProducts').'</label>';
926 $moreforfilter .= '</div>';
927}
928
929$parameters = array();
930$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
931if (empty($reshook)) {
932 $moreforfilter .= $hookmanager->resPrint;
933} else {
934 $moreforfilter = $hookmanager->resPrint;
935}
936
937if (!empty($moreforfilter)) {
938 print '<div class="liste_titre liste_titre_bydiv centpercent">';
939 print $moreforfilter;
940 print '</div>';
941}
942
943$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
944$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields
945$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
946
947print '<div class="div-table-responsive">';
948print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
949
950// Fields title search
951// --------------------------------------------------------------------
952print '<tr class="liste_titre_filter">';
953// Action column
954if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
955 print '<td class="liste_titre center maxwidthsearch">';
956 $searchpicto = $form->showFilterButtons('left');
957 print $searchpicto;
958 print '</td>';
959}
960if (!empty($arrayfields['p.rowid']['checked'])) {
961 print '<td class="liste_titre left">';
962 print '<input class="flat" type="text" name="search_id" size="4" value="'.dol_escape_htmltag($search_id).'">';
963 print '</td>';
964}
965if (!empty($arrayfields['p.ref']['checked'])) {
966 print '<td class="liste_titre left">';
967 print '<input class="flat" type="text" name="search_ref" size="8" value="'.dol_escape_htmltag($search_ref).'">';
968 print '</td>';
969}
970if (!empty($arrayfields['pfp.ref_fourn']['checked'])) {
971 print '<td class="liste_titre left">';
972 print '<input class="flat" type="text" name="search_ref_supplier" size="8" value="'.dol_escape_htmltag($search_ref_supplier).'">';
973 print '</td>';
974}
975// Thumbnail
976if (!empty($arrayfields['thumbnail']['checked'])) {
977 print '<td class="liste_titre center">';
978 print '</td>';
979}
980if (!empty($arrayfields['p.label']['checked'])) {
981 print '<td class="liste_titre left">';
982 print '<input class="flat" type="text" name="search_label" size="12" value="'.dol_escape_htmltag($search_label).'">';
983 print '</td>';
984}
985// Type
986if (!empty($arrayfields['p.fk_product_type']['checked'])) {
987 print '<td class="liste_titre center">';
988 $array = array('-1'=>'&nbsp;', '0'=>$langs->trans('Product'), '1'=>$langs->trans('Service'));
989 print $form->selectarray('search_type', $array, $search_type);
990 print '</td>';
991}
992// Barcode
993if (!empty($arrayfields['p.barcode']['checked'])) {
994 print '<td class="liste_titre">';
995 print '<input class="flat" type="text" name="search_barcode" size="6" value="'.dol_escape_htmltag($search_barcode).'">';
996 print '</td>';
997}
998// Duration
999if (!empty($arrayfields['p.duration']['checked'])) {
1000 print '<td class="liste_titre">';
1001 print '</td>';
1002}
1003
1004// Finished
1005if (!empty($arrayfields['p.finished']['checked'])) {
1006 print '<td class="liste_titre">';
1007 print $formproduct->selectProductNature('search_finished', $search_finished);
1008 print '</td>';
1009}
1010// Weight
1011if (!empty($arrayfields['p.weight']['checked'])) {
1012 print '<td class="liste_titre">';
1013 print '</td>';
1014}
1015// Weight units
1016if (!empty($arrayfields['p.weight_units']['checked'])) {
1017 print '<td class="liste_titre">';
1018 print '</td>';
1019}
1020// Length
1021if (!empty($arrayfields['p.length']['checked'])) {
1022 print '<td class="liste_titre">';
1023 print '</td>';
1024}
1025// Length units
1026if (!empty($arrayfields['p.length_units']['checked'])) {
1027 print '<td class="liste_titre">';
1028 print '</td>';
1029}
1030// Width
1031if (!empty($arrayfields['p.width']['checked'])) {
1032 print '<td class="liste_titre">';
1033 print '</td>';
1034}
1035// Width units
1036if (!empty($arrayfields['p.width_units']['checked'])) {
1037 print '<td class="liste_titre">';
1038 print '</td>';
1039}
1040// Height
1041if (!empty($arrayfields['p.height']['checked'])) {
1042 print '<td class="liste_titre">';
1043 print '</td>';
1044}
1045// Height units
1046if (!empty($arrayfields['p.height_units']['checked'])) {
1047 print '<td class="liste_titre">';
1048 print '</td>';
1049}
1050// Surface
1051if (!empty($arrayfields['p.surface']['checked'])) {
1052 print '<td class="liste_titre">';
1053 print '</td>';
1054}
1055// Surface units
1056if (!empty($arrayfields['p.surface_units']['checked'])) {
1057 print '<td class="liste_titre">';
1058 print '</td>';
1059}
1060// Volume
1061if (!empty($arrayfields['p.volume']['checked'])) {
1062 print '<td class="liste_titre">';
1063 print '</td>';
1064}
1065// Volume units
1066if (!empty($arrayfields['p.volume_units']['checked'])) {
1067 print '<td class="liste_titre">';
1068 print '</td>';
1069}
1070
1071// Unit
1072if (!empty($arrayfields['cu.label']['checked'])) {
1073 print '<td class="liste_titre">';
1074 print $form->selectUnits($search_units, 'search_units', 1);
1075 print '</td>';
1076}
1077
1078// Default workstation
1079if (!empty($arrayfields['p.fk_default_workstation']['checked'])) {
1080 print '<td class="liste_titre">';
1081 print '<input class="flat width75" type="text" name="search_default_workstation" value="'.dol_escape_htmltag($search_default_workstation).'">';
1082 print '</td>';
1083}
1084
1085// Sell price
1086if (!empty($arrayfields['p.sellprice']['checked'])) {
1087 print '<td class="liste_titre right">';
1088 print '</td>';
1089}
1090
1091// Multiprice
1092if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
1093 foreach ($arraypricelevel as $key => $value) {
1094 if (!empty($arrayfields['p.sellprice'.$key]['checked'])) {
1095 print '<td class="liste_titre right">';
1096 print '</td>';
1097 }
1098 }
1099}
1100
1101// Minimum buying Price
1102if (!empty($arrayfields['p.minbuyprice']['checked'])) {
1103 print '<td class="liste_titre">';
1104 print '&nbsp;';
1105 print '</td>';
1106}
1107// Number buying Price
1108if (!empty($arrayfields['p.numbuyprice']['checked'])) {
1109 print '<td class="liste_titre">';
1110 print '&nbsp;';
1111 print '</td>';
1112}
1113// Sell price
1114if (!empty($arrayfields['p.tva_tx']['checked'])) {
1115 print '<td class="liste_titre right">';
1116 print '<input class="right flat maxwidth50" placeholder="%" type="text" name="search_vatrate" size="1" value="'.dol_escape_htmltag($search_vatrate).'">';
1117 print '</td>';
1118}
1119// WAP
1120if (!empty($arrayfields['p.pmp']['checked'])) {
1121 print '<td class="liste_titre">';
1122 print '&nbsp;';
1123 print '</td>';
1124}
1125// cost_price
1126if (!empty($arrayfields['p.cost_price']['checked'])) {
1127 print '<td class="liste_titre">';
1128 print '&nbsp;';
1129 print '</td>';
1130}
1131// Limit for alert
1132if (!empty($arrayfields['p.seuil_stock_alerte']['checked'])) {
1133 print '<td class="liste_titre">';
1134 print '&nbsp;';
1135 print '</td>';
1136}
1137// Desired stock
1138if (!empty($arrayfields['p.desiredstock']['checked'])) {
1139 print '<td class="liste_titre">';
1140 print '&nbsp;';
1141 print '</td>';
1142}
1143// Stock
1144if (!empty($arrayfields['p.stock']['checked'])) {
1145 print '<td class="liste_titre">&nbsp;</td>';
1146}
1147// Stock
1148if (!empty($arrayfields['stock_virtual']['checked'])) {
1149 print '<td class="liste_titre">&nbsp;</td>';
1150}
1151// To batch
1152if (!empty($arrayfields['p.tobatch']['checked'])) {
1153 print '<td class="liste_titre center">';
1154 $statutarray = array(
1155 '-1' => '',
1156 '0' => $langs->trans("ProductStatusNotOnBatchShort"),
1157 '1' => $langs->trans("ProductStatusOnBatchShort"),
1158 '2' => $langs->trans("ProductStatusOnSerialShort")
1159 );
1160 print $form->selectarray('search_tobatch', $statutarray, $search_tobatch);
1161 print '</td>';
1162}
1163// Country
1164if (!empty($arrayfields['p.fk_country']['checked'])) {
1165 print '<td class="liste_titre center">';
1166 print $form->select_country($search_country, 'search_country', '', 0);
1167 print '</td>';
1168}
1169// State
1170if (!empty($arrayfields['p.fk_state']['checked'])) {
1171 print '<td class="liste_titre center">';
1172 print $formcompany->select_state($search_state, $search_country);
1173 print '</td>';
1174}
1175// Accountancy code sell
1176if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell']['checked'])) {
1177 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>';
1178}
1179if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_intra']['checked'])) {
1180 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>';
1181}
1182if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_export']['checked'])) {
1183 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>';
1184}
1185// Accountancy code buy
1186if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy']['checked'])) {
1187 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>';
1188}
1189if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_intra']['checked'])) {
1190 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>';
1191}
1192if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_export']['checked'])) {
1193 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>';
1194}
1195// Extra fields
1196include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
1197// Fields from hook
1198$parameters = array('arrayfields'=>$arrayfields);
1199$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1200print $hookmanager->resPrint;
1201// Date creation
1202if (!empty($arrayfields['p.datec']['checked'])) {
1203 print '<td class="liste_titre">';
1204 print '</td>';
1205}
1206// Date modification
1207if (!empty($arrayfields['p.tms']['checked'])) {
1208 print '<td class="liste_titre">';
1209 print '</td>';
1210}
1211if (!empty($arrayfields['p.tosell']['checked'])) {
1212 print '<td class="liste_titre center parentonrightofpage">';
1213 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');
1214 print '</td>';
1215}
1216if (!empty($arrayfields['p.tobuy']['checked'])) {
1217 print '<td class="liste_titre center parentonrightofpage">';
1218 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');
1219 print '</td>';
1220}
1221// Action column
1222if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1223 print '<td class="liste_titre center maxwidthsearch">';
1224 $searchpicto = $form->showFilterButtons();
1225 print $searchpicto;
1226 print '</td>';
1227}
1228print '</tr>'."\n";
1229
1230$totalarray = array();
1231$totalarray['nbfield'] = 0;
1232
1233// Fields title label
1234// --------------------------------------------------------------------
1235print '<tr class="liste_titre">';
1236// Action column
1237if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1238 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1239 $totalarray['nbfield']++;
1240}
1241if (!empty($arrayfields['p.rowid']['checked'])) {
1242 print_liste_field_titre($arrayfields['p.rowid']['label'], $_SERVER["PHP_SELF"], "p.rowid", "", $param, "", $sortfield, $sortorder);
1243 $totalarray['nbfield']++;
1244}
1245if (!empty($arrayfields['p.ref']['checked'])) {
1246 print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, "", $sortfield, $sortorder);
1247 $totalarray['nbfield']++;
1248}
1249if (!empty($arrayfields['pfp.ref_fourn']['checked'])) {
1250 print_liste_field_titre($arrayfields['pfp.ref_fourn']['label'], $_SERVER["PHP_SELF"], "pfp.ref_fourn", "", $param, "", $sortfield, $sortorder);
1251 $totalarray['nbfield']++;
1252}
1253if (!empty($arrayfields['thumbnail']['checked'])) {
1254 print_liste_field_titre($arrayfields['thumbnail']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ');
1255 $totalarray['nbfield']++;
1256}
1257if (!empty($arrayfields['p.label']['checked'])) {
1258 print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"], "p.label", "", $param, "", $sortfield, $sortorder);
1259 $totalarray['nbfield']++;
1260}
1261if (!empty($arrayfields['p.fk_product_type']['checked'])) {
1262 print_liste_field_titre($arrayfields['p.fk_product_type']['label'], $_SERVER["PHP_SELF"], "p.fk_product_type", "", $param, "", $sortfield, $sortorder, 'center ');
1263 $totalarray['nbfield']++;
1264}
1265if (!empty($arrayfields['p.barcode']['checked'])) {
1266 print_liste_field_titre($arrayfields['p.barcode']['label'], $_SERVER["PHP_SELF"], "p.barcode", "", $param, "", $sortfield, $sortorder);
1267 $totalarray['nbfield']++;
1268}
1269if (!empty($arrayfields['p.duration']['checked'])) {
1270 print_liste_field_titre($arrayfields['p.duration']['label'], $_SERVER["PHP_SELF"], "p.duration", "", $param, '', $sortfield, $sortorder, 'center ');
1271 $totalarray['nbfield']++;
1272}
1273if (!empty($arrayfields['p.finished']['checked'])) {
1274 print_liste_field_titre($arrayfields['p.finished']['label'], $_SERVER["PHP_SELF"], "p.finished", "", $param, '', $sortfield, $sortorder, 'center ');
1275 $totalarray['nbfield']++;
1276}
1277
1278if (!empty($arrayfields['p.weight']['checked'])) {
1279 print_liste_field_titre($arrayfields['p.weight']['label'], $_SERVER['PHP_SELF'], 'p.weight', '', $param, '', $sortfield, $sortorder, 'center ');
1280 $totalarray['nbfield']++;
1281}
1282if (!empty($arrayfields['p.weight_units']['checked'])) {
1283 print_liste_field_titre($arrayfields['p.weight_units']['label'], $_SERVER['PHP_SELF'], 'p.weight_units', '', $param, '', $sortfield, $sortorder, 'center ');
1284 $totalarray['nbfield']++;
1285}
1286if (!empty($arrayfields['p.length']['checked'])) {
1287 print_liste_field_titre($arrayfields['p.length']['label'], $_SERVER['PHP_SELF'], 'p.length', '', $param, '', $sortfield, $sortorder, 'center ');
1288 $totalarray['nbfield']++;
1289}
1290if (!empty($arrayfields['p.length_units']['checked'])) {
1291 print_liste_field_titre($arrayfields['p.length_units']['label'], $_SERVER['PHP_SELF'], 'p.length_units', '', $param, '', $sortfield, $sortorder, 'center ');
1292 $totalarray['nbfield']++;
1293}
1294if (!empty($arrayfields['p.width']['checked'])) {
1295 print_liste_field_titre($arrayfields['p.width']['label'], $_SERVER['PHP_SELF'], 'p.width', '', $param, '', $sortfield, $sortorder, 'center ');
1296 $totalarray['nbfield']++;
1297}
1298if (!empty($arrayfields['p.width_units']['checked'])) {
1299 print_liste_field_titre($arrayfields['p.width_units']['label'], $_SERVER['PHP_SELF'], 'p.width_units', '', $param, '', $sortfield, $sortorder, 'center ');
1300 $totalarray['nbfield']++;
1301}
1302if (!empty($arrayfields['p.height']['checked'])) {
1303 print_liste_field_titre($arrayfields['p.height']['label'], $_SERVER['PHP_SELF'], 'p.height', '', $param, '', $sortfield, $sortorder, 'center ');
1304 $totalarray['nbfield']++;
1305}
1306if (!empty($arrayfields['p.height_units']['checked'])) {
1307 print_liste_field_titre($arrayfields['p.height_units']['label'], $_SERVER['PHP_SELF'], 'p.height_units', '', $param, '', $sortfield, $sortorder, 'center ');
1308 $totalarray['nbfield']++;
1309}
1310if (!empty($arrayfields['p.surface']['checked'])) {
1311 print_liste_field_titre($arrayfields['p.surface']['label'], $_SERVER['PHP_SELF'], "p.surface", '', $param, '', $sortfield, $sortorder, 'center ');
1312 $totalarray['nbfield']++;
1313}
1314if (!empty($arrayfields['p.surface_units']['checked'])) {
1315 print_liste_field_titre($arrayfields['p.surface_units']['label'], $_SERVER['PHP_SELF'], 'p.surface_units', '', $param, '', $sortfield, $sortorder, 'center ');
1316 $totalarray['nbfield']++;
1317}
1318if (!empty($arrayfields['p.volume']['checked'])) {
1319 print_liste_field_titre($arrayfields['p.volume']['label'], $_SERVER['PHP_SELF'], 'p.volume', '', $param, '', $sortfield, $sortorder, 'center ');
1320 $totalarray['nbfield']++;
1321}
1322if (!empty($arrayfields['p.volume_units']['checked'])) {
1323 print_liste_field_titre($arrayfields['p.volume_units']['label'], $_SERVER['PHP_SELF'], 'p.volume_units', '', $param, '', $sortfield, $sortorder, 'center ');
1324 $totalarray['nbfield']++;
1325}
1326if (!empty($arrayfields['cu.label']['checked'])) {
1327 print_liste_field_titre($arrayfields['cu.label']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'center ');
1328 $totalarray['nbfield']++;
1329}
1330if (!empty($arrayfields['p.fk_default_workstation']['checked'])) {
1331 print_liste_field_titre($arrayfields['p.fk_default_workstation']['label'], $_SERVER['PHP_SELF'], 'ws.ref', '', $param, '', $sortfield, $sortorder);
1332 $totalarray['nbfield']++;
1333}
1334if (!empty($arrayfields['p.sellprice']['checked'])) {
1335 print_liste_field_titre($arrayfields['p.sellprice']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1336 $totalarray['nbfield']++;
1337}
1338
1339// Multiprices
1340if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
1341 foreach ($arraypricelevel as $key => $value) {
1342 if (!empty($arrayfields['p.sellprice'.$key]['checked'])) {
1343 print_liste_field_titre($arrayfields['p.sellprice'.$key]['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1344 $totalarray['nbfield']++;
1345 }
1346 }
1347}
1348
1349if (!empty($arrayfields['p.minbuyprice']['checked'])) {
1350 print_liste_field_titre($arrayfields['p.minbuyprice']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1351 $totalarray['nbfield']++;
1352}
1353if (!empty($arrayfields['p.numbuyprice']['checked'])) {
1354 print_liste_field_titre($arrayfields['p.numbuyprice']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1355 $totalarray['nbfield']++;
1356}
1357if (!empty($arrayfields['p.tva_tx']['checked'])) {
1358 print_liste_field_titre($arrayfields['p.tva_tx']['label'], $_SERVER["PHP_SELF"], 'p.tva_tx', "", $param, '', $sortfield, $sortorder, 'right ');
1359 $totalarray['nbfield']++;
1360}
1361if (!empty($arrayfields['p.pmp']['checked'])) {
1362 print_liste_field_titre($arrayfields['p.pmp']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1363 $totalarray['nbfield']++;
1364}
1365if (!empty($arrayfields['p.cost_price']['checked'])) {
1366 print_liste_field_titre($arrayfields['p.cost_price']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ');
1367 $totalarray['nbfield']++;
1368}
1369if (!empty($arrayfields['p.seuil_stock_alerte']['checked'])) {
1370 print_liste_field_titre($arrayfields['p.seuil_stock_alerte']['label'], $_SERVER["PHP_SELF"], "p.seuil_stock_alerte", "", $param, '', $sortfield, $sortorder, 'right ');
1371 $totalarray['nbfield']++;
1372}
1373if (!empty($arrayfields['p.desiredstock']['checked'])) {
1374 print_liste_field_titre($arrayfields['p.desiredstock']['label'], $_SERVER["PHP_SELF"], "p.desiredstock", "", $param, '', $sortfield, $sortorder, 'right ');
1375 $totalarray['nbfield']++;
1376}
1377if (!empty($arrayfields['p.stock']['checked'])) {
1378 print_liste_field_titre($arrayfields['p.stock']['label'], $_SERVER["PHP_SELF"], "p.stock", "", $param, '', $sortfield, $sortorder, 'right ');
1379 $totalarray['nbfield']++;
1380}
1381if (!empty($arrayfields['stock_virtual']['checked'])) {
1382 print_liste_field_titre($arrayfields['stock_virtual']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'right ', 'VirtualStockDesc');
1383 $totalarray['nbfield']++;
1384}
1385if (!empty($arrayfields['p.tobatch']['checked'])) {
1386 print_liste_field_titre($arrayfields['p.tobatch']['label'], $_SERVER["PHP_SELF"], "p.tobatch", "", $param, '', $sortfield, $sortorder, 'center ');
1387 $totalarray['nbfield']++;
1388}
1389if (!empty($arrayfields['p.fk_country']['checked'])) {
1390 print_liste_field_titre($arrayfields['p.fk_country']['label'], $_SERVER["PHP_SELF"], "p.fk_country", "", $param, '', $sortfield, $sortorder);
1391 $totalarray['nbfield']++;
1392}
1393if (!empty($arrayfields['p.fk_state']['checked'])) {
1394 print_liste_field_titre($arrayfields['p.fk_state']['label'], $_SERVER["PHP_SELF"], "p.fk_state", "", $param, '', $sortfield, $sortorder);
1395 $totalarray['nbfield']++;
1396}
1397if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell']['checked'])) {
1398 print_liste_field_titre($arrayfields[$alias_product_perentity . '.accountancy_code_sell']['label'], $_SERVER["PHP_SELF"], $alias_product_perentity . ".accountancy_code_sell", "", $param, '', $sortfield, $sortorder);
1399 $totalarray['nbfield']++;
1400}
1401if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_intra']['checked'])) {
1402 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);
1403 $totalarray['nbfield']++;
1404}
1405if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_export']['checked'])) {
1406 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);
1407 $totalarray['nbfield']++;
1408}
1409if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy']['checked'])) {
1410 print_liste_field_titre($arrayfields[$alias_product_perentity . '.accountancy_code_buy']['label'], $_SERVER["PHP_SELF"], $alias_product_perentity . ".accountancy_code_buy", "", $param, '', $sortfield, $sortorder);
1411 $totalarray['nbfield']++;
1412}
1413if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_intra']['checked'])) {
1414 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);
1415 $totalarray['nbfield']++;
1416}
1417if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_export']['checked'])) {
1418 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);
1419 $totalarray['nbfield']++;
1420}
1421// Extra fields
1422include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1423// Hook fields
1424$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray);
1425$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1426print $hookmanager->resPrint;
1427if (!empty($arrayfields['p.datec']['checked'])) {
1428 print_liste_field_titre($arrayfields['p.datec']['label'], $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1429 $totalarray['nbfield']++;
1430}
1431if (!empty($arrayfields['p.tms']['checked'])) {
1432 print_liste_field_titre($arrayfields['p.tms']['label'], $_SERVER["PHP_SELF"], "p.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1433 $totalarray['nbfield']++;
1434}
1435if (!empty($arrayfields['p.tosell']['checked'])) {
1436 print_liste_field_titre($arrayfields['p.tosell']['label'], $_SERVER["PHP_SELF"], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center ');
1437 $totalarray['nbfield']++;
1438}
1439if (!empty($arrayfields['p.tobuy']['checked'])) {
1440 print_liste_field_titre($arrayfields['p.tobuy']['label'], $_SERVER["PHP_SELF"], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'center ');
1441 $totalarray['nbfield']++;
1442}
1443// Action column
1444if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1445 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1446 $totalarray['nbfield']++;
1447}
1448print '</tr>'."\n";
1449
1450
1451// Loop on record
1452// --------------------------------------------------------------------
1453$i = 0;
1454$savnbfield = $totalarray['nbfield'];
1455$totalarray = array();
1456$totalarray['nbfield'] = 0;
1457$imaxinloop = ($limit ? min($num, $limit) : $num);
1458while ($i < $imaxinloop) {
1459 $obj = $db->fetch_object($resql);
1460 if (empty($obj)) {
1461 break; // Should not happen
1462 }
1463
1464 // Multilangs
1465 if (getDolGlobalInt('MAIN_MULTILANGS')) { // If multilang is enabled
1466 $sql = "SELECT label";
1467 $sql .= " FROM ".MAIN_DB_PREFIX."product_lang";
1468 $sql .= " WHERE fk_product = ".((int) $obj->rowid);
1469 $sql .= " AND lang = '".$db->escape($langs->getDefaultLang())."'";
1470 $sql .= " LIMIT 1";
1471
1472 $result = $db->query($sql);
1473 if ($result) {
1474 $objtp = $db->fetch_object($result);
1475 if (!empty($objtp->label)) {
1476 $obj->label = $objtp->label;
1477 }
1478 }
1479 }
1480
1481 $parameters = array('staticdata' => $obj);
1482 // Note that $action and $object may have been modified by hook
1483 // do product_static fetch in hook if wanted or anything else
1484 $reshook = $hookmanager->executeHooks('loadStaticObject', $parameters, $product_static, $action);
1485 if (empty($reshook)) {
1486 $product_static->id = $obj->rowid;
1487 $product_static->ref = $obj->ref;
1488 $product_static->ref_fourn = empty($obj->ref_supplier) ? '' : $obj->ref_supplier; // deprecated
1489 $product_static->ref_supplier = empty($obj->ref_supplier) ? '' : $obj->ref_supplier;
1490 $product_static->label = $obj->label;
1491 $product_static->barcode = $obj->barcode;
1492 $product_static->finished = $obj->finished;
1493 $product_static->type = $obj->fk_product_type;
1494 $product_static->status_buy = $obj->tobuy;
1495 $product_static->status = $obj->tosell;
1496 $product_static->status_batch = $obj->tobatch;
1497 $product_static->entity = $obj->entity;
1498 $product_static->pmp = $obj->pmp;
1499 $product_static->accountancy_code_sell = $obj->accountancy_code_sell;
1500 $product_static->accountancy_code_sell_export = $obj->accountancy_code_sell_export;
1501 $product_static->accountancy_code_sell_intra = $obj->accountancy_code_sell_intra;
1502 $product_static->accountancy_code_buy = $obj->accountancy_code_buy;
1503 $product_static->accountancy_code_buy_intra = $obj->accountancy_code_buy_intra;
1504 $product_static->accountancy_code_buy_export = $obj->accountancy_code_buy_export;
1505 $product_static->length = $obj->length;
1506 $product_static->length_units = $obj->length_units;
1507 $product_static->width = $obj->width;
1508 $product_static->width_units = $obj->width_units;
1509 $product_static->height = $obj->height;
1510 $product_static->height_units = $obj->height_units;
1511 $product_static->weight = $obj->weight;
1512 $product_static->weight_units = $obj->weight_units;
1513 $product_static->volume = $obj->volume;
1514 $product_static->volume_units = $obj->volume_units;
1515 $product_static->surface = $obj->surface;
1516 $product_static->surface_units = $obj->surface_units;
1517 if (!empty($conf->global->PRODUCT_USE_UNITS)) {
1518 $product_static->fk_unit = $obj->fk_unit;
1519 }
1520
1521 // STOCK_DISABLE_OPTIM_LOAD can be set to force load_stock whatever is permissions on stock.
1522 if ((isModEnabled('stock') && $user->hasRight('stock', 'lire') && $search_type != 1) || !empty($conf->global->STOCK_DISABLE_OPTIM_LOAD)) { // To optimize call of load_stock
1523 if ($product_static->type != 1 || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { // Not a service
1524 $option = 'nobatch';
1525 if (empty($arrayfields['stock_virtual']['checked'])) {
1526 $option .= ',novirtual';
1527 }
1528 $product_static->load_stock($option); // Load stock_reel + stock_warehouse. This can also call load_virtual_stock()
1529 }
1530 }
1531 }
1532
1533 $product_static->price = $obj->price;
1534
1535 $object = $product_static;
1536
1537 $usercancreadprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS')?$user->hasRight('product', 'product_advance', 'read_prices'):$user->hasRight('product', 'lire');
1538 if ($product_static->isService()) {
1539 $usercancreadprice = getDolGlobalString('MAIN_USE_ADVANCED_PERMS')?$user->hasRight('service', 'service_advance', 'read_prices'):$user->hasRight('service', 'lire');
1540 }
1541
1542 if ($mode == 'kanban') {
1543 if ($i == 0) {
1544 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
1545 print '<div class="box-flex-container kanban">';
1546 }
1547
1548 // Output Kanban
1549 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1550 $selected = 0;
1551 if (in_array($object->id, $arrayofselected)) {
1552 $selected = 1;
1553 }
1554 }
1555 print $object->getKanbanView('', array('selected' => in_array($object->id, $arrayofselected)));
1556 if ($i == ($imaxinloop - 1)) {
1557 print '</div>';
1558 print '</td></tr>';
1559 }
1560 } else {
1561 // Show line of result
1562 $j = 0;
1563 print '<tr data-rowid="'.$object->id.'" class="oddeven">';
1564
1565 // Action column
1566 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1567 print '<td class="nowrap center">';
1568 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1569 $selected = 0;
1570 if (in_array($object->id, $arrayofselected)) {
1571 $selected = 1;
1572 }
1573 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
1574 }
1575 print '</td>';
1576 if (!$i) {
1577 $totalarray['nbfield']++;
1578 }
1579 }
1580 // Rowid
1581 if (!empty($arrayfields['p.rowid']['checked'])) {
1582 print '<td class="nowraponall">';
1583 print $product_static->id;
1584 print "</td>\n";
1585 if (!$i) {
1586 $totalarray['nbfield']++;
1587 }
1588 }
1589
1590 // Ref
1591 if (!empty($arrayfields['p.ref']['checked'])) {
1592 print '<td class="tdoverflowmax250">';
1593 print $product_static->getNomUrl(1);
1594 print "</td>\n";
1595 if (!$i) {
1596 $totalarray['nbfield']++;
1597 }
1598 }
1599
1600 // Ref supplier
1601 if (!empty($arrayfields['pfp.ref_fourn']['checked'])) {
1602 print '<td class="tdoverflowmax200">';
1603 print $product_static->getNomUrl(1);
1604 print "</td>\n";
1605 if (!$i) {
1606 $totalarray['nbfield']++;
1607 }
1608 }
1609
1610 // Thumbnail
1611 if (!empty($arrayfields['thumbnail']['checked'])) {
1612 $product_thumbnail_html = '';
1613 if (!empty($product_static->entity)) {
1614 $product_thumbnail = $product_static->show_photos('product', $conf->product->multidir_output[$product_static->entity], 1, 1, 0, 0, 0, 80);
1615 if ($product_static->nbphoto > 0) {
1616 $product_thumbnail_html = $product_thumbnail;
1617 }
1618 }
1619
1620 print '<td class="center">' . $product_thumbnail_html . '</td>';
1621 if (!$i) {
1622 $totalarray['nbfield']++;
1623 }
1624 }
1625
1626 // Label
1627 if (!empty($arrayfields['p.label']['checked'])) {
1628 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($product_static->label).'">'.$product_static->label.'</td>';
1629 if (!$i) {
1630 $totalarray['nbfield']++;
1631 }
1632 }
1633
1634 // Type
1635 if (!empty($arrayfields['p.fk_product_type']['checked'])) {
1636 print '<td class="center">';
1637 $s = '';
1638 if ($product_static->type == 0) {
1639 $s .= img_picto($langs->trans("Product"), 'product', 'class="paddingleftonly paddingrightonly colorgrey"');
1640 } else {
1641 $s .= img_picto($langs->trans("Service"), 'service', 'class="paddingleftonly paddingrightonly colorgrey"');
1642 }
1643 print $s;
1644 print '</td>';
1645 if (!$i) {
1646 $totalarray['nbfield']++;
1647 }
1648 }
1649
1650 // Barcode
1651 if (!empty($arrayfields['p.barcode']['checked'])) {
1652 print '<td>'.$product_static->barcode.'</td>';
1653 if (!$i) {
1654 $totalarray['nbfield']++;
1655 }
1656 }
1657
1658 // Duration
1659 if (!empty($arrayfields['p.duration']['checked'])) {
1660 print '<td class="center nowraponall">';
1661
1662 if (preg_match('/([^a-z]+)[a-z]$/i', $obj->duration)) {
1663 $duration_value = substr($obj->duration, 0, dol_strlen($obj->duration) - 1);
1664 $duration_unit = substr($obj->duration, -1);
1665
1666 if ((float) $duration_value > 1) {
1667 $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"));
1668 } elseif ((float) $duration_value > 0) {
1669 $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"));
1670 }
1671 print $duration_value;
1672 print ((!empty($duration_unit) && isset($dur[$duration_unit]) && $duration_value != '') ? ' '.$langs->trans($dur[$duration_unit]) : '');
1673 } elseif (!preg_match('/^[a-z]$/i', $obj->duration)) { // If duration is a simple char (like 's' of 'm'), we do not show value
1674 print $obj->duration;
1675 }
1676
1677 print '</td>';
1678 if (!$i) {
1679 $totalarray['nbfield']++;
1680 }
1681 }
1682
1683 // Finished
1684 if (!empty($arrayfields['p.finished']['checked'])) {
1685 print '<td class="center">';
1686 print $product_static->getLibFinished();
1687 print '</td>';
1688 if (!$i) {
1689 $totalarray['nbfield']++;
1690 }
1691 }
1692
1693 // Weight
1694 if (!empty($arrayfields['p.weight']['checked'])) {
1695 print '<td class="center">';
1696 print $product_static->weight;
1697 print '</td>';
1698 if (!$i) {
1699 $totalarray['nbfield']++;
1700 }
1701 }
1702 // Weight units
1703 if (!empty($arrayfields['p.weight_units']['checked'])) {
1704 print '<td class="center">';
1705 if ($product_static->weight != '') {
1706 print measuringUnitString(0, 'weight', $product_static->weight_units);
1707 }
1708 print '</td>';
1709 if (!$i) {
1710 $totalarray['nbfield']++;
1711 }
1712 }
1713 // Length
1714 if (!empty($arrayfields['p.length']['checked'])) {
1715 print '<td class="center">';
1716 print $product_static->length;
1717 print '</td>';
1718 if (!$i) {
1719 $totalarray['nbfield']++;
1720 }
1721 }
1722 // Length units
1723 if (!empty($arrayfields['p.length_units']['checked'])) {
1724 print '<td class="center">';
1725 if ($product_static->length != '') {
1726 print measuringUnitString(0, 'size', $product_static->length_units);
1727 }
1728 print '</td>';
1729 if (!$i) {
1730 $totalarray['nbfield']++;
1731 }
1732 }
1733 // Width
1734 if (!empty($arrayfields['p.width']['checked'])) {
1735 print '<td align="center">';
1736 print $product_static->width;
1737 print '</td>';
1738 if (!$i) {
1739 $totalarray['nbfield']++;
1740 }
1741 }
1742 // Width units
1743 if (!empty($arrayfields['p.width_units']['checked'])) {
1744 print '<td class="center">';
1745 if ($product_static->width != '') {
1746 print measuringUnitString(0, 'size', $product_static->width_units);
1747 }
1748 print '</td>';
1749 if (!$i) {
1750 $totalarray['nbfield']++;
1751 }
1752 }
1753 // Height
1754 if (!empty($arrayfields['p.height']['checked'])) {
1755 print '<td align="center">';
1756 print $product_static->height;
1757 print '</td>';
1758 if (!$i) {
1759 $totalarray['nbfield']++;
1760 }
1761 }
1762 // Height units
1763 if (!empty($arrayfields['p.height_units']['checked'])) {
1764 print '<td class="center">';
1765 if ($product_static->height != '') {
1766 print measuringUnitString(0, 'size', $product_static->height_units);
1767 }
1768 print '</td>';
1769 if (!$i) {
1770 $totalarray['nbfield']++;
1771 }
1772 }
1773 // Surface
1774 if (!empty($arrayfields['p.surface']['checked'])) {
1775 print '<td class="center">';
1776 print $product_static->surface;
1777 print '</td>';
1778 if (!$i) {
1779 $totalarray['nbfield']++;
1780 }
1781 }
1782 // Surface units
1783 if (!empty($arrayfields['p.surface_units']['checked'])) {
1784 print '<td class="center">';
1785 if ($product_static->surface != '') {
1786 print measuringUnitString(0, 'surface', $product_static->surface_units);
1787 }
1788 print '</td>';
1789 if (!$i) {
1790 $totalarray['nbfield']++;
1791 }
1792 }
1793 // Volume
1794 if (!empty($arrayfields['p.volume']['checked'])) {
1795 print '<td class="center">';
1796 print $product_static->volume;
1797 print '</td>';
1798 if (!$i) {
1799 $totalarray['nbfield']++;
1800 }
1801 }
1802 // Volume units
1803 if (!empty($arrayfields['p.volume_units']['checked'])) {
1804 print '<td class="center">';
1805 if ($product_static->volume != '') {
1806 print measuringUnitString(0, 'volume', $product_static->volume_units);
1807 }
1808 print '</td>';
1809 if (!$i) {
1810 $totalarray['nbfield']++;
1811 }
1812 }
1813 // Unit
1814 if (!empty($arrayfields['cu.label']['checked'])) {
1815 print '<td align="center">';
1816 if (!empty($obj->cu_label)) {
1817 print $langs->trans($obj->cu_label);
1818 }
1819 print '</td>';
1820 if (!$i) {
1821 $totalarray['nbfield']++;
1822 }
1823 }
1824
1825 // Default Workstation
1826 if (!empty($arrayfields['p.fk_default_workstation']['checked'])) {
1827 print '<td align="left">';
1828 if (!empty($obj->fk_default_workstation)) {
1829 $static_ws->id = $obj->fk_default_workstation;
1830 $static_ws->ref = $obj->ref_workstation;
1831 $static_ws->status = $obj->status_workstation;
1832
1833 print $static_ws->getNomUrl(1);
1834 }
1835 print '</td>';
1836 if (!$i) {
1837 $totalarray['nbfield']++;
1838 }
1839 }
1840
1841 // Sell price
1842 if (!empty($arrayfields['p.sellprice']['checked'])) {
1843 print '<td class="right nowraponall">';
1844 if ($product_static->status && $usercancreadprice) {
1845 if ($obj->price_base_type == 'TTC') {
1846 print '<span class="amount">'.price($obj->price_ttc).' '.$langs->trans("TTC").'</span>';
1847 } else {
1848 print '<span class="amount">'.price($obj->price).' '.$langs->trans("HT").'</span>';
1849 }
1850 }
1851 print '</td>';
1852 if (!$i) {
1853 $totalarray['nbfield']++;
1854 }
1855 }
1856
1857
1858 // Multiprices
1859 if (!empty($conf->global->PRODUIT_MULTIPRICES)) {
1860 if (! isset($productpricescache)) {
1861 $productpricescache=array();
1862 }
1863 if (! isset($productpricescache[$obj->rowid])) {
1864 $productpricescache[$obj->rowid] = array();
1865 }
1866
1867 if ($product_static->status && $usercancreadprice) {
1868 // Make 1 request for all price levels (without filter on price_level) and saved result into an cache array
1869 // then reuse the cache array if we need prices for other price levels
1870 $sqlp = "SELECT p.rowid, p.fk_product, p.price, p.price_ttc, p.price_level, p.date_price, p.price_base_type";
1871 $sqlp .= " FROM ".MAIN_DB_PREFIX."product_price as p";
1872 $sqlp .= " WHERE fk_product = ".((int) $obj->rowid);
1873 $sqlp .= " ORDER BY p.date_price DESC, p.rowid DESC, p.price_level ASC";
1874 $resultp = $db->query($sqlp);
1875 if ($resultp) {
1876 $nump = $db->num_rows($resultp);
1877 $j = 0;
1878 while ($j < $nump) {
1879 $objp = $db->fetch_object($resultp);
1880
1881 if (empty($productpricescache[$obj->rowid][$objp->price_level])) {
1882 $productpricescache[$obj->rowid][$objp->price_level]['price'] = $objp->price;
1883 $productpricescache[$obj->rowid][$objp->price_level]['price_ttc'] = $objp->price_ttc;
1884 $productpricescache[$obj->rowid][$objp->price_level]['price_base_type'] = $objp->price_base_type;
1885 }
1886
1887 $j++;
1888 }
1889
1890 $db->free($resultp);
1891 } else {
1892 dol_print_error($db);
1893 }
1894 }
1895
1896 foreach ($arraypricelevel as $key => $value) {
1897 if (!empty($arrayfields['p.sellprice'.$key]['checked'])) {
1898 print '<td class="right nowraponall">';
1899 if (!empty($productpricescache[$obj->rowid])) {
1900 if ($productpricescache[$obj->rowid][$key]['price_base_type'] == 'TTC') {
1901 print '<span class="amount">'.price($productpricescache[$obj->rowid][$key]['price_ttc']).' '.$langs->trans("TTC").'</span>';
1902 } else {
1903 print '<span class="amount">'.price($productpricescache[$obj->rowid][$key]['price']).' '.$langs->trans("HT").'</span>';
1904 }
1905 }
1906 print '</td>';
1907 if (!$i) {
1908 $totalarray['nbfield']++;
1909 }
1910 }
1911 }
1912 }
1913
1914 // Better buy price
1915 if (!empty($arrayfields['p.minbuyprice']['checked'])) {
1916 print '<td class="right nowraponall">';
1917 if ($product_static->status_buy && $obj->bestpurchaseprice != '' && $usercancreadprice) {
1918 if ($product_fourn->find_min_price_product_fournisseur($obj->rowid) > 0) {
1919 if ($product_fourn->product_fourn_price_id > 0) {
1920 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))) {
1921 $htmltext = $product_fourn->display_price_product_fournisseur(1, 1, 0, 1);
1922 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>';
1923 } else {
1924 print '<span class="amount">'.price($product_fourn->fourn_unitprice).' '.$langs->trans("HT").'</span>';
1925 }
1926 }
1927 }
1928 }
1929 print '</td>';
1930 if (!$i) {
1931 $totalarray['nbfield']++;
1932 }
1933 }
1934
1935 // Number of buy prices
1936 if (!empty($arrayfields['p.numbuyprice']['checked'])) {
1937 print '<td class="right">';
1938 if ($product_static->status_buy && $usercancreadprice) {
1939 if (count($productFournList = $product_fourn->list_product_fournisseur_price($obj->rowid)) > 0) {
1940 $htmltext = $product_fourn->display_price_product_fournisseur(1, 1, 0, 1, $productFournList);
1941 print $form->textwithpicto(count($productFournList), $htmltext);
1942 }
1943 }
1944 print '</td>';
1945 }
1946
1947 // VAT or Sell Tax Rate
1948 if (!empty($arrayfields['p.tva_tx']['checked'])) {
1949 print '<td class="right">';
1950 print vatrate($obj->tva_tx, true);
1951 print '</td>';
1952 if (!$i) {
1953 $totalarray['nbfield']++;
1954 }
1955 }
1956
1957 // WAP
1958 if (!empty($arrayfields['p.pmp']['checked'])) {
1959 print '<td class="nowrap right">';
1960 if ($usercancreadprice) {
1961 print '<span class="amount">'.price($product_static->pmp, 1, $langs)."</span>";
1962 }
1963 print '</td>';
1964 }
1965 // Cost price
1966 if (!empty($arrayfields['p.cost_price']['checked'])) {
1967 print '<td class="nowrap right">';
1968 //print $obj->cost_price;
1969 if ($usercancreadprice) {
1970 print '<span class="amount">'.price($obj->cost_price).' '.$langs->trans("HT").'</span>';
1971 }
1972 print '</td>';
1973 }
1974
1975 // Limit alert
1976 if (!empty($arrayfields['p.seuil_stock_alerte']['checked'])) {
1977 print '<td class="right">';
1978 if ($product_static->type != 1) {
1979 print $obj->seuil_stock_alerte;
1980 }
1981 print '</td>';
1982 if (!$i) {
1983 $totalarray['nbfield']++;
1984 }
1985 }
1986 // Desired stock
1987 if (!empty($arrayfields['p.desiredstock']['checked'])) {
1988 print '<td class="right">';
1989 if ($product_static->type != 1) {
1990 print $obj->desiredstock;
1991 }
1992 print '</td>';
1993 if (!$i) {
1994 $totalarray['nbfield']++;
1995 }
1996 }
1997 // Stock real
1998 if (!empty($arrayfields['p.stock']['checked'])) {
1999 print '<td class="right">';
2000 if ($product_static->type != 1) {
2001 if ($obj->seuil_stock_alerte != '' && $product_static->stock_reel < (float) $obj->seuil_stock_alerte) {
2002 print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
2003 }
2004 if ($usercancreadprice) {
2005 if ($product_static->stock_reel < 0) { print '<span class="warning">'; }
2006 print price(price2num($product_static->stock_reel, 'MS'), 0, $langs, 1, 0);
2007 if ($product_static->stock_reel < 0) { print '</span>'; }
2008 }
2009 }
2010 print '</td>';
2011 if (!$i) {
2012 $totalarray['nbfield']++;
2013 }
2014 }
2015 // Stock virtual
2016 if (!empty($arrayfields['stock_virtual']['checked'])) {
2017 print '<td class="right">';
2018 if ($product_static->type != 1) {
2019 if ($obj->seuil_stock_alerte != '' && $product_static->stock_theorique < (float) $obj->seuil_stock_alerte) {
2020 print img_warning($langs->trans("StockLowerThanLimit", $obj->seuil_stock_alerte)).' ';
2021 }
2022 if ($usercancreadprice) {
2023 if ($product_static->stock_theorique < 0) { print '<span class="warning">'; }
2024 print price(price2num($product_static->stock_theorique, 'MS'), 0, $langs, 1, 0);
2025 if ($product_static->stock_theorique < 0) { print '</span>'; }
2026 }
2027 }
2028 print '</td>';
2029 if (!$i) {
2030 $totalarray['nbfield']++;
2031 }
2032 }
2033 // Lot/Serial
2034 if (!empty($arrayfields['p.tobatch']['checked'])) {
2035 print '<td class="center">';
2036 print $product_static->getLibStatut(1, 2);
2037 print '</td>';
2038 if (!$i) {
2039 $totalarray['nbfield']++;
2040 }
2041 }
2042 // Country
2043 if (!empty($arrayfields['p.fk_country']['checked'])) {
2044 print '<td>'.getCountry($obj->fk_country, 0, $db).'</td>';
2045 if (!$i) {
2046 $totalarray['nbfield']++;
2047 }
2048 }
2049 // State
2050 if (!empty($arrayfields['p.fk_state']['checked'])) {
2051 print '<td>';
2052 if (!empty($obj->fk_state)) {
2053 print getState($obj->fk_state, 0, $db);
2054 }
2055 print '</td>';
2056 if (!$i) {
2057 $totalarray['nbfield']++;
2058 }
2059 }
2060 // Accountancy code sell
2061 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell']['checked'])) {
2062 print '<td>'.length_accountg($product_static->accountancy_code_sell).'</td>';
2063 if (!$i) {
2064 $totalarray['nbfield']++;
2065 }
2066 }
2067 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_intra']['checked'])) {
2068 print '<td>'.length_accountg($product_static->accountancy_code_sell_intra).'</td>';
2069 if (!$i) {
2070 $totalarray['nbfield']++;
2071 }
2072 }
2073 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_sell_export']['checked'])) {
2074 print '<td>'.length_accountg($product_static->accountancy_code_sell_export).'</td>';
2075 if (!$i) {
2076 $totalarray['nbfield']++;
2077 }
2078 }
2079 // Accountancy code buy
2080 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy']['checked'])) {
2081 print '<td>'.length_accountg($product_static->accountancy_code_buy).'</td>';
2082 if (!$i) {
2083 $totalarray['nbfield']++;
2084 }
2085 }
2086 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_intra']['checked'])) {
2087 print '<td>'.length_accountg($product_static->accountancy_code_buy_intra).'</td>';
2088 if (!$i) {
2089 $totalarray['nbfield']++;
2090 }
2091 }
2092 if (!empty($arrayfields[$alias_product_perentity . '.accountancy_code_buy_export']['checked'])) {
2093 print '<td>'.length_accountg($product_static->accountancy_code_buy_export).'</td>';
2094 if (!$i) {
2095 $totalarray['nbfield']++;
2096 }
2097 }
2098 // Extra fields
2099 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
2100 // Fields from hook
2101 $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
2102 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2103 print $hookmanager->resPrint;
2104 // Date creation
2105 if (!empty($arrayfields['p.datec']['checked'])) {
2106 print '<td class="center nowraponall">';
2107 print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
2108 print '</td>';
2109 if (!$i) {
2110 $totalarray['nbfield']++;
2111 }
2112 }
2113 // Date modification
2114 if (!empty($arrayfields['p.tms']['checked'])) {
2115 print '<td class="center nowraponall">';
2116 print dol_print_date($db->jdate($obj->date_update), 'dayhour', 'tzuser');
2117 print '</td>';
2118 if (!$i) {
2119 $totalarray['nbfield']++;
2120 }
2121 }
2122
2123 // Status (to sell)
2124 if (!empty($arrayfields['p.tosell']['checked'])) {
2125 print '<td class="center nowrap">';
2126 if (!empty($conf->use_javascript_ajax) && $user->hasRight("produit", "creer") && !empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
2127 print ajax_object_onoff($product_static, 'status', 'tosell', 'ProductStatusOnSell', 'ProductStatusNotOnSell');
2128 } else {
2129 print $product_static->LibStatut($product_static->status, 5, 0);
2130 }
2131 print '</td>';
2132 if (!$i) {
2133 $totalarray['nbfield']++;
2134 }
2135 }
2136 // Status (to buy)
2137 if (!empty($arrayfields['p.tobuy']['checked'])) {
2138 print '<td class="center nowrap">';
2139 if (!empty($conf->use_javascript_ajax) && $user->hasRight("produit", "creer") && !empty($conf->global->MAIN_DIRECT_STATUS_UPDATE)) {
2140 print ajax_object_onoff($product_static, 'status_buy', 'tobuy', 'ProductStatusOnBuy', 'ProductStatusNotOnBuy');
2141 } else {
2142 print $product_static->LibStatut($product_static->status_buy, 5, 1);
2143 }
2144 print '</td>';
2145 if (!$i) {
2146 $totalarray['nbfield']++;
2147 }
2148 }
2149
2150 // Action column
2151 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2152 print '<td class="nowrap center">';
2153 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
2154 $selected = 0;
2155 if (in_array($object->id, $arrayofselected)) {
2156 $selected = 1;
2157 }
2158 print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
2159 }
2160 print '</td>';
2161 if (!$i) {
2162 $totalarray['nbfield']++;
2163 }
2164 }
2165
2166 print '</tr>'."\n";
2167 }
2168
2169 $i++;
2170}
2171
2172// If no record found
2173if ($num == 0) {
2174 $colspan = 1;
2175 foreach ($arrayfields as $key => $val) {
2176 if (!empty($val['checked'])) {
2177 $colspan++;
2178 }
2179 }
2180 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
2181}
2182
2183$db->free($resql);
2184
2185print '</table>'."\n";
2186print '</div>'."\n";
2187
2188print '</form>'."\n";
2189
2190// End of page
2191llxFooter();
2192$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.