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