29 require
'../../main.inc.php';
30 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formfile.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 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formother.class.php';
36 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
37 require_once DOL_DOCUMENT_ROOT.
'/core/lib/stock.lib.php';
38 require_once DOL_DOCUMENT_ROOT.
'/core/lib/product.lib.php';
39 require_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
40 if (!empty($conf->project->enabled)) {
41 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formprojet.class.php';
42 require_once DOL_DOCUMENT_ROOT.
'/projet/class/project.class.php';
46 $langs->loadLangs(array(
'products',
'stocks',
'orders'));
47 if (!empty($conf->productbatch->enabled)) {
48 $langs->load(
"productbatch");
57 $product_id =
GETPOST(
"product_id",
'int');
58 $action =
GETPOST(
'action',
'aZ09');
59 $cancel =
GETPOST(
'cancel',
'alpha');
60 $contextpage =
GETPOST(
'contextpage',
'aZ') ?
GETPOST(
'contextpage',
'aZ') :
'movementlist';
62 $idproduct =
GETPOST(
'idproduct',
'int');
64 $month =
GETPOST(
"month",
'int');
65 $search_ref =
GETPOST(
'search_ref',
'alpha');
66 $search_movement =
GETPOST(
"search_movement",
'alpha');
67 $search_product_ref = trim(
GETPOST(
"search_product_ref",
'alpha'));
68 $search_product = trim(
GETPOST(
"search_product",
'alpha'));
69 $search_warehouse = trim(
GETPOST(
"search_warehouse",
'alpha'));
70 $search_inventorycode = trim(
GETPOST(
"search_inventorycode",
'alpha'));
71 $search_user = trim(
GETPOST(
"search_user",
'alpha'));
72 $search_batch = trim(
GETPOST(
"search_batch",
'alpha'));
73 $search_qty = trim(
GETPOST(
"search_qty",
'alpha'));
74 $search_type_mouvement =
GETPOST(
'search_type_mouvement',
'int');
76 $limit =
GETPOST(
'limit',
'int') ?
GETPOST(
'limit',
'int') : $conf->liste_limit;
78 $sortfield =
GETPOST(
'sortfield',
'aZ09comma');
79 $sortorder =
GETPOST(
'sortorder',
'aZ09comma');
80 if (empty($page) || $page == -1) {
83 $offset = $limit * $page;
85 $sortfield =
"m.datem";
91 $pdluoid =
GETPOST(
'pdluoid',
'int');
95 $hookmanager->initHooks(array(
'movementlist'));
100 $extrafields->fetch_name_optionals_label($object->table_element);
102 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element,
'',
'search_');
104 $arrayfields = array(
105 'm.rowid'=>array(
'label'=>$langs->trans(
"Ref"),
'checked'=>1),
106 'm.datem'=>array(
'label'=>$langs->trans(
"Date"),
'checked'=>1),
107 'p.ref'=>array(
'label'=>$langs->trans(
"ProductRef"),
'checked'=>1,
'css'=>
'maxwidth100'),
108 'p.label'=>array(
'label'=>$langs->trans(
"ProductLabel"),
'checked'=>1),
109 'm.batch'=>array(
'label'=>$langs->trans(
"BatchNumberShort"),
'checked'=>1,
'enabled'=>(!empty($conf->productbatch->enabled))),
110 'pl.eatby'=>array(
'label'=>$langs->trans(
"EatByDate"),
'checked'=>0,
'position'=>10,
'enabled'=>(!empty($conf->productbatch->enabled))),
111 'pl.sellby'=>array(
'label'=>$langs->trans(
"SellByDate"),
'checked'=>0,
'position'=>10,
'enabled'=>(!empty($conf->productbatch->enabled))),
112 'e.ref'=>array(
'label'=>$langs->trans(
"Warehouse"),
'checked'=>1,
'enabled'=>(!($id > 0))),
113 'm.fk_user_author'=>array(
'label'=>$langs->trans(
"Author"),
'checked'=>0),
114 'm.inventorycode'=>array(
'label'=>$langs->trans(
"InventoryCodeShort"),
'checked'=>1),
115 'm.label'=>array(
'label'=>$langs->trans(
"MovementLabel"),
'checked'=>1),
116 'm.type_mouvement'=>array(
'label'=>$langs->trans(
"TypeMovement"),
'checked'=>1),
117 'origin'=>array(
'label'=>$langs->trans(
"Origin"),
'checked'=>1),
118 'm.value'=>array(
'label'=>$langs->trans(
"Qty"),
'checked'=>1),
119 'm.price'=>array(
'label'=>$langs->trans(
"UnitPurchaseValue"),
'checked'=>0),
124 $usercanread = (($user->rights->stock->mouvement->lire));
125 $usercancreate = (($user->rights->stock->mouvement->creer));
126 $usercandelete = (($user->rights->stock->mouvement->supprimer));
134 if (
GETPOST(
'cancel',
'alpha')) {
135 $action =
'list'; $massaction =
'';
137 if (!
GETPOST(
'confirmmassaction',
'alpha') && $massaction !=
'presend' && $massaction !=
'confirm_presend') {
141 $parameters = array();
142 $reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
147 include DOL_DOCUMENT_ROOT.
'/core/actions_changeselectedfields.inc.php';
150 if (
GETPOST(
'button_removefilter_x',
'alpha') ||
GETPOST(
'button_removefilter.x',
'alpha') ||
GETPOST(
'button_removefilter',
'alpha')) {
154 $search_movement =
"";
155 $search_type_mouvement =
"";
156 $search_inventorycode =
"";
157 $search_product_ref =
"";
158 $search_product =
"";
159 $search_warehouse =
"";
165 $search_array_options = array();
169 if ($action ==
"correct_stock") {
171 if (!empty($product_id)) {
172 $result = $product->fetch($product_id);
177 if (empty($product_id)) {
179 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"Product")), null,
'errors');
180 $action =
'correction';
182 if (!is_numeric(
GETPOST(
"nbpiece"))) {
184 setEventMessages($langs->trans(
"ErrorFieldMustBeANumeric", $langs->transnoentitiesnoconv(
"NumberOfUnit")), null,
'errors');
185 $action =
'correction';
189 $origin_element =
'';
192 if (
GETPOST(
'projectid',
'int')) {
193 $origin_element =
'project';
194 $origin_id =
GETPOST(
'projectid',
'int');
197 if ($product->hasbatch()) {
198 $batch =
GETPOST(
'batch_number',
'alpha');
205 $result = $product->correct_stock_batch(
215 GETPOST(
'inventorycode',
'alpha'),
220 $result = $product->correct_stock(
227 GETPOST(
'inventorycode',
'alpha'),
234 header(
"Location: ".$_SERVER[
"PHP_SELF"].
"?id=".$id);
239 $action =
'correction';
249 if ($action ==
"transfert_stock" && !$cancel) {
251 if (!empty($product_id)) {
252 $result = $product->fetch($product_id);
255 if (!(
GETPOST(
"id_entrepot_destination",
'int') > 0)) {
256 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"Warehouse")), null,
'errors');
258 $action =
'transfert';
260 if (empty($product_id)) {
262 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"Product")), null,
'errors');
263 $action =
'transfert';
265 if (!
GETPOST(
"nbpiece",
'int')) {
266 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"NumberOfUnit")), null,
'errors');
268 $action =
'transfert';
270 if ($id ==
GETPOST(
"id_entrepot_destination",
'int')) {
271 setEventMessages($langs->trans(
"ErrorSrcAndTargetWarehouseMustDiffers"), null,
'errors');
273 $action =
'transfert';
276 if (!empty($conf->productbatch->enabled)) {
278 $result = $product->fetch($product_id);
280 if ($product->hasbatch() && !
GETPOST(
"batch_number",
'alpha')) {
281 setEventMessages($langs->trans(
"ErrorFieldRequired", $langs->transnoentitiesnoconv(
"batch_number")), null,
'errors');
283 $action =
'transfert';
290 $result = $object->fetch($id);
294 $product->load_stock(
'novirtual');
298 if (isset($product->pmp)) {
299 $pricesrc = $product->pmp;
301 $pricedest = $pricesrc;
303 if ($product->hasbatch()) {
307 $result = $pdluo->fetch($pdluoid);
309 $srcwarehouseid = $pdluo->warehouseid;
310 $batch = $pdluo->batch;
311 $eatby = $pdluo->eatby;
312 $sellby = $pdluo->sellby;
318 $srcwarehouseid = $id;
319 $batch =
GETPOST(
'batch_number',
'alpha');
326 $result1 = $product->correct_stock_batch(
336 GETPOST(
'inventorycode',
'alpha')
339 $result2 = $product->correct_stock_batch(
341 GETPOST(
"id_entrepot_destination",
'int'),
349 GETPOST(
'inventorycode',
'alpha')
354 $result1 = $product->correct_stock(
361 GETPOST(
'inventorycode',
'alpha')
365 $result2 = $product->correct_stock(
367 GETPOST(
"id_entrepot_destination"),
372 GETPOST(
'inventorycode',
'alpha')
375 if (!$error && $result1 >= 0 && $result2 >= 0) {
379 header(
"Location: ".$backtopage);
382 header(
"Location: movement_list.php?id=".$object->id);
388 $action =
'transfert';
400 $upload_dir = $conf->stock->dir_output.
"movement/";
401 $permissiontoadd = $user->rights->stock->creer;
402 include DOL_DOCUMENT_ROOT.
'/core/actions_builddoc.inc.php';
405 if (empty($reshook) && $action !=
'remove_file') {
406 $objectclass =
'MouvementStock';
407 $objectlabel =
'Movements';
408 $permissiontoread = $user->rights->stock->lire;
409 $permissiontodelete = $user->rights->stock->supprimer;
410 $uploaddir = $conf->stock->dir_output.
"/movement/";
411 include DOL_DOCUMENT_ROOT.
'/core/actions_massactions.inc.php';
420 $productlot =
new ProductLot($db);
421 $productstatic =
new Product($db);
422 $warehousestatic =
new Entrepot($db);
424 $userstatic =
new User($db);
428 if (!empty($conf->project->enabled)) {
432 $sql =
"SELECT p.rowid, p.ref as product_ref, p.label as produit, p.tobatch, p.fk_product_type as type, p.entity,";
433 $sql .=
" e.ref as warehouse_ref, e.rowid as entrepot_id, e.lieu,";
434 $sql .=
" m.rowid as mid, m.value as qty, m.datem, m.fk_user_author, m.label, m.inventorycode, m.fk_origin, m.origintype,";
435 $sql .=
" m.batch, m.price,";
436 $sql .=
" m.type_mouvement,";
437 $sql .=
" pl.rowid as lotid, pl.eatby, pl.sellby,";
438 $sql .=
" u.login, u.photo, u.lastname, u.firstname";
440 if (!empty($extrafields->attributes[$object->table_element][
'label'])) {
441 foreach ($extrafields->attributes[$object->table_element][
'label'] as $key => $val) {
442 $sql .= ($extrafields->attributes[$object->table_element][
'type'][$key] !=
'separate' ?
", ef.".$key.
" as options_".$key :
'');
446 $parameters = array();
447 $reshook = $hookmanager->executeHooks(
'printFieldListSelect', $parameters);
448 $sql .= $hookmanager->resPrint;
449 $sql .=
" FROM ".MAIN_DB_PREFIX.
"entrepot as e,";
450 $sql .=
" ".MAIN_DB_PREFIX.
"product as p,";
451 $sql .=
" ".MAIN_DB_PREFIX.
"stock_mouvement as m";
452 if (isset($extrafields->attributes[$object->table_element][
'label']) && is_array($extrafields->attributes[$object->table_element][
'label']) && count($extrafields->attributes[$object->table_element][
'label'])) {
453 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element.
"_extrafields as ef on (m.rowid = ef.fk_object)";
455 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user as u ON m.fk_user_author = u.rowid";
456 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"product_lot as pl ON m.batch = pl.batch AND m.fk_product = pl.fk_product";
457 $sql .=
" WHERE m.fk_product = p.rowid";
459 $sql .=
" AND m.rowid = ".((int) $msid);
461 $sql .=
" AND m.fk_entrepot = e.rowid";
462 $sql .=
" AND e.entity IN (".getEntity(
'stock').
")";
463 if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
464 $sql .=
" AND p.fk_product_type = 0";
467 $sql .=
" AND e.rowid = ".((int) $id);
470 if ($idproduct > 0) {
471 $sql .=
" AND p.rowid = ".((int) $idproduct);
473 if (!empty($search_ref)) {
476 if (!empty($search_movement)) {
479 if (!empty($search_inventorycode)) {
482 if (!empty($search_product_ref)) {
485 if (!empty($search_product)) {
488 if ($search_warehouse !=
'' && $search_warehouse !=
'-1') {
491 if (!empty($search_user)) {
492 $sql .=
natural_search(array(
'u.lastname',
'u.firstname',
'u.login'), $search_user);
494 if (!empty($search_batch)) {
497 if ($search_qty !=
'') {
500 if ($search_type_mouvement !=
'' && $search_type_mouvement !=
'-1') {
501 $sql .=
natural_search(
'm.type_mouvement', $search_type_mouvement, 2);
504 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_list_search_sql.tpl.php';
506 $parameters = array();
507 $reshook = $hookmanager->executeHooks(
'printFieldListWhere', $parameters);
508 $sql .= $hookmanager->resPrint;
509 $sql .= $db->order($sortfield, $sortorder);
511 $nbtotalofrecords =
'';
512 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
513 $result = $db->query($sql);
514 $nbtotalofrecords = $db->num_rows($result);
515 if (($page * $limit) > $nbtotalofrecords) {
523 $resql = $db->query($sql);
529 if ($idproduct > 0) {
530 $product->fetch($idproduct);
532 if ($id > 0 || $ref) {
533 $result = $object->fetch($id, $ref);
539 $num = $db->num_rows(
$resql);
541 $arrayofselected = is_array($toselect) ? $toselect : array();
545 $help_url =
'EN:Module_Stocks_En|FR:Module_Stock|ES:Módulo_Stocks';
547 $texte = $langs->trans(
'StockMovementForId', $msid);
549 $texte = $langs->trans(
"ListOfStockMovements");
551 $texte .=
' ('.$langs->trans(
"ForThisWarehouse").
')';
559 if ($object->id > 0) {
562 print
dol_get_fiche_head($head,
'movements', $langs->trans(
"Warehouse"), -1,
'stock');
565 $linkback =
'<a href="'.DOL_URL_ROOT.
'/product/stock/list.php?restore_lastsearch_values=1">'.$langs->trans(
"BackToList").
'</a>';
567 $morehtmlref =
'<div class="refidno">';
568 $morehtmlref .= $langs->trans(
"LocationSummary").
' : '.$object->lieu;
569 $morehtmlref .=
'</div>';
572 if ($user->socid && !in_array(
'stock', explode(
',', $conf->global->MAIN_MODULES_FOR_EXTERNAL))) {
576 dol_banner_tab($object,
'ref', $linkback, $shownav,
'ref',
'ref', $morehtmlref);
579 print
'<div class="fichecenter">';
580 print
'<div class="fichehalfleft">';
581 print
'<div class="underbanner clearboth"></div>';
583 print
'<table class="border centpercent">';
588 print
'<td class="titlefield tdtop">'.$langs->trans(
"Description").
'</td><td>'.
dol_htmlentitiesbr($object->description).
'</td></tr>';
590 $calcproductsunique = $object->nb_different_products();
591 $calcproducts = $object->nb_products();
594 print
'<tr><td>'.$langs->trans(
"NumberOfDifferentProducts").
'</td><td>';
595 print empty($calcproductsunique[
'nb']) ?
'0' : $calcproductsunique[
'nb'];
599 print
'<tr><td>'.$langs->trans(
"NumberOfProducts").
'</td><td>';
600 $valtoshow =
price2num($calcproducts[
'nb'],
'MS');
601 print empty($valtoshow) ?
'0' : $valtoshow;
607 print
'<div class="fichehalfright">';
608 print
'<div class="underbanner clearboth"></div>';
610 print
'<table class="border centpercent">';
613 print
'<tr><td class="titlefield">'.$langs->trans(
"EstimatedStockValueShort").
'</td><td>';
614 print
price((empty($calcproducts[
'value']) ?
'0' :
price2num($calcproducts[
'value'],
'MT')), 0, $langs, 0, -1, -1, $conf->currency);
618 $sql =
"SELECT MAX(m.datem) as datem";
619 $sql .=
" FROM ".MAIN_DB_PREFIX.
"stock_mouvement as m";
620 $sql .=
" WHERE m.fk_entrepot = ".(int) $object->id;
621 $resqlbis = $db->query($sql);
623 $obj = $db->fetch_object($resqlbis);
624 $lastmovementdate = $db->jdate($obj->datem);
629 print
'<tr><td>'.$langs->trans(
"LastMovement").
'</td><td>';
630 if ($lastmovementdate) {
633 print $langs->trans(
"None");
642 print
'<div class="clearboth"></div>';
651 if ($action ==
"correction") {
652 include DOL_DOCUMENT_ROOT.
'/product/stock/tpl/stockcorrection.tpl.php';
659 if ($action ==
"transfert") {
660 include DOL_DOCUMENT_ROOT.
'/product/stock/tpl/stocktransfer.tpl.php';
668 if ((empty($action) || $action ==
'list') && $id > 0) {
669 print
"<div class=\"tabsAction\">\n";
671 if ($user->rights->stock->mouvement->creer) {
672 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$id.
'&action=correction">'.$langs->trans(
"CorrectStock").
'</a>';
675 if ($user->rights->stock->mouvement->creer) {
676 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$id.
'&action=transfert">'.$langs->trans(
"TransferStock").
'</a>';
683 if (!empty($contextpage) && $contextpage != $_SERVER[
"PHP_SELF"]) {
684 $param .=
'&contextpage='.urlencode($contextpage);
686 if ($limit > 0 && $limit != $conf->liste_limit) {
687 $param .=
'&limit='.urlencode($limit);
690 $param .=
'&id='.urlencode($id);
692 if ($search_movement) {
693 $param .=
'&search_movement='.urlencode($search_movement);
695 if ($search_inventorycode) {
696 $param .=
'&search_inventorycode='.urlencode($search_inventorycode);
698 if ($search_type_mouvement) {
699 $param .=
'&search_type_mouvement='.urlencode($search_type_mouvement);
701 if ($search_product_ref) {
702 $param .=
'&search_product_ref='.urlencode($search_product_ref);
704 if ($search_product) {
705 $param .=
'&search_product='.urlencode($search_product);
708 $param .=
'&search_batch='.urlencode($search_batch);
710 if ($search_warehouse > 0) {
711 $param .=
'&search_warehouse='.urlencode($search_warehouse);
714 $param .=
'&search_user='.urlencode($search_user);
716 if ($idproduct > 0) {
717 $param .=
'&idproduct='.urlencode($idproduct);
720 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_list_search_param.tpl.php';
723 $arrayofmassactions = array(
728 if (in_array($massaction, array(
'presend',
'predelete'))) {
729 $arrayofmassactions = array();
731 $massactionbutton =
$form->selectMassAction(
'', $arrayofmassactions);
733 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'">';
734 if ($optioncss !=
'') {
735 print
'<input type="hidden" name="optioncss" value="'.$optioncss.
'">';
737 print
'<input type="hidden" name="token" value="'.newToken().
'">';
738 print
'<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
739 print
'<input type="hidden" name="action" value="list">';
740 print
'<input type="hidden" name="sortfield" value="'.$sortfield.
'">';
741 print
'<input type="hidden" name="sortorder" value="'.$sortorder.
'">';
742 print
'<input type="hidden" name="page" value="'.$page.
'">';
743 print
'<input type="hidden" name="contextpage" value="'.$contextpage.
'">';
745 print
'<input type="hidden" name="id" value="'.$id.
'">';
749 print_barre_liste($texte, $page, $_SERVER[
"PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords,
'', 0,
'',
'', $limit);
751 print_barre_liste($texte, $page, $_SERVER[
"PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords,
'generic', 0,
'',
'', $limit);
755 foreach ($fieldstosearchall as $key => $val) {
756 $fieldstosearchall[$key] = $langs->trans($val);
758 print
'<div class="divsearchfieldfilter">'.$langs->trans(
"FilterOnInto", $sall).join(
', ', $fieldstosearchall).
'</div>';
763 $parameters = array();
764 $reshook = $hookmanager->executeHooks(
'printFieldPreListTitle', $parameters);
765 if (empty($reshook)) {
766 $moreforfilter .= $hookmanager->resPrint;
768 $moreforfilter = $hookmanager->resPrint;
771 if (!empty($moreforfilter)) {
772 print
'<div class="liste_titre liste_titre_bydiv centpercent">';
773 print $moreforfilter;
777 $varpage = empty($contextpage) ? $_SERVER[
"PHP_SELF"] : $contextpage;
778 $selectedfields =
$form->multiSelectArrayWithCheckbox(
'selectedfields', $arrayfields, $varpage);
780 print
'<div class="div-table-responsive">';
781 print
'<table class="tagtable liste'.($moreforfilter ?
" listwithfilterbefore" :
"").
'">'.
"\n";
784 print
'<tr class="liste_titre_filter">';
785 if (!empty($arrayfields[
'm.rowid'][
'checked'])) {
787 print
'<td class="liste_titre left">';
788 print
'<input class="flat maxwidth25" type="text" name="search_ref" value="'.dol_escape_htmltag($search_ref).
'">';
791 if (!empty($arrayfields[
'm.datem'][
'checked'])) {
792 print
'<td class="liste_titre nowraponall">';
793 print
'<input class="flat" type="text" size="2" maxlength="2" placeholder="'.dol_escape_htmltag($langs->trans(
"Month")).
'" name="month" value="'.$month.
'">';
794 if (empty($conf->productbatch->enabled)) {
798 $syear = $year ? $year : -1;
799 print
'<input class="flat maxwidth50" type="text" maxlength="4" placeholder="'.dol_escape_htmltag($langs->trans(
"Year")).
'" name="year" value="'.($syear > 0 ? $syear :
'').
'">';
803 if (!empty($arrayfields[
'p.ref'][
'checked'])) {
805 print
'<td class="liste_titre left">';
806 print
'<input class="flat maxwidth75" type="text" name="search_product_ref" value="'.dol_escape_htmltag($idproduct ? $product->ref : $search_product_ref).
'">';
809 if (!empty($arrayfields[
'p.label'][
'checked'])) {
811 print
'<td class="liste_titre left">';
812 print
'<input class="flat maxwidth100" type="text" name="search_product" value="'.dol_escape_htmltag($idproduct ? $product->label : $search_product).
'">';
816 if (!empty($arrayfields[
'm.batch'][
'checked'])) {
817 print
'<td class="liste_titre center"><input class="flat maxwidth75" type="text" name="search_batch" value="'.dol_escape_htmltag($search_batch).
'"></td>';
819 if (!empty($arrayfields[
'pl.eatby'][
'checked'])) {
820 print
'<td class="liste_titre left">';
823 if (!empty($arrayfields[
'pl.sellby'][
'checked'])) {
824 print
'<td class="liste_titre left">';
828 if (!empty($arrayfields[
'e.ref'][
'checked'])) {
829 print
'<td class="liste_titre maxwidthonsmartphone left">';
831 print $formproduct->selectWarehouses($search_warehouse,
'search_warehouse',
'warehouseopen,warehouseinternal', 1, 0, 0,
'', 0, 0, null,
'maxwidth200');
834 if (!empty($arrayfields[
'm.fk_user_author'][
'checked'])) {
836 print
'<td class="liste_titre left">';
837 print
'<input class="flat" type="text" size="6" name="search_user" value="'.dol_escape_htmltag($search_user).
'">';
840 if (!empty($arrayfields[
'm.inventorycode'][
'checked'])) {
842 print
'<td class="liste_titre left">';
843 print
'<input class="flat" type="text" size="4" name="search_inventorycode" value="'.dol_escape_htmltag($search_inventorycode).
'">';
846 if (!empty($arrayfields[
'm.label'][
'checked'])) {
848 print
'<td class="liste_titre left">';
849 print
'<input class="flat" type="text" size="8" name="search_movement" value="'.dol_escape_htmltag($search_movement).
'">';
852 if (!empty($arrayfields[
'm.type_mouvement'][
'checked'])) {
854 print
'<td class="liste_titre center">';
856 print
'<select id="search_type_mouvement" name="search_type_mouvement" class="maxwidth150">';
857 print
'<option value="" '.(($search_type_mouvement ==
"") ?
'selected="selected"' :
'').
'></option>';
858 print
'<option value="0" '.(($search_type_mouvement ==
"0") ?
'selected="selected"' :
'').
'>'.$langs->trans(
'StockIncreaseAfterCorrectTransfer').
'</option>';
859 print
'<option value="1" '.(($search_type_mouvement ==
"1") ?
'selected="selected"' :
'').
'>'.$langs->trans(
'StockDecreaseAfterCorrectTransfer').
'</option>';
860 print
'<option value="2" '.(($search_type_mouvement ==
"2") ?
'selected="selected"' :
'').
'>'.$langs->trans(
'StockDecrease').
'</option>';
861 print
'<option value="3" '.(($search_type_mouvement ==
"3") ?
'selected="selected"' :
'').
'>'.$langs->trans(
'StockIncrease').
'</option>';
868 if (!empty($arrayfields[
'origin'][
'checked'])) {
870 print
'<td class="liste_titre left">';
874 if (!empty($arrayfields[
'm.value'][
'checked'])) {
876 print
'<td class="liste_titre right">';
877 print
'<input class="flat" type="text" size="4" name="search_qty" value="'.dol_escape_htmltag($search_qty).
'">';
880 if (!empty($arrayfields[
'm.price'][
'checked'])) {
882 print
'<td class="liste_titre left">';
889 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_list_search_input.tpl.php';
892 $parameters = array(
'arrayfields'=>$arrayfields);
893 $reshook = $hookmanager->executeHooks(
'printFieldListOption', $parameters);
894 print $hookmanager->resPrint;
896 if (!empty($arrayfields[
'm.datec'][
'checked'])) {
897 print
'<td class="liste_titre">';
901 if (!empty($arrayfields[
'm.tms'][
'checked'])) {
902 print
'<td class="liste_titre">';
906 print
'<td class="liste_titre maxwidthsearch">';
907 $searchpicto =
$form->showFilterAndCheckAddButtons(0);
912 print
'<tr class="liste_titre">';
913 if (!empty($arrayfields[
'm.rowid'][
'checked'])) {
914 print_liste_field_titre($arrayfields[
'm.rowid'][
'label'], $_SERVER[
"PHP_SELF"],
'm.rowid',
'', $param,
'', $sortfield, $sortorder);
916 if (!empty($arrayfields[
'm.datem'][
'checked'])) {
917 print_liste_field_titre($arrayfields[
'm.datem'][
'label'], $_SERVER[
"PHP_SELF"],
'm.datem',
'', $param,
'', $sortfield, $sortorder);
919 if (!empty($arrayfields[
'p.ref'][
'checked'])) {
920 print_liste_field_titre($arrayfields[
'p.ref'][
'label'], $_SERVER[
"PHP_SELF"],
'p.ref',
'', $param,
'', $sortfield, $sortorder);
922 if (!empty($arrayfields[
'p.label'][
'checked'])) {
923 print_liste_field_titre($arrayfields[
'p.label'][
'label'], $_SERVER[
"PHP_SELF"],
'p.label',
'', $param,
'', $sortfield, $sortorder);
925 if (!empty($arrayfields[
'm.batch'][
'checked'])) {
926 print_liste_field_titre($arrayfields[
'm.batch'][
'label'], $_SERVER[
"PHP_SELF"],
'm.batch',
'', $param,
'', $sortfield, $sortorder,
'center ');
928 if (!empty($arrayfields[
'pl.eatby'][
'checked'])) {
929 print_liste_field_titre($arrayfields[
'pl.eatby'][
'label'], $_SERVER[
"PHP_SELF"],
'pl.eatby',
'', $param,
'', $sortfield, $sortorder,
'center ');
931 if (!empty($arrayfields[
'pl.sellby'][
'checked'])) {
932 print_liste_field_titre($arrayfields[
'pl.sellby'][
'label'], $_SERVER[
"PHP_SELF"],
'pl.sellby',
'', $param,
'', $sortfield, $sortorder,
'center ');
934 if (!empty($arrayfields[
'e.ref'][
'checked'])) {
936 print_liste_field_titre($arrayfields[
'e.ref'][
'label'], $_SERVER[
"PHP_SELF"],
"e.ref",
"", $param,
"", $sortfield, $sortorder);
938 if (!empty($arrayfields[
'm.fk_user_author'][
'checked'])) {
939 print_liste_field_titre($arrayfields[
'm.fk_user_author'][
'label'], $_SERVER[
"PHP_SELF"],
"m.fk_user_author",
"", $param,
"", $sortfield, $sortorder);
941 if (!empty($arrayfields[
'm.inventorycode'][
'checked'])) {
942 print_liste_field_titre($arrayfields[
'm.inventorycode'][
'label'], $_SERVER[
"PHP_SELF"],
"m.inventorycode",
"", $param,
"", $sortfield, $sortorder);
944 if (!empty($arrayfields[
'm.label'][
'checked'])) {
945 print_liste_field_titre($arrayfields[
'm.label'][
'label'], $_SERVER[
"PHP_SELF"],
"m.label",
"", $param,
"", $sortfield, $sortorder);
947 if (!empty($arrayfields[
'm.type_mouvement'][
'checked'])) {
948 print_liste_field_titre($arrayfields[
'm.type_mouvement'][
'label'], $_SERVER[
"PHP_SELF"],
"m.type_mouvement",
"", $param,
'', $sortfield, $sortorder,
'center ');
950 if (!empty($arrayfields[
'origin'][
'checked'])) {
951 print_liste_field_titre($arrayfields[
'origin'][
'label'], $_SERVER[
"PHP_SELF"],
"",
"", $param,
"", $sortfield, $sortorder);
953 if (!empty($arrayfields[
'm.value'][
'checked'])) {
954 print_liste_field_titre($arrayfields[
'm.value'][
'label'], $_SERVER[
"PHP_SELF"],
"m.value",
"", $param,
'', $sortfield, $sortorder,
'right ');
956 if (!empty($arrayfields[
'm.price'][
'checked'])) {
957 print_liste_field_titre($arrayfields[
'm.price'][
'label'], $_SERVER[
"PHP_SELF"],
"m.price",
"", $param,
'', $sortfield, $sortorder,
'right ');
961 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_list_search_title.tpl.php';
964 $parameters = array(
'arrayfields'=>$arrayfields,
'param'=>$param,
'sortfield'=>$sortfield,
'sortorder'=>$sortorder);
965 $reshook = $hookmanager->executeHooks(
'printFieldListTitle', $parameters);
966 print $hookmanager->resPrint;
967 if (!empty($arrayfields[
'm.datec'][
'checked'])) {
968 print_liste_field_titre($arrayfields[
'p.datec'][
'label'], $_SERVER[
"PHP_SELF"],
"p.datec",
"", $param,
'', $sortfield, $sortorder,
'center nowrap ');
970 if (!empty($arrayfields[
'm.tms'][
'checked'])) {
971 print_liste_field_titre($arrayfields[
'p.tms'][
'label'], $_SERVER[
"PHP_SELF"],
"p.tms",
"", $param,
'', $sortfield, $sortorder,
'center nowrap ');
973 print_liste_field_titre($selectedfields, $_SERVER[
"PHP_SELF"],
"",
'',
'',
'', $sortfield, $sortorder,
'center maxwidthsearch ');
977 $arrayofuniqueproduct = array();
978 while ($i < ($limit ? min($num, $limit) : $num)) {
979 $objp = $db->fetch_object(
$resql);
981 $userstatic->id = $objp->fk_user_author;
982 $userstatic->login = $objp->login;
983 $userstatic->lastname = $objp->lastname;
984 $userstatic->firstname = $objp->firstname;
985 $userstatic->photo = $objp->photo;
987 $productstatic->id = $objp->rowid;
988 $productstatic->ref = $objp->product_ref;
989 $productstatic->label = $objp->produit;
990 $productstatic->type = $objp->type;
991 $productstatic->entity = $objp->entity;
992 $productstatic->status_batch = $objp->tobatch;
994 $productlot->id = $objp->lotid;
995 $productlot->batch = $objp->batch;
996 $productlot->eatby = $objp->eatby;
997 $productlot->sellby = $objp->sellby;
999 $warehousestatic->id = $objp->entrepot_id;
1000 $warehousestatic->label = $objp->warehouse_ref;
1001 $warehousestatic->lieu = $objp->lieu;
1003 $arrayofuniqueproduct[$objp->rowid] = $objp->produit;
1004 if (!empty($objp->fk_origin)) {
1005 $origin = $movement->get_origin($objp->fk_origin, $objp->origintype);
1010 print
'<tr class="oddeven">';
1012 if (!empty($arrayfields[
'm.rowid'][
'checked'])) {
1014 print
'<td>'.$objp->mid.
'</td>';
1016 if (!empty($arrayfields[
'm.datem'][
'checked'])) {
1018 print
'<td>'.dol_print_date($db->jdate($objp->datem),
'dayhour').
'</td>';
1020 if (!empty($arrayfields[
'p.ref'][
'checked'])) {
1022 print
'<td class="nowraponall">';
1023 print $productstatic->getNomUrl(1,
'stock', 16);
1026 if (!empty($arrayfields[
'p.label'][
'checked'])) {
1033 print $productstatic->label;
1036 if (!empty($arrayfields[
'm.batch'][
'checked'])) {
1037 print
'<td class="center nowraponall">';
1038 if ($productlot->id > 0) {
1039 print $productlot->getNomUrl(1);
1041 print $productlot->batch;
1045 if (!empty($arrayfields[
'pl.eatby'][
'checked'])) {
1046 print
'<td class="center">'.dol_print_date($objp->eatby,
'day').
'</td>';
1048 if (!empty($arrayfields[
'pl.sellby'][
'checked'])) {
1049 print
'<td class="center">'.dol_print_date($objp->sellby,
'day').
'</td>';
1052 if (!empty($arrayfields[
'e.ref'][
'checked'])) {
1054 print $warehousestatic->getNomUrl(1);
1058 if (!empty($arrayfields[
'm.fk_user_author'][
'checked'])) {
1059 print
'<td class="tdoverflowmax100">';
1060 print $userstatic->getNomUrl(-1);
1063 if (!empty($arrayfields[
'm.inventorycode'][
'checked'])) {
1065 print
'<td><a href="'
1066 .DOL_URL_ROOT.
'/product/stock/movement_card.php?id='.urlencode($objp->entrepot_id)
1067 .
'&search_inventorycode='.urlencode($objp->inventorycode)
1068 .
'&search_type_mouvement='.urlencode($objp->type_mouvement)
1070 .$objp->inventorycode
1073 if (!empty($arrayfields[
'm.label'][
'checked'])) {
1075 print
'<td class="tdoverflowmax100aaa">'.$objp->label.
'</td>';
1077 if (!empty($arrayfields[
'm.type_mouvement'][
'checked'])) {
1079 switch ($objp->type_mouvement) {
1081 print
'<td class="center">'.$langs->trans(
'StockIncreaseAfterCorrectTransfer').
'</td>';
1084 print
'<td class="center">'.$langs->trans(
'StockDecreaseAfterCorrectTransfer').
'</td>';
1087 print
'<td class="center">'.$langs->trans(
'StockDecrease').
'</td>';
1090 print
'<td class="center">'.$langs->trans(
'StockIncrease').
'</td>';
1094 if (!empty($arrayfields[
'origin'][
'checked'])) {
1096 print
'<td class="nowraponall">'.$origin.
'</td>';
1098 if (!empty($arrayfields[
'm.value'][
'checked'])) {
1100 print
'<td class="right">';
1101 if ($objp->qt > 0) {
1107 if (!empty($arrayfields[
'm.price'][
'checked'])) {
1109 print
'<td class="right">';
1110 if ($objp->price != 0) {
1111 print
price($objp->price);
1116 print
'<td class="nowrap center">';
1117 if ($massactionbutton || $massaction) {
1119 if (in_array($obj->rowid, $arrayofselected)) {
1122 print
'<input id="cb'.$obj->rowid.
'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.
'"'.($selected ?
' checked="checked"' :
'').
'>';
1126 $totalarray[
'nbfield']++;
1139 if (count($arrayofuniqueproduct) == 1 && is_numeric($year)) {
1142 $productidselected = 0;
1143 foreach ($arrayofuniqueproduct as $key => $val) {
1144 $productidselected = $key;
1145 $productlabelselected = $val;
1147 $datebefore =
dol_get_first_day($year ? $year : strftime(
"%Y", time()), $month ? $month : 1,
true);
1148 $dateafter =
dol_get_last_day($year ? $year : strftime(
"%Y", time()), $month ? $month : 12,
true);
1149 $balancebefore = $movement->calculateBalanceForProductBefore($productidselected, $datebefore);
1150 $balanceafter = $movement->calculateBalanceForProductBefore($productidselected, $dateafter);
1153 print $langs->trans(
"NbOfProductBeforePeriod", $productlabelselected,
dol_print_date($datebefore,
'day',
'gmt'));
1156 print
': '.$balancebefore;
1160 print $langs->trans(
"NbOfProductAfterPeriod", $productlabelselected,
dol_print_date($dateafter,
'day',
'gmt'));
1163 print
': '.$balanceafter;
1177 $modulepart =
'movement';
1179 if ($action !=
'create' && $action !=
'edit' && $action !=
'delete' && $id > 0) {
1181 print
'<div class="fichecenter"><div class="fichehalfleft">';
1182 print
'<a name="builddoc"></a>';
1187 if (!empty($search_inventorycode)) {
1188 $objectref .=
"_".$id.
"_".$search_inventorycode;
1190 if ($search_type_mouvement) {
1191 $objectref .=
"_".$search_type_mouvement;
1193 $relativepath = $comref.
'/'.$objectref.
'.pdf';
1194 $filedir = $conf->stock->dir_output.
'/movement/'.$objectref;
1196 $urlsource = $_SERVER[
"PHP_SELF"].
"?id=".$object->id.
"&search_inventorycode=".$search_inventorycode.
"&search_type_mouvement=$search_type_mouvement";
1197 $genallowed = $usercanread;
1198 $delallowed = $usercancreate;
1200 $genallowed = $user->rights->stock->lire;
1201 $delallowed = $user->rights->stock->creer;
1203 print $formfile->showdocuments($modulepart, $objectref, $filedir, $urlsource, $genallowed, $delallowed,
'', 0, 0, 0, 28, 0,
'', 0,
'', $object->default_lang,
'', $object);
1204 $somethingshown = $formfile->numoffiles;
1206 print
'</div><div class="fichehalfright">';
1210 $morehtmlcenter =
dolGetButtonTitle($langs->trans(
'SeeAll'),
'',
'fa fa-bars imgforviewmode', DOL_URL_ROOT.
'/product/agenda.php?id='.$object->id);
1213 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formactions.class.php';
1215 $somethingshown =
$formactions->showactions($object,
'mouvement', 0, 1,
'', $MAXEVENT,
'', $morehtmlcenter);
1217 print
'</div></div>';
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)...
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Class to manage stock movements.
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action== 'set') elseif($action== 'specimen') elseif($action== 'setmodel') elseif($action== 'del') elseif($action== 'setdoc') $formactions
View.
if($cancel &&!$id) if($action== 'add'&&!$cancel) if($action== 'delete') if($id) $form
Actions.
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...
dolGetButtonTitle($label, $helpText= '', $iconClass= 'fa fa-file', $url= '', $id= '', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
Class to manage products or services.
Class to manage Dolibarr users.
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOCSRFCHECK')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
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...
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
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.
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...
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
print_barre_liste($titre, $page, $file, $options= '', $sortfield= '', $sortorder= '', $morehtmlcenter= '', $num=-1, $totalnboflines= '', $picto= 'generic', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow= '')
Print a title with navigation controls for pagination.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form...
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
stock_prepare_head($object)
Prepare array with list of tabs.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is '...
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete= 'resolve', $idforemptyvalue= '-1')
Convert a html select field into an ajax combobox.
restrictedArea($user, $features, $objectid=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.
if(isModEnabled('facture')&&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur')&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)&&$user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice')&&$user->rights->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->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Manage record for batch number management.
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_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.
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.
Class to manage warehouses.