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>';