dolibarr  17.0.4
mo_movements.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2019 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2022 Ferran Marcet <fmarcet@2byte.es>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
25 // Load Dolibarr environment
26 require '../main.inc.php';
27 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
35 dol_include_once('/mrp/class/mo.class.php');
36 dol_include_once('/mrp/lib/mrp_mo.lib.php');
37 
38 // Load translation files required by the page
39 $langs->loadLangs(array("mrp", "stocks", "other"));
40 
41 // Get parameters
42 $id = GETPOST('id', 'int');
43 $ref = GETPOST('ref', 'alpha');
44 $action = GETPOST('action', 'aZ09');
45 $confirm = GETPOST('confirm', 'alpha');
46 $cancel = GETPOST('cancel', 'aZ09');
47 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'mostockmovement'; // To manage different context of search
48 $backtopage = GETPOST('backtopage', 'alpha');
49 $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
50 $massaction = GETPOST('massaction', 'aZ09');
51 $lineid = GETPOST('lineid', 'int');
52 
53 $msid = GETPOST('msid', 'int');
54 $year = GETPOST("year", 'int');
55 $month = GETPOST("month", 'int');
56 $search_ref = GETPOST('search_ref', 'alpha');
57 $search_movement = GETPOST("search_movement", 'alpha');
58 $search_product_ref = trim(GETPOST("search_product_ref", 'alpha'));
59 $search_product = trim(GETPOST("search_product", 'alpha'));
60 $search_warehouse = trim(GETPOST("search_warehouse", 'alpha'));
61 $search_inventorycode = trim(GETPOST("search_inventorycode", 'alpha'));
62 $search_user = trim(GETPOST("search_user", 'alpha'));
63 $search_batch = trim(GETPOST("search_batch", 'alpha'));
64 $search_qty = trim(GETPOST("search_qty", 'alpha'));
65 $search_type_mouvement = GETPOST('search_type_mouvement', 'int');
66 
67 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
68 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
69 $sortfield = GETPOST('sortfield', 'aZ09comma');
70 $sortorder = GETPOST('sortorder', 'aZ09comma');
71 if (empty($page) || $page == -1) {
72  $page = 0;
73 } // If $page is not defined, or '' or -1
74 $offset = $limit * $page;
75 if (!$sortfield) {
76  $sortfield = "m.datem";
77 }
78 if (!$sortorder) {
79  $sortorder = "DESC";
80 }
81 
82 // Initialize technical objects
83 $object = new Mo($db);
84 $extrafields = new ExtraFields($db);
85 $diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
86 $hookmanager->initHooks(array('mocard', 'globalcard')); // Note that conf->hooks_modules contains array
87 
88 // Fetch optionals attributes and labels
89 $extrafields->fetch_name_optionals_label($object->table_element);
90 
91 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
92 
93 // Initialize array of search criterias
94 $search_all = trim(GETPOST("search_all", 'alpha'));
95 $search = array();
96 foreach ($object->fields as $key => $val) {
97  if (GETPOST('search_'.$key, 'alpha')) {
98  $search[$key] = GETPOST('search_'.$key, 'alpha');
99  }
100 }
101 
102 if (empty($action) && empty($id) && empty($ref)) {
103  $action = 'view';
104 }
105 
106 // Load object
107 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
108 
109 // Security check - Protection if external user
110 //if ($user->socid > 0) accessforbidden();
111 //if ($user->socid > 0) $socid = $user->socid;
112 $isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
113 $result = restrictedArea($user, 'mrp', $object->id, 'mrp_mo', '', 'fk_soc', 'rowid', $isdraft);
114 
115 $objectlist = new MouvementStock($db);
116 
117 // Definition of fields for list
118 $arrayfields = array(
119  'm.rowid'=>array('label'=>"Ref", 'checked'=>1, 'position'=>1),
120  'm.datem'=>array('label'=>"Date", 'checked'=>1, 'position'=>2),
121  'p.ref'=>array('label'=>"ProductRef", 'checked'=>1, 'css'=>'maxwidth100', 'position'=>3),
122  'p.label'=>array('label'=>"ProductLabel", 'checked'=>0, 'position'=>5),
123  'm.batch'=>array('label'=>"BatchNumberShort", 'checked'=>1, 'position'=>8, 'enabled'=>(isModEnabled('productbatch'))),
124  'pl.eatby'=>array('label'=>"EatByDate", 'checked'=>0, 'position'=>9, 'enabled'=>(isModEnabled('productbatch'))),
125  'pl.sellby'=>array('label'=>"SellByDate", 'checked'=>0, 'position'=>10, 'enabled'=>(isModEnabled('productbatch'))),
126  'e.ref'=>array('label'=>"Warehouse", 'checked'=>1, 'position'=>100, 'enabled'=>(!($id > 0))), // If we are on specific warehouse, we hide it
127  'm.fk_user_author'=>array('label'=>"Author", 'checked'=>0, 'position'=>120),
128  'm.inventorycode'=>array('label'=>"InventoryCodeShort", 'checked'=>1, 'position'=>130),
129  'm.label'=>array('label'=>"MovementLabel", 'checked'=>1, 'position'=>140),
130  'm.type_mouvement'=>array('label'=>"TypeMovement", 'checked'=>0, 'position'=>150),
131  'origin'=>array('label'=>"Origin", 'checked'=>1, 'position'=>155),
132  'm.fk_projet'=>array('label'=>'Project', 'checked'=>0, 'position'=>180),
133  'm.value'=>array('label'=>"Qty", 'checked'=>1, 'position'=>200),
134  'm.price'=>array('label'=>"UnitPurchaseValue", 'checked'=>0, 'position'=>210)
135  //'m.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500),
136  //'m.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500)
137 );
138 if (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
139  unset($arrayfields['pl.sellby']);
140 }
141 if (!empty($conf->global->PRODUCT_DISABLE_EATBY)) {
142  unset($arrayfields['pl.eatby']);
143 }
144 $objectlist->fields = dol_sort_array($objectlist->fields, 'position');
145 $arrayfields = dol_sort_array($arrayfields, 'position');
146 
147 $permissionnote = $user->rights->mrp->write; // Used by the include of actions_setnotes.inc.php
148 $permissiondellink = $user->rights->mrp->write; // Used by the include of actions_dellink.inc.php
149 $permissiontoadd = $user->rights->mrp->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
150 $permissiontodelete = $user->rights->mrp->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
151 $upload_dir = $conf->mrp->multidir_output[isset($object->entity) ? $object->entity : 1];
152 
153 $permissiontoproduce = $permissiontoadd;
154 $permissiontoupdatecost = $user->rights->bom->write; // User who can define cost must have knowledge of pricing
155 
156 if ($permissiontoupdatecost) {
157  $arrayfields['m.price']['enabled'] = 1;
158 }
159 
160 $arrayofselected = array();
161 
162 
163 /*
164  * Actions
165  */
166 
167 if (GETPOST('cancel', 'alpha')) {
168  $action = 'list'; $massaction = '';
169 }
170 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
171  $massaction = '';
172 }
173 
174 $parameters = array();
175 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
176 if ($reshook < 0) {
177  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
178 }
179 
180 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
181 
182 // Do we click on purge search criteria ?
183 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
184  $year = '';
185  $month = '';
186  $search_ref = '';
187  $search_movement = "";
188  $search_type_mouvement = "";
189  $search_inventorycode = "";
190  $search_product_ref = "";
191  $search_product = "";
192  $search_warehouse = "";
193  $search_user = "";
194  $search_batch = "";
195  $search_qty = '';
196  $sall = "";
197  $toselect = array();
198  $search_array_options = array();
199 }
200 
201 if (empty($reshook)) {
202  $error = 0;
203 
204  $backurlforlist = dol_buildpath('/mrp/mo_list.php', 1);
205 
206  if (empty($backtopage) || ($cancel && empty($id))) {
207  //var_dump($backurlforlist);exit;
208  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
209  $backtopage = $backurlforlist;
210  } else {
211  $backtopage = DOL_URL_ROOT.'/mrp/mo_production.php?id='.($id > 0 ? $id : '__ID__');
212  }
213  }
214  $triggermodname = 'MO_MODIFY'; // Name of trigger action code to execute when we modify record
215 
216  // Actions cancel, add, update, delete or clone
217  include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
218 
219  // Actions when linking object each other
220  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
221 
222  // Actions when printing a doc from card
223  include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
224 
225  // Actions to send emails
226  $triggersendname = 'MO_SENTBYMAIL';
227  $autocopy = 'MAIN_MAIL_AUTOCOPY_MO_TO';
228  $trackid = 'mo'.$object->id;
229  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
230 
231  // Action to move up and down lines of object
232  //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once
233 
234  if ($action == 'set_thirdparty' && $permissiontoadd) {
235  $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, $triggermodname);
236  }
237  if ($action == 'classin' && $permissiontoadd) {
238  $object->setProject(GETPOST('projectid', 'int'));
239  }
240 
241  if ($action == 'confirm_reopen') {
242  $result = $object->setStatut($object::STATUS_INPROGRESS, 0, '', 'MRP_REOPEN');
243  }
244 }
245 
246 
247 
248 /*
249  * View
250  */
251 
252 $form = new Form($db);
253 $formproject = new FormProjets($db);
254 $formproduct = new FormProduct($db);
255 $productstatic = new Product($db);
256 $productlot = new ProductLot($db);
257 $warehousestatic = new Entrepot($db);
258 $userstatic = new User($db);
259 
260 $help_url = 'EN:Module_Manufacturing_Orders|FR:Module_Ordres_de_Fabrication';
261 
262 llxHeader('', $langs->trans('Mo'), $help_url);
263 
264 // Part to show record
265 if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
266  $res = $object->fetch_thirdparty();
267  $res = $object->fetch_optionals();
268 
269  $head = moPrepareHead($object);
270 
271  print dol_get_fiche_head($head, 'stockmovement', $langs->trans("ManufacturingOrder"), -1, $object->picto);
272 
273  $formconfirm = '';
274 
275  // Confirmation to delete
276  if ($action == 'delete') {
277  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteMo'), $langs->trans('ConfirmDeleteMo'), 'confirm_delete', '', 0, 1);
278  }
279  // Confirmation to delete line
280  if ($action == 'deleteline') {
281  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
282  }
283  // Clone confirmation
284  if ($action == 'clone') {
285  // Create an array for form
286  $formquestion = array();
287  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneMo', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
288  }
289 
290  // Confirmation of action xxxx
291  if ($action == 'xxx') {
292  $formquestion = array();
293  /*
294  $forcecombo=0;
295  if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
296  $formquestion = array(
297  // 'text' => $langs->trans("ConfirmClone"),
298  // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
299  // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
300  // array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
301  );
302  */
303  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220);
304  }
305 
306  // Call Hook formConfirm
307  $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
308  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
309  if (empty($reshook)) {
310  $formconfirm .= $hookmanager->resPrint;
311  } elseif ($reshook > 0) {
312  $formconfirm = $hookmanager->resPrint;
313  }
314 
315  // Print form confirm
316  print $formconfirm;
317 
318 
319  // Object card
320  // ------------------------------------------------------------
321  $linkback = '<a href="'.dol_buildpath('/mrp/mo_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
322 
323  $morehtmlref = '<div class="refidno">';
324  /*
325  // Ref bis
326  $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->mrp->creer, 'string', '', 0, 1);
327  $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->mrp->creer, 'string', '', null, null, '', 1);*/
328  // Thirdparty
329  if (is_object($object->thirdparty)) {
330  $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer');
331  if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) {
332  $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
333  }
334  }
335  // Project
336  if (isModEnabled('project')) {
337  $langs->load("projects");
338  if (is_object($object->thirdparty)) {
339  $morehtmlref .= '<br>';
340  }
341  if ($permissiontoadd) {
342  $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
343  if ($action != 'classify') {
344  $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
345  }
346  $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
347  } else {
348  if (!empty($object->fk_project)) {
349  $proj = new Project($db);
350  $proj->fetch($object->fk_project);
351  $morehtmlref .= $proj->getNomUrl(1);
352  if ($proj->title) {
353  $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
354  }
355  }
356  }
357  }
358  $morehtmlref .= '</div>';
359 
360 
361  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
362 
363 
364  print '<div class="fichecenter">';
365  print '<div class="fichehalfleft">';
366  print '<div class="underbanner clearboth"></div>';
367  print '<table class="border centpercent tableforfield">'."\n";
368 
369  // Common attributes
370  $keyforbreak = 'fk_warehouse';
371  unset($object->fields['fk_project']);
372  unset($object->fields['fk_soc']);
373  include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
374 
375  // Other attributes
376  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
377 
378  print '</table>';
379  print '</div>';
380  print '</div>';
381 
382  print '<div class="clearboth"></div>';
383 
384  print dol_get_fiche_end();
385 
386  /*
387  print '<div class="tabsAction">';
388 
389  $parameters = array();
390  // Note that $action and $object may be modified by hook
391  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action);
392  if (empty($reshook)) {
393  // Cancel - Reopen
394  if ($permissiontoadd)
395  {
396  if ($object->status == $object::STATUS_VALIDATED || $object->status == $object::STATUS_INPROGRESS)
397  {
398  print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_close&confirm=yes">'.$langs->trans("Cancel").'</a>'."\n";
399  }
400 
401  if ($object->status == $object::STATUS_CANCELED)
402  {
403  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_reopen&confirm=yes">'.$langs->trans("Re-Open").'</a>'."\n";
404  }
405 
406  if ($object->status == $object::STATUS_PRODUCED) {
407  if ($permissiontoproduce) {
408  print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_reopen">'.$langs->trans('ReOpen').'</a>';
409  } else {
410  print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans('ReOpen').'</a>';
411  }
412  }
413  }
414  }
415 
416  print '</div>';
417  */
418 
419 
420  $sql = "SELECT p.rowid, p.ref as product_ref, p.label as produit, p.tobatch, p.fk_product_type as type, p.entity,";
421  $sql .= " e.ref as warehouse_ref, e.rowid as entrepot_id, e.lieu,";
422  $sql .= " m.rowid as mid, m.value as qty, m.datem, m.fk_user_author, m.label, m.inventorycode, m.fk_origin, m.origintype,";
423  $sql .= " m.batch, m.price,";
424  $sql .= " m.type_mouvement,";
425  $sql .= " pl.rowid as lotid, pl.eatby, pl.sellby,";
426  $sql .= " u.login, u.photo, u.lastname, u.firstname";
427  // Add fields from extrafields
428  if (!empty($extrafields->attributes[$objectlist->table_element]['label'])) {
429  foreach ($extrafields->attributes[$objectlist->table_element]['label'] as $key => $val) {
430  $sql .= ($extrafields->attributes[$objectlist->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
431  }
432  }
433  // Add fields from hooks
434  $parameters = array();
435  $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $objectlist may have been modified by hook
436  $sql .= $hookmanager->resPrint;
437  $sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e,";
438  $sql .= " ".MAIN_DB_PREFIX."product as p,";
439  $sql .= " ".MAIN_DB_PREFIX."stock_mouvement as m";
440  if (!empty($extrafields->attributes[$objectlist->table_element]) && is_array($extrafields->attributes[$objectlist->table_element]['label']) && count($extrafields->attributes[$objectlist->table_element]['label'])) {
441  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$objectlist->table_element."_extrafields as ef on (m.rowid = ef.fk_object)";
442  }
443  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON m.fk_user_author = u.rowid";
444  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_lot as pl ON m.batch = pl.batch AND m.fk_product = pl.fk_product";
445  $sql .= " WHERE m.fk_product = p.rowid";
446  $sql .= " AND m.origintype = 'mo' AND m.fk_origin = ".(int) $object->id;
447  if ($msid > 0) {
448  $sql .= " AND m.rowid = ".((int) $msid);
449  }
450  $sql .= " AND m.fk_entrepot = e.rowid";
451  $sql .= " AND e.entity IN (".getEntity('stock').")";
452  if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
453  $sql .= " AND p.fk_product_type = 0";
454  }
455  $sql .= dolSqlDateFilter('m.datem', 0, $month, $year);
456  if (!empty($search_ref)) {
457  $sql .= natural_search('m.rowid', $search_ref, 1);
458  }
459  if (!empty($search_movement)) {
460  $sql .= natural_search('m.label', $search_movement);
461  }
462  if (!empty($search_inventorycode)) {
463  $sql .= natural_search('m.inventorycode', $search_inventorycode);
464  }
465  if (!empty($search_product_ref)) {
466  $sql .= natural_search('p.ref', $search_product_ref);
467  }
468  if (!empty($search_product)) {
469  $sql .= natural_search('p.label', $search_product);
470  }
471  if ($search_warehouse != '' && $search_warehouse != '-1') {
472  $sql .= natural_search('e.rowid', $search_warehouse, 2);
473  }
474  if (!empty($search_user)) {
475  $sql .= natural_search(array('u.lastname', 'u.firstname', 'u.login'), $search_user);
476  }
477  if (!empty($search_batch)) {
478  $sql .= natural_search('m.batch', $search_batch);
479  }
480  if ($search_qty != '') {
481  $sql .= natural_search('m.value', $search_qty, 1);
482  }
483  if ($search_type_mouvement != '' && $search_type_mouvement != '-1') {
484  $sql .= natural_search('m.type_mouvement', $search_type_mouvement, 2);
485  }
486  // Add where from extra fields
487  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
488  // Add where from hooks
489  $parameters = array();
490  $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $objectlist may have been modified by hook
491  $sql .= $hookmanager->resPrint;
492  $sql .= $db->order($sortfield, $sortorder);
493 
494  $nbtotalofrecords = '';
495  if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
496  $result = $db->query($sql);
497  $nbtotalofrecords = $db->num_rows($result);
498  if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
499  $page = 0;
500  $offset = 0;
501  }
502  }
503  $sql .= $db->plimit($limit + 1, $offset);
504 
505  $resql = $db->query($sql);
506  if (!$resql) {
507  dol_print_error($db);
508  }
509  $num = $db->num_rows($resql);
510 
511  $param = '';
512  if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
513  $param .= '&contextpage='.urlencode($contextpage);
514  }
515  if ($limit > 0 && $limit != $conf->liste_limit) {
516  $param .= '&limit='.urlencode($limit);
517  }
518  if ($id > 0) {
519  $param .= '&id='.urlencode($id);
520  }
521  if ($search_movement) {
522  $param .= '&search_movement='.urlencode($search_movement);
523  }
524  if ($search_inventorycode) {
525  $param .= '&search_inventorycode='.urlencode($search_inventorycode);
526  }
527  if ($search_type_mouvement) {
528  $param .= '&search_type_mouvement='.urlencode($search_type_mouvement);
529  }
530  if ($search_product_ref) {
531  $param .= '&search_product_ref='.urlencode($search_product_ref);
532  }
533  if ($search_product) {
534  $param .= '&search_product='.urlencode($search_product);
535  }
536  if ($search_batch) {
537  $param .= '&search_batch='.urlencode($search_batch);
538  }
539  if ($search_warehouse > 0) {
540  $param .= '&search_warehouse='.urlencode($search_warehouse);
541  }
542  if ($search_user) {
543  $param .= '&search_user='.urlencode($search_user);
544  }
545 
546  // Add $param from extra fields
547  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
548 
549  // List of mass actions available
550  $arrayofmassactions = array(
551  // 'presend'=>$langs->trans("SendByMail"),
552  // 'builddoc'=>$langs->trans("PDFMerge"),
553  );
554  //if ($user->rights->stock->supprimer) $arrayofmassactions['predelete']='<span class="fa fa-trash paddingrightonly"></span>'.$langs->trans("Delete");
555  if (in_array($massaction, array('presend', 'predelete'))) {
556  $arrayofmassactions = array();
557  }
558  $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
559 
560  print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
561  if ($optioncss != '') {
562  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
563  }
564  print '<input type="hidden" name="token" value="'.newToken().'">';
565  print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
566  print '<input type="hidden" name="action" value="list">';
567  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
568  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
569  print '<input type="hidden" name="page" value="'.$page.'">';
570  print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
571  if ($id > 0) {
572  print '<input type="hidden" name="id" value="'.$id.'">';
573  }
574 
575  if ($id > 0) {
576  print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, '', '', $limit);
577  } else {
578  print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, '', '', $limit);
579  }
580 
581  $moreforfilter = '';
582 
583  $parameters = array();
584  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
585  if (empty($reshook)) {
586  $moreforfilter .= $hookmanager->resPrint;
587  } else {
588  $moreforfilter = $hookmanager->resPrint;
589  }
590 
591  if (!empty($moreforfilter)) {
592  print '<div class="liste_titre liste_titre_bydiv centpercent">';
593  print $moreforfilter;
594  print '</div>';
595  }
596 
597  $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
598  $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
599 
600  print '<div class="div-table-responsive">';
601  print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
602 
603  // Fields title search
604  print '<tr class="liste_titre_filter">';
605  if (!empty($arrayfields['m.rowid']['checked'])) {
606  // Ref
607  print '<td class="liste_titre left">';
608  print '<input class="flat maxwidth25" type="text" name="search_ref" value="'.dol_escape_htmltag($search_ref).'">';
609  print '</td>';
610  }
611  if (!empty($arrayfields['m.datem']['checked'])) {
612  print '<td class="liste_titre nowraponall">';
613  print '<input class="flat" type="text" size="2" maxlength="2" placeholder="'.dol_escape_htmltag($langs->trans("Month")).'" name="month" value="'.$month.'">';
614  if (!isModEnabled('productbatch')) {
615  print '&nbsp;';
616  }
617  //else print '<br>';
618  $syear = $year ? $year : -1;
619  print '<input class="flat maxwidth50" type="text" maxlength="4" placeholder="'.dol_escape_htmltag($langs->trans("Year")).'" name="year" value="'.($syear > 0 ? $syear : '').'">';
620  //print $formother->selectyear($syear,'year',1, 20, 5);
621  print '</td>';
622  }
623  if (!empty($arrayfields['p.ref']['checked'])) {
624  // Product Ref
625  print '<td class="liste_titre left">';
626  print '<input class="flat maxwidth75" type="text" name="search_product_ref" value="'.dol_escape_htmltag($search_product_ref).'">';
627  print '</td>';
628  }
629  if (!empty($arrayfields['p.label']['checked'])) {
630  // Product label
631  print '<td class="liste_titre left">';
632  print '<input class="flat maxwidth100" type="text" name="search_product" value="'.dol_escape_htmltag($search_product).'">';
633  print '</td>';
634  }
635  // Batch
636  if (!empty($arrayfields['m.batch']['checked'])) {
637  print '<td class="liste_titre center"><input class="flat maxwidth75" type="text" name="search_batch" value="'.dol_escape_htmltag($search_batch).'"></td>';
638  }
639  if (!empty($arrayfields['pl.eatby']['checked'])) {
640  print '<td class="liste_titre left">';
641  print '</td>';
642  }
643  if (!empty($arrayfields['pl.sellby']['checked'])) {
644  print '<td class="liste_titre left">';
645  print '</td>';
646  }
647  // Warehouse
648  if (!empty($arrayfields['e.ref']['checked'])) {
649  print '<td class="liste_titre maxwidthonsmartphone left">';
650  //print '<input class="flat" type="text" size="8" name="search_warehouse" value="'.($search_warehouse).'">';
651  print $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'maxwidth200');
652  print '</td>';
653  }
654  if (!empty($arrayfields['m.fk_user_author']['checked'])) {
655  // Author
656  print '<td class="liste_titre left">';
657  print '<input class="flat" type="text" size="6" name="search_user" value="'.dol_escape_htmltag($search_user).'">';
658  print '</td>';
659  }
660  if (!empty($arrayfields['m.inventorycode']['checked'])) {
661  // Inventory code
662  print '<td class="liste_titre left">';
663  print '<input class="flat" type="text" size="4" name="search_inventorycode" value="'.dol_escape_htmltag($search_inventorycode).'">';
664  print '</td>';
665  }
666  if (!empty($arrayfields['m.label']['checked'])) {
667  // Label of movement
668  print '<td class="liste_titre left">';
669  print '<input class="flat" type="text" size="8" name="search_movement" value="'.dol_escape_htmltag($search_movement).'">';
670  print '</td>';
671  }
672  if (!empty($arrayfields['m.type_mouvement']['checked'])) {
673  // Type of movement
674  print '<td class="liste_titre center">';
675  //print '<input class="flat" type="text" size="3" name="search_type_mouvement" value="'.dol_escape_htmltag($search_type_mouvement).'">';
676  print '<select id="search_type_mouvement" name="search_type_mouvement" class="maxwidth150">';
677  print '<option value="" '.(($search_type_mouvement == "") ? 'selected="selected"' : '').'>&nbsp;</option>';
678  print '<option value="0" '.(($search_type_mouvement == "0") ? 'selected="selected"' : '').'>'.$langs->trans('StockIncreaseAfterCorrectTransfer').'</option>';
679  print '<option value="1" '.(($search_type_mouvement == "1") ? 'selected="selected"' : '').'>'.$langs->trans('StockDecreaseAfterCorrectTransfer').'</option>';
680  print '<option value="2" '.(($search_type_mouvement == "2") ? 'selected="selected"' : '').'>'.$langs->trans('StockDecrease').'</option>';
681  print '<option value="3" '.(($search_type_mouvement == "3") ? 'selected="selected"' : '').'>'.$langs->trans('StockIncrease').'</option>';
682  print '</select>';
683  print ajax_combobox('search_type_mouvement');
684  // TODO: add new function $formentrepot->selectTypeOfMovement(...) like
685  // print $formproduct->selectWarehouses($search_warehouse, 'search_warehouse', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'maxwidth200');
686  print '</td>';
687  }
688  if (!empty($arrayfields['origin']['checked'])) {
689  // Origin of movement
690  print '<td class="liste_titre left">';
691  print '&nbsp; ';
692  print '</td>';
693  }
694  if (!empty($arrayfields['m.fk_projet']['checked'])) {
695  // fk_project
696  print '<td class="liste_titre" align="left">';
697  print '&nbsp; ';
698  print '</td>';
699  }
700  if (!empty($arrayfields['m.value']['checked'])) {
701  // Qty
702  print '<td class="liste_titre right">';
703  print '<input class="flat" type="text" size="4" name="search_qty" value="'.dol_escape_htmltag($search_qty).'">';
704  print '</td>';
705  }
706  if (!empty($arrayfields['m.price']['checked'])) {
707  // Price
708  print '<td class="liste_titre left">';
709  print '&nbsp; ';
710  print '</td>';
711  }
712 
713 
714  // Extra fields
715  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
716 
717  // Fields from hook
718  $parameters = array('arrayfields'=>$arrayfields);
719  $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook
720  print $hookmanager->resPrint;
721  // Date creation
722  if (!empty($arrayfields['m.datec']['checked'])) {
723  print '<td class="liste_titre">';
724  print '</td>';
725  }
726  // Date modification
727  if (!empty($arrayfields['m.tms']['checked'])) {
728  print '<td class="liste_titre">';
729  print '</td>';
730  }
731  // Actions
732  print '<td class="liste_titre maxwidthsearch">';
733  $searchpicto = $form->showFilterAndCheckAddButtons(0);
734  print $searchpicto;
735  print '</td>';
736  print "</tr>\n";
737 
738  $totalarray = array();
739  $totalarray['nbfield'] = 0;
740 
741  print '<tr class="liste_titre">';
742  if (!empty($arrayfields['m.rowid']['checked'])) {
743  print_liste_field_titre($arrayfields['m.rowid']['label'], $_SERVER["PHP_SELF"], 'm.rowid', '', $param, '', $sortfield, $sortorder);
744  $totalarray['nbfield']++;
745  }
746  if (!empty($arrayfields['m.datem']['checked'])) {
747  print_liste_field_titre($arrayfields['m.datem']['label'], $_SERVER["PHP_SELF"], 'm.datem', '', $param, '', $sortfield, $sortorder);
748  $totalarray['nbfield']++;
749  }
750  if (!empty($arrayfields['p.ref']['checked'])) {
751  print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], 'p.ref', '', $param, '', $sortfield, $sortorder);
752  $totalarray['nbfield']++;
753  }
754  if (!empty($arrayfields['p.label']['checked'])) {
755  print_liste_field_titre($arrayfields['p.label']['label'], $_SERVER["PHP_SELF"], 'p.label', '', $param, '', $sortfield, $sortorder);
756  $totalarray['nbfield']++;
757  }
758  if (!empty($arrayfields['m.batch']['checked'])) {
759  print_liste_field_titre($arrayfields['m.batch']['label'], $_SERVER["PHP_SELF"], 'm.batch', '', $param, '', $sortfield, $sortorder, 'center ');
760  $totalarray['nbfield']++;
761  }
762  if (!empty($arrayfields['pl.eatby']['checked'])) {
763  print_liste_field_titre($arrayfields['pl.eatby']['label'], $_SERVER["PHP_SELF"], 'pl.eatby', '', $param, '', $sortfield, $sortorder, 'center ');
764  $totalarray['nbfield']++;
765  }
766  if (!empty($arrayfields['pl.sellby']['checked'])) {
767  print_liste_field_titre($arrayfields['pl.sellby']['label'], $_SERVER["PHP_SELF"], 'pl.sellby', '', $param, '', $sortfield, $sortorder, 'center ');
768  $totalarray['nbfield']++;
769  }
770  if (!empty($arrayfields['e.ref']['checked'])) {
771  // We are on a specific warehouse card, no filter on other should be possible
772  print_liste_field_titre($arrayfields['e.ref']['label'], $_SERVER["PHP_SELF"], "e.ref", "", $param, "", $sortfield, $sortorder);
773  $totalarray['nbfield']++;
774  }
775  if (!empty($arrayfields['m.fk_user_author']['checked'])) {
776  print_liste_field_titre($arrayfields['m.fk_user_author']['label'], $_SERVER["PHP_SELF"], "m.fk_user_author", "", $param, "", $sortfield, $sortorder);
777  $totalarray['nbfield']++;
778  }
779  if (!empty($arrayfields['m.inventorycode']['checked'])) {
780  print_liste_field_titre($arrayfields['m.inventorycode']['label'], $_SERVER["PHP_SELF"], "m.inventorycode", "", $param, "", $sortfield, $sortorder);
781  $totalarray['nbfield']++;
782  }
783  if (!empty($arrayfields['m.label']['checked'])) {
784  print_liste_field_titre($arrayfields['m.label']['label'], $_SERVER["PHP_SELF"], "m.label", "", $param, "", $sortfield, $sortorder);
785  $totalarray['nbfield']++;
786  }
787  if (!empty($arrayfields['m.type_mouvement']['checked'])) {
788  print_liste_field_titre($arrayfields['m.type_mouvement']['label'], $_SERVER["PHP_SELF"], "m.type_mouvement", "", $param, '', $sortfield, $sortorder, 'center ');
789  $totalarray['nbfield']++;
790  }
791  if (!empty($arrayfields['origin']['checked'])) {
792  print_liste_field_titre($arrayfields['origin']['label'], $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
793  $totalarray['nbfield']++;
794  }
795  if (!empty($arrayfields['m.fk_projet']['checked'])) {
796  print_liste_field_titre($arrayfields['m.fk_projet']['label'], $_SERVER["PHP_SELF"], "m.fk_projet", "", $param, '', $sortfield, $sortorder);
797  $totalarray['nbfield']++;
798  }
799  if (!empty($arrayfields['m.value']['checked'])) {
800  print_liste_field_titre($arrayfields['m.value']['label'], $_SERVER["PHP_SELF"], "m.value", "", $param, '', $sortfield, $sortorder, 'right ');
801  $totalarray['nbfield']++;
802  }
803  if (!empty($arrayfields['m.price']['checked'])) {
804  print_liste_field_titre($arrayfields['m.price']['label'], $_SERVER["PHP_SELF"], "m.price", "", $param, '', $sortfield, $sortorder, 'right ');
805  $totalarray['nbfield']++;
806  }
807 
808  // Extra fields
809  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
810 
811  // Hook fields
812  $parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder);
813  $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
814  print $hookmanager->resPrint;
815  if (!empty($arrayfields['m.datec']['checked'])) {
816  print_liste_field_titre($arrayfields['p.datec']['label'], $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
817  $totalarray['nbfield']++;
818  }
819  if (!empty($arrayfields['m.tms']['checked'])) {
820  print_liste_field_titre($arrayfields['p.tms']['label'], $_SERVER["PHP_SELF"], "p.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
821  $totalarray['nbfield']++;
822  }
823  print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
824  $totalarray['nbfield']++;
825  print "</tr>\n";
826 
827  $i = 0;
828  $savnbfield = $totalarray['nbfield'];
829  $totalarray = array();
830  $totalarray['nbfield'] = 0;
831  $imaxinloop = ($limit ? min($num, $limit) : $num);
832  while ($i < $imaxinloop) {
833  $objp = $db->fetch_object($resql);
834 
835  // Multilangs
836  if (getDolGlobalInt('MAIN_MULTILANGS')) { // If multilang is enabled
837  // TODO Use a cache here
838  $sql = "SELECT label";
839  $sql .= " FROM ".MAIN_DB_PREFIX."product_lang";
840  $sql .= " WHERE fk_product = ".((int) $objp->rowid);
841  $sql .= " AND lang = '".$db->escape($langs->getDefaultLang())."'";
842  $sql .= " LIMIT 1";
843 
844  $result = $db->query($sql);
845  if ($result) {
846  $objtp = $db->fetch_object($result);
847  if (!empty($objtp->label)) {
848  $objp->produit = $objtp->label;
849  }
850  }
851  }
852 
853  $userstatic->id = $objp->fk_user_author;
854  $userstatic->login = $objp->login;
855  $userstatic->lastname = $objp->lastname;
856  $userstatic->firstname = $objp->firstname;
857  $userstatic->photo = $objp->photo;
858 
859  $productstatic->id = $objp->rowid;
860  $productstatic->ref = $objp->product_ref;
861  $productstatic->label = $objp->produit;
862  $productstatic->type = $objp->type;
863  $productstatic->entity = $objp->entity;
864  $productstatic->status_batch = $objp->tobatch;
865 
866  $productlot->id = $objp->lotid;
867  $productlot->batch = $objp->batch;
868  $productlot->eatby = $objp->eatby;
869  $productlot->sellby = $objp->sellby;
870 
871  $warehousestatic->id = $objp->entrepot_id;
872  $warehousestatic->libelle = $objp->warehouse_ref; // deprecated
873  $warehousestatic->label = $objp->warehouse_ref;
874  $warehousestatic->lieu = $objp->lieu;
875 
876  if (!empty($objp->fk_origin)) {
877  $origin = $objectlist->get_origin($objp->fk_origin, $objp->origintype);
878  } else {
879  $origin = '';
880  }
881 
882  print '<tr class="oddeven">';
883  // Id movement
884  if (!empty($arrayfields['m.rowid']['checked'])) {
885  // This is primary not movement id
886  print '<td>'.dol_escape_htmltag($objp->mid).'</td>';
887  }
888  if (!empty($arrayfields['m.datem']['checked'])) {
889  // Date
890  print '<td>'.dol_print_date($db->jdate($objp->datem), 'dayhour').'</td>';
891  }
892  if (!empty($arrayfields['p.ref']['checked'])) {
893  // Product ref
894  print '<td class="nowraponall">';
895  print $productstatic->getNomUrl(1, 'stock', 16);
896  print "</td>\n";
897  }
898  if (!empty($arrayfields['p.label']['checked'])) {
899  // Product label
900  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($productstatic->label).'">';
901  print $productstatic->label;
902  print "</td>\n";
903  }
904  if (!empty($arrayfields['m.batch']['checked'])) {
905  print '<td class="center nowraponall">';
906  if ($productlot->id > 0) {
907  print $productlot->getNomUrl(1);
908  } else {
909  print dol_escape_htmltag($productlot->batch); // the id may not be defined if movement was entered when lot was not saved or if lot was removed after movement.
910  }
911  print '</td>';
912  }
913  if (!empty($arrayfields['pl.eatby']['checked'])) {
914  print '<td class="center">'.dol_print_date($objp->eatby, 'day').'</td>';
915  }
916  if (!empty($arrayfields['pl.sellby']['checked'])) {
917  print '<td class="center">'.dol_print_date($objp->sellby, 'day').'</td>';
918  }
919  // Warehouse
920  if (!empty($arrayfields['e.ref']['checked'])) {
921  print '<td>';
922  print $warehousestatic->getNomUrl(1);
923  print "</td>\n";
924  }
925  // Author
926  if (!empty($arrayfields['m.fk_user_author']['checked'])) {
927  print '<td class="tdoverflowmax100">';
928  print $userstatic->getNomUrl(-1);
929  print "</td>\n";
930  }
931  // Inventory code
932  if (!empty($arrayfields['m.inventorycode']['checked'])) {
933  print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($objp->inventorycode).'">';
934  //print '<a href="' . DOL_URL_ROOT . '/product/stock/movement_card.php' . '?id=' . $objp->entrepot_id . '&amp;search_inventorycode=' . $objp->inventorycode . '&amp;search_type_mouvement=' . $objp->type_mouvement . '">';
935  print dol_escape_htmltag($objp->inventorycode);
936  //print '</a>';
937  print '</td>';
938  }
939  // Label of movement
940  if (!empty($arrayfields['m.label']['checked'])) {
941  print '<td class="tdoverflowmax300" title="'.dol_escape_htmltag($objp->label).'">'.dol_escape_htmltag($objp->label).'</td>';
942  }
943  // Type of movement
944  if (!empty($arrayfields['m.type_mouvement']['checked'])) {
945  switch ($objp->type_mouvement) {
946  case "0":
947  print '<td class="center">'.$langs->trans('StockIncreaseAfterCorrectTransfer').'</td>';
948  break;
949  case "1":
950  print '<td class="center">'.$langs->trans('StockDecreaseAfterCorrectTransfer').'</td>';
951  break;
952  case "2":
953  print '<td class="center">'.$langs->trans('StockDecrease').'</td>';
954  break;
955  case "3":
956  print '<td class="center">'.$langs->trans('StockIncrease').'</td>';
957  break;
958  }
959  }
960  if (!empty($arrayfields['origin']['checked'])) {
961  // Origin of movement
962  print '<td class="nowraponall">'.$origin.'</td>';
963  }
964  if (!empty($arrayfields['m.fk_projet']['checked'])) {
965  // fk_project
966  print '<td>';
967  if ($objp->fk_project != 0) {
968  print $movement->get_origin($objp->fk_project, 'project');
969  }
970  print '</td>';
971  }
972  if (!empty($arrayfields['m.value']['checked'])) {
973  // Qty
974  print '<td class="right">';
975  if ($objp->qty >0) {
976  print '<span class="stockmovemententry">+'.$objp->qty.'</span>';
977  } else {
978  print '<span class="stockmovementexit">'.$objp->qty.'<span>';
979  }
980  print '</td>';
981  }
982  if (!empty($arrayfields['m.price']['checked'])) {
983  // Price
984  print '<td class="right">';
985  if ($objp->price != 0) {
986  print '<span class="opacitymedium">'.price($objp->price).'</span>';
987  }
988  print '</td>';
989  }
990  // Action column
991  print '<td class="nowrap center">';
992  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
993  $selected = 0;
994  if (in_array($obj->rowid, $arrayofselected)) {
995  $selected = 1;
996  }
997  print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
998  }
999  print '</td>';
1000  if (!$i) {
1001  $totalarray['nbfield']++;
1002  }
1003 
1004  print "</tr>\n";
1005  $i++;
1006  }
1007  if (empty($num)) {
1008  print '<tr><td colspan="'.$savnbfield.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1009  }
1010 
1011  $db->free($resql);
1012 
1013  print "</table>";
1014  print '</div>';
1015  print "</form>";
1016 }
1017 
1018 // End of page
1019 llxFooter();
1020 $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 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 for Mo.
Definition: mo.class.php:36
Class to manage stock movements.
Class to manage products or services.
Class to manage projects.
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
dolSqlDateFilter($datefield, $day_date, $month_date, $year_date, $excludefirstand=0, $gm=false)
Generate a SQL string to make a filter into a range (for second of date until last second of date).
Definition: date.lib.php:358
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_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
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.
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
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_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
newToken()
Return the value of token currently saved into session with name 'newtoken'.
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_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo editer/modifier fiche.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
$formconfirm
if ($action == 'delbookkeepingyear') {
moPrepareHead($object)
Prepare array of tabs for Mo.
Definition: mrp_mo.lib.php:30
$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.