34require
'../main.inc.php';
35require_once DOL_DOCUMENT_ROOT.
'/core/modules/supplier_order/modules_commandefournisseur.php';
36require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
37require_once DOL_DOCUMENT_ROOT.
'/core/lib/fourn.lib.php';
38require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.class.php';
39require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.dispatch.class.php';
40require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
41require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
42require_once DOL_DOCUMENT_ROOT.
'/core/lib/sendings.lib.php';
43if (isModEnabled(
'project')) {
44 require_once DOL_DOCUMENT_ROOT.
'/projet/class/project.class.php';
48$langs->loadLangs(array(
"sendings",
"companies",
"bills",
'deliveries',
'orders',
'stocks',
'other',
'propal',
'receptions'));
50if (isModEnabled(
'productbatch')) {
51 $langs->load(
'productbatch');
57$lineid =
GETPOST(
'lineid',
'int');
58$action =
GETPOST(
'action',
'aZ09');
59$fk_default_warehouse =
GETPOST(
'fk_default_warehouse',
'int');
60$cancel =
GETPOST(
'cancel',
'alpha');
61$confirm =
GETPOST(
'confirm',
'alpha');
67 $socid = $user->socid;
70$hookmanager->initHooks(array(
'expeditiondispatch'));
74if (GETPOSTISSET(
"projectid")) {
75 $projectid =
GETPOST(
"projectid",
'int');
82if ($id > 0 || !empty($ref)) {
83 $result = $object->fetch($id, $ref);
87 $result = $object->fetch_thirdparty();
91 if (!empty($object->origin)) {
92 $origin = $object->origin;
94 $object->fetch_origin();
95 $typeobject = $object->origin;
102if (!isModEnabled(
'stock')) {
106$usercancreate = $user->hasRight(
'expedition',
'creer');
107$permissiontoadd = $usercancreate;
114$parameters = array();
115$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
121if ($action ==
'updatelines' && $usercancreate) {
130 foreach ($_POST as $key => $value) {
133 if (preg_match(
'/^product_.*([0-9]+)_([0-9]+)$/i', $key, $reg)) {
135 if (preg_match(
'/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
136 $modebatch =
"barcode";
137 } elseif (preg_match(
'/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
138 $modebatch =
"batch";
142 if ($modebatch ==
"barcode") {
143 $prod =
"product_".$reg[1].
'_'.$reg[2];
145 $prod =
'product_batch_'.$reg[1].
'_'.$reg[2];
147 $qty =
"qty_".$reg[1].
'_'.$reg[2];
148 $ent =
"entrepot_".$reg[1].
'_'.$reg[2];
149 $fk_commandedet =
"fk_commandedet_".$reg[1].
'_'.$reg[2];
150 $idline =
GETPOST(
"idline_".$reg[1].
'_'.$reg[2]);
151 $pu =
"pu_".$reg[1].
'_'.$reg[2];
155 if ($modebatch ==
"batch") {
156 $lot =
GETPOST(
'lot_number_'.$reg[1].
'_'.$reg[2]);
157 $dDLUO =
dol_mktime(12, 0, 0,
GETPOST(
'dluo_'.$reg[1].
'_'.$reg[2].
'month',
'int'),
GETPOST(
'dluo_'.$reg[1].
'_'.$reg[2].
'day',
'int'),
GETPOST(
'dluo_'.$reg[1].
'_'.$reg[2].
'year',
'int'));
158 $dDLC =
dol_mktime(12, 0, 0,
GETPOST(
'dlc_'.$reg[1].
'_'.$reg[2].
'month',
'int'),
GETPOST(
'dlc_'.$reg[1].
'_'.$reg[2].
'day',
'int'),
GETPOST(
'dlc_'.$reg[1].
'_'.$reg[2].
'year',
'int'));
165 if (($modebatch ==
"batch" && $newqty >= 0) || ($modebatch ==
"barcode" && $newqty != 0)) {
167 if (!(
GETPOST($ent,
'int') > 0)) {
168 dol_syslog(
'No dispatch for line '.$key.
' as no warehouse was chosen.');
169 $text = $langs->transnoentities(
'Warehouse').
', '.$langs->transnoentities(
'Line').
' '.($numline);
170 setEventMessages($langs->trans(
'ErrorFieldRequired', $text),
null,
'errors');
173 if (!$error && $modebatch ==
"batch") {
174 $sql =
"SELECT pb.rowid ";
175 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_batch as pb";
176 $sql .=
" JOIN ".MAIN_DB_PREFIX.
"product_stock as ps";
177 $sql .=
" ON ps.rowid = pb.fk_product_stock";
178 $sql .=
" WHERE pb.batch = '".$db->escape($lot).
"'";
179 $sql .=
" AND ps.fk_product = ".((int)
GETPOST($prod,
'int')) ;
180 $sql .=
" AND ps.fk_entrepot = ".((int)
GETPOST($ent,
'int')) ;
182 $resql = $db->query($sql);
184 $num = $db->num_rows($resql);
186 dol_syslog(
'No dispatch for line '.$key.
' as too many combination warehouse, product, batch code was found ('.$num.
').');
187 setEventMessages($langs->trans(
'ErrorTooManyCombinationBatchcode', $numline, $num),
null,
'errors');
189 } elseif ($num < 1) {
190 dol_syslog(
'No dispatch for line '.$key.
' as no combination warehouse, product, batch code was found.');
191 setEventMessages($langs->trans(
'ErrorNoCombinationBatchcode', $numline),
null,
'errors');
204 $result = $expeditiondispatch->fetch($idline);
206 setEventMessages($expeditiondispatch->error, $expeditiondispatch->errors,
'errors');
209 $qtystart = $expeditiondispatch->qty;
210 $expeditiondispatch->qty = $newqty;
211 $expeditiondispatch->entrepot_id =
GETPOST($ent,
'int');
214 $result = $expeditiondispatch->update($user);
216 $result = $expeditiondispatch->delete($user);
219 setEventMessages($expeditiondispatch->error, $expeditiondispatch->errors,
'errors');
223 if (!$error && $modebatch ==
"batch") {
225 $suffixkeyfordate = preg_replace(
'/^product_batch/',
'', $key);
226 $sellby =
dol_mktime(0, 0, 0,
GETPOST(
'dlc'.$suffixkeyfordate.
'month'),
GETPOST(
'dlc'.$suffixkeyfordate.
'day'),
GETPOST(
'dlc'.$suffixkeyfordate.
'year'),
'');
227 $eatby =
dol_mktime(0, 0, 0,
GETPOST(
'dluo'.$suffixkeyfordate.
'month'),
GETPOST(
'dluo'.$suffixkeyfordate.
'day'),
GETPOST(
'dluo'.$suffixkeyfordate.
'year'));
229 $sqlsearchdet =
"SELECT rowid FROM ".MAIN_DB_PREFIX.$expeditionlinebatch->table_element;
230 $sqlsearchdet .=
" WHERE fk_expeditiondet = ".((int) $idline);
231 $sqlsearchdet .=
" AND batch = '".$db->escape($lot).
"'";
232 $resqlsearchdet = $db->query($sqlsearchdet);
234 if ($resqlsearchdet) {
235 $objsearchdet = $db->fetch_object($resqlsearchdet);
241 $sql =
"UPDATE ".MAIN_DB_PREFIX.$expeditionlinebatch->table_element.
" SET";
242 $sql .=
" eatby = ".($eatby ?
"'".$db->idate($eatby).
"'" :
"null");
243 $sql .=
" , sellby = ".($sellby ?
"'".$db->idate($sellby).
"'" :
"null");
244 $sql .=
" , qty = ".((float) $newqty);
246 $sql .=
" WHERE rowid = ".((int) $objsearchdet->rowid);
248 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$expeditionlinebatch->table_element.
" (";
249 $sql .=
"fk_expeditiondet, eatby, sellby, batch, qty, fk_origin_stock)";
251 $sql .=
" VALUES (".((int) $idline).
", ".($eatby ?
"'".$db->idate($eatby).
"'" :
"null").
", ".($sellby ?
"'".$db->idate($sellby).
"'" :
"null").
", ";
252 $sql .=
" '".$db->escape($lot).
"', ".((float) $newqty).
", 0)";
255 $sql =
" DELETE FROM ".MAIN_DB_PREFIX.$expeditionlinebatch->table_element;
256 $sql .=
" WHERE fk_expeditiondet = ".((int) $idline);
257 $sql .=
" AND batch = '".$db->escape($lot).
"'";
260 $resql = $db->query($sql);
268 $expeditiondispatch->fk_expedition = $object->id;
269 $expeditiondispatch->entrepot_id =
GETPOST($ent,
'int');
270 $expeditiondispatch->fk_origin_line =
GETPOST($fk_commandedet,
'int');
271 $expeditiondispatch->qty = $newqty;
274 $idline = $expeditiondispatch->insert($user);
276 setEventMessages($expeditiondispatch->error, $expeditiondispatch->errors,
'errors');
280 if ($modebatch ==
"batch" && !$error) {
281 $expeditionlinebatch->sellby = $dDLUO;
282 $expeditionlinebatch->eatby = $dDLC;
283 $expeditionlinebatch->batch = $lot;
284 $expeditionlinebatch->qty = $newqty;
285 $expeditionlinebatch->fk_origin_stock = 0;
286 $expeditionlinebatch->fk_warehouse =
GETPOST($ent,
'int');
288 $result = $expeditionlinebatch->create($idline);
290 setEventMessages($expeditionlinebatch->error, $expeditionlinebatch->errors,
'errors');
347 header(
"Location: ".DOL_URL_ROOT.
'/expedition/dispatch.php?id='.$object->id);
350} elseif ($action ==
'setdate_livraison' && $usercancreate) {
351 $datedelivery =
dol_mktime(
GETPOST(
'liv_hour',
'int'),
GETPOST(
'liv_min',
'int'), 0,
GETPOST(
'liv_month',
'int'),
GETPOST(
'liv_day',
'int'),
GETPOST(
'liv_year',
'int'));
354 $result = $object->setDeliveryDate($user, $datedelivery);
367$form =
new Form($db);
369$warehouse_static =
new Entrepot($db);
371$title = $object->ref.
" - ".$langs->trans(
'ShipmentDistribution');
372$help_url =
'EN:Module_Shipments|FR:Module_Expéditions|ES:Módulo_Expediciones|DE:Modul_Lieferungen';
373$morejs = array(
'/expedition/js/lib_dispatch.js.php');
375llxHeader(
'', $title, $help_url,
'', 0, 0, $morejs);
377if ($object->id > 0 || !empty($object->ref)) {
378 $lines = $object->lines;
381 $num_prod = count($lines);
383 if (!empty($object->origin) && $object->origin_id > 0) {
384 $object->origin =
'commande';
385 $typeobject = $object->origin;
386 $origin = $object->origin;
387 $origin_id = $object->origin_id;
388 $object->fetch_origin();
391 $soc->fetch($object->socid);
393 $author =
new User($db);
394 $author->fetch($object->user_author_id);
398 print
dol_get_fiche_head($head,
'dispatch', $langs->trans(
"Shipment"), -1, $object->picto);
404 if ($action ==
'ask_deleteline') {
405 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&lineid='.$lineid, $langs->trans(
'DeleteLine'), $langs->trans(
'ConfirmDeleteLine'),
'confirm_deleteline',
'', 0, 1);
409 $parameters = array(
'lineid' => $lineid);
411 $reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
412 if (empty($reshook)) {
413 $formconfirm .= $hookmanager->resPrint;
414 } elseif ($reshook > 0) {
415 $formconfirm = $hookmanager->resPrint;
421 if ($typeobject ==
'commande' && $object->$typeobject->id && isModEnabled(
'commande')) {
423 $objectsrc->fetch($object->$typeobject->id);
425 if ($typeobject ==
'propal' && $object->$typeobject->id && isModEnabled(
"propal")) {
426 $objectsrc =
new Propal($db);
427 $objectsrc->fetch($object->$typeobject->id);
431 $linkback =
'<a href="'.DOL_URL_ROOT.
'/expedition/list.php?restore_lastsearch_values=1'.(!empty($socid) ?
'&socid='.$socid :
'').
'">'.$langs->trans(
"BackToList").
'</a>';
432 $morehtmlref =
'<div class="refidno">';
435 $morehtmlref .= $form->editfieldkey(
"RefCustomer",
'ref_customer', $object->ref_customer, $object, $user->rights->expedition->creer,
'string',
'', 0, 1);
436 $morehtmlref .= $form->editfieldval(
"RefCustomer",
'ref_customer', $object->ref_customer, $object, $user->rights->expedition->creer,
'string'.(isset($conf->global->THIRDPARTY_REF_INPUT_SIZE) ?
':'.$conf->global->THIRDPARTY_REF_INPUT_SIZE :
''),
'', null, null,
'', 1);
439 $morehtmlref .=
'<br>'.$object->thirdparty->getNomUrl(1);
441 if (isModEnabled(
'project')) {
442 $langs->load(
"projects");
443 $morehtmlref .=
'<br>';
445 $morehtmlref .=
img_picto($langs->trans(
"Project"),
'project',
'class="pictofixedwidth"');
446 if ($action !=
'classify' && $permissiontoadd) {
447 $morehtmlref .=
'<a class="editfielda" href="'.$_SERVER[
'PHP_SELF'].
'?action=classify&token='.newToken().
'&id='.$object->id.
'">'.
img_edit($langs->transnoentitiesnoconv(
'SetProject')).
'</a> ';
449 $morehtmlref .= $form->form_project($_SERVER[
'PHP_SELF'].
'?id='.$object->id, (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $object->socid : -1), $object->fk_project, ($action ==
'classify' ?
'projectid' :
'none'), 0, 0, 0, 1,
'',
'maxwidth300');
451 if (!empty($objectsrc) && !empty($objectsrc->fk_project)) {
453 $proj->fetch($objectsrc->fk_project);
454 $morehtmlref .= $proj->getNomUrl(1);
456 $morehtmlref .=
'<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).
'</span>';
461 $morehtmlref .=
'</div>';
463 dol_banner_tab($object,
'ref', $linkback, 1,
'ref',
'ref', $morehtmlref);
466 print
'<div class="fichecenter">';
467 print
'<div class="underbanner clearboth"></div>';
469 print
'<table class="border tableforfield centpercent">';
472 if ($typeobject ==
'commande' && $object->$typeobject->id && isModEnabled(
'commande')) {
474 print $langs->trans(
"RefOrder").
'</td>';
475 print
'<td colspan="3">';
476 print $objectsrc->getNomUrl(1,
'commande');
480 if ($typeobject ==
'propal' && $object->$typeobject->id && isModEnabled(
"propal")) {
482 print $langs->trans(
"RefProposal").
'</td>';
483 print
'<td colspan="3">';
484 print $objectsrc->getNomUrl(1,
'expedition');
490 print
'<tr><td class="titlefield">'.$langs->trans(
"DateCreation").
'</td>';
491 print
'<td colspan="3">'.dol_print_date($object->date_creation,
"dayhour",
"tzuserrel").
"</td>\n";
495 print
'<tr><td height="10">';
496 print
'<table class="nobordernopadding" width="100%"><tr><td>';
497 print $langs->trans(
'DateDeliveryPlanned');
499 if ($action !=
'editdate_livraison') {
500 print
'<td class="right"><a class="editfielda" href="'.$_SERVER[
"PHP_SELF"].
'?action=editdate_livraison&token='.newToken().
'&id='.$object->id.
'">'.
img_edit($langs->trans(
'SetDeliveryDate'), 1).
'</a></td>';
502 print
'</tr></table>';
503 print
'</td><td colspan="2">';
504 if ($action ==
'editdate_livraison') {
505 print
'<form name="setdate_livraison" action="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'" method="post">';
506 print
'<input type="hidden" name="token" value="'.newToken().
'">';
507 print
'<input type="hidden" name="action" value="setdate_livraison">';
508 print $form->selectDate($object->date_delivery ? $object->date_delivery : -1,
'liv_', 1, 1,
'',
"setdate_livraison", 1, 0);
509 print
'<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans(
'Modify').
'">';
512 print $object->date_delivery ?
dol_print_date($object->date_delivery,
'dayhour') :
' ';
515 print
'</tr></table>';
517 print
'<br><center>';
518 print
'<a href="#" id="resetalltoexpected" class="marginrightonly paddingright marginleftonly paddingleft">'.img_picto(
"",
'autofill',
'class="pictofixedwidth"').$langs->trans(
"RestoreWithCurrentQtySaved").
'</a></td>';
520 print
'<a href="#" id="autoreset" class="marginrightonly paddingright marginleftonly paddingleft">'.img_picto(
"",
'eraser',
'class="pictofixedwidth"').$langs->trans(
"ClearQtys").
'</a></td>';
527 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
529 $formproduct->loadWarehouses();
531 $listwarehouses = $entrepot->list_array(1);
534 print
'<form method="post" action="'.$_SERVER[
"PHP_SELF"].
'">';
536 print
'<input type="hidden" name="token" value="'.newToken().
'">';
537 print
'<input type="hidden" name="action" value="updatelines">';
538 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
540 print
'<div class="div-table-responsive-no-min">';
541 print
'<table class="noborder centpercent">';
544 $products_dispatched = array();
545 $sql =
"SELECT ed.fk_origin_line as rowid, sum(ed.qty) as qty";
546 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expeditiondet as ed";
547 $sql .=
" WHERE ed.fk_expedition = ".((int) $object->id);
548 $sql .=
" GROUP BY ed.fk_origin_line";
550 $resql = $db->query($sql);
552 $num = $db->num_rows($resql);
557 $objd = $db->fetch_object($resql);
558 $products_dispatched[$objd->rowid] =
price2num($objd->qty,
'MS');
566 $sql =
"SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, '' AS sref, l.qty as qty,";
567 $sql .=
" p.ref, p.label, p.tobatch, p.fk_default_warehouse";
569 $parameters = array();
570 $reshook = $hookmanager->executeHooks(
571 'printFieldListSelect',
579 $sql .= $hookmanager->resPrint;
581 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commandedet as l";
582 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"product as p ON l.fk_product=p.rowid";
583 $sql .=
" WHERE l.fk_commande = ".((int) $objectsrc->id);
584 if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
585 $sql .=
" AND l.product_type = 0";
588 $parameters = array();
589 $reshook = $hookmanager->executeHooks(
590 'printFieldListWhere',
598 $sql .= $hookmanager->resPrint;
601 $sql .=
" ORDER BY l.rang, p.ref, p.label";
603 $resql = $db->query($sql);
605 $num = $db->num_rows($resql);
610 print
'<tr class="liste_titre">';
612 print
'<td>'.$langs->trans(
"Description").
'</td>';
613 if (isModEnabled(
'productbatch')) {
614 print
'<td class="dispatch_batch_number_title">'.$langs->trans(
"batch_number").
'</td>';
615 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
616 print
'<td class="dispatch_dlc_title">'.$langs->trans(
"SellByDate").
'</td>';
618 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
619 print
'<td class="dispatch_dluo_title">'.$langs->trans(
"EatByDate").
'</td>';
626 print
'<td class="right">'.$langs->trans(
"QtyOrdered").
'</td>';
628 print
'<td class="right">'.$langs->trans(
"QtyToShip");
630 print
'<td class="right">'.$langs->trans(
"QtyDispatchedShort").
'</td>';
632 print
'<td class="right">'.$langs->trans(
"Details");
633 print
'<td width="32"></td>';
635 if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) {
636 if (!isModEnabled(
"multicurrency") && empty($conf->dynamicprices->enabled)) {
637 print
'<td class="right">'.$langs->trans(
"Price").
'</td>';
638 print
'<td class="right">'.$langs->trans(
"ReductionShort").
' (%)</td>';
639 print
'<td class="right">'.$langs->trans(
"UpdatePrice").
'</td>';
643 print
'<td align="right">'.$langs->trans(
"Warehouse");
646 if (count($listwarehouses) > 1) {
647 print
'<br><span class="opacitymedium">'.$langs->trans(
"ForceTo").
'</span> '.$form->selectarray(
'fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 1, 0, 0,
'', 0, 0, $disabled,
'',
'minwidth100 maxwidth300', 1);
648 } elseif (count($listwarehouses) == 1) {
649 print
'<br><span class="opacitymedium">'.$langs->trans(
"ForceTo").
'</span> '.$form->selectarray(
'fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0,
'', 0, 0, $disabled,
'',
'minwidth100 maxwidth300', 1);
655 $parameters = array();
656 $reshook = $hookmanager->executeHooks(
657 'printFieldListTitle',
665 print $hookmanager->resPrint;
674 $conf->cache[
'product'] = array();
678 $objp = $db->fetch_object($resql);
681 if (!$objp->fk_product > 0) {
684 $alreadydispatched = isset($products_dispatched[$objp->rowid])?$products_dispatched[$objp->rowid]:0;
685 $remaintodispatch =
price2num($objp->qty, 5);
686 if ($remaintodispatch < 0 && empty($conf->global->SUPPLIER_ORDER_ALLOW_NEGATIVE_QTY_FOR_SUPPLIER_ORDER_RETURN)) {
687 $remaintodispatch = 0;
690 if ($remaintodispatch || empty($conf->global->SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED)) {
699 print
'<!-- Line to dispatch '.$suffix.
' -->'.
"\n";
701 print
'<input id="qty_ordered'.$suffix.
'" type="hidden" value="'.$objp->qty.
'">';
702 print
'<input id="qty_dispatched'.$suffix.
'" type="hidden" data-dispatched="'.((float) $alreadydispatched).
'" value="'.(float) $alreadydispatched.
'">';
703 print
'<tr class="oddeven">';
705 if (empty($conf->cache[
'product'][$objp->fk_product])) {
706 $tmpproduct =
new Product($db);
707 $tmpproduct->fetch($objp->fk_product);
708 $conf->cache[
'product'][$objp->fk_product] = $tmpproduct;
710 $tmpproduct = $conf->cache[
'product'][$objp->fk_product];
713 $linktoprod = $tmpproduct->getNomUrl(1);
714 $linktoprod .=
' - '.$objp->label.
"\n";
716 if (isModEnabled(
'productbatch')) {
717 if ($objp->tobatch) {
722 print
'<td class="dispatch_batch_number"></td>';
723 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
724 print
'<td class="dispatch_dlc"></td>';
726 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
727 print
'<td class="dispatch_dluo"></td>';
734 print
'<td class="dispatch_batch_number">';
735 print
'<span class="opacitymedium small">'.$langs->trans(
"ProductDoesNotUseBatchSerial").
'</span>';
737 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
738 print
'<td class="dispatch_dlc"></td>';
740 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
741 print
'<td class="dispatch_dluo"></td>';
745 print
'<td colspan="4">';
751 $up_ht_disc = $objp->subprice;
752 if (!empty($objp->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) {
753 $up_ht_disc =
price2num($up_ht_disc * (100 - $objp->remise_percent) / 100,
'MU');
757 print
'<td class="right">'.$objp->qty.
'</td>';
760 print
'<td class="right">'.$alreadydispatched.
'</td>';
762 print
'<td class="right">';
772 $sql =
"SELECT ed.rowid, ed.qty, ed.fk_entrepot, eb.batch, eb.eatby, eb.sellby, cd.fk_product";
773 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expeditiondet as ed";
774 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"expeditiondet_batch as eb on ed.rowid = eb.fk_expeditiondet";
775 $sql .=
" JOIN ".MAIN_DB_PREFIX.
"commandedet as cd on ed.fk_origin_line = cd.rowid";
776 $sql .=
" WHERE ed.fk_origin_line =".(int) $objp->rowid;
777 $sql .=
" AND ed.fk_expedition =".(int) $object->id;
778 $sql .=
" ORDER BY ed.rowid, ed.fk_origin_line";
780 $resultsql = $db->query($sql);
783 $numd = $db->num_rows($resultsql);
786 $suffix =
"_".$j.
"_".$i;
787 $objd = $db->fetch_object($resultsql);
789 if (isModEnabled(
'productbatch') && (!empty($objd->batch) || (is_null($objd->batch) && $tmpproduct->status_batch > 0))) {
795 'is_information_row' =>
true,
800 $reshook = $hookmanager->executeHooks(
801 'printFieldListValue',
809 print $hookmanager->resPrint;
813 print
'<!-- line for batch '.$numline.
' -->';
814 print
'<tr class="oddeven autoresettr" name="'.$type.$suffix.
'" data-remove="clear">';
816 print
'<input id="fk_commandedet'.$suffix.
'" name="fk_commandedet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
817 print
'<input id="idline'.$suffix.
'" name="idline'.$suffix.
'" type="hidden" value="'.$objd->rowid.
'">';
818 print
'<input name="product_batch'.$suffix.
'" type="hidden" value="'.$objd->fk_product.
'">';
820 print
'<!-- This is a U.P. (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
821 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
826 print
'<input type="text" class="inputlotnumber quatrevingtquinzepercent" id="lot_number'.$suffix.
'" name="lot_number'.$suffix.
'" value="'.(GETPOSTISSET(
'lot_number'.$suffix) ?
GETPOST(
'lot_number'.$suffix) : $objd->batch).
'">';
829 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
830 print
'<td class="nowraponall">';
832 print $form->selectDate($dlcdatesuffix,
'dlc'.$suffix,
'',
'', 1,
'');
835 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
836 print
'<td class="nowraponall">';
838 print $form->selectDate($dluodatesuffix,
'dluo'.$suffix,
'',
'', 1,
'');
841 print
'<td colspan="2"> </td>';
845 $colspan = (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) ? --$colspan : $colspan;
846 $colspan = (!empty($conf->global->PRODUCT_DISABLE_EATBY)) ? --$colspan : $colspan;
851 'is_information_row' =>
true,
856 $reshook = $hookmanager->executeHooks(
857 'printFieldListValue',
865 print $hookmanager->resPrint;
869 print
'<!-- line no batch '.$numline.
' -->';
870 print
'<tr class="oddeven autoresettr" name="'.$type.$suffix.
'" data-remove="clear">';
871 print
'<td colspan="'.$colspan.
'">';
872 print
'<input id="fk_commandedet'.$suffix.
'" name="fk_commandedet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
873 print
'<input id="idline'.$suffix.
'" name="idline'.$suffix.
'" type="hidden" value="'.$objd->rowid.
'">';
874 print
'<input name="product'.$suffix.
'" type="hidden" value="'.$objd->fk_product.
'">';
875 print
'<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
876 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
880 print
'<td class="right">';
881 print
'<a href="" id="reset'.$suffix.
'" class="resetline">'.
img_picto($langs->trans(
"Reset"),
'eraser',
'class="pictofixedwidth opacitymedium"').
'</a>';
882 $suggestedvalue = (GETPOSTISSET(
'qty'.$suffix) ?
GETPOST(
'qty'.$suffix,
'int') : $objd->qty);
884 print
'<input id="qty'.$suffix.
'" onchange="onChangeDispatchLineQty($(this))" name="qty'.$suffix.
'" data-type="'.$type.
'" data-index="'.$i.
'" class="width50 right qtydispatchinput" value="'.$suggestedvalue.
'" data-expected="'.$objd->qty.
'">';
887 if (isModEnabled(
'productbatch') && $objp->tobatch > 0) {
889 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" '.($numd != $j+1 ?
'style="display:none"' :
'').
' onClick="addDispatchLine('.$i.
', \''.$type.
'\')"');
892 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" '.($numd != $j+1 ?
'style="display:none"' :
'').
' onClick="addDispatchLine('.$i.
', \''.$type.
'\')"');
898 print
'<td class="right">';
899 if (count($listwarehouses) > 1) {
900 print $formproduct->selectWarehouses(
GETPOST(
"entrepot".$suffix) ?
GETPOST(
"entrepot".$suffix) : $objd->fk_entrepot,
"entrepot".$suffix,
'', 1, 0, $objp->fk_product,
'', 1, 0, null,
'csswarehouse'.$suffix);
901 } elseif (count($listwarehouses) == 1) {
902 print $formproduct->selectWarehouses(
GETPOST(
"entrepot".$suffix) ?
GETPOST(
"entrepot".$suffix) : $objd->fk_entrepot,
"entrepot".$suffix,
'', 0, 0, $objp->fk_product,
'', 1, 0, null,
'csswarehouse'.$suffix);
904 $langs->load(
"errors");
905 print $langs->trans(
"ErrorNoWarehouseDefined");
911 'is_information_row' =>
false,
916 $reshook = $hookmanager->executeHooks(
917 'printFieldListValue',
925 print $hookmanager->resPrint;
932 $suffix =
"_".$j.
"_".$i;
936 if (isModEnabled(
'productbatch') && !empty($objp->tobatch)) {
942 'is_information_row' =>
true,
947 $reshook = $hookmanager->executeHooks(
948 'printFieldListValue',
956 print $hookmanager->resPrint;
960 print
'<!-- line for batch '.$numline.
' (not dispatched line yet for this order line) -->';
961 print
'<tr class="oddeven autoresettr" name="'.$type.$suffix.
'">';
963 print
'<input id="fk_commandedet'.$suffix.
'" name="fk_commandedet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
964 print
'<input id="idline'.$suffix.
'" name="idline'.$suffix.
'" type="hidden" value="-1">';
965 print
'<input name="product_batch'.$suffix.
'" type="hidden" value="'.$objp->fk_product.
'">';
967 print
'<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
968 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
972 print
'<input type="text" class="inputlotnumber quatrevingtquinzepercent" id="lot_number'.$suffix.
'" name="lot_number'.$suffix.
'" value="'.
GETPOST(
'lot_number'.$suffix).
'">';
974 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
975 print
'<td class="nowraponall">';
977 print $form->selectDate($dlcdatesuffix,
'dlc'.$suffix,
'',
'', 1,
'');
980 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
981 print
'<td class="nowraponall">';
983 print $form->selectDate($dluodatesuffix,
'dluo'.$suffix,
'',
'', 1,
'');
986 print
'<td colspan="2"> </td>';
990 $colspan = (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) ? --$colspan : $colspan;
991 $colspan = (!empty($conf->global->PRODUCT_DISABLE_EATBY)) ? --$colspan : $colspan;
996 'is_information_row' =>
true,
1001 $reshook = $hookmanager->executeHooks(
1002 'printFieldListValue',
1010 print $hookmanager->resPrint;
1014 print
'<!-- line no batch '.$numline.
' (not dispatched line yet for this order line) -->';
1015 print
'<tr class="oddeven autoresettr" name="'.$type.$suffix.
'" data-remove="clear">';
1016 print
'<td colspan="'.$colspan.
'">';
1017 print
'<input id="fk_commandedet'.$suffix.
'" name="fk_commandedet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
1018 print
'<input id="idline'.$suffix.
'" name="idline'.$suffix.
'" type="hidden" value="-1">';
1019 print
'<input name="product'.$suffix.
'" type="hidden" value="'.$objp->fk_product.
'">';
1021 print
'<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
1022 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
1026 print
'<td class="right">';
1027 print
'<a href="" id="reset'.$suffix.
'" class="resetline">'.
img_picto($langs->trans(
"Reset"),
'eraser',
'class="pictofixedwidth opacitymedium"').
'</a>';
1028 $amounttosuggest = (GETPOSTISSET(
'qty'.$suffix) ?
GETPOST(
'qty'.$suffix,
'int') : (empty($conf->global->SUPPLIER_ORDER_DISPATCH_FORCE_QTY_INPUT_TO_ZERO) ? $remaintodispatch : 0));
1029 if (count($products_dispatched)) {
1032 $amounttosuggest = (GETPOSTISSET(
'qty'.$suffix) ?
GETPOST(
'qty'.$suffix,
'int') : (isset($products_dispatched[$objp->
rowid]) ? $products_dispatched[$objp->
rowid] :
''));
1034 print
'<input id="qty'.$suffix.
'" onchange="onChangeDispatchLineQty($(this))" name="qty'.$suffix.
'" data-index="'.$i.
'" data-type="text" class="width50 right qtydispatchinput" value="'.$amounttosuggest.
'" data-expected="'.$amounttosuggest.
'">';
1037 if (isModEnabled(
'productbatch') && $objp->tobatch > 0) {
1039 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" onClick="addDispatchLine('.$i.
', \''.$type.
'\')
"');
1042 print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton
" onClick="addDispatchLine(
'.$i.', \
''.$type.
'\')
"');
1048 print '<td class="right
">';
1049 if (count($listwarehouses) > 1) {
1050 print $formproduct->selectWarehouses(GETPOST("entrepot
".$suffix) ?GETPOST("entrepot
".$suffix) : ($objp->fk_default_warehouse ? $objp->fk_default_warehouse : ''), "entrepot
".$suffix, '', 1, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix);
1051 } elseif (count($listwarehouses) == 1) {
1052 print $formproduct->selectWarehouses(GETPOST("entrepot
".$suffix) ?GETPOST("entrepot
".$suffix) : ($objp->fk_default_warehouse ? $objp->fk_default_warehouse : ''), "entrepot
".$suffix, '', 0, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix);
1054 $langs->load("errors
");
1055 print $langs->trans("ErrorNoWarehouseDefined
");
1059 // Enable hooks to append additional columns
1060 $parameters = array(
1061 'is_information_row' => false, // this is a dispatch form row
1063 'suffix' => $suffix,
1066 $reshook = $hookmanager->executeHooks(
1067 'printFieldListValue',
1073 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1075 print $hookmanager->resPrint;
1084 dol_print_error($db);
1091 //$checkboxlabel = $langs->trans("CloseReceivedSupplierOrdersAutomatically
", $langs->transnoentitiesnoconv('StatusOrderReceivedAll'));
1093 print '<div class="center
">';
1094 $parameters = array();
1095 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1097 if (empty($reshook)) {
1098 /*if (empty($conf->reception->enabled)) {
1099 print $langs->trans("Comment").' : ';
1100 print '<input type="text
" class="minwidth400
" maxlength="128
" name="comment
" value="';
1101 print GETPOSTISSET("comment") ? GETPOST("comment") : $langs->trans("DispatchSupplierOrder", $object->ref);
1102 // print ' /
'.$object->ref_supplier; // Not yet available
1103 print '" class="flat
"><br>';
1105 print '<input type="checkbox
" checked="checked
" name="closeopenorder
"> '.$checkboxlabel;
1108 $dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive
") : $langs->trans("CreateReception
");
1113 print '<input type="submit
" id="submitform
" class="button" name="dispatch
" value="'.$langs->trans("Save").'"';
1115 if (!$usercancreate) {
1118 if (count($listwarehouses) <= 0) {
1130 // Message if nothing to dispatch
1133 if (empty($conf->global->SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED)) {
1134 print '<div class="opacitymedium
">'.$langs->trans("NoPredefinedProductToDispatch
").'</div>'; // No predefined line at all
1136 print '<div class="opacitymedium
">'.$langs->trans("NoMorePredefinedProductToDispatch
").'</div>'; // No predefined line that remain to be dispatched.
1143 print dol_get_fiche_end();
1145 // traitement entrepot par défaut
1146 print '<script type="text/javascript
">
1147 $(document).ready(function () {
1148 $("select[
name=fk_default_warehouse]
").change(function() {
1149 console.log("warehouse is modified
");
1150 var fk_default_warehouse = $("option:selected
", this).val();
1151 $("select[
name^=entrepot_]
").val(fk_default_warehouse).change();
1154 $("#autoreset
").click(function() {
1155 console.log("we click on autoreset
");
1156 $(".autoresettr
").each(function(){
1157 id = $(this).attr("name");
1158 idtab = id.split("_
");
1159 if ($(this).data("remove") == "clear
"){
1160 console.log("We clear the
object to expected value
")
1161 $("#qty_
"+idtab[1]+"_
"+idtab[2]).val("");
1163 qtyexpected = $("#qty_
"+idtab[1]+"_
"+idtab[2]).data("expected
")
1164 console.log(qtyexpected);
1165 $("#qty_
"+idtab[1]+"_
"+idtab[2]).val(qtyexpected);
1166 qtydispatched = $("#qty_dispatched_0_
"+idtab[2]).data("dispatched
")
1167 $("#qty_dispatched_0_
"+idtab[2]).val(qtydispatched);
1170 console.log("We
remove the
object")
1172 $("tr[
name^=\
'"+idtab[0]+"_\'][name$=\'_"+idtab[2]+"\']:last .splitbutton").show();
1178 $("#resetalltoexpected").click(function(){
1179 $(".qtydispatchinput").each(function(){
1180 console.log("We reset to expected "+$(this).attr("id")+" qty to dispatch");
1181 $(this).val($(this).data("expected"));
1186 $(".resetline").on("click", function(event) {
1187 event.preventDefault();
1188 id = $(this).attr("id");
1189 id = id.split("reset_");
1190 console.log("Reset trigger for id = qty_"+id[1]);
1191 $("#qty_"+id[1]).val("");
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Class to manage customers orders.
Class to manage warehouses.
Class to manage shipments.
const STATUS_DRAFT
Draft status.
Classe to manage lines of shipment.
CRUD class for batch number management within shipment.
Class to manage products or services.
Class to manage projects.
Class to manage proposals.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
img_edit($titlealt='default', $float=0, $other='')
Show logo editer/modifier fiche.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
ui dialog ui datepicker calendar ui widget content ui state ui datepicker calendar ui widget header ui state ui datepicker calendar ui button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
$conf db name
Only used if Module[ID]Name translation string is not found.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
shipping_prepare_head($object)
Prepare array with list of tabs.