dolibarr 18.0.6
movement_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-2017 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2014 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2015 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2018-2022 Ferran Marcet <fmarcet@2byte.es>
7 * Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
29// Load Dolibarr environment
30require '../../main.inc.php';
31require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
32require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
33require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
34require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
35require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
37require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/stock.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
42if (isModEnabled('project')) {
43 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
44 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
45}
46
47// Load translation files required by the page
48$langs->loadLangs(array('products', 'stocks', 'orders'));
49if (isModEnabled('productbatch')) {
50 $langs->load("productbatch");
51}
52
53$action = GETPOST('action', 'aZ09');
54$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
55$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
56$cancel = GETPOST('cancel', 'alpha');
57$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
58$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
59$backtopage = GETPOST("backtopage", "alpha");
60$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
61$mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...)
62
63$id = GETPOST('id', 'int');
64$ref = GETPOST('ref', 'alpha');
65$msid = GETPOST('msid', 'int');
66$idproduct = GETPOST('idproduct', 'int');
67$product_id = GETPOST("product_id", 'int');
68
69$search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
70$search_date_startday = GETPOST('search_date_startday', 'int');
71$search_date_startmonth = GETPOST('search_date_startmonth', 'int');
72$search_date_startyear = GETPOST('search_date_startyear', 'int');
73$search_date_endday = GETPOST('search_date_endday', 'int');
74$search_date_endmonth = GETPOST('search_date_endmonth', 'int');
75$search_date_endyear = GETPOST('search_date_endyear', 'int');
76$search_date_start = dol_mktime(0, 0, 0, GETPOST('search_date_startmonth', 'int'), GETPOST('search_date_startday', 'int'), GETPOST('search_date_startyear', 'int'), 'tzuserrel');
77$search_date_end = dol_mktime(23, 59, 59, GETPOST('search_date_endmonth', 'int'), GETPOST('search_date_endday', 'int'), GETPOST('search_date_endyear', 'int'), 'tzuserrel');
78$search_ref = GETPOST('search_ref', 'alpha');
79$search_movement = GETPOST("search_movement");
80$search_product_ref = trim(GETPOST("search_product_ref"));
81$search_product = trim(GETPOST("search_product"));
82$search_warehouse = trim(GETPOST("search_warehouse"));
83$search_inventorycode = trim(GETPOST("search_inventorycode"));
84$search_user = trim(GETPOST("search_user"));
85$search_batch = trim(GETPOST("search_batch"));
86$search_qty = trim(GETPOST("search_qty"));
87$search_type_mouvement = GETPOST('search_type_mouvement', 'int');
88$search_fk_projet=GETPOST("search_fk_projet", 'int');
89
90$type = GETPOST("type", "int");
91
92// Load variable for pagination
93$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
94$sortfield = GETPOST('sortfield', 'aZ09comma');
95$sortorder = GETPOST('sortorder', 'aZ09comma');
96$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
97if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
98 // If $page is not defined, or '' or -1 or if we click on clear filters
99 $page = 0;
100}
101$offset = $limit * $page;
102$pageprev = $page - 1;
103$pagenext = $page + 1;
104
105if (!$sortfield) {
106 $sortfield = "m.datem";
107}
108if (!$sortorder) {
109 $sortorder = "DESC";
110}
111
112$pdluoid = GETPOST('pdluoid', 'int');
113
114// Initialize technical objects
115$object = new MouvementStock($db);
116$extrafields = new ExtraFields($db);
117$diroutputmassaction = $conf->stock->dir_output.'/temp/massgeneration/'.$user->id;
118$hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array of activated contexes
119
120$formfile = new FormFile($db);
121
122// Fetch optionals attributes and labels
123$extrafields->fetch_name_optionals_label($object->table_element);
124
125$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
126
127$arrayfields = array(
128 'm.rowid'=>array('label'=>"Ref", 'checked'=>1, 'position'=>1),
129 'm.datem'=>array('label'=>"Date", 'checked'=>1, 'position'=>2),
130 'p.ref'=>array('label'=>"ProductRef", 'checked'=>1, 'css'=>'maxwidth100', 'position'=>3),
131 'p.label'=>array('label'=>"ProductLabel", 'checked'=>0, 'position'=>5),
132 'm.batch'=>array('label'=>"BatchNumberShort", 'checked'=>1, 'position'=>8, 'enabled'=>(isModEnabled('productbatch'))),
133 'pl.eatby'=>array('label'=>"EatByDate", 'checked'=>0, 'position'=>9, 'enabled'=>(isModEnabled('productbatch'))),
134 'pl.sellby'=>array('label'=>"SellByDate", 'checked'=>0, 'position'=>10, 'enabled'=>(isModEnabled('productbatch'))),
135 'e.ref'=>array('label'=>"Warehouse", 'checked'=>1, 'position'=>100, 'enabled'=>(!($id > 0))), // If we are on specific warehouse, we hide it
136 'm.fk_user_author'=>array('label'=>"Author", 'checked'=>0, 'position'=>120),
137 'm.inventorycode'=>array('label'=>"InventoryCodeShort", 'checked'=>1, 'position'=>130),
138 'm.label'=>array('label'=>"MovementLabel", 'checked'=>1, 'position'=>140),
139 'm.type_mouvement'=>array('label'=>"TypeMovement", 'checked'=>0, 'position'=>150),
140 'origin'=>array('label'=>"Origin", 'checked'=>1, 'position'=>155),
141 'm.fk_projet'=>array('label'=>'Project', 'checked'=>0, 'position'=>180),
142 'm.value'=>array('label'=>"Qty", 'checked'=>1, 'position'=>200),
143 'm.price'=>array('label'=>"UnitPurchaseValue", 'checked'=>0, 'position'=>210, 'enabled'=>(!getDolGlobalInt('STOCK_MOVEMENT_LIST_HIDE_UNIT_PRICE')))
144 //'m.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500),
145 //'m.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500)
146);
147
148include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
149
150if (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
151 unset($arrayfields['pl.sellby']);
152}
153if (!empty($conf->global->PRODUCT_DISABLE_EATBY)) {
154 unset($arrayfields['pl.eatby']);
155}
156
157
158$tmpwarehouse = new Entrepot($db);
159if ($id > 0 || !empty($ref)) {
160 $tmpwarehouse->fetch($id, $ref);
161 $id = $tmpwarehouse->id;
162}
163
164
165// Security check
166//$result=restrictedArea($user, 'stock', $id, 'entrepot&stock');
167$result = restrictedArea($user, 'stock');
168
169// Security check
170if (!$user->rights->stock->mouvement->lire) {
172}
173
174$uploaddir = $conf->stock->dir_output.'/movements';
175
176$permissiontoread = $user->rights->stock->mouvement->lire;
177$permissiontoadd = $user->rights->stock->mouvement->creer;
178$permissiontodelete = $user->rights->stock->mouvement->creer; // There is no deletion permission for stock movement as we shoul dnever delete
179
180$usercanread = $user->rights->stock->mouvement->lire;
181$usercancreate = $user->rights->stock->mouvement->creer;
182$usercandelete = $user->rights->stock->mouvement->creer;
183
184$error = 0;
185
186
187/*
188 * Actions
189 */
190
191if (GETPOST('cancel', 'alpha')) {
192 $action = 'list';
193 $massaction = '';
194}
195if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
196 $massaction = '';
197}
198
199$parameters = array();
200$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
201if ($reshook < 0) {
202 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
203}
204
205if (empty($reshook)) {
206 // Selection of new fields
207 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
208
209 // Purge search criteria
210 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // Both test are required to be compatible with all browsers
211 $search_date_startday = '';
212 $search_date_startmonth = '';
213 $search_date_startyear = '';
214 $search_date_endday = '';
215 $search_date_endmonth = '';
216 $search_date_endyear = '';
217 $search_date_start = '';
218 $search_date_end = '';
219 $search_ref = '';
220 $search_movement = "";
221 $search_type_mouvement = "";
222 $search_inventorycode = "";
223 $search_product_ref = "";
224 $search_product = "";
225 $search_warehouse = "";
226 $search_user = "";
227 $search_batch = "";
228 $search_qty = '';
229 $search_fk_projet=0;
230 $search_all = "";
231 $toselect = array();
232 $search_array_options = array();
233 }
234 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
235 || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
236 $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
237 }
238
239 // Mass actions
240 $objectclass = 'MouvementStock';
241 $objectlabel = 'MouvementStock';
242
243 if (!$error && $massaction == "builddoc" && $permissiontoread && !GETPOST('button_search')) {
244 if (empty($diroutputmassaction)) {
245 dol_print_error(null, 'include of actions_massactions.inc.php is done but var $diroutputmassaction was not defined');
246 exit;
247 }
248
249 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
250 require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
251 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
252
253 $objecttmp = new $objectclass($db);
254 $listofobjectid = array();
255 foreach ($toselect as $toselectid) {
256 $objecttmp = new $objectclass($db); // must create new instance because instance is saved into $listofobjectref array for future use
257 $result = $objecttmp->fetch($toselectid);
258 if ($result > 0) {
259 $listofobjectid[$toselectid] = $toselectid;
260 }
261 }
262
263 $arrayofinclusion = array();
264 foreach ($listofobjectref as $tmppdf) {
265 $arrayofinclusion[] = '^'.preg_quote(dol_sanitizeFileName($tmppdf), '/').'\.pdf$';
266 }
267 foreach ($listofobjectref as $tmppdf) {
268 $arrayofinclusion[] = '^'.preg_quote(dol_sanitizeFileName($tmppdf), '/').'_[a-zA-Z0-9-_]+\.pdf$'; // To include PDF generated from ODX files
269 }
270 $listoffiles = dol_dir_list($uploaddir, 'all', 1, implode('|', $arrayofinclusion), '\.meta$|\.png', 'date', SORT_DESC, 0, true);
271
272 // Define output language (Here it is not used because we do only merging existing PDF)
273 $outputlangs = $langs;
274 $newlang = '';
275 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
276 $newlang = GETPOST('lang_id', 'aZ09');
277 }
278 //elseif (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && is_object($objecttmp->thirdparty)) { // On massaction, we can have several values for $objecttmp->thirdparty
279 // $newlang = $objecttmp->thirdparty->default_lang;
280 //}
281 if (!empty($newlang)) {
282 $outputlangs = new Translate("", $conf);
283 $outputlangs->setDefaultLang($newlang);
284 }
285
286 // Create output dir if not exists
287 dol_mkdir($diroutputmassaction);
288
289 // Defined name of merged file
290 $filename = strtolower(dol_sanitizeFileName($langs->transnoentities($objectlabel)));
291 $filename = preg_replace('/\s/', '_', $filename);
292
293 // Save merged file
294 /*
295 if ($year) {
296 $filename .= '_'.$year;
297 }
298 if ($month) {
299 $filename .= '_'.$month;
300 }
301 */
302 $now = dol_now();
303 $file = $diroutputmassaction.'/'.$filename.'_'.dol_print_date($now, 'dayhourlog').'.pdf';
304
305
306 // Create PDF
307 // TODO Create the pdf including list of movement ids found into $listofobjectid
308 // ...
309
310
311 if (!$error) {
312 $langs->load("exports");
313 setEventMessages($langs->trans('FileSuccessfullyBuilt', $filename.'_'.dol_print_date($now, 'dayhourlog')), null, 'mesgs');
314 }
315
316 $massaction = '';
317 $action = '';
318 }
319
320 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
321}
322
323if ($action == 'update_extras') {
324 $tmpwarehouse->oldcopy = dol_clone($tmpwarehouse);
325
326 // Fill array 'array_options' with data from update form
327 $ret = $extrafields->setOptionalsFromPost(null, $tmpwarehouse, GETPOST('attribute', 'restricthtml'));
328 if ($ret < 0) {
329 $error++;
330 }
331 if (!$error) {
332 $result = $tmpwarehouse->insertExtraFields();
333 if ($result < 0) {
334 setEventMessages($tmpwarehouse->error, $tmpwarehouse->errors, 'errors');
335 $error++;
336 }
337 }
338 if ($error) {
339 $action = 'edit_extras';
340 }
341}
342
343// Correct stock
344if ($action == "correct_stock") {
345 $product = new Product($db);
346 if (!empty($product_id)) {
347 $result = $product->fetch($product_id);
348 }
349
350 $error = 0;
351
352 if (empty($product_id)) {
353 $error++;
354 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors');
355 $action = 'correction';
356 }
357 if (!is_numeric(GETPOST("nbpiece"))) {
358 $error++;
359 setEventMessages($langs->trans("ErrorFieldMustBeANumeric", $langs->transnoentitiesnoconv("NumberOfUnit")), null, 'errors');
360 $action = 'correction';
361 }
362
363 if (!$error) {
364 $origin_element = '';
365 $origin_id = null;
366
367 if (GETPOST('projectid', 'int')) {
368 $origin_element = 'project';
369 $origin_id = GETPOST('projectid', 'int');
370 }
371
372 if ($product->hasbatch()) {
373 $batch = GETPOST('batch_number', 'alphanohtml');
374
375 //$eatby=GETPOST('eatby');
376 //$sellby=GETPOST('sellby');
377 $eatby = dol_mktime(0, 0, 0, GETPOST('eatbymonth', 'int'), GETPOST('eatbyday', 'int'), GETPOST('eatbyyear', 'int'));
378 $sellby = dol_mktime(0, 0, 0, GETPOST('sellbymonth', 'int'), GETPOST('sellbyday', 'int'), GETPOST('sellbyyear', 'int'));
379
380 $result = $product->correct_stock_batch(
381 $user,
382 $id,
383 GETPOST("nbpiece", 'int'),
384 GETPOST("mouvement", 'int'),
385 GETPOST("label", 'alphanohtml'),
386 price2num(GETPOST('unitprice'), 'MT'),
387 $eatby,
388 $sellby,
389 $batch,
390 GETPOST('inventorycode', 'alphanohtml'),
391 $origin_element,
392 $origin_id,
393 0,
394 $extrafields
395 ); // We do not change value of stock for a correction
396 } else {
397 $result = $product->correct_stock(
398 $user,
399 $id,
400 GETPOST("nbpiece", 'int'),
401 GETPOST("mouvement", "int"),
402 GETPOST("label", 'alphanohtml'),
403 price2num(GETPOST('unitprice'), 'MT'),
404 GETPOST('inventorycode', 'alphanohtml'),
405 $origin_element,
406 $origin_id,
407 0,
408 $extrafields
409 ); // We do not change value of stock for a correction
410 }
411
412 if ($result > 0) {
413 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
414 exit;
415 } else {
416 $error++;
417 setEventMessages($product->error, $product->errors, 'errors');
418 $action = 'correction';
419 }
420 }
421
422 if (!$error) {
423 $action = '';
424 }
425}
426
427// Transfer stock from a warehouse to another warehouse
428if ($action == "transfert_stock" && !$cancel) {
429 $product = new Product($db);
430 if (!empty($product_id)) {
431 $result = $product->fetch($product_id);
432 }
433
434 if (!(GETPOST("id_entrepot_destination", 'int') > 0)) {
435 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
436 $error++;
437 $action = 'transfert';
438 }
439 if (empty($product_id)) {
440 $error++;
441 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Product")), null, 'errors');
442 $action = 'transfert';
443 }
444 if (!GETPOST("nbpiece", 'int')) {
445 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NumberOfUnit")), null, 'errors');
446 $error++;
447 $action = 'transfert';
448 }
449 if ($id == GETPOST("id_entrepot_destination", 'int')) {
450 setEventMessages($langs->trans("ErrorSrcAndTargetWarehouseMustDiffers"), null, 'errors');
451 $error++;
452 $action = 'transfert';
453 }
454
455 if (isModEnabled('productbatch')) {
456 $product = new Product($db);
457 $result = $product->fetch($product_id);
458
459 if ($product->hasbatch() && !GETPOST("batch_number")) {
460 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("batch_number")), null, 'errors');
461 $error++;
462 $action = 'transfert';
463 }
464 }
465
466 if (!$error) {
467 if ($id) {
468 $object = new Entrepot($db);
469 $result = $object->fetch($id);
470
471 $db->begin();
472
473 $product->load_stock('novirtual'); // Load array product->stock_warehouse
474
475 // Define value of products moved
476 $pricesrc = 0;
477 if (isset($product->pmp)) {
478 $pricesrc = $product->pmp;
479 }
480 $pricedest = $pricesrc;
481
482 if ($product->hasbatch()) {
483 $pdluo = new Productbatch($db);
484
485 if ($pdluoid > 0) {
486 $result = $pdluo->fetch($pdluoid);
487 if ($result) {
488 $srcwarehouseid = $pdluo->warehouseid;
489 $batch = $pdluo->batch;
490 $eatby = $pdluo->eatby;
491 $sellby = $pdluo->sellby;
492 } else {
493 setEventMessages($pdluo->error, $pdluo->errors, 'errors');
494 $error++;
495 }
496 } else {
497 $srcwarehouseid = $id;
498 $batch = GETPOST('batch_number', 'alphanohtml');
499 $eatby = $d_eatby;
500 $sellby = $d_sellby;
501 }
502
503 if (!$error) {
504 // Remove stock
505 $result1 = $product->correct_stock_batch(
506 $user,
507 $srcwarehouseid,
508 GETPOST("nbpiece", 'int'),
509 1,
510 GETPOST("label", 'san_alpha'),
511 $pricesrc,
512 $eatby,
513 $sellby,
514 $batch,
515 GETPOST('inventorycode'),
516 '',
517 null,
518 0,
519 $extrafields
520 );
521 // Add stock
522 $result2 = $product->correct_stock_batch(
523 $user,
524 GETPOST("id_entrepot_destination", 'int'),
525 GETPOST("nbpiece", 'int'),
526 0,
527 GETPOST("label", 'san_alpha'),
528 $pricedest,
529 $eatby,
530 $sellby,
531 $batch,
532 GETPOST('inventorycode', 'alphanohtml'),
533 '',
534 null,
535 0,
536 $extrafields
537 );
538 }
539 } else {
540 // Remove stock
541 $result1 = $product->correct_stock(
542 $user,
543 $id,
544 GETPOST("nbpiece"),
545 1,
546 GETPOST("label", 'san_alpha'),
547 $pricesrc,
548 GETPOST('inventorycode', 'alphanohtml'),
549 '',
550 null,
551 0,
552 $extrafields
553 );
554
555 // Add stock
556 $result2 = $product->correct_stock(
557 $user,
558 GETPOST("id_entrepot_destination"),
559 GETPOST("nbpiece"),
560 0,
561 GETPOST("label", 'san_alpha'),
562 $pricedest,
563 GETPOST('inventorycode', 'alphanohtml'),
564 '',
565 null,
566 0,
567 $extrafields
568 );
569 }
570 if (!$error && $result1 >= 0 && $result2 >= 0) {
571 $db->commit();
572
573 if ($backtopage) {
574 header("Location: ".$backtopage);
575 exit;
576 } else {
577 header("Location: movement_list.php?id=".$object->id);
578 exit;
579 }
580 } else {
581 setEventMessages($product->error, $product->errors, 'errors');
582 $db->rollback();
583 $action = 'transfert';
584 }
585 }
586 }
587}
588
589
590/*
591 * View
592 */
593
594$form = new Form($db);
595$formproduct = new FormProduct($db);
596if (isModEnabled('project')) {
597 $formproject = new FormProjets($db);
598}
599$productlot = new Productlot($db);
600$productstatic = new Product($db);
601$warehousestatic = new Entrepot($db);
602$movement = new MouvementStock($db);
603$userstatic = new User($db);
604
605$now = dol_now();
606
607// Build and execute select
608// --------------------------------------------------------------------
609$sql = "SELECT p.rowid, p.ref as product_ref, p.label as produit, p.tosell, p.tobuy, p.tobatch, p.fk_product_type as type, p.entity,";
610$sql .= " e.ref as warehouse_ref, e.rowid as entrepot_id, e.lieu, e.fk_parent, e.statut,";
611$sql .= " m.rowid as mid, m.value as qty, m.datem, m.fk_user_author, m.label, m.inventorycode, m.fk_origin, m.origintype,";
612$sql .= " m.batch, m.price,";
613$sql .= " m.type_mouvement,";
614$sql .= " m.fk_projet as fk_project,";
615$sql .= " pl.rowid as lotid, pl.eatby, pl.sellby,";
616$sql .= " u.login, u.photo, u.lastname, u.firstname, u.email as user_email, u.statut as user_status";
617// Add fields from extrafields
618if (!empty($extrafields->attributes[$object->table_element]['label'])) {
619 foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
620 $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
621 }
622}
623// Add fields from hooks
624$parameters = array();
625$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
626$sql .= $hookmanager->resPrint;
627$sql = preg_replace('/,\s*$/', '', $sql);
628
629$sqlfields = $sql; // $sql fields to remove for count total
630
631$sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e,";
632$sql .= " ".MAIN_DB_PREFIX."product as p,";
633$sql .= " ".MAIN_DB_PREFIX."stock_mouvement as m";
634if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
635 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (m.rowid = ef.fk_object)";
636}
637$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON m.fk_user_author = u.rowid";
638$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_lot as pl ON m.batch = pl.batch AND m.fk_product = pl.fk_product";
639
640// Add table from hooks
641$parameters = array();
642$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
643$sql .= $hookmanager->resPrint;
644
645$sql .= " WHERE m.fk_product = p.rowid";
646if ($msid > 0) {
647 $sql .= " AND m.rowid = ".((int) $msid);
648}
649$sql .= " AND m.fk_entrepot = e.rowid";
650$sql .= " AND e.entity IN (".getEntity('stock').")";
651if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
652 $sql .= " AND p.fk_product_type = 0";
653}
654if ($id > 0) {
655 $sql .= " AND e.rowid = ".((int) $id);
656}
657if (!empty($search_date_start)) {
658 $sql .= " AND m.datem >= '" . $db->idate($search_date_start) . "'";
659}
660if (!empty($search_date_end)) {
661 $sql .= " AND m.datem <= '" . $db->idate($search_date_end) . "'";
662}
663if ($idproduct > 0) {
664 $sql .= " AND p.rowid = ".((int) $idproduct);
665}
666if (!empty($search_ref)) {
667 $sql .= natural_search('m.rowid', $search_ref, 1);
668}
669if (!empty($search_movement)) {
670 $sql .= natural_search('m.label', $search_movement);
671}
672if (!empty($search_inventorycode)) {
673 $sql .= natural_search('m.inventorycode', $search_inventorycode);
674}
675if (!empty($search_product_ref)) {
676 $sql .= natural_search('p.ref', $search_product_ref);
677}
678if (!empty($search_product)) {
679 $sql .= natural_search('p.label', $search_product);
680}
681if ($search_warehouse != '' && $search_warehouse != '-1') {
682 $sql .= natural_search('e.rowid', $search_warehouse, 2);
683}
684if (!empty($search_user)) {
685 $sql .= natural_search(array('u.lastname', 'u.firstname', 'u.login'), $search_user);
686}
687if (!empty($search_batch)) {
688 $sql .= natural_search('m.batch', $search_batch);
689}
690if (!empty($product_id) && $product_id != '-1') {
691 $sql .= natural_search('p.rowid', $product_id);
692}
693if (!empty($search_fk_projet) && $search_fk_projet != '-1') {
694 $sql .= natural_search('m.fk_projet', $search_fk_projet);
695}
696if ($search_qty != '') {
697 $sql .= natural_search('m.value', $search_qty, 1);
698}
699if ($search_type_mouvement != '' && $search_type_mouvement != '-1') {
700 $sql .= natural_search('m.type_mouvement', $search_type_mouvement, 2);
701}
702// Add where from extra fields
703include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
704// Add where from hooks
705$parameters = array();
706$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
707$sql .= $hookmanager->resPrint;
708
709// Count total nb of records
710$nbtotalofrecords = '';
711if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
712 /* The fast and low memory method to get and count full list converts the sql into a sql count */
713 $sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
714 $sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
715 $resql = $db->query($sqlforcount);
716 if ($resql) {
717 $objforcount = $db->fetch_object($resql);
718 $nbtotalofrecords = $objforcount->nbtotalofrecords;
719 } else {
720 dol_print_error($db);
721 }
722
723 if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
724 $page = 0;
725 $offset = 0;
726 }
727 $db->free($resql);
728}
729
730// Complete request and execute it with limit
731$sql .= $db->order($sortfield, $sortorder);
732if ($limit) {
733 $sql .= $db->plimit($limit + 1, $offset);
734}
735
736$resql = $db->query($sql);
737if (!$resql) {
738 dol_print_error($db);
739 exit;
740}
741
742$num = $db->num_rows($resql);
743
744
745$product = new Product($db);
746$object = new Entrepot($db);
747
748if ($idproduct > 0) {
749 $product->fetch($idproduct);
750}
751if ($id > 0 || $ref) {
752 $result = $object->fetch($id, $ref);
753 if ($result < 0) {
754 dol_print_error($db);
755 }
756}
757
758
759// Output page
760// --------------------------------------------------------------------
761
762$i = 0;
763$help_url = 'EN:Module_Stocks_En|FR:Module_Stock|ES:M&oacute;dulo_Stocks';
764if ($msid) {
765 $title = $langs->trans('StockMovementForId', $msid);
766} else {
767 $title = $langs->trans("ListOfStockMovements");
768 if ($id) {
769 if (!empty($object->ref)) {
770 $title .= ' ('.$object->ref.')';
771 } else {
772 $title .= ' ('.$langs->trans("ForThisWarehouse").')';
773 }
774 }
775}
776
777
778// Output page
779// --------------------------------------------------------------------
780
781llxHeader('', $title, $help_url);
782
783/*
784 * Show tab only if we ask a particular warehouse
785 */
786if ($object->id > 0) {
787 $head = stock_prepare_head($object);
788
789 print dol_get_fiche_head($head, 'movements', $langs->trans("Warehouse"), -1, 'stock');
790
791
792 $linkback = '<a href="'.DOL_URL_ROOT.'/product/stock/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
793
794 $morehtmlref = '<div class="refidno">';
795 $morehtmlref .= $langs->trans("LocationSummary").' : '.$object->lieu;
796
797 // Project
798 if (isModEnabled('project')) {
799 $langs->load("projects");
800 $morehtmlref .= '<br>'.img_picto('', 'project').' '.$langs->trans('Project').' ';
801 if ($usercancreate && 1 == 2) {
802 if ($action != 'classify') {
803 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
804 }
805 if ($action == 'classify') {
806 $projectid = $object->fk_project;
807 $morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
808 $morehtmlref .= '<input type="hidden" name="action" value="classin">';
809 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
810 $morehtmlref .= $formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
811 $morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
812 $morehtmlref .= '</form>';
813 } else {
814 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300');
815 }
816 } else {
817 if (!empty($object->fk_project)) {
818 $proj = new Project($db);
819 $proj->fetch($object->fk_project);
820 $morehtmlref .= ' : '.$proj->getNomUrl(1);
821 if ($proj->title) {
822 $morehtmlref .= ' - '.$proj->title;
823 }
824 } else {
825 $morehtmlref .= '';
826 }
827 }
828 }
829 $morehtmlref .= '</div>';
830
831 $shownav = 1;
832 if ($user->socid && !in_array('stock', explode(',', $conf->global->MAIN_MODULES_FOR_EXTERNAL))) {
833 $shownav = 0;
834 }
835
836 dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref', 'ref', $morehtmlref);
837
838
839 print '<div class="fichecenter">';
840 print '<div class="fichehalfleft">';
841 print '<div class="underbanner clearboth"></div>';
842
843 print '<table class="border centpercent tableforfield">';
844
845 print '<tr>';
846
847 // Description
848 print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>'.dol_htmlentitiesbr($object->description).'</td></tr>';
849
850 $calcproductsunique = $object->nb_different_products();
851 $calcproducts = $object->nb_products();
852
853 // Total nb of different products
854 print '<tr><td>'.$langs->trans("NumberOfDifferentProducts").'</td><td>';
855 print empty($calcproductsunique['nb']) ? '0' : $calcproductsunique['nb'];
856 print "</td></tr>";
857
858 // Nb of products
859 print '<tr><td>'.$langs->trans("NumberOfProducts").'</td><td>';
860 $valtoshow = price2num($calcproducts['nb'], 'MS');
861 print empty($valtoshow) ? '0' : $valtoshow;
862 print "</td></tr>";
863
864 print '</table>';
865
866 print '</div>';
867 print '<div class="fichehalfright">';
868 print '<div class="underbanner clearboth"></div>';
869
870 print '<table class="border centpercent tableforfield">';
871
872 // Value
873 print '<tr><td class="titlefield">'.$langs->trans("EstimatedStockValueShort").'</td><td>';
874 print price((empty($calcproducts['value']) ? '0' : price2num($calcproducts['value'], 'MT')), 0, $langs, 0, -1, -1, $conf->currency);
875 print "</td></tr>";
876
877 // Last movement
878 $sql = "SELECT MAX(m.datem) as datem";
879 $sql .= " FROM ".MAIN_DB_PREFIX."stock_mouvement as m";
880 $sql .= " WHERE m.fk_entrepot = ".((int) $object->id);
881 $resqlbis = $db->query($sql);
882 if ($resqlbis) {
883 $objbis = $db->fetch_object($resqlbis);
884 $lastmovementdate = $db->jdate($objbis->datem);
885 } else {
886 dol_print_error($db);
887 }
888
889 print '<tr><td>'.$langs->trans("LastMovement").'</td><td>';
890 if ($lastmovementdate) {
891 print dol_print_date($lastmovementdate, 'dayhour');
892 } else {
893 print $langs->trans("None");
894 }
895 print "</td></tr>";
896
897 // Other attributes
898 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
899
900 // Categories
901 if (isModEnabled('categorie')) {
902 print '<tr><td valign="middle">'.$langs->trans("Categories").'</td><td colspan="3">';
903 print $form->showCategories($object->id, Categorie::TYPE_WAREHOUSE, 1);
904 print "</td></tr>";
905 }
906
907 print "</table>";
908
909 print '</div>';
910 print '</div>';
911
912 print '<div class="clearboth"></div>';
913
914 print dol_get_fiche_end();
915}
916
917
918// Correct stock
919if ($action == "correction") {
920 include DOL_DOCUMENT_ROOT.'/product/stock/tpl/stockcorrection.tpl.php';
921 print '<br>';
922}
923
924// Transfer of units
925if ($action == "transfert") {
926 include DOL_DOCUMENT_ROOT.'/product/stock/tpl/stocktransfer.tpl.php';
927 print '<br>';
928}
929
930
931// Action bar
932if ((empty($action) || $action == 'list') && $id > 0) {
933 print "<div class=\"tabsAction\">\n";
934
935 $parameters = array();
936 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
937 // modified by hook
938 if (empty($reshook)) {
939 if ($user->rights->stock->mouvement->creer) {
940 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&action=correction">'.$langs->trans("CorrectStock").'</a>';
941 }
942
943 if ($user->rights->stock->mouvement->creer) {
944 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$id.'&action=transfert">'.$langs->trans("TransferStock").'</a>';
945 }
946 }
947
948 print '</div><br>';
949}
950
951$arrayofselected = is_array($toselect) ? $toselect : array();
952
953$param = '';
954if (!empty($mode)) {
955 $param .= '&mode='.urlencode($mode);
956}
957if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
958 $param .= '&contextpage='.urlencode($contextpage);
959}
960if ($limit > 0 && $limit != $conf->liste_limit) {
961 $param .= '&limit='.((int) $limit);
962}
963if ($id > 0) {
964 $param .= '&id='.urlencode($id);
965}
966if ($search_date_startday) {
967 $param .= '&search_date_startday='.urlencode($search_date_startday);
968}
969if ($search_date_startmonth) {
970 $param .= '&search_date_startmonth='.urlencode($search_date_startmonth);
971}
972if ($search_date_startyear) {
973 $param .= '&search_date_startyear='.urlencode($search_date_startyear);
974}
975if ($search_date_endday) {
976 $param .= '&search_date_endday='.urlencode($search_date_endday);
977}
978if ($search_date_endmonth) {
979 $param .= '&search_date_endmonth='.urlencode($search_date_endmonth);
980}
981if ($search_date_endyear) {
982 $param .= '&search_date_endyear='.urlencode($search_date_endyear);
983}
984if ($search_movement) {
985 $param .= '&search_movement='.urlencode($search_movement);
986}
987if ($search_inventorycode) {
988 $param .= '&search_inventorycode='.urlencode($search_inventorycode);
989}
990if ($search_type_mouvement) {
991 $param .= '&search_type_mouvement='.urlencode($search_type_mouvement);
992}
993if ($search_product_ref) {
994 $param .= '&search_product_ref='.urlencode($search_product_ref);
995}
996if ($search_product) {
997 $param .= '&search_product='.urlencode($search_product);
998}
999if ($search_batch) {
1000 $param .= '&search_batch='.urlencode($search_batch);
1001}
1002if ($search_warehouse > 0) {
1003 $param .= '&search_warehouse='.urlencode($search_warehouse);
1004}
1005if ($search_user) {
1006 $param .= '&search_user='.urlencode($search_user);
1007}
1008if ($idproduct > 0) {
1009 $param .= '&idproduct='.urlencode($idproduct);
1010}
1011// Add $param from extra fields
1012include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
1013// Add $param from hooks
1014$parameters = array();
1015$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1016$param .= $hookmanager->resPrint;
1017
1018// List of mass actions available
1019$arrayofmassactions = array();
1020if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
1021 $arrayofmassactions['builddoc'] = img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("GeneratePDF");
1022}
1023// By default, we should never accept deletion of stock movement
1024if (!empty($conf->global->STOCK_ALLOW_DELETE_OF_MOVEMENT) && $permissiontodelete) {
1025 $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
1026}
1027if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
1028 $arrayofmassactions = array();
1029}
1030$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
1031
1032print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
1033if ($optioncss != '') {
1034 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
1035}
1036print '<input type="hidden" name="token" value="'.newToken().'">';
1037print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
1038print '<input type="hidden" name="action" value="list">';
1039print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
1040print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
1041print '<input type="hidden" name="type" value="'.$type.'">';
1042print '<input type="hidden" name="page" value="'.$page.'">';
1043print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
1044print '<input type="hidden" name="page_y" value="">';
1045print '<input type="hidden" name="mode" value="'.$mode.'">';
1046if ($id > 0) {
1047 print '<input type="hidden" name="id" value="'.$id.'">';
1048}
1049
1050
1051$newcardbutton = '';
1052
1053if ($id > 0) {
1054 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'movement', 0, '', '', $limit, 0, 0, 1);
1055} else {
1056 print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'movement', 0, '', '', $limit, 0, 0, 1);
1057}
1058
1059// Add code for pre mass action (confirmation or email presend form)
1060$topicmail = "SendStockMovement";
1061$modelmail = "movementstock";
1062$objecttmp = new MouvementStock($db);
1063$trackid = 'mov'.$object->id;
1064include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
1065
1066if ($search_all) {
1067 $setupstring = '';
1068 foreach ($fieldstosearchall as $key => $val) {
1069 $fieldstosearchall[$key] = $langs->trans($val);
1070 $setupstring .= $key."=".$val.";";
1071 }
1072 print '<!-- Search done like if STOCK_QUICKSEARCH_ON_FIELDS = '.$setupstring.' -->'."\n";
1073 print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>'."\n";
1074}
1075
1076$moreforfilter = '';
1077
1078$parameters = array('arrayfields'=>&$arrayfields);
1079$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1080if (empty($reshook)) {
1081 $moreforfilter .= $hookmanager->resPrint;
1082} else {
1083 $moreforfilter = $hookmanager->resPrint;
1084}
1085
1086if (!empty($moreforfilter)) {
1087 print '<div class="liste_titre liste_titre_bydiv centpercent">';
1088 print $moreforfilter;
1089 print '</div>';
1090}
1091
1092$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
1093$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields
1094$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
1095
1096print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
1097print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
1098
1099// Fields title search
1100// --------------------------------------------------------------------
1101print '<tr class="liste_titre">';
1102// Action column
1103if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1104 print '<td class="liste_titre center maxwidthsearch">';
1105 $searchpicto = $form->showFilterButtons('left');
1106 print $searchpicto;
1107 print '</td>';
1108}
1109if (!empty($arrayfields['m.rowid']['checked'])) {
1110 // Ref
1111 print '<td class="liste_titre left">';
1112 print '<input class="flat maxwidth40" type="text" name="search_ref" value="'.dol_escape_htmltag($search_ref).'">';
1113 print '</td>';
1114}
1115if (!empty($arrayfields['m.datem']['checked'])) {
1116 // Date
1117 print '<td class="liste_titre center">';
1118 print '<div class="nowrap">';
1119 print $form->selectDate($search_date_start?$search_date_start:-1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'), 'tzuserrel');
1120 print '</div>';
1121 print '<div class="nowrap">';
1122 print $form->selectDate($search_date_end?$search_date_end:-1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'), 'tzuserrel');
1123 print '</div>';
1124 print '</td>';
1125}
1126if (!empty($arrayfields['p.ref']['checked'])) {
1127 // Product Ref
1128 print '<td class="liste_titre left">';
1129 print '<input class="flat maxwidth75" type="text" name="search_product_ref" value="'.dol_escape_htmltag($idproduct ? $product->ref : $search_product_ref).'">';
1130 print '</td>';
1131}
1132if (!empty($arrayfields['p.label']['checked'])) {
1133 // Product label
1134 print '<td class="liste_titre left">';
1135 print '<input class="flat maxwidth100" type="text" name="search_product" value="'.dol_escape_htmltag($idproduct ? $product->label : $search_product).'">';
1136 print '</td>';
1137}
1138// Batch
1139if (!empty($arrayfields['m.batch']['checked'])) {
1140 print '<td class="liste_titre center"><input class="flat maxwidth75" type="text" name="search_batch" value="'.dol_escape_htmltag($search_batch).'"></td>';
1141}
1142if (!empty($arrayfields['pl.eatby']['checked'])) {
1143 print '<td class="liste_titre left">';
1144 print '</td>';
1145}
1146if (!empty($arrayfields['pl.sellby']['checked'])) {
1147 print '<td class="liste_titre left">';
1148 print '</td>';
1149}
1150// Warehouse
1151if (!empty($arrayfields['e.ref']['checked'])) {
1152 print '<td class="liste_titre maxwidthonsmartphone left">';
1153 //print '<input class="flat" type="text" size="8" name="search_warehouse" value="'.($search_warehouse).'">';
1154 print $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'maxwidth200');
1155 print '</td>';
1156}
1157if (!empty($arrayfields['m.fk_user_author']['checked'])) {
1158 // Author
1159 print '<td class="liste_titre left">';
1160 print '<input class="flat" type="text" size="6" name="search_user" value="'.dol_escape_htmltag($search_user).'">';
1161 print '</td>';
1162}
1163if (!empty($arrayfields['m.inventorycode']['checked'])) {
1164 // Inventory code
1165 print '<td class="liste_titre left">';
1166 print '<input class="flat" type="text" size="4" name="search_inventorycode" value="'.dol_escape_htmltag($search_inventorycode).'">';
1167 print '</td>';
1168}
1169if (!empty($arrayfields['m.label']['checked'])) {
1170 // Label of movement
1171 print '<td class="liste_titre left">';
1172 print '<input class="flat" type="text" size="8" name="search_movement" value="'.dol_escape_htmltag($search_movement).'">';
1173 print '</td>';
1174}
1175if (!empty($arrayfields['origin']['checked'])) {
1176 // Origin of movement
1177 print '<td class="liste_titre left">';
1178 print '&nbsp; ';
1179 print '</td>';
1180}
1181if (!empty($arrayfields['m.fk_projet']['checked'])) {
1182 // fk_project
1183 print '<td class="liste_titre" align="left">';
1184 print '&nbsp; ';
1185 print '</td>';
1186}
1187if (!empty($arrayfields['m.type_mouvement']['checked'])) {
1188 // Type of movement
1189 print '<td class="liste_titre center">';
1190 //print '<input class="flat" type="text" size="3" name="search_type_mouvement" value="'.dol_escape_htmltag($search_type_mouvement).'">';
1191 print '<select id="search_type_mouvement" name="search_type_mouvement" class="maxwidth150">';
1192 print '<option value="" '.(($search_type_mouvement == "") ? 'selected="selected"' : '').'>&nbsp;</option>';
1193 print '<option value="0" '.(($search_type_mouvement == "0") ? 'selected="selected"' : '').'>'.$langs->trans('StockIncreaseAfterCorrectTransfer').'</option>';
1194 print '<option value="1" '.(($search_type_mouvement == "1") ? 'selected="selected"' : '').'>'.$langs->trans('StockDecreaseAfterCorrectTransfer').'</option>';
1195 print '<option value="2" '.(($search_type_mouvement == "2") ? 'selected="selected"' : '').'>'.$langs->trans('StockDecrease').'</option>';
1196 print '<option value="3" '.(($search_type_mouvement == "3") ? 'selected="selected"' : '').'>'.$langs->trans('StockIncrease').'</option>';
1197 print '</select>';
1198 print ajax_combobox('search_type_mouvement');
1199 // TODO: add new function $formentrepot->selectTypeOfMovement(...) like
1200 // print $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'maxwidth200');
1201 print '</td>';
1202}
1203if (!empty($arrayfields['m.value']['checked'])) {
1204 // Qty
1205 print '<td class="liste_titre right">';
1206 print '<input class="flat" type="text" size="4" name="search_qty" value="'.dol_escape_htmltag($search_qty).'">';
1207 print '</td>';
1208}
1209if (!empty($arrayfields['m.price']['checked'])) {
1210 // Price
1211 print '<td class="liste_titre" align="left">';
1212 print '&nbsp; ';
1213 print '</td>';
1214}
1215
1216// Extra fields
1217include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
1218
1219// Fields from hook
1220$parameters = array('arrayfields'=>$arrayfields);
1221$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1222print $hookmanager->resPrint;
1223// Date creation
1224if (!empty($arrayfields['m.datec']['checked'])) {
1225 print '<td class="liste_titre">';
1226 print '</td>';
1227}
1228// Date modification
1229if (!empty($arrayfields['m.tms']['checked'])) {
1230 print '<td class="liste_titre">';
1231 print '</td>';
1232}
1233// Action column
1234if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1235 print '<td class="liste_titre center maxwidthsearch">';
1236 $searchpicto = $form->showFilterButtons();
1237 print $searchpicto;
1238 print '</td>';
1239}
1240print '</tr>'."\n";
1241
1242$totalarray = array();
1243$totalarray['nbfield'] = 0;
1244
1245// Fields title label
1246// --------------------------------------------------------------------
1247print '<tr class="liste_titre">';
1248// Action column
1249if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1250 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
1251 $totalarray['nbfield']++;
1252}
1253if (!empty($arrayfields['m.rowid']['checked'])) {
1254 print_liste_field_titre($arrayfields['m.rowid']['label'], $_SERVER["PHP_SELF"], 'm.rowid', '', $param, '', $sortfield, $sortorder);
1255}
1256if (!empty($arrayfields['m.datem']['checked'])) {
1257 print_liste_field_titre($arrayfields['m.datem']['label'], $_SERVER["PHP_SELF"], 'm.datem', '', $param, '', $sortfield, $sortorder, 'center ');
1258}
1259if (!empty($arrayfields['p.ref']['checked'])) {
1260 print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], 'p.ref', '', $param, '', $sortfield, $sortorder);
1261}
1262if (!empty($arrayfields['p.label']['checked'])) {
1263 print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"], 'p.label', '', $param, '', $sortfield, $sortorder);
1264}
1265if (!empty($arrayfields['m.batch']['checked'])) {
1266 print_liste_field_titre($arrayfields['m.batch']['label'], $_SERVER["PHP_SELF"], 'm.batch', '', $param, '', $sortfield, $sortorder, 'center ');
1267}
1268if (!empty($arrayfields['pl.eatby']['checked'])) {
1269 print_liste_field_titre($arrayfields['pl.eatby']['label'], $_SERVER["PHP_SELF"], 'pl.eatby', '', $param, '', $sortfield, $sortorder, 'center ');
1270}
1271if (!empty($arrayfields['pl.sellby']['checked'])) {
1272 print_liste_field_titre($arrayfields['pl.sellby']['label'], $_SERVER["PHP_SELF"], 'pl.sellby', '', $param, '', $sortfield, $sortorder, 'center ');
1273}
1274if (!empty($arrayfields['e.ref']['checked'])) {
1275 // We are on a specific warehouse card, no filter on other should be possible
1276 print_liste_field_titre($arrayfields['e.ref']['label'], $_SERVER["PHP_SELF"], "e.ref", "", $param, "", $sortfield, $sortorder);
1277}
1278if (!empty($arrayfields['m.fk_user_author']['checked'])) {
1279 print_liste_field_titre($arrayfields['m.fk_user_author']['label'], $_SERVER["PHP_SELF"], "m.fk_user_author", "", $param, "", $sortfield, $sortorder);
1280}
1281if (!empty($arrayfields['m.inventorycode']['checked'])) {
1282 print_liste_field_titre($arrayfields['m.inventorycode']['label'], $_SERVER["PHP_SELF"], "m.inventorycode", "", $param, "", $sortfield, $sortorder);
1283}
1284if (!empty($arrayfields['m.label']['checked'])) {
1285 print_liste_field_titre($arrayfields['m.label']['label'], $_SERVER["PHP_SELF"], "m.label", "", $param, "", $sortfield, $sortorder);
1286}
1287if (!empty($arrayfields['origin']['checked'])) {
1288 print_liste_field_titre($arrayfields['origin']['label'], $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
1289}
1290if (!empty($arrayfields['m.fk_projet']['checked'])) {
1291 print_liste_field_titre($arrayfields['m.fk_projet']['label'], $_SERVER["PHP_SELF"], "m.fk_projet", "", $param, '', $sortfield, $sortorder);
1292}
1293if (!empty($arrayfields['m.type_mouvement']['checked'])) {
1294 print_liste_field_titre($arrayfields['m.type_mouvement']['label'], $_SERVER["PHP_SELF"], "m.type_mouvement", "", $param, '', $sortfield, $sortorder, 'center ');
1295}
1296if (!empty($arrayfields['m.value']['checked'])) {
1297 print_liste_field_titre($arrayfields['m.value']['label'], $_SERVER["PHP_SELF"], "m.value", "", $param, '', $sortfield, $sortorder, 'right ');
1298}
1299if (!empty($arrayfields['m.price']['checked'])) {
1300 print_liste_field_titre($arrayfields['m.price']['label'], $_SERVER["PHP_SELF"], "m.price", "", $param, '', $sortfield, $sortorder, 'right ');
1301}
1302
1303// Extra fields
1304include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1305
1306// Hook fields
1307$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray);
1308$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1309print $hookmanager->resPrint;
1310if (!empty($arrayfields['m.datec']['checked'])) {
1311 print_liste_field_titre($arrayfields['p.datec']['label'], $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1312}
1313if (!empty($arrayfields['m.tms']['checked'])) {
1314 print_liste_field_titre($arrayfields['p.tms']['label'], $_SERVER["PHP_SELF"], "p.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
1315}
1316// Action column
1317if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1318 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
1319 $totalarray['nbfield']++;
1320}
1321print '</tr>'."\n";
1322
1323
1324$arrayofuniqueproduct = array();
1325
1326
1327// Loop on record
1328// --------------------------------------------------------------------
1329$i = 0;
1330$savnbfield = $totalarray['nbfield'];
1331$totalarray = array();
1332$totalarray['nbfield'] = 0;
1333$imaxinloop = ($limit ? min($num, $limit) : $num);
1334while ($i < $imaxinloop) {
1335 $obj = $db->fetch_object($resql);
1336 if (empty($obj)) {
1337 break; // Should not happen
1338 }
1339
1340 $userstatic->id = $obj->fk_user_author;
1341 $userstatic->login = $obj->login;
1342 $userstatic->lastname = $obj->lastname;
1343 $userstatic->firstname = $obj->firstname;
1344 $userstatic->photo = $obj->photo;
1345 $userstatic->email = $obj->user_email;
1346 $userstatic->statut = $obj->user_status;
1347
1348 // Multilangs
1349 if (getDolGlobalInt('MAIN_MULTILANGS')) { // If multilang is enabled
1350 // TODO Use a cache
1351 $sql = "SELECT label";
1352 $sql .= " FROM ".MAIN_DB_PREFIX."product_lang";
1353 $sql .= " WHERE fk_product = ".((int) $obj->rowid);
1354 $sql .= " AND lang = '".$db->escape($langs->getDefaultLang())."'";
1355 $sql .= " LIMIT 1";
1356
1357 $result = $db->query($sql);
1358 if ($result) {
1359 $objtp = $db->fetch_object($result);
1360 if (!empty($objtp->label)) {
1361 $obj->produit = $objtp->label;
1362 }
1363 }
1364 }
1365
1366 $productstatic->id = $obj->rowid;
1367 $productstatic->ref = $obj->product_ref;
1368 $productstatic->label = $obj->produit;
1369 $productstatic->type = $obj->type;
1370 $productstatic->entity = $obj->entity;
1371 $productstatic->status = $obj->tosell;
1372 $productstatic->status_buy = $obj->tobuy;
1373 $productstatic->status_batch = $obj->tobatch;
1374
1375 $productlot->id = $obj->lotid;
1376 $productlot->batch = $obj->batch;
1377 $productlot->eatby = $obj->eatby;
1378 $productlot->sellby = $obj->sellby;
1379
1380 $warehousestatic->id = $obj->entrepot_id;
1381 $warehousestatic->ref = $obj->warehouse_ref;
1382 $warehousestatic->label = $obj->warehouse_ref;
1383 $warehousestatic->lieu = $obj->lieu;
1384 $warehousestatic->fk_parent = $obj->fk_parent;
1385 $warehousestatic->statut = $obj->statut;
1386
1387 $movement->type = $obj->type_mouvement;
1388
1389 $arrayofuniqueproduct[$obj->rowid] = $obj->produit;
1390 if (!empty($obj->fk_origin)) {
1391 $origin = $movement->get_origin($obj->fk_origin, $obj->origintype);
1392 } else {
1393 $origin = '';
1394 }
1395
1396 if ($mode == 'kanban') {
1397 if ($i == 0) {
1398 print '<tr class="trkanban"><td colspan="'.$savnbfield.'">';
1399 print '<div class="box-flex-container kanban">';
1400 }
1401 // Output Kanban
1402 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1403 $selected = 0;
1404 if (in_array($object->id, $arrayofselected)) {
1405 $selected = 1;
1406 }
1407 }
1408 print $object->getKanbanView('', array('selected' => in_array($warehousestatic->id, $arrayofselected)));
1409 if ($i == ($imaxinloop - 1)) {
1410 print '</div>';
1411 print '</td></tr>';
1412 }
1413 } else {
1414 // Show here line of result
1415 $j = 0;
1416 print '<tr data-rowid="'.$object->id.'" class="oddeven">';
1417 // Action column
1418 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1419 print '<td class="nowrap center">';
1420 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1421 $selected = 0;
1422 if (in_array($obj->mid, $arrayofselected)) {
1423 $selected = 1;
1424 }
1425 print '<input id="cb'.$obj->mid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->mid.'"'.($selected ? ' checked="checked"' : '').'>';
1426 }
1427 print '</td>';
1428 if (!$i) {
1429 $totalarray['nbfield']++;
1430 }
1431 }
1432 // Id movement
1433 if (!empty($arrayfields['m.rowid']['checked'])) {
1434 print '<td class="nowraponall">';
1435 print img_picto($langs->trans("StockMovement"), 'movement', 'class="pictofixedwidth"');
1436 print $obj->mid;
1437 print '</td>'; // This is primary not movement id
1438 }
1439 if (!empty($arrayfields['m.datem']['checked'])) {
1440 // Date
1441 print '<td class="nowraponall center">'.dol_print_date($db->jdate($obj->datem), 'dayhour', 'tzuserrel').'</td>';
1442 }
1443 if (!empty($arrayfields['p.ref']['checked'])) {
1444 // Product ref
1445 print '<td class="nowraponall">';
1446 print $productstatic->getNomUrl(1, 'stock', 16);
1447 print "</td>\n";
1448 }
1449 if (!empty($arrayfields['p.label']['checked'])) {
1450 // Product label
1451 print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($productstatic->label).'">';
1452 print $productstatic->label;
1453 print "</td>\n";
1454 }
1455 if (!empty($arrayfields['m.batch']['checked'])) {
1456 print '<td class="center nowraponall">';
1457 if ($productlot->id > 0) {
1458 print $productlot->getNomUrl(1);
1459 } else {
1460 print $productlot->batch; // the id may not be defined if movement was entered when lot was not saved or if lot was removed after movement.
1461 }
1462 print '</td>';
1463 }
1464 if (!empty($arrayfields['pl.eatby']['checked'])) {
1465 print '<td class="center">'.dol_print_date($obj->eatby, 'day').'</td>';
1466 }
1467 if (!empty($arrayfields['pl.sellby']['checked'])) {
1468 print '<td class="center">'.dol_print_date($obj->sellby, 'day').'</td>';
1469 }
1470 // Warehouse
1471 if (!empty($arrayfields['e.ref']['checked'])) {
1472 print '<td class="tdoverflowmax100">';
1473 print $warehousestatic->getNomUrl(1);
1474 print "</td>\n";
1475 }
1476 // Author
1477 if (!empty($arrayfields['m.fk_user_author']['checked'])) {
1478 print '<td class="tdoverflowmax100">';
1479 print $userstatic->getNomUrl(-1);
1480 print "</td>\n";
1481 }
1482 if (!empty($arrayfields['m.inventorycode']['checked'])) {
1483 // Inventory code
1484 print '<td><a href="'.$_SERVER["PHP_SELF"].'?search_inventorycode='.urlencode('^'.$obj->inventorycode.'$').'">'.dol_escape_htmltag($obj->inventorycode).'</a></td>';
1485 }
1486 if (!empty($arrayfields['m.label']['checked'])) {
1487 // Label of movement
1488 print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($obj->label).'">'.dol_escape_htmltag($obj->label).'</td>';
1489 }
1490 if (!empty($arrayfields['origin']['checked'])) {
1491 // Origin of movement
1492 print '<td class="nowraponall">'.$origin.'</td>';
1493 }
1494 if (!empty($arrayfields['m.fk_projet']['checked'])) {
1495 // fk_project
1496 print '<td>';
1497 if ($obj->fk_project != 0) {
1498 print $movement->get_origin($obj->fk_project, 'project');
1499 }
1500 print '</td>';
1501 }
1502 if (!empty($arrayfields['m.type_mouvement']['checked'])) {
1503 // Type of movement
1504 print '<td class="center">';
1505 print $movement->getTypeMovement();
1506 print '</td>';
1507 }
1508 if (!empty($arrayfields['m.value']['checked'])) {
1509 // Qty
1510 print '<td class="right">';
1511 if ($obj->qty > 0) {
1512 print '<span class="stockmovemententry">';
1513 print '+';
1514 print $obj->qty;
1515 print '</span>';
1516 } else {
1517 print '<span class="stockmovementexit">';
1518 print $obj->qty;
1519 print '</span>';
1520 }
1521 print '</td>';
1522 }
1523 if (!empty($arrayfields['m.price']['checked'])) {
1524 // Price
1525 print '<td class="right">';
1526 if ($obj->price != 0) {
1527 print price($obj->price);
1528 }
1529 print '</td>';
1530 }
1531
1532 // Extra fields
1533 $object = $movement;
1534 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1535 // Fields from hook
1536 $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
1537 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1538 print $hookmanager->resPrint;
1539
1540 // Action column
1541 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1542 print '<td class="nowrap center">';
1543 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1544 $selected = 0;
1545 if (in_array($obj->mid, $arrayofselected)) {
1546 $selected = 1;
1547 }
1548 print '<input id="cb'.$obj->mid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->mid.'"'.($selected ? ' checked="checked"' : '').'>';
1549 }
1550 print '</td>';
1551 if (!$i) {
1552 $totalarray['nbfield']++;
1553 }
1554 }
1555
1556 print '</tr>'."\n";
1557 }
1558
1559 $i++;
1560}
1561
1562// If no record found
1563if ($num == 0) {
1564 $colspan = 1;
1565 foreach ($arrayfields as $key => $val) {
1566 if (!empty($val['checked'])) {
1567 $colspan++;
1568 }
1569 }
1570 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1571}
1572
1573$db->free($resql);
1574
1575$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
1576$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1577print $hookmanager->resPrint;
1578
1579print '</table>'."\n";
1580print '</div>'."\n";
1581
1582print '</form>'."\n";
1583
1584// Add number of product when there is a filter on period
1585if (count($arrayofuniqueproduct) == 1 && !empty($year) && is_numeric($year)) {
1586 print "<br>";
1587
1588 $productidselected = 0;
1589 foreach ($arrayofuniqueproduct as $key => $val) {
1590 $productidselected = $key;
1591 $productlabelselected = $val;
1592 }
1593 $datebefore = dol_get_first_day($year ? $year : strftime("%Y", time()), $month ? $month : 1, true);
1594 $dateafter = dol_get_last_day($year ? $year : strftime("%Y", time()), $month ? $month : 12, true);
1595 $balancebefore = $movement->calculateBalanceForProductBefore($productidselected, $datebefore);
1596 $balanceafter = $movement->calculateBalanceForProductBefore($productidselected, $dateafter);
1597
1598 //print '<tr class="total"><td class="liste_total">';
1599 print $langs->trans("NbOfProductBeforePeriod", $productlabelselected, dol_print_date($datebefore, 'day', 'gmt'));
1600 //print '</td>';
1601 //print '<td class="liste_total right" colspan="6">';
1602 print ': '.$balancebefore;
1603 print "<br>\n";
1604 //print '</td></tr>';
1605 //print '<tr class="total"><td class="liste_total">';
1606 print $langs->trans("NbOfProductAfterPeriod", $productlabelselected, dol_print_date($dateafter, 'day', 'gmt'));
1607 //print '</td>';
1608 //print '<td class="liste_total right" colspan="6">';
1609 print ': '.$balanceafter;
1610 print "<br>\n";
1611 //print '</td></tr>';
1612}
1613
1614if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
1615 $hidegeneratedfilelistifempty = 1;
1616 if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
1617 $hidegeneratedfilelistifempty = 0;
1618 }
1619
1620 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
1621 $formfile = new FormFile($db);
1622
1623 // Show list of available documents
1624 $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
1625 $urlsource .= str_replace('&amp;', '&', $param);
1626
1627 $filedir = $diroutputmassaction;
1628 $genallowed = $permissiontoread;
1629 $delallowed = $permissiontoadd;
1630
1631 print $formfile->showdocuments('massfilesarea_'.$object->module, '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
1632}
1633
1634// End of page
1635llxFooter();
1636$db->close();
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:464
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:56
llxFooter()
Empty footer.
Definition wrapper.php:70
Class to manage warehouses.
Class to manage standard extra fields.
Class to offer components to list and upload files.
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 building of HTML components.
Class to manage stock movements.
Class to manage products or services.
Manage record for batch number management.
Class with list of lots and properties.
Class to manage projects.
Class to manage translations.
Class to manage Dolibarr users.
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:578
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:597
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:62
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_get_fiche_end($notab=0)
Return tab footer of a card.
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...
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.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
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.
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo editer/modifier fiche.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
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...
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.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
stock_prepare_head($object)
Prepare array with list of tabs.
Definition stock.lib.php:30