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