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