34 require
'../../main.inc.php';
35 require_once DOL_DOCUMENT_ROOT.
'/core/modules/supplier_order/modules_commandefournisseur.php';
36 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
37 require_once DOL_DOCUMENT_ROOT.
'/core/lib/fourn.lib.php';
38 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.class.php';
39 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.dispatch.class.php';
40 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
41 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
44 require_once DOL_DOCUMENT_ROOT.
'/projet/class/project.class.php';
48 $langs->loadLangs(array(
"bills",
"orders",
"sendings",
"companies",
"deliveries",
"products",
"stocks",
"receptions"));
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');
64 $socid = $user->socid;
67 $hookmanager->initHooks(array(
'ordersupplierdispatch'));
72 $projectid =
GETPOST(
"projectid",
'int');
77 if ($id > 0 || !empty($ref)) {
78 $result = $object->fetch($id, $ref);
82 $result = $object->fetch_thirdparty();
88 if (empty($conf->reception->enabled)) {
89 $permissiontoreceive = $user->rights->fournisseur->commande->receptionner;
90 $permissiontocontrol = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande->receptionner)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->fournisseur->commande_advance->check)));
92 $permissiontoreceive = $user->rights->reception->creer;
93 $permissiontocontrol = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->reception->reception_advance->validate)));
97 $result =
restrictedArea($user,
'fournisseur', $id,
'commande_fournisseur',
'commande');
103 $usercancreate = ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer);
104 $permissiontoadd = $usercancreate;
111 $parameters = array();
112 $reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
117 if ($action ==
'checkdispatchline' && $permissiontocontrol) {
123 $result = $supplierorderdispatch->fetch($lineid);
126 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors,
'errors');
131 $result = $supplierorderdispatch->setStatut(1);
133 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors,
'errors');
140 $result = $object->calcAndSetStatusDispatch($user);
154 if ($action ==
'uncheckdispatchline' && $permissiontocontrol) {
160 $result = $supplierorderdispatch->fetch($lineid);
163 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors,
'errors');
168 $result = $supplierorderdispatch->setStatut(0);
170 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors,
'errors');
176 $result = $object->calcAndSetStatusDispatch($user);
190 if ($action ==
'denydispatchline' && $permissiontocontrol) {
196 $result = $supplierorderdispatch->fetch($lineid);
199 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors,
'errors');
204 $result = $supplierorderdispatch->setStatut(2);
206 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors,
'errors');
212 $result = $object->calcAndSetStatusDispatch($user);
226 if ($action ==
'dispatch' && $permissiontoreceive) {
233 foreach ($_POST as $key => $value) {
236 if (preg_match(
'/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
241 $prod =
"product_".$reg[1].
'_'.$reg[2];
242 $qty =
"qty_".$reg[1].
'_'.$reg[2];
243 $ent =
"entrepot_".$reg[1].
'_'.$reg[2];
245 $ent = $fk_default_warehouse;
247 $pu =
"pu_".$reg[1].
'_'.$reg[2];
248 $fk_commandefourndet =
"fk_commandefourndet_".$reg[1].
'_'.$reg[2];
250 if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) {
251 if (!
isModEnabled(
"multicurrency") && empty($conf->dynamicprices->enabled)) {
252 $dto =
GETPOST(
"dto_".$reg[1].
'_'.$reg[2],
'int');
256 $saveprice =
"saveprice_".$reg[1].
'_'.$reg[2];
262 if (!(
GETPOST($ent,
'int') > 0)) {
263 dol_syslog(
'No dispatch for line '.$key.
' as no warehouse was chosen.');
264 $text = $langs->transnoentities(
'Warehouse').
', '.$langs->transnoentities(
'Line').
' '.($numline);
265 setEventMessages($langs->trans(
'ErrorFieldRequired', $text),
null,
'errors');
270 $result = $object->dispatchProduct($user,
GETPOST($prod,
'int'),
GETPOST($qty),
GETPOST($ent,
'int'),
GETPOST($pu),
GETPOST(
'comment'),
'',
'',
'',
GETPOST($fk_commandefourndet,
'int'), $notrigger);
276 if (!$error && !empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) {
277 if (!
isModEnabled(
"multicurrency") && empty($conf->dynamicprices->enabled)) {
286 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"product_fournisseur_price";
287 $sql .=
" SET unitprice='".price2num(
GETPOST($pu),
'MU').
"'";
288 $sql .=
", price=".price2num(
GETPOST($pu),
'MU').
"*quantity";
289 $sql .=
", remise_percent = ".((float) $dto);
290 $sql .=
" WHERE fk_soc=".((int) $object->socid);
291 $sql .=
" AND fk_product=".((int)
GETPOST($prod,
'int'));
293 $resql = $db->query($sql);
301 if (preg_match(
'/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
307 $prod =
'product_batch_'.$reg[1].
'_'.$reg[2];
308 $qty =
'qty_'.$reg[1].
'_'.$reg[2];
309 $ent =
'entrepot_'.$reg[1].
'_'.$reg[2];
310 $pu =
'pu_'.$reg[1].
'_'.$reg[2];
311 $fk_commandefourndet =
'fk_commandefourndet_'.$reg[1].
'_'.$reg[2];
312 $lot =
'lot_number_'.$reg[1].
'_'.$reg[2];
313 $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'));
314 $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'));
316 $fk_commandefourndet =
'fk_commandefourndet_'.$reg[1].
'_'.$reg[2];
318 if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) {
319 if (!
isModEnabled(
"multicurrency") && empty($conf->dynamicprices->enabled)) {
320 $dto =
GETPOST(
"dto_".$reg[1].
'_'.$reg[2],
'int');
324 $saveprice =
"saveprice_".$reg[1].
'_'.$reg[2];
330 if (!(
GETPOST($ent,
'int') > 0)) {
331 dol_syslog(
'No dispatch for line '.$key.
' as no warehouse was chosen.');
332 $text = $langs->transnoentities(
'Warehouse').
', '.$langs->transnoentities(
'Line').
' '.($numline).
'-'.($reg[1] + 1);
333 setEventMessages($langs->trans(
'ErrorFieldRequired', $text),
null,
'errors');
337 if (!(
GETPOST($lot,
'alpha') || $dDLUO || $dDLC)) {
338 dol_syslog(
'No dispatch for line '.$key.
' as serial/eat-by/sellby date are not set');
339 $text = $langs->transnoentities(
'atleast1batchfield').
', '.$langs->transnoentities(
'Line').
' '.($numline).
'-'.($reg[1] + 1);
340 setEventMessages($langs->trans(
'ErrorFieldRequired', $text),
null,
'errors');
345 $result = $object->dispatchProduct($user,
GETPOST($prod,
'int'),
GETPOST($qty),
GETPOST($ent,
'int'),
GETPOST($pu),
GETPOST(
'comment'), $dDLUO, $dDLC,
GETPOST($lot,
'alpha'),
GETPOST($fk_commandefourndet,
'int'), $notrigger);
351 if (!$error && !empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) {
352 if (!
isModEnabled(
"multicurrency") && empty($conf->dynamicprices->enabled)) {
353 $dto =
GETPOST(
"dto_".$reg[1].
'_'.$reg[2],
'int');
357 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"product_fournisseur_price";
358 $sql .=
" SET unitprice = ".price2num(
GETPOST($pu),
'MU', 2);
359 $sql .=
", price = ".price2num(
GETPOST($pu),
'MU', 2).
" * quantity";
360 $sql .=
", remise_percent = ".price2num((empty($dto) ? 0 : $dto), 3, 2).
"'";
361 $sql .=
" WHERE fk_soc = ".((int) $object->socid);
362 $sql .=
" AND fk_product=".((int)
GETPOST($prod,
'int'));
364 $resql = $db->query($sql);
374 $result = $object->calcAndSetStatusDispatch($user,
GETPOST(
'closeopenorder') ? 1 : 0,
GETPOST(
'comment'));
381 if ($result >= 0 && !$error) {
384 header(
"Location: dispatch.php?id=".$id);
392 if ($action ==
'confirm_deleteline' && $confirm ==
'yes' && $permissiontoreceive) {
396 $result = $supplierorderdispatch->fetch($lineid);
398 $qty = $supplierorderdispatch->qty;
399 $entrepot = $supplierorderdispatch->fk_entrepot;
400 $product = $supplierorderdispatch->fk_product;
402 $comment = $supplierorderdispatch->comment;
403 $eatby = $supplierorderdispatch->eatby;
404 $sellby = $supplierorderdispatch->sellby;
405 $batch = $supplierorderdispatch->batch;
407 $result = $supplierorderdispatch->delete($user);
410 $errors = $object->errors;
414 if ($entrepot > 0 &&
isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) && empty($supplierorderdispatch->fk_reception)) {
417 $mouv->origin = &$object;
418 $mouv->setOrigin($object->element, $object->id);
419 $result = $mouv->livraison($user, $product, $entrepot, $qty, $price, $comment,
'', $eatby, $sellby, $batch);
421 $errors = $mouv->errors;
436 if ($action ==
'updateline' && $permissiontoreceive) {
441 $result = $supplierorderdispatch->fetch($lineid);
443 $qty = $supplierorderdispatch->qty;
444 $entrepot = $supplierorderdispatch->fk_entrepot;
445 $product = $supplierorderdispatch->fk_product;
447 $comment = $supplierorderdispatch->comment;
448 $eatby = $supplierorderdispatch->eatby;
449 $sellby = $supplierorderdispatch->sellby;
450 $batch = $supplierorderdispatch->batch;
453 $supplierorderdispatch->fk_entrepot =
GETPOST(
'fk_entrepot');
454 $result = $supplierorderdispatch->update($user);
458 $errors = $supplierorderdispatch->errors;
461 if ($entrepot > 0 &&
isModEnabled(
'stock') && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) {
464 $mouv->origin = &$object;
465 $mouv->setOrigin($object->element, $object->id);
466 $result = $mouv->livraison($user, $product, $entrepot, $qty, $price, $comment,
'', $eatby, $sellby, $batch);
468 $errors = $mouv->errors;
471 $mouv->origin = &$object;
472 $result = $mouv->reception($user, $product, $supplierorderdispatch->fk_entrepot, $supplierorderdispatch->qty, $price, $comment, $eatby, $sellby, $batch);
474 $errors = $mouv->errors;
497 $warehouse_static =
new Entrepot($db);
500 $title = $object->ref.
" - ".$langs->trans(
'OrderDispatch');
501 $help_url =
'EN:Module_Suppliers_Orders|FR:CommandeFournisseur|ES:Módulo_Pedidos_a_proveedores';
502 $morejs = array(
'/fourn/js/lib_dispatch.js.php');
506 if ($id > 0 || !empty($ref)) {
508 $soc->fetch($object->socid);
510 $author =
new User($db);
511 $author->fetch($object->user_author_id);
515 $title = $langs->trans(
"SupplierOrder");
521 if ($action ==
'ask_deleteline') {
522 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&lineid='.$lineid, $langs->trans(
'DeleteLine'), $langs->trans(
'ConfirmDeleteLine'),
'confirm_deleteline',
'', 0, 1);
526 $parameters = array(
'lineid' => $lineid);
528 $reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
529 if (empty($reshook)) {
531 } elseif ($reshook > 0) {
540 $linkback =
'<a href="'.DOL_URL_ROOT.
'/fourn/commande/list.php'.(!empty($socid) ?
'?socid='.$socid :
'').
'">'.$langs->trans(
"BackToList").
'</a>';
542 $morehtmlref =
'<div class="refidno">';
544 $morehtmlref .=
$form->editfieldkey(
"RefSupplier",
'ref_supplier', $object->ref_supplier, $object, 0,
'string',
'', 0, 1);
545 $morehtmlref .=
$form->editfieldval(
"RefSupplier",
'ref_supplier', $object->ref_supplier, $object, 0,
'string',
'',
null,
null,
'', 1);
547 $morehtmlref .=
'<br>'.$object->thirdparty->getNomUrl(1);
550 $langs->load(
"projects");
551 $morehtmlref .=
'<br>';
553 $morehtmlref .=
img_picto($langs->trans(
"Project"),
'project',
'class="pictofixedwidth"');
554 if ($action !=
'classify' && $caneditproject) {
555 $morehtmlref .=
'<a class="editfielda" href="'.$_SERVER[
'PHP_SELF'].
'?action=classify&token='.
newToken().
'&id='.$object->id.
'">'.
img_edit($langs->transnoentitiesnoconv(
'SetProject')).
'</a> ';
557 $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');
559 if (!empty($object->fk_project)) {
561 $proj->fetch($object->fk_project);
562 $morehtmlref .= $proj->getNomUrl(1);
564 $morehtmlref .=
'<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).
'</span>';
569 $morehtmlref .=
'</div>';
572 dol_banner_tab($object,
'ref', $linkback, 1,
'ref',
'ref', $morehtmlref);
575 print
'<div class="fichecenter">';
576 print
'<div class="underbanner clearboth"></div>';
578 print
'<table class="border tableforfield" width="100%">';
581 if ($object->methode_commande_id > 0) {
582 print
'<tr><td class="titlefield">'.$langs->trans(
"Date").
'</td><td>';
583 if ($object->date_commande) {
588 if ($object->methode_commande) {
589 print
'<tr><td>'.$langs->trans(
"Method").
'</td><td>'.$object->getInputMethod().
'</td></tr>';
594 print
'<tr><td class="titlefield">'.$langs->trans(
"AuthorRequest").
'</td>';
595 print
'<td>'.$author->getNomUrl(1,
'', 0, 0, 0).
'</td>';
598 $parameters = array();
599 $reshook = $hookmanager->executeHooks(
'formObjectOptions', $parameters, $object, $action);
616 print
'<br><span class="opacitymedium">'.$langs->trans(
"OrderStatusNotReadyToDispatch").
'</span>';
622 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
624 $formproduct->loadWarehouses();
626 $listwarehouses = $entrepot->list_array(1);
629 if (empty($conf->reception->enabled)) {
630 print
'<form method="POST" action="dispatch.php?id='.$object->id.
'">';
632 print
'<form method="post" action="'.dol_buildpath(
'/reception/card.php', 1).
'?originid='.$object->id.
'&origin=supplierorder">';
635 print
'<input type="hidden" name="token" value="'.newToken().
'">';
636 if (empty($conf->reception->enabled)) {
637 print
'<input type="hidden" name="action" value="dispatch">';
639 print
'<input type="hidden" name="action" value="create">';
642 print
'<div class="div-table-responsive-no-min">';
643 print
'<table class="noborder centpercent">';
646 $products_dispatched = array();
647 $sql =
"SELECT l.rowid, cfd.fk_product, sum(cfd.qty) as qty";
648 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commande_fournisseur_dispatch as cfd";
649 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"commande_fournisseurdet as l on l.rowid = cfd.fk_commandefourndet";
650 $sql .=
" WHERE cfd.fk_commande = ".((int) $object->id);
651 $sql .=
" GROUP BY l.rowid, cfd.fk_product";
653 $resql = $db->query($sql);
655 $num = $db->num_rows(
$resql);
660 $objd = $db->fetch_object(
$resql);
661 $products_dispatched[$objd->rowid] =
price2num($objd->qty, 5);
669 $sql =
"SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, l.qty as qty,";
670 $sql .=
" p.ref, p.label, p.tobatch, p.fk_default_warehouse";
673 $parameters = array();
674 $reshook = $hookmanager->executeHooks(
675 'printFieldListSelect',
683 $sql .= $hookmanager->resPrint;
685 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commande_fournisseurdet as l";
686 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"product as p ON l.fk_product=p.rowid";
687 $sql .=
" WHERE l.fk_commande = ".((int) $object->id);
688 if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) {
689 $sql .=
" AND l.product_type = 0";
693 $parameters = array();
694 $reshook = $hookmanager->executeHooks(
695 'printFieldListWhere',
703 $sql .= $hookmanager->resPrint;
706 $sql .=
" ORDER BY l.rang, p.ref, p.label";
708 $resql = $db->query($sql);
710 $num = $db->num_rows(
$resql);
714 print
'<tr class="liste_titre">';
716 print
'<td>'.$langs->trans(
"Description").
'</td>';
718 print
'<td class="dispatch_batch_number_title">'.$langs->trans(
"batch_number").
'</td>';
719 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
720 print
'<td class="dispatch_dlc_title">'.$langs->trans(
"SellByDate").
'</td>';
722 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
723 print
'<td class="dispatch_dluo_title">'.$langs->trans(
"EatByDate").
'</td>';
730 print
'<td class="right">'.$langs->trans(
"SupplierRef").
'</td>';
731 print
'<td class="right">'.$langs->trans(
"QtyOrdered").
'</td>';
732 print
'<td class="right">'.$langs->trans(
"QtyDispatchedShort").
'</td>';
733 print
' <td class="right">'.$langs->trans(
"QtyToDispatchShort");
734 print
'<br><a href="#" id="autoreset">'.$langs->trans(
"Reset").
'</a></td>';
735 print
'<td width="32"></td>';
737 if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) {
738 if (!
isModEnabled(
"multicurrency") && empty($conf->dynamicprices->enabled)) {
739 print
'<td class="right">'.$langs->trans(
"Price").
'</td>';
740 print
'<td class="right">'.$langs->trans(
"ReductionShort").
' (%)</td>';
741 print
'<td class="right">'.$langs->trans(
"UpdatePrice").
'</td>';
745 print
'<td align="right">'.$langs->trans(
"Warehouse");
748 if (count($listwarehouses) > 1) {
749 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);
750 } elseif (count($listwarehouses) == 1) {
751 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);
757 $parameters = array();
758 $reshook = $hookmanager->executeHooks(
759 'printFieldListTitle',
767 print $hookmanager->resPrint;
776 $conf->cache[
'product'] = array();
779 $objp = $db->fetch_object(
$resql);
782 if (!$objp->fk_product > 0) {
785 $alreadydispatched = isset($products_dispatched[$objp->rowid])?$products_dispatched[$objp->rowid]:0;
786 $remaintodispatch =
price2num($objp->qty - ((
float) $alreadydispatched), 5);
787 if ($remaintodispatch < 0 && empty($conf->global->SUPPLIER_ORDER_ALLOW_NEGATIVE_QTY_FOR_SUPPLIER_ORDER_RETURN)) {
788 $remaintodispatch = 0;
791 if ($remaintodispatch || empty($conf->global->SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED)) {
800 print
'<!-- Line to dispatch '.$suffix.
' -->'.
"\n";
802 print
'<input id="qty_ordered'.$suffix.
'" type="hidden" value="'.$objp->qty.
'">';
803 print
'<input id="qty_dispatched'.$suffix.
'" type="hidden" value="'.(
float) $alreadydispatched.
'">';
804 print
'<tr class="oddeven">';
806 if (empty($conf->cache[
'product'][$objp->fk_product])) {
807 $tmpproduct =
new Product($db);
808 $tmpproduct->fetch($objp->fk_product);
809 $conf->cache[
'product'][$objp->fk_product] = $tmpproduct;
811 $tmpproduct = $conf->cache[
'product'][$objp->fk_product];
814 $linktoprod = $tmpproduct->getNomUrl(1);
815 $linktoprod .=
' - '.$objp->label.
"\n";
818 if ($objp->tobatch) {
823 print
'<td class="dispatch_batch_number"></td>';
824 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
825 print
'<td class="dispatch_dlc"></td>';
827 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
828 print
'<td class="dispatch_dluo"></td>';
835 print
'<td class="dispatch_batch_number">';
836 print $langs->trans(
"ProductDoesNotUseBatchSerial");
838 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
839 print
'<td class="dispatch_dlc"></td>';
841 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
842 print
'<td class="dispatch_dluo"></td>';
846 print
'<td colspan="4">';
852 $up_ht_disc = $objp->subprice;
853 if (!empty($objp->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) {
854 $up_ht_disc =
price2num($up_ht_disc * (100 - $objp->remise_percent) / 100,
'MU');
858 print
'<td class="right">'.$objp->sref.
'</td>';
861 print
'<td class="right">'.$objp->qty.
'</td>';
864 print
'<td class="right">'.$alreadydispatched.
'</td>';
866 if (
isModEnabled(
'productbatch') && $objp->tobatch > 0) {
868 print
'<td class="right">';
878 'is_information_row' =>
true,
883 $reshook = $hookmanager->executeHooks(
884 'printFieldListValue',
892 print $hookmanager->resPrint;
896 print
'<tr class="oddeven" name="'.$type.$suffix.
'">';
898 print
'<input name="fk_commandefourndet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
899 print
'<input name="product_batch'.$suffix.
'" type="hidden" value="'.$objp->fk_product.
'">';
901 print
'<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
902 if (!empty($conf->global->SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT)) {
903 print $langs->trans(
"BuyingPrice").
': <input class="maxwidth75" name="pu'.$suffix.
'" type="text" value="'.
price2num($up_ht_disc,
'MU').
'">';
905 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
911 print
'<input type="text" class="inputlotnumber quatrevingtquinzepercent" id="lot_number'.$suffix.
'" name="lot_number'.$suffix.
'" value="'.
GETPOST(
'lot_number'.$suffix).
'">';
913 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
914 print
'<td class="nowraponall">';
916 print
$form->selectDate($dlcdatesuffix,
'dlc'.$suffix,
'',
'', 1,
'');
919 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
920 print
'<td class="nowraponall">';
922 print
$form->selectDate($dluodatesuffix,
'dluo'.$suffix,
'',
'', 1,
'');
925 print
'<td colspan="3"> </td>';
929 $colspan = (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) ? --$colspan : $colspan;
930 $colspan = (!empty($conf->global->PRODUCT_DISABLE_EATBY)) ? --$colspan : $colspan;
931 print
'<td class="right">';
941 'is_information_row' =>
true,
946 $reshook = $hookmanager->executeHooks(
947 'printFieldListValue',
955 print $hookmanager->resPrint;
959 print
'<tr class="oddeven" name="'.$type.$suffix.
'">';
960 print
'<td colspan="'.$colspan.
'">';
961 print
'<input name="fk_commandefourndet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
962 print
'<input name="product'.$suffix.
'" type="hidden" value="'.$objp->fk_product.
'">';
964 print
'<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
965 if (!empty($conf->global->SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT)) {
966 print $langs->trans(
"BuyingPrice").
': <input class="maxwidth75" name="pu'.$suffix.
'" type="text" value="'.
price2num($up_ht_disc,
'MU').
'">';
968 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
975 print
'<td class="right">';
976 print
'<input id="qty'.$suffix.
'" name="qty'.$suffix.
'" type="text" class="width50 right" value="'.(
GETPOSTISSET(
'qty'.$suffix) ?
GETPOST(
'qty'.$suffix,
'int') : (empty($conf->global->SUPPLIER_ORDER_DISPATCH_FORCE_QTY_INPUT_TO_ZERO) ? $remaintodispatch : 0)).
'">';
980 if (
isModEnabled(
'productbatch') && $objp->tobatch > 0) {
982 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" onClick="addDispatchLine('.$i.
', \''.$type.
'\')
"');
985 print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton
" onClick="addDispatchLine(
'.$i.', \
''.$type.
'\')
"');
989 if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) {
990 if (!isModEnabled("multicurrency
") && empty($conf->dynamicprices->enabled)) {
992 print '<td class="right
">';
993 print '<input id="pu
'.$suffix.'" name="pu
'.$suffix.'" type="text
" size="8
" value="'.price((GETPOST('pu
'.$suffix) != '' ? price2num(GETPOST('pu
'.$suffix)) : $up_ht_disc)).'">';
997 print '<td class="right
">';
998 print '<input id="dto
'.$suffix.'" name="dto
'.$suffix.'" type="text
" size="8
" value="'.(GETPOST('dto
'.$suffix) != '' ? GETPOST('dto
'.$suffix) : '').'">';
1002 print '<td class="center
">';
1003 print '<input class="flat checkformerge
" type="checkbox
" name="saveprice
'.$suffix.'" value="'.(GETPOST('saveprice
'.$suffix) != '' ? GETPOST('saveprice
'.$suffix) : '').'">';
1009 print '<td class="right
">';
1010 if (count($listwarehouses) > 1) {
1011 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);
1012 } elseif (count($listwarehouses) == 1) {
1013 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);
1015 $langs->load("errors
");
1016 print $langs->trans("ErrorNoWarehouseDefined
");
1020 // Enable hooks to append additional columns
1021 $parameters = array(
1022 'is_information_row' => false, // this is a dispatch form row
1024 'suffix' => $suffix,
1027 $reshook = $hookmanager->executeHooks(
1028 'printFieldListValue',
1034 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1036 print $hookmanager->resPrint;
1045 dol_print_error($db);
1052 $checkboxlabel = $langs->trans("CloseReceivedSupplierOrdersAutomatically
", $langs->transnoentitiesnoconv('StatusOrderReceivedAll'));
1054 print '<div class="center
">';
1055 $parameters = array();
1056 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1058 if (empty($reshook)) {
1059 if (empty($conf->reception->enabled)) {
1060 print $langs->trans("Comment").' : ';
1061 print '<input type="text
" class="minwidth400
" maxlength="128
" name="comment
" value="';
1062 print GETPOSTISSET("comment") ? GETPOST("comment") : $langs->trans("DispatchSupplierOrder", $object->ref);
1063 // print ' /
'.$object->ref_supplier; // Not yet available
1064 print '" class="flat
"><br>';
1066 print '<input type="checkbox
" checked="checked
" name="closeopenorder
"> '.$checkboxlabel;
1069 $dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive
") : $langs->trans("CreateReception
");
1072 print '<input type="hidden
" name="backtopageforcancel
" value="'.$_SERVER["PHP_SELF"].'?
id=
'.$object->id.'">';
1073 print '<input type="submit
" class="button" name="dispatch
" value="'.dol_escape_htmltag($dispatchBt).'"';
1075 if (!$permissiontoreceive) {
1078 if (count($listwarehouses) <= 0) {
1090 // Message if nothing to dispatch
1093 if (empty($conf->global->SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED)) {
1094 print '<div class="opacitymedium
">'.$langs->trans("NoPredefinedProductToDispatch
").'</div>'; // No predefined line at all
1096 print '<div class="opacitymedium
">'.$langs->trans("NoMorePredefinedProductToDispatch
").'</div>'; // No predefined line that remain to be dispatched.
1103 print dol_get_fiche_end();
1105 // traitement entrepot par défaut
1106 print '<script type="text/javascript
">
1107 $(document).ready(function () {
1108 $("select[
name=fk_default_warehouse]
").change(function() {
1109 var fk_default_warehouse = $("option:selected
", this).val();
1110 $("select[
name^=entrepot_]
").val(fk_default_warehouse).change();
1113 jQuery("#autoreset
").click(function() {';
1115 while ($i < $nbproduct) {
1116 print ' jQuery("#qty_0_
'.$i.'").val("");';
1124 // List of lines already dispatched
1125 $sql = "SELECT p.rowid as pid, p.ref, p.label,
";
1126 $sql .= " e.rowid as warehouse_id, e.ref as entrepot,
";
1127 $sql .= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status, cfd.datec
";
1128 $sql .= " ,cd.rowid, cd.subprice
";
1129 if ($conf->reception->enabled) {
1130 $sql .= " ,cfd.fk_reception, r.date_delivery
";
1132 $sql .= " FROM
".MAIN_DB_PREFIX."product as p,
";
1133 $sql .= " ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as cfd
";
1134 $sql .= " LEFT JOIN
".MAIN_DB_PREFIX."commande_fournisseurdet as cd ON cd.rowid = cfd.fk_commandefourndet
";
1135 $sql .= " LEFT JOIN
".MAIN_DB_PREFIX."entrepot as e ON cfd.fk_entrepot = e.rowid
";
1136 if ($conf->reception->enabled) {
1137 $sql .= " LEFT JOIN
".MAIN_DB_PREFIX."reception as r ON cfd.fk_reception = r.rowid
";
1139 $sql .= " WHERE cfd.fk_commande =
".((int) $object->id);
1140 $sql .= " AND cfd.fk_product = p.rowid
";
1141 $sql .= " ORDER BY cfd.rowid ASC
";
1143 $resql = $db->query($sql);
1145 $num = $db->num_rows($resql);
1151 print load_fiche_titre($langs->trans("ReceivingForSameOrder
"));
1153 print '<div class="div-table-responsive
">';
1154 print '<table id="dispatch_received_products
" class="noborder centpercent
">';
1156 print '<tr class="liste_titre
">';
1158 if ($conf->reception->enabled) {
1159 print '<td>'.$langs->trans("Reception").'</td>';
1162 print '<td>'.$langs->trans("Product").'</td>';
1163 print '<td class="center
">'.$langs->trans("DateCreation
").'</td>';
1164 print '<td class="center
">'.$langs->trans("DateDeliveryPlanned
").'</td>';
1165 if (isModEnabled('productbatch')) {
1166 print '<td class="dispatch_batch_number_title
">'.$langs->trans("batch_number
").'</td>';
1167 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
1168 print '<td class="dispatch_dlc_title
">'.$langs->trans("SellByDate
").'</td>';
1170 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
1171 print '<td class="dispatch_dluo_title
">'.$langs->trans("EatByDate
").'</td>';
1174 print '<td class="right
">'.$langs->trans("QtyDispatched
").'</td>';
1175 print '<td>'.$langs->trans("Warehouse
").'</td>';
1176 print '<td>'.$langs->trans("Comment").'</td>';
1179 if (!empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS) && empty($reception->rowid)) {
1180 print '<td class="center
" colspan="2
">'.$langs->trans("Status").'</td>';
1181 } elseif (isModEnabled("reception
")) {
1182 print '<td class="center
"></td>';
1185 print '<td class="center
" colspan="2
"></td>';
1191 $objp = $db->fetch_object($resql);
1193 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1194 print '<form name="editdispatchedlines
" id="editdispatchedlines
" action="'.$_SERVER["PHP_SELF"].'?
id=
'.$object->id.'#line_
'.GETPOST('lineid
', 'int').'" method="POST
">
1195 <input type="hidden
" name="token
" value="'.newToken().'">
1196 <input type="hidden
" name="action
" value="updateline
">
1197 <input type="hidden
" name="mode
" value="">
1198 <input type="hidden
" name="lineid
" value="'.$objp->dispatchlineid.'">';
1201 print '<tr class="oddeven
" id="line_
'.$objp->dispatchlineid.'" >';
1204 if (isModEnabled("reception
")) {
1205 print '<td class="nowraponall
">';
1206 if (!empty($objp->fk_reception)) {
1207 $reception = new Reception($db);
1208 $reception->fetch($objp->fk_reception);
1209 print $reception->getNomUrl(1);
1216 print '<td class="tdoverflowmax150
">';
1217 if (empty($conf->cache['product'][$objp->fk_product])) {
1218 $tmpproduct = new Product($db);
1219 $tmpproduct->fetch($objp->fk_product);
1220 $conf->cache['product'][$objp->fk_product] = $tmpproduct;
1222 $tmpproduct = $conf->cache['product'][$objp->fk_product];
1224 print $tmpproduct->getNomUrl(1);
1225 print ' - '.$objp->label;
1229 print '<td class="center
">'.dol_print_date($db->jdate($objp->datec), 'day').'</td>';
1232 print '<td class="center
">'.dol_print_date($db->jdate($objp->date_delivery), 'day').'</td>';
1234 // Batch / Eat by / Sell by
1235 if (isModEnabled('productbatch')) {
1237 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
1238 $lot = new Productlot($db);
1239 $lot->fetch(0, $objp->pid, $objp->batch);
1240 print '<td class="dispatch_batch_number
">'.$lot->getNomUrl(1).'</td>';
1241 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
1242 print '<td class="dispatch_dlc
">'.dol_print_date($lot->sellby, 'day').'</td>';
1244 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
1245 print '<td class="dispatch_dluo
">'.dol_print_date($lot->eatby, 'day').'</td>';
1248 print '<td class="dispatch_batch_number
"></td>';
1249 if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) {
1250 print '<td class="dispatch_dlc
"></td>';
1252 if (empty($conf->global->PRODUCT_DISABLE_EATBY)) {
1253 print '<td class="dispatch_dluo
"></td>';
1259 print '<td class="right
">';
1260 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1261 print '<input style="width: 50px;
" type="text
" min="1
" name="qty
" value="'.$objp->qty.'" />';
1265 print '<input type="hidden
" name="price" value="'.$objp->subprice.'" />';
1269 print '<td class="tdoverflowmax150
">';
1270 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1271 if (count($listwarehouses) > 1) {
1272 print $formproduct->selectWarehouses(GETPOST("fk_entrepot
") ?GETPOST("fk_entrepot
") : ($objp->warehouse_id ? $objp->warehouse_id : ''), "fk_entrepot
", '', 1, 0, $objp->fk_product, '', 1, 1, null, 'csswarehouse');
1273 } elseif (count($listwarehouses) == 1) {
1274 print $formproduct->selectWarehouses(GETPOST("fk_entrepot
") ?GETPOST("fk_entrepot
") : ($objp->warehouse_id ? $objp->warehouse_id : ''), "fk_entrepot
", '', 0, 0, $objp->fk_product, '', 1, 1, null, 'csswarehouse');
1276 $langs->load("errors
");
1277 print $langs->trans("ErrorNoWarehouseDefined
");
1280 $warehouse_static->id = $objp->warehouse_id;
1281 $warehouse_static->label = $objp->entrepot;
1282 print $warehouse_static->getNomUrl(1);
1287 print '<td class="tdoverflowmax300
" style="white-space: pre;
">'.$objp->comment.'</td>';
1290 if (!empty($conf->global->SUPPLIER_ORDER_USE_DISPATCH_STATUS) && empty($reception->rowid)) {
1291 print '<td class="right
">';
1292 $supplierorderdispatch->status = (empty($objp->status) ? 0 : $objp->status);
1293 // print $supplierorderdispatch->status;
1294 print $supplierorderdispatch->getLibStatut(5);
1297 // Add button to check/uncheck disaptching
1298 print '<td class="center
">';
1299 if (!$permissiontocontrol) {
1300 if (empty($objp->status)) {
1301 print '<a class="button buttonRefused
" href="#
">'.$langs->trans("Approve
").'</a>';
1302 print '<a class="button buttonRefused
" href="#
">'.$langs->trans("Deny
").'</a>';
1304 print '<a class="button buttonRefused
" href="#
">'.$langs->trans("Disapprove
").'</a>';
1305 print '<a class="button buttonRefused
" href="#
">'.$langs->trans("Deny
").'</a>';
1309 if ($object->statut == 5) {
1312 if (empty($objp->status)) {
1313 print '<a class="button'.($disabled ? ' buttonRefused
' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=checkdispatchline&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Approve
").'</a>';
1314 print '<a class="button'.($disabled ? ' buttonRefused
' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=denydispatchline&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Deny
").'</a>';
1316 if ($objp->status == 1) {
1317 print '<a class="button'.($disabled ? ' buttonRefused
' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=uncheckdispatchline&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Reinit
").'</a>';
1318 print '<a class="button'.($disabled ? ' buttonRefused
' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=denydispatchline&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Deny
").'</a>';
1320 if ($objp->status == 2) {
1321 print '<a class="button'.($disabled ? ' buttonRefused
' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=uncheckdispatchline&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Reinit
").'</a>';
1322 print '<a class="button'.($disabled ? ' buttonRefused
' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=checkdispatchline&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Approve
").'</a>';
1326 } elseif (isModEnabled("reception
")) {
1327 print '<td class="right
">';
1328 if (!empty($reception->id)) {
1329 print $reception->getLibStatut(5);
1335 if ($action != 'editline' || $lineid != $objp->dispatchlineid) {
1336 if (empty($reception->id) || ($reception->statut == Reception::STATUS_DRAFT)) { // only allow edit on draft reception
1337 print '<td class="linecoledit center
">';
1338 print '<a class="reposition
" href="'.$_SERVER["PHP_SELF"].'?
id=
'.$object->id.'&action=editline&token=
'.newToken().'&lineid=
'.$objp->dispatchlineid.'#line_
'.$objp->dispatchlineid.'">';
1343 print '<td class="linecoldelete center
">';
1344 print '<a href="'.$_SERVER["PHP_SELF"].'?
id=
'.$object->id.'&action=ask_deleteline&token=
'.newToken().'&lineid=
'.$objp->dispatchlineid.'#dispatch_received_products
">';
1349 print '<td></td><td></td>';
1352 print '<td class="center valignmiddle
">';
1353 print '<input type="submit
" class="button button-save
" id="savelinebutton
" name="save
" value="'.$langs->trans("Save").'" />';
1355 print '<td class="center valignmiddle
">';
1356 print '<input type="submit
" class="button button-cancel
" id="cancellinebutton
" name="cancel
" value="'.$langs->trans("Cancel").'" />';
1362 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1374 dol_print_error($db);