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