dolibarr 20.0.0
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
42require '../main.inc.php';
43require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
44require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
45require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
46require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
48require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
49require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
50require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
51
52if (isModEnabled('workstation')) {
53 require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php';
54}
55if (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'));
62if (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;
89if (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');
96if (!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;
117if (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");
128if (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;
135if (!$sortfield) {
136 $sortfield = "p.ref";
137}
138if (!$sortorder) {
139 $sortorder = "ASC";
140}
141
142// Initialize context for list
143$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'productservicelist';
144if ((string) $type == '1') {
145 $contextpage = 'servicelist';
146 if ($search_type == '') {
147 $search_type = '1';
148 }
149}
150if ((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
169if (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;
176if (!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;
184if (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
202if (getDolGlobalInt('MAIN_MULTILANGS')) {
203 $fieldstosearchall['pl.label'] = 'ProductLabelTranslated';
204 $fieldstosearchall['pl.description'] = 'ProductDescriptionTranslated';
205 $fieldstosearchall['pl.note'] = 'ProductNoteTranslated';
206}
207if (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;'
212if (getDolGlobalString('PRODUCT_QUICKSEARCH_ON_FIELDS')) {
213 $fieldstosearchall = dolExplodeIntoArray($conf->global->PRODUCT_QUICKSEARCH_ON_FIELDS);
214}
215
216if (!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 && (bool) dol_eval($val['enabled'], 1)),
288 'position'=>$val['position']
289 );
290 }
291}*/
292
293
294// MultiPrices
295if (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
310include 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
317if ($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
330if (GETPOST('cancel', 'alpha')) {
331 $action = 'list';
332 $massaction = '';
333}
334if (!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
339if ($reshook < 0) {
340 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
341}
342
343$rightskey = 'produit';
344if ($type == Product::TYPE_SERVICE) {
345 $rightskey = 'service';
346}
347
348if (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);
429if (isModEnabled('workstation')) {
430 $workstation_static = new Workstation($db);
431}
432$product_fourn = new ProductFournisseur($db);
433
434$title = $langs->trans("ProductsAndServices");
435
436if ($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, ';
449if (isModEnabled('workstation')) {
450 $sql .= ' p.fk_default_workstation, ws.status as status_workstation, ws.ref as ref_workstation, ';
451}
452if (!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,';
461if (getDolGlobalString('PRODUCT_USE_UNITS')) {
462 $sql .= ' p.fk_unit, cu.label as cu_label,';
463}
464$sql .= ' MIN(pfp.unitprice) as bestpurchaseprice';
465if (isModEnabled('variants')) {
466 $sql .= ', pac.rowid as prod_comb_id';
467 $sql .= ', pac.fk_product_parent';
468}
469// Add fields from extrafields
470if (!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';
484if (isModEnabled('workstation')) {
485 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "workstation_workstation as ws ON (p.fk_default_workstation = ws.rowid)";
486}
487if (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}
490if (!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
496if (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}
499if (isModEnabled('variants')) {
500 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_attribute_combination pac ON pac.fk_product_child = p.rowid";
501}
502if (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').')';
512if ($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)
530if (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
538if (isModEnabled('variants') && !$show_childproducts) {
539 $sql .= " AND pac.rowid IS NULL";
540}
541
542if ($search_id) {
543 $sql .= natural_search('p.rowid', $search_id, 1);
544}
545if ($search_ref) {
546 $sql .= natural_search('p.ref', $search_ref);
547}
548if ($search_label) {
549 $sql .= natural_search('p.label', $search_label);
550}
551if ($search_default_workstation) {
552 $sql .= natural_search('ws.ref', $search_default_workstation);
553}
554if ($search_barcode) {
555 $sql .= natural_search('p.barcode', $search_barcode);
556}
557if ($search_import_key) {
558 $sql .= natural_search('p.import_key', $search_import_key);
559}
560if (isset($search_tosell) && dol_strlen($search_tosell) > 0 && $search_tosell != -1) {
561 $sql .= " AND p.tosell = ".((int) $search_tosell);
562}
563if (isset($search_tobuy) && dol_strlen($search_tobuy) > 0 && $search_tobuy != -1) {
564 $sql .= " AND p.tobuy = ".((int) $search_tobuy);
565}
566if (isset($search_tobatch) && dol_strlen($search_tobatch) > 0 && $search_tobatch != -1) {
567 $sql .= " AND p.tobatch = ".((int) $search_tobatch);
568}
569if ($search_vatrate) {
570 $sql .= natural_search('p.tva_tx', $search_vatrate, 1);
571}
572if (dol_strlen($canvas) > 0) {
573 $sql .= " AND p.canvas = '".$db->escape($canvas)."'";
574}
575// Search for tag/category ($searchCategoryProductList is an array of ID)
576if (!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}
603if ($fourn_id > 0) {
604 $sql .= " AND pfp.fk_soc = ".((int) $fourn_id);
605}
606if ($search_country) {
607 $sql .= " AND p.fk_country = ".((int) $search_country);
608}
609if ($search_state) {
610 $sql .= " AND p.fk_state = ".((int) $search_state);
611}
612if ($search_finished >= 0 && $search_finished !== '') {
613 $sql .= " AND p.finished = ".((int) $search_finished);
614}
615if ($search_accountancy_code_sell) {
616 $sql .= natural_search($alias_product_perentity . '.accountancy_code_sell', clean_account($search_accountancy_code_sell));
617}
618if ($search_accountancy_code_sell_intra) {
619 $sql .= natural_search($alias_product_perentity . '.accountancy_code_sell_intra', clean_account($search_accountancy_code_sell_intra));
620}
621if ($search_accountancy_code_sell_export) {
622 $sql .= natural_search($alias_product_perentity . '.accountancy_code_sell_export', clean_account($search_accountancy_code_sell_export));
623}
624if ($search_accountancy_code_buy) {
625 $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy', clean_account($search_accountancy_code_buy));
626}
627if ($search_accountancy_code_buy_intra) {
628 $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy_intra', clean_account($search_accountancy_code_buy_intra));
629}
630if ($search_accountancy_code_buy_export) {
631 $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy_export', clean_account($search_accountancy_code_buy_export));
632}
633if (getDolGlobalString('PRODUCT_USE_UNITS') && $search_units) {
634 $sql .= natural_search('cu.rowid', $search_units);
635}
636// Add where from extra fields
637include 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,';
645if (!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';
653if (getDolGlobalString('PRODUCT_USE_UNITS')) {
654 $sql .= ', p.fk_unit, cu.label';
655}
656if (isModEnabled('workstation')) {
657 $sql .= ', p.fk_default_workstation, ws.status, ws.ref';
658}
659if (isModEnabled('variants')) {
660 $sql .= ', pac.rowid';
661 $sql .= ', pac.fk_product_parent';
662}
663// Add fields from extrafields
664if (!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 = '';
676if (!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);
699if ($limit) {
700 $sql .= $db->plimit($limit + 1, $offset);
701}
702
703$resql = $db->query($sql);
704if (!$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
713if ($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 = '';
725if ($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 = '';
734foreach ($searchCategoryProductList as $searchCategoryProduct) {
735 $paramsCat .= "&search_category_product_list[]=".urlencode($searchCategoryProduct);
736}
737
738//llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, 'classforhorizontalscrolloftabs');
739llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, 'bodyforlist mod-product page-list');
740
741$arrayofselected = is_array($toselect) ? $toselect : array();
742
743// Displays product removal confirmation
744if (GETPOST('delprod')) {
745 setEventMessages($langs->trans("ProductDeleted", GETPOST('delprod')), null, 'mesgs');
746}
747
748$param = '';
749if (!empty($mode)) {
750 $param .= '&mode='.urlencode($mode);
751}
752if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
753 $param .= '&contextpage='.urlencode($contextpage);
754}
755if ($limit > 0 && $limit != $conf->liste_limit) {
756 $param .= '&limit='.((int) $limit);
757}
758if ($optioncss != '') {
759 $param .= '&optioncss='.urlencode($optioncss);
760}
761if ($search_all) {
762 $param .= "&search_all=".urlencode($search_all);
763}
764if ($searchCategoryProductOperator == 1) {
765 $param .= "&search_category_product_operator=".urlencode((string) ($searchCategoryProductOperator));
766}
767foreach ($searchCategoryProductList as $searchCategoryProduct) {
768 $param .= "&search_category_product_list[]=".urlencode($searchCategoryProduct);
769}
770if ($search_ref) {
771 $param .= "&search_ref=".urlencode($search_ref);
772}
773if ($search_ref_supplier) {
774 $param .= "&search_ref_supplier=".urlencode($search_ref_supplier);
775}
776if ($search_barcode) {
777 $param .= ($search_barcode ? "&search_barcode=".urlencode($search_barcode) : "");
778}
779if ($search_import_key) {
780 $param .= "&search_import_key=".urlencode($search_import_key);
781}
782if ($search_label) {
783 $param .= "&search_label=".urlencode($search_label);
784}
785if ($search_default_workstation) {
786 $param .= "&search_default_workstation=".urlencode($search_default_workstation);
787}
788if ($search_tosell != '') {
789 $param .= "&search_tosell=".urlencode($search_tosell);
790}
791if ($search_tobuy != '') {
792 $param .= "&search_tobuy=".urlencode($search_tobuy);
793}
794if ($search_tobatch) {
795 $param .= "&search_tobatch=".urlencode($search_tobatch);
796}
797if ($search_country != '') {
798 $param .= "&search_country=".urlencode((string) ($search_country));
799}
800if ($search_state != '') {
801 $param .= "&search_state=".urlencode((string) ($search_state));
802}
803if ($search_vatrate) {
804 $param .= "&search_vatrate=".urlencode($search_vatrate);
805}
806if ($fourn_id > 0) {
807 $param .= "&fourn_id=".urlencode((string) ($fourn_id));
808}
809if ($show_childproducts) {
810 $param .= ($show_childproducts ? "&search_show_childproducts=".urlencode($show_childproducts) : "");
811}
812if ($type != '') {
813 $param .= '&type='.urlencode((string) ($type));
814}
815if ($search_type != '') {
816 $param .= '&search_type='.urlencode($search_type);
817}
818if ($search_accountancy_code_sell) {
819 $param .= "&search_accountancy_code_sell=".urlencode($search_accountancy_code_sell);
820}
821if ($search_accountancy_code_sell_intra) {
822 $param .= "&search_accountancy_code_sell_intra=".urlencode($search_accountancy_code_sell_intra);
823}
824if ($search_accountancy_code_sell_export) {
825 $param .= "&search_accountancy_code_sell_export=".urlencode($search_accountancy_code_sell_export);
826}
827if ($search_accountancy_code_buy) {
828 $param .= "&search_accountancy_code_buy=".urlencode($search_accountancy_code_buy);
829}
830if ($search_accountancy_code_buy_intra) {
831 $param .= "&search_accountancy_code_buy_intra=".urlencode($search_accountancy_code_buy_intra);
832}
833if ($search_accountancy_code_buy_export) {
834 $param .= "&search_accountancy_code_buy_export=".urlencode($search_accountancy_code_buy_export);
835}
836if ($search_finished) {
837 $param .= "&search_finished=".urlencode($search_finished);
838}
839// Add $param from extra fields
840include 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);
854if ($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}
859if (isModEnabled('category') && $user->hasRight($rightskey, 'creer')) {
860 $arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
861}
862if (in_array($massaction, array('presend', 'predelete','preaffecttag', 'edit_extrafields', 'preupdateprice'))) {
863 $arrayofmassactions = array();
864}
865if ($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
874if ($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();
883if ($type === "") {
884 $params['forcenohideoftext'] = 1;
885}
886$newcardbutton .= dolGetButtonTitleSeparator();
887if ((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}
891if ((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
896print '<form id="searchFormList" action="'.$_SERVER["PHP_SELF"].'" method="POST" name="formulaire">';
897if ($optioncss != '') {
898 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
899}
900print '<input type="hidden" name="token" value="'.newToken().'">';
901print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
902print '<input type="hidden" name="action" value="list">';
903print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
904print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
905//print '<input type="hidden" name="page" value="'.$page.'">';
906print '<input type="hidden" name="type" value="'.$type.'">';
907print '<input type="hidden" name="page_y" value="">';
908print '<input type="hidden" name="mode" value="'.$mode.'">';
909
910if (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';
915if ($type == 1) {
916 $picto = 'service';
917}
918
919print_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;
925include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
926
927if (!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
935if ($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 = '';
947if (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
953if (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
962if (empty($reshook)) {
963 $moreforfilter .= $hookmanager->resPrint;
964} else {
965 $moreforfilter = $hookmanager->resPrint;
966}
967
968if (!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
979print '<div class="div-table-responsive">';
980print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
981
982// Fields title search
983// --------------------------------------------------------------------
984print '<tr class="liste_titre_filter">';
985// Action column
986if (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}
992if (!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}
997if (!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}
1002if (!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
1008if (!empty($arrayfields['thumbnail']['checked'])) {
1009 print '<td class="liste_titre center">';
1010 print '</td>';
1011}
1012if (!empty($arrayfields['p.label']['checked'])) {
1013 print '<td class="liste_titre left">';
1014 print '<input class="flat width100" type="text" name="search_label" value="'.dol_escape_htmltag($search_label).'">';
1015 print '</td>';
1016}
1017// Type
1018if (!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
1025if (!empty($arrayfields['p.description']['checked'])) {
1026 print '<td class="liste_titre left">';
1027 print '</td>';
1028}
1029// Barcode
1030if (!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
1036if (!empty($arrayfields['p.duration']['checked'])) {
1037 print '<td class="liste_titre">';
1038 print '</td>';
1039}
1040// Parent
1041if (!empty($arrayfields['pac.fk_product_parent']['checked'])) {
1042 print '<td class="liste_titre">';
1043 print '</td>';
1044}
1045// Finished
1046if (!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
1052if (!empty($arrayfields['p.weight']['checked'])) {
1053 print '<td class="liste_titre">';
1054 print '</td>';
1055}
1056// Weight units
1057if (!empty($arrayfields['p.weight_units']['checked'])) {
1058 print '<td class="liste_titre">';
1059 print '</td>';
1060}
1061// Length
1062if (!empty($arrayfields['p.length']['checked'])) {
1063 print '<td class="liste_titre">';
1064 print '</td>';
1065}
1066// Length units
1067if (!empty($arrayfields['p.length_units']['checked'])) {
1068 print '<td class="liste_titre">';
1069 print '</td>';
1070}
1071// Width
1072if (!empty($arrayfields['p.width']['checked'])) {
1073 print '<td class="liste_titre">';
1074 print '</td>';
1075}
1076// Width units
1077if (!empty($arrayfields['p.width_units']['checked'])) {
1078 print '<td class="liste_titre">';
1079 print '</td>';
1080}
1081// Height
1082if (!empty($arrayfields['p.height']['checked'])) {
1083 print '<td class="liste_titre">';
1084 print '</td>';
1085}
1086// Height units
1087if (!empty($arrayfields['p.height_units']['checked'])) {
1088 print '<td class="liste_titre">';
1089 print '</td>';
1090}
1091// Surface
1092if (!empty($arrayfields['p.surface']['checked'])) {
1093 print '<td class="liste_titre">';
1094 print '</td>';
1095}
1096// Surface units
1097if (!empty($arrayfields['p.surface_units']['checked'])) {
1098 print '<td class="liste_titre">';
1099 print '</td>';
1100}
1101// Volume
1102if (!empty($arrayfields['p.volume']['checked'])) {
1103 print '<td class="liste_titre">';
1104 print '</td>';
1105}
1106// Volume units
1107if (!empty($arrayfields['p.volume_units']['checked'])) {
1108 print '<td class="liste_titre">';
1109 print '</td>';
1110}
1111
1112// Unit
1113if (!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
1120if (!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
1127if (!empty($arrayfields['p.sellprice']['checked'])) {
1128 print '<td class="liste_titre right">';
1129 print '</td>';
1130}
1131
1132// Multiprice
1133if (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
1143if (!empty($arrayfields['p.minbuyprice']['checked'])) {
1144 print '<td class="liste_titre">';
1145 print '&nbsp;';
1146 print '</td>';
1147}
1148// Number buying Price
1149if (!empty($arrayfields['p.numbuyprice']['checked'])) {
1150 print '<td class="liste_titre">';
1151 print '&nbsp;';
1152 print '</td>';
1153}
1154// VAT or Sell Tax Rate
1155if (!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
1161if (!empty($arrayfields['p.pmp']['checked'])) {
1162 print '<td class="liste_titre">';
1163 print '&nbsp;';
1164 print '</td>';
1165}
1166// cost_price
1167if (!empty($arrayfields['p.cost_price']['checked'])) {
1168 print '<td class="liste_titre">';
1169 print '&nbsp;';
1170 print '</td>';
1171}
1172// Limit for alert
1173if (!empty($arrayfields['p.seuil_stock_alerte']['checked'])) {
1174 print '<td class="liste_titre">';
1175 print '&nbsp;';
1176 print '</td>';
1177}
1178// Desired stock
1179if (!empty($arrayfields['p.desiredstock']['checked'])) {
1180 print '<td class="liste_titre">';
1181 print '&nbsp;';
1182 print '</td>';
1183}
1184// Stock
1185if (!empty($arrayfields['p.stock']['checked'])) {
1186 print '<td class="liste_titre">&nbsp;</td>';
1187}
1188// Stock
1189if (!empty($arrayfields['stock_virtual']['checked'])) {
1190 print '<td class="liste_titre">&nbsp;</td>';
1191}
1192// To batch
1193if (!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
1205if (!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
1211if (!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
1217if (!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}
1220if (!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}
1223if (!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
1227if (!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}
1230if (!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}
1233if (!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
1237include 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
1241print $hookmanager->resPrint;
1242// Date creation
1243if (!empty($arrayfields['p.datec']['checked'])) {
1244 print '<td class="liste_titre">';
1245 print '</td>';
1246}
1247// Date modification
1248if (!empty($arrayfields['p.tms']['checked'])) {
1249 print '<td class="liste_titre">';
1250 print '</td>';
1251}
1252if (!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}
1257if (!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}
1262if (!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
1268if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1269 print '<td class="liste_titre center maxwidthsearch">';
1270 $searchpicto = $form->showFilterButtons();
1271 print $searchpicto;
1272 print '</td>';
1273}
1274print '</tr>'."\n";
1275
1276$totalarray = array();
1277$totalarray['nbfield'] = 0;
1278
1279// Fields title label
1280// --------------------------------------------------------------------
1281print '<tr class="liste_titre">';
1282// Action column
1283if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1284 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1285 $totalarray['nbfield']++;
1286}
1287if (!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}
1291if (!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}
1295if (!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}
1299if (!empty($arrayfields['thumbnail']['checked'])) {
1300 print_liste_field_titre($arrayfields['thumbnail']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'center ');
1301 $totalarray['nbfield']++;
1302}
1303if (!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}
1307if (!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}
1311if (!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}
1315if (!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}
1319if (!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}
1323if (!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}
1327if (!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}
1331if (!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}
1335if (!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}
1339if (!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}
1343if (!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}
1347if (!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}
1351if (!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}
1355if (!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}
1359if (!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}
1363if (!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}
1367if (!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}
1371if (!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}
1375if (!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}
1379if (!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}
1383if (!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}
1387if (!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
1393if (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
1402if (!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}
1406if (!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}
1410if (!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}
1414if (!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}
1418if (!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}
1422if (!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}
1426if (!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}
1430if (!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}
1434if (!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}
1438if (!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}
1442if (!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}
1446if (!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}
1450if (!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}
1454if (!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}
1458if (!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}
1462if (!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}
1466if (!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}
1470if (!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
1475include 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
1479print $hookmanager->resPrint;
1480if (!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}
1484if (!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}
1488if (!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}
1492if (!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}
1496if (!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
1501if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1502 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1503 $totalarray['nbfield']++;
1504}
1505print '</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);
1515while ($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
2287if ($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
2299print '</table>'."\n";
2300print '</div>'."\n";
2301
2302print '</form>'."\n";
2303
2304// End of page
2305llxFooter();
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, $moreparam='')
On/off button to change a property status of an object This uses the ajax service objectonoff....
Definition ajax.lib.php:725
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)
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...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
measuringUnitString($unit, $measuring_style='', $scale='', $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.