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