35require
'../main.inc.php';
36require_once DOL_DOCUMENT_ROOT.
'/core/modules/supplier_order/modules_commandefournisseur.php';
37require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
38require_once DOL_DOCUMENT_ROOT.
'/core/lib/fourn.lib.php';
39require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.class.php';
40require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.dispatch.class.php';
41require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
42require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
43require_once DOL_DOCUMENT_ROOT.
'/core/lib/sendings.lib.php';
44if (isModEnabled(
'project')) {
45 require_once DOL_DOCUMENT_ROOT.
'/projet/class/project.class.php';
57$langs->loadLangs(array(
"sendings",
"companies",
"bills",
'deliveries',
'orders',
'stocks',
'other',
'propal',
'receptions'));
59if (isModEnabled(
'productbatch')) {
60 $langs->load(
'productbatch');
67$action =
GETPOST(
'action',
'aZ09');
68$fk_default_warehouse =
GETPOSTINT(
'fk_default_warehouse');
69$cancel =
GETPOST(
'cancel',
'alpha');
70$confirm =
GETPOST(
'confirm',
'alpha');
76 $socid = $user->socid;
79$hookmanager->initHooks(array(
'expeditiondispatch'));
83if (GETPOSTISSET(
"projectid")) {
91if ($id > 0 || !empty($ref)) {
92 $result =
$object->fetch($id, $ref);
96 $result =
$object->fetch_thirdparty();
111if (!isModEnabled(
'stock')) {
115$usercancreate = $user->hasRight(
'expedition',
'creer');
116$permissiontoadd = $usercancreate;
123$parameters = array();
124$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
130if ($action ==
'updatelines' && $usercancreate) {
139 foreach ($_POST as $key => $value) {
142 if (preg_match(
'/^product_.*([0-9]+)_([0-9]+)$/i', $key, $reg)) {
144 if (preg_match(
'/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
145 $modebatch =
"barcode";
146 } elseif (preg_match(
'/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
147 $modebatch =
"batch";
151 if ($modebatch ==
"barcode") {
152 $prod =
"product_".$reg[1].
'_'.$reg[2];
154 $prod =
'product_batch_'.$reg[1].
'_'.$reg[2];
156 $qty =
"qty_".$reg[1].
'_'.$reg[2];
157 $ent =
"entrepot_".$reg[1].
'_'.$reg[2];
158 $fk_commandedet =
"fk_commandedet_".$reg[1].
'_'.$reg[2];
159 $idline =
GETPOST(
"idline_".$reg[1].
'_'.$reg[2]);
166 if ($modebatch ==
"batch") {
167 $lot =
GETPOST(
'lot_number_'.$reg[1].
'_'.$reg[2]);
176 if (($modebatch ==
"batch" && $newqty >= 0) || ($modebatch ==
"barcode" && $newqty != 0)) {
178 if (!($warehouse_id > 0)) {
179 dol_syslog(
'No dispatch for line '.$key.
' as no warehouse was chosen.');
180 $text = $langs->transnoentities(
'Warehouse').
', '.$langs->transnoentities(
'Line').
' '.($numline);
181 setEventMessages($langs->trans(
'ErrorFieldRequired', $text),
null,
'errors');
184 if (!$error && $modebatch ==
"batch") {
185 $sql =
"SELECT pb.rowid ";
186 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product_batch as pb";
187 $sql .=
" JOIN ".MAIN_DB_PREFIX.
"product_stock as ps";
188 $sql .=
" ON ps.rowid = pb.fk_product_stock";
189 $sql .=
" WHERE pb.batch = '".$db->escape($lot).
"'";
190 $sql .=
" AND ps.fk_product = ".((int) $prod_id) ;
191 $sql .=
" AND ps.fk_entrepot = ".((int) $warehouse_id) ;
193 $resql = $db->query($sql);
195 $num = $db->num_rows($resql);
197 dol_syslog(
'No dispatch for line '.$key.
' as too many combination warehouse, product, batch code was found ('.$num.
').');
198 setEventMessages($langs->trans(
'ErrorTooManyCombinationBatchcode', $numline, $num),
null,
'errors');
200 } elseif ($num < 1) {
202 $tmpwarehouse->fetch($warehouse_id);
204 $tmpprod->fetch($prod_id);
205 dol_syslog(
'No dispatch for line '.$key.
' as no combination warehouse, product, batch code was found.');
206 setEventMessages($langs->trans(
'ErrorNoCombinationBatchcode', $numline, $tmpwarehouse->ref, $tmpprod->ref, $lot),
null,
'errors');
218 $result = $expeditiondispatch->fetch($idline);
220 setEventMessages($expeditiondispatch->error, $expeditiondispatch->errors,
'errors');
223 $qtystart = $expeditiondispatch->qty;
224 $expeditiondispatch->qty = $newqty;
225 $expeditiondispatch->entrepot_id =
GETPOSTINT($ent);
228 $result = $expeditiondispatch->update($user);
230 $result = $expeditiondispatch->delete($user);
233 setEventMessages($expeditiondispatch->error, $expeditiondispatch->errors,
'errors');
237 if (!$error && $modebatch ==
"batch") {
239 $suffixkeyfordate = preg_replace(
'/^product_batch/',
'', $key);
243 $sqlsearchdet =
"SELECT rowid FROM ".MAIN_DB_PREFIX.$expeditionlinebatch->table_element;
244 $sqlsearchdet .=
" WHERE fk_expeditiondet = ".((int) $idline);
245 $sqlsearchdet .=
" AND batch = '".$db->escape($lot).
"'";
246 $resqlsearchdet = $db->query($sqlsearchdet);
248 if ($resqlsearchdet) {
249 $objsearchdet = $db->fetch_object($resqlsearchdet);
255 $sql =
"UPDATE ".MAIN_DB_PREFIX.$expeditionlinebatch->table_element.
" SET";
256 $sql .=
" eatby = ".($eatby ?
"'".$db->idate($eatby).
"'" :
"null");
257 $sql .=
" , sellby = ".($sellby ?
"'".$db->idate($sellby).
"'" :
"null");
258 $sql .=
" , qty = ".((float) $newqty);
259 $sql .=
" , fk_warehouse = ".((int) $warehouse_id);
260 $sql .=
" WHERE rowid = ".((int) $objsearchdet->rowid);
262 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.$expeditionlinebatch->table_element.
" (";
263 $sql .=
"fk_expeditiondet, eatby, sellby, batch, qty, fk_origin_stock, fk_warehouse)";
264 $sql .=
" VALUES (".((int) $idline).
", ".($eatby ?
"'".$db->idate($eatby).
"'" :
"null").
", ".($sellby ?
"'".$db->idate($sellby).
"'" :
"null").
", ";
265 $sql .=
" '".$db->escape($lot).
"', ".((float) $newqty).
", 0, ".((int) $warehouse_id).
")";
268 $sql =
" DELETE FROM ".MAIN_DB_PREFIX.$expeditionlinebatch->table_element;
269 $sql .=
" WHERE fk_expeditiondet = ".((int) $idline);
270 $sql .=
" AND batch = '".$db->escape($lot).
"'";
273 $resql = $db->query($sql);
281 $expeditiondispatch->fk_expedition =
$object->id;
282 $expeditiondispatch->entrepot_id =
GETPOSTINT($ent);
283 $expeditiondispatch->fk_elementdet =
GETPOSTINT($fk_commandedet);
284 $expeditiondispatch->qty = $newqty;
287 $idline = $expeditiondispatch->insert($user);
289 setEventMessages($expeditiondispatch->error, $expeditiondispatch->errors,
'errors');
293 if ($modebatch ==
"batch" && !$error) {
294 $expeditionlinebatch->sellby = $dDLUO;
295 $expeditionlinebatch->eatby = $dDLC;
296 $expeditionlinebatch->batch = $lot;
297 $expeditionlinebatch->qty = $newqty;
298 $expeditionlinebatch->fk_origin_stock = 0;
299 $expeditionlinebatch->fk_warehouse =
GETPOSTINT($ent);
301 $result = $expeditionlinebatch->create($idline);
303 setEventMessages($expeditionlinebatch->error, $expeditionlinebatch->errors,
'errors');
360 header(
"Location: ".DOL_URL_ROOT.
'/expedition/dispatch.php?id='.
$object->id);
363} elseif ($action ==
'setdate_livraison' && $usercancreate) {
367 $result =
$object->setDeliveryDate($user, $datedelivery);
380$form =
new Form($db);
382$warehouse_static =
new Entrepot($db);
384$title =
$object->ref.
" - ".$langs->trans(
'ShipmentDistribution');
385$help_url =
'EN:Module_Shipments|FR:Module_Expéditions|ES:Módulo_Expediciones|DE:Modul_Lieferungen';
386$morejs = array(
'/expedition/js/lib_dispatch.js.php');
388llxHeader(
'', $title, $help_url,
'', 0, 0, $morejs,
'',
'',
'mod-expedition page-card_dispatch');
394 $num_prod = count($lines);
406 $author =
new User($db);
407 $author->fetch(
$object->user_author_id);
417 if ($action ==
'ask_deleteline') {
418 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&lineid='.$lineid, $langs->trans(
'DeleteLine'), $langs->trans(
'ConfirmDeleteLine'),
'confirm_deleteline',
'', 0, 1);
422 $parameters = array(
'lineid' => $lineid);
424 $reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
425 if (empty($reshook)) {
426 $formconfirm .= $hookmanager->resPrint;
427 } elseif ($reshook > 0) {
428 $formconfirm = $hookmanager->resPrint;
434 if ($typeobject ==
'commande' &&
$object->origin_object->id && isModEnabled(
'order')) {
436 $objectsrc->fetch(
$object->origin_object->id);
438 if ($typeobject ==
'propal' &&
$object->origin_object->id && isModEnabled(
"propal")) {
439 $objectsrc =
new Propal($db);
440 $objectsrc->fetch(
$object->origin_object->id);
444 $linkback =
'<a href="'.DOL_URL_ROOT.
'/expedition/list.php?restore_lastsearch_values=1'.(!empty($socid) ?
'&socid='.$socid :
'').
'">'.$langs->trans(
"BackToList").
'</a>';
445 $morehtmlref =
'<div class="refidno">';
448 $morehtmlref .= $form->editfieldkey(
"RefCustomer",
'ref_customer',
$object->ref_customer, $object, $user->hasRight(
'expedition',
'creer'),
'string',
'', 0, 1);
449 $morehtmlref .= $form->editfieldval(
"RefCustomer",
'ref_customer',
$object->ref_customer, $object, $user->hasRight(
'expedition',
'creer'),
'string'.(isset(
$conf->global->THIRDPARTY_REF_INPUT_SIZE) ?
':' .
getDolGlobalString(
'THIRDPARTY_REF_INPUT_SIZE') :
''),
'', null, null,
'', 1);
452 $morehtmlref .=
'<br>'.$object->thirdparty->getNomUrl(1);
454 if (isModEnabled(
'project')) {
455 $langs->load(
"projects");
456 $morehtmlref .=
'<br>';
458 $morehtmlref .=
img_picto($langs->trans(
"Project"),
'project',
'class="pictofixedwidth"');
459 if ($action !=
'classify' && $permissiontoadd) {
460 $morehtmlref .=
'<a class="editfielda" href="'.$_SERVER[
'PHP_SELF'].
'?action=classify&token='.
newToken().
'&id='.
$object->id.
'">'.
img_edit($langs->transnoentitiesnoconv(
'SetProject')).
'</a> ';
462 $morehtmlref .= $form->form_project($_SERVER[
'PHP_SELF'].
'?id='.
$object->id, (!
getDolGlobalString(
'PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ?
$object->socid : -1),
$object->fk_project, ($action ==
'classify' ?
'projectid' :
'none'), 0, 0, 0, 1,
'',
'maxwidth300');
464 if (!empty($objectsrc) && !empty($objectsrc->fk_project)) {
466 $proj->fetch($objectsrc->fk_project);
467 $morehtmlref .= $proj->getNomUrl(1);
469 $morehtmlref .=
'<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).
'</span>';
474 $morehtmlref .=
'</div>';
476 dol_banner_tab($object,
'ref', $linkback, 1,
'ref',
'ref', $morehtmlref);
479 print
'<div class="fichecenter">';
480 print
'<div class="underbanner clearboth"></div>';
482 print
'<table class="border tableforfield centpercent">';
485 if ($typeobject ==
'commande' &&
$object->origin_object->id && isModEnabled(
'order')) {
487 print $langs->trans(
"RefOrder").
'</td>';
488 print
'<td colspan="3">';
489 print $objectsrc->getNomUrl(1,
'commande');
493 if ($typeobject ==
'propal' &&
$object->origin_object->id && isModEnabled(
"propal")) {
495 print $langs->trans(
"RefProposal").
'</td>';
496 print
'<td colspan="3">';
497 print $objectsrc->getNomUrl(1,
'expedition');
503 print
'<tr><td class="titlefield">'.$langs->trans(
"DateCreation").
'</td>';
504 print
'<td colspan="3">'.dol_print_date(
$object->date_creation,
"dayhour",
"tzuserrel").
"</td>\n";
508 print
'<tr><td height="10">';
509 print
'<table class="nobordernopadding" width="100%"><tr><td>';
510 print $langs->trans(
'DateDeliveryPlanned');
512 if ($action !=
'editdate_livraison') {
513 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>';
515 print
'</tr></table>';
516 print
'</td><td colspan="2">';
517 if ($action ==
'editdate_livraison') {
518 print
'<form name="setdate_livraison" action="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'" method="post">';
519 print
'<input type="hidden" name="token" value="'.newToken().
'">';
520 print
'<input type="hidden" name="action" value="setdate_livraison">';
521 print $form->selectDate(
$object->date_delivery ?
$object->date_delivery : -1,
'liv_', 1, 1, 0,
"setdate_livraison", 1, 0);
522 print
'<input type="submit" class="button button-edit smallpaddingimp" value="'.$langs->trans(
'Modify').
'">';
528 print
'</tr></table>';
530 print
'<br><br><center>';
531 if (isModEnabled(
'barcode') || isModEnabled(
'productbatch')) {
532 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=updatebyscaning&token='.
currentToken().
'" class="marginrightonly paddingright marginleftonly paddingleft">'.
img_picto(
'',
'barcode',
'class="paddingrightonly"').$langs->trans(
"UpdateByScaning").
'</a>';
534 print
'<a href="#" id="resetalltoexpected" class="marginrightonly paddingright marginleftonly paddingleft">'.img_picto(
"",
'autofill',
'class="pictofixedwidth"').$langs->trans(
"RestoreWithCurrentQtySaved").
'</a></td>';
536 print
'<a href="#" id="autoreset" class="marginrightonly paddingright marginleftonly paddingleft">'.img_picto(
"",
'eraser',
'class="pictofixedwidth"').$langs->trans(
"ClearQtys").
'</a></td>';
543 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
545 $formproduct->loadWarehouses();
547 $listwarehouses = $entrepot->list_array(1);
550 print
'<form method="post" action="'.$_SERVER[
"PHP_SELF"].
'">';
552 print
'<input type="hidden" name="token" value="'.newToken().
'">';
553 print
'<input type="hidden" name="action" value="updatelines">';
554 print
'<input type="hidden" name="id" value="'.$object->id.
'">';
556 print
'<div class="div-table-responsive-no-min">';
557 print
'<table class="noborder centpercent">';
560 $products_dispatched = array();
561 $sql =
"SELECT ed.fk_elementdet as rowid, sum(ed.qty) as qty";
562 $sql .=
" FROM ".MAIN_DB_PREFIX.
"expeditiondet as ed";
563 $sql .=
" WHERE ed.fk_expedition = ".((int)
$object->id);
564 $sql .=
" GROUP BY ed.fk_elementdet";
566 $resql = $db->query($sql);
568 $num = $db->num_rows($resql);
573 $objd = $db->fetch_object($resql);
574 $products_dispatched[$objd->rowid] =
price2num($objd->qty,
'MS');
582 $sql =
"SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, '' AS sref, l.qty as qty,";
583 $sql .=
" p.ref, p.label, p.tobatch, p.fk_default_warehouse, p.barcode";
585 $parameters = array();
586 $reshook = $hookmanager->executeHooks(
587 'printFieldListSelect',
595 $sql .= $hookmanager->resPrint;
597 $sql .=
" FROM ".MAIN_DB_PREFIX.
"commandedet as l";
598 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"product as p ON l.fk_product=p.rowid";
599 $sql .=
" WHERE l.fk_commande = ".((int) $objectsrc->id);
601 $sql .=
" AND l.product_type = 0";
604 $parameters = array();
605 $reshook = $hookmanager->executeHooks(
606 'printFieldListWhere',
614 $sql .= $hookmanager->resPrint;
617 $sql .=
" ORDER BY l.rang, p.ref, p.label";
619 $resql = $db->query($sql);
621 $num = $db->num_rows($resql);
626 print
'<tr class="liste_titre">';
628 print
'<td>'.$langs->trans(
"Description").
'</td>';
629 if (isModEnabled(
'productbatch')) {
630 print
'<td class="dispatch_batch_number_title">'.$langs->trans(
"batch_number").
'</td>';
632 print
'<td class="dispatch_dlc_title">'.$langs->trans(
"SellByDate").
'</td>';
635 print
'<td class="dispatch_dluo_title">'.$langs->trans(
"EatByDate").
'</td>';
642 print
'<td class="right">'.$langs->trans(
"QtyOrdered").
'</td>';
644 print
'<td class="right">'.$langs->trans(
"QtyToShip");
646 print
'<td class="right">'.$langs->trans(
"QtyDispatchedShort").
'</td>';
648 print
'<td class="right">'.$langs->trans(
"Details");
649 print
'<td width="32"></td>';
652 if (!isModEnabled(
"multicurrency") && empty(
$conf->dynamicprices->enabled)) {
653 print
'<td class="right">'.$langs->trans(
"Price").
'</td>';
654 print
'<td class="right">'.$langs->trans(
"ReductionShort").
' (%)</td>';
655 print
'<td class="right">'.$langs->trans(
"UpdatePrice").
'</td>';
659 print
'<td align="right">'.$langs->trans(
"Warehouse");
662 if (count($listwarehouses) > 1) {
663 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);
664 } elseif (count($listwarehouses) == 1) {
665 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);
671 $parameters = array();
672 $reshook = $hookmanager->executeHooks(
673 'printFieldListTitle',
681 print $hookmanager->resPrint;
690 $conf->cache[
'product'] = array();
694 $objp = $db->fetch_object($resql);
697 if (!$objp->fk_product > 0) {
700 $alreadydispatched = isset($products_dispatched[$objp->rowid]) ? $products_dispatched[$objp->rowid] : 0;
701 $remaintodispatch =
price2num($objp->qty, 5);
702 if ($remaintodispatch < 0 && !
getDolGlobalString(
'SUPPLIER_ORDER_ALLOW_NEGATIVE_QTY_FOR_SUPPLIER_ORDER_RETURN')) {
703 $remaintodispatch = 0;
706 if ($remaintodispatch || !
getDolGlobalString(
'SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED')) {
715 print
'<!-- Line to dispatch '.$suffix.
' -->'.
"\n";
717 print
'<input id="qty_ordered'.$suffix.
'" type="hidden" value="'.$objp->qty.
'">';
718 print
'<input id="qty_dispatched'.$suffix.
'" type="hidden" data-dispatched="'.((float) $alreadydispatched).
'" value="'.(float) $alreadydispatched.
'">';
719 print
'<tr class="oddeven">';
721 if (empty(
$conf->cache[
'product'][$objp->fk_product])) {
722 $tmpproduct =
new Product($db);
723 $tmpproduct->fetch($objp->fk_product);
724 $conf->cache[
'product'][$objp->fk_product] = $tmpproduct;
726 $tmpproduct =
$conf->cache[
'product'][$objp->fk_product];
729 $linktoprod = $tmpproduct->getNomUrl(1);
730 $linktoprod .=
' - '.$objp->label.
"\n";
732 if (isModEnabled(
'productbatch')) {
733 if ($objp->tobatch) {
735 print
'<td id="product_'.$i.
'" data-idproduct="'.$objp->fk_product.
'" data-barcode="'.$objp->barcode.
'">';
738 print
'<td class="dispatch_batch_number"></td>';
740 print
'<td class="dispatch_dlc"></td>';
743 print
'<td class="dispatch_dluo"></td>';
747 print
'<td id="product_'.$i.
'" data-idproduct="'.$objp->fk_product.
'" data-barcode="'.$objp->barcode.
'">';
750 print
'<td class="dispatch_batch_number">';
751 print
'<span class="opacitymedium small">'.$langs->trans(
"ProductDoesNotUseBatchSerial").
'</span>';
754 print
'<td class="dispatch_dlc"></td>';
757 print
'<td class="dispatch_dluo"></td>';
761 print
'<td colspan="4">';
767 $up_ht_disc = $objp->subprice;
768 if (!empty($objp->remise_percent) && !
getDolGlobalString(
'STOCK_EXCLUDE_DISCOUNT_FOR_PMP')) {
769 $up_ht_disc =
price2num($up_ht_disc * (100 - $objp->remise_percent) / 100,
'MU');
773 print
'<td class="right">'.$objp->qty.
'</td>';
776 print
'<td class="right">'.$alreadydispatched.
'</td>';
778 print
'<td class="right">';
784 $sql =
"SELECT ed.rowid";
785 $sql .=
", cd.fk_product";
786 $sql .=
", ".$db->ifsql(
'eb.rowid IS NULL',
'ed.qty',
'eb.qty').
" as qty";
787 $sql .=
", ed.fk_entrepot";
788 $sql .=
", eb.batch, eb.eatby, eb.sellby";
789 $sql .=
" FROM ".$db->prefix().
"expeditiondet as ed";
790 $sql .=
" LEFT JOIN ".$db->prefix().
"expeditiondet_batch as eb on ed.rowid = eb.fk_expeditiondet";
791 $sql .=
" INNER JOIN ".$db->prefix().
"commandedet as cd on ed.fk_elementdet = cd.rowid";
792 $sql .=
" WHERE ed.fk_elementdet = ".(int) $objp->rowid;
793 $sql .=
" AND ed.fk_expedition = ".(int)
$object->id;
794 $sql .=
" ORDER BY ed.rowid, ed.fk_elementdet";
796 $resultsql = $db->query($sql);
799 $numd = $db->num_rows($resultsql);
802 $suffix =
"_".$j.
"_".$i;
803 $objd = $db->fetch_object($resultsql);
805 if (isModEnabled(
'productbatch') && (!empty($objd->batch) || (is_null($objd->batch) && $tmpproduct->status_batch > 0))) {
811 'is_information_row' =>
true,
816 $reshook = $hookmanager->executeHooks(
817 'printFieldListValue',
825 print $hookmanager->resPrint;
829 print
'<!-- line for batch '.$numline.
' -->';
830 print
'<tr class="oddeven autoresettr" name="'.$type.$suffix.
'" data-remove="clear">';
832 print
'<input id="fk_commandedet'.$suffix.
'" name="fk_commandedet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
833 print
'<input id="idline'.$suffix.
'" name="idline'.$suffix.
'" type="hidden" value="'.$objd->rowid.
'">';
834 print
'<input name="product_batch'.$suffix.
'" type="hidden" value="'.$objd->fk_product.
'">';
836 print
'<!-- This is a U.P. (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
837 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
842 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).
'">';
846 print
'<td class="nowraponall">';
848 print $form->selectDate($dlcdatesuffix,
'dlc'.$suffix, 0, 0, 1,
'');
852 print
'<td class="nowraponall">';
854 print $form->selectDate($dluodatesuffix,
'dluo'.$suffix, 0, 0, 1,
'');
857 print
'<td colspan="2"> </td>';
867 'is_information_row' =>
true,
872 $reshook = $hookmanager->executeHooks(
873 'printFieldListValue',
881 print $hookmanager->resPrint;
885 print
'<!-- line no batch '.$numline.
' -->';
886 print
'<tr class="oddeven autoresettr" name="'.$type.$suffix.
'" data-remove="clear">';
887 print
'<td colspan="'.$colspan.
'">';
888 print
'<input id="fk_commandedet'.$suffix.
'" name="fk_commandedet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
889 print
'<input id="idline'.$suffix.
'" name="idline'.$suffix.
'" type="hidden" value="'.$objd->rowid.
'">';
890 print
'<input name="product'.$suffix.
'" type="hidden" value="'.$objd->fk_product.
'">';
891 print
'<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
892 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
896 print
'<td class="right nowraponall">';
897 print
'<a href="" id="reset'.$suffix.
'" class="resetline">'.
img_picto($langs->trans(
"Reset"),
'eraser',
'class="pictofixedwidth opacitymedium"').
'</a>';
898 $suggestedvalue = (GETPOSTISSET(
'qty'.$suffix) ?
GETPOSTINT(
'qty'.$suffix) : $objd->qty);
900 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.
'">';
903 if (isModEnabled(
'productbatch') && $objp->tobatch > 0) {
905 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" '.($numd != $j + 1 ?
'style="display:none"' :
'').
' onClick="addDispatchLine('.$i.
', \''.$type.
'\')"');
908 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" '.($numd != $j + 1 ?
'style="display:none"' :
'').
' onClick="addDispatchLine('.$i.
', \''.$type.
'\')"');
914 print
'<td class="right">';
915 if (count($listwarehouses) > 1) {
916 print $formproduct->selectWarehouses(
GETPOST(
"entrepot".$suffix) ?
GETPOST(
"entrepot".$suffix) : $objd->fk_entrepot,
"entrepot".$suffix,
'', 1, 0, $objp->fk_product,
'', 1, 0, array(),
'csswarehouse'.$suffix);
917 } elseif (count($listwarehouses) == 1) {
918 print $formproduct->selectWarehouses(
GETPOST(
"entrepot".$suffix) ?
GETPOST(
"entrepot".$suffix) : $objd->fk_entrepot,
"entrepot".$suffix,
'', 0, 0, $objp->fk_product,
'', 1, 0, array(),
'csswarehouse'.$suffix);
920 $langs->load(
"errors");
921 print $langs->trans(
"ErrorNoWarehouseDefined");
927 'is_information_row' =>
false,
932 $reshook = $hookmanager->executeHooks(
933 'printFieldListValue',
941 print $hookmanager->resPrint;
948 $suffix =
"_".$j.
"_".$i;
950 $errorMsg =
'Shipment dispatch SQL error : '.$db->lasterror();
956 if (isModEnabled(
'productbatch') && !empty($objp->tobatch)) {
962 'is_information_row' =>
true,
967 $reshook = $hookmanager->executeHooks(
968 'printFieldListValue',
976 print $hookmanager->resPrint;
980 print
'<!-- line for batch '.$numline.
' (not dispatched line yet for this order line) -->';
981 print
'<tr class="oddeven autoresettr" name="'.$type.$suffix.
'" data-remove="clear">';
983 print
'<input id="fk_commandedet'.$suffix.
'" name="fk_commandedet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
984 print
'<input id="idline'.$suffix.
'" name="idline'.$suffix.
'" type="hidden" value="-1">';
985 print
'<input name="product_batch'.$suffix.
'" type="hidden" value="'.$objp->fk_product.
'">';
987 print
'<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
988 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
992 print
'<input type="text" class="inputlotnumber quatrevingtquinzepercent" id="lot_number'.$suffix.
'" name="lot_number'.$suffix.
'" value="'.
GETPOST(
'lot_number'.$suffix).
'">';
995 print
'<td class="nowraponall">';
997 print $form->selectDate($dlcdatesuffix,
'dlc'.$suffix, 0, 0, 1,
'');
1001 print
'<td class="nowraponall">';
1003 print $form->selectDate($dluodatesuffix,
'dluo'.$suffix, 0, 0, 1,
'');
1006 print
'<td colspan="2"> </td>';
1014 $parameters = array(
1016 'is_information_row' =>
true,
1018 'suffix' => $suffix,
1021 $reshook = $hookmanager->executeHooks(
1022 'printFieldListValue',
1030 print $hookmanager->resPrint;
1034 print
'<!-- line no batch '.$numline.
' (not dispatched line yet for this order line) -->';
1035 print
'<tr class="oddeven autoresettr" name="'.$type.$suffix.
'" data-remove="clear">';
1036 print
'<td colspan="'.$colspan.
'">';
1037 print
'<input id="fk_commandedet'.$suffix.
'" name="fk_commandedet'.$suffix.
'" type="hidden" value="'.$objp->rowid.
'">';
1038 print
'<input id="idline'.$suffix.
'" name="idline'.$suffix.
'" type="hidden" value="-1">';
1039 print
'<input name="product'.$suffix.
'" type="hidden" value="'.$objp->fk_product.
'">';
1041 print
'<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
1042 print
'<input class="maxwidth75" name="pu'.$suffix.
'" type="hidden" value="'.
price2num($up_ht_disc,
'MU').
'">';
1046 print
'<td class="right">';
1047 print
'<a href="" id="reset'.$suffix.
'" class="resetline">'.
img_picto($langs->trans(
"Reset"),
'eraser',
'class="pictofixedwidth opacitymedium"').
'</a>';
1048 $amounttosuggest = (GETPOSTISSET(
'qty'.$suffix) ?
GETPOSTINT(
'qty'.$suffix) : (!
getDolGlobalString(
'SUPPLIER_ORDER_DISPATCH_FORCE_QTY_INPUT_TO_ZERO') ? $remaintodispatch : 0));
1049 if (count($products_dispatched)) {
1052 $amounttosuggest = (GETPOSTISSET(
'qty'.$suffix) ?
GETPOSTINT(
'qty'.$suffix) : (isset($products_dispatched[$objp->rowid]) ? $products_dispatched[$objp->rowid] :
''));
1054 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.
'">';
1057 if (isModEnabled(
'productbatch') && $objp->tobatch > 0) {
1059 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" onClick="addDispatchLine('.$i.
', \''.$type.
'\')
"');
1062 print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton
" onClick="addDispatchLine(
'.$i.', \
''.$type.
'\')
"');
1068 print '<td class="right
">';
1069 if (count($listwarehouses) > 1) {
1070 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, array(), 'csswarehouse'.$suffix);
1071 } elseif (count($listwarehouses) == 1) {
1072 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, array(), 'csswarehouse'.$suffix);
1074 $langs->load("errors
");
1075 print $langs->trans("ErrorNoWarehouseDefined
");
1079 // Enable hooks to append additional columns
1080 $parameters = array(
1081 'is_information_row' => false, // this is a dispatch form row
1083 'suffix' => $suffix,
1086 $reshook = $hookmanager->executeHooks(
1087 'printFieldListValue',
1093 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1095 print $hookmanager->resPrint;
1104 dol_print_error($db);
1111 //$checkboxlabel = $langs->trans("CloseReceivedSupplierOrdersAutomatically
", $langs->transnoentitiesnoconv('StatusOrderReceivedAll'));
1113 print '<div class="center
">';
1114 $parameters = array();
1115 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1117 if (empty($reshook)) {
1118 /*if (empty($conf->reception->enabled)) {
1119 print $langs->trans("Comment").' : ';
1120 print '<input type="text
" class="minwidth400
" maxlength="128
" name="comment
" value="';
1121 print GETPOSTISSET("comment") ? GETPOST("comment") : $langs->trans("DispatchSupplierOrder", $object->ref);
1122 // print ' /
'.$object->ref_supplier; // Not yet available
1123 print '" class="flat
"><br>';
1125 print '<input type="checkbox
" checked="checked
" name="closeopenorder
"> '.$checkboxlabel;
1128 $dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive
") : $langs->trans("CreateReception
");
1133 print '<input type="submit
" id="submitform
" class="button" name="dispatch
" value="'.$langs->trans("Save").'"';
1135 if (!$usercancreate) {
1138 if (count($listwarehouses) <= 0) {
1150 // Message if nothing to dispatch
1153 if (!getDolGlobalString('SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED')) {
1154 print '<div class="opacitymedium
">'.$langs->trans("NoPredefinedProductToDispatch
").'</div>'; // No predefined line at all
1156 print '<div class="opacitymedium
">'.$langs->trans("NoMorePredefinedProductToDispatch
").'</div>'; // No predefined line that remain to be dispatched.
1163 print dol_get_fiche_end();
1165 // Popup for mass barcode scanning
1166 if ($action == 'updatebyscaning') {
1167 if ($permissiontoadd) {
1168 // Output the javascript to manage the scanner tool.
1172 var duplicatedbatchcode = [];
1178 function barcodescannerjs(){
1179 console.log("We
catch inputs in scanner box
");
1180 jQuery("#scantoolmessage
").text();
1182 var selectaddorreplace = $("select[
name=selectaddorreplace]
").val();
1183 var barcodemode = $("input[
name=barcodemode]:checked
").val();
1184 var barcodeproductqty = $("input[
name=barcodeproductqty]
").val();
1185 var warehousetouse = $("select[
name=warehousenew]
").val();
1186 var textarea = $("textarea[
name=barcodelist]
").val();
1187 var textarray = textarea.split(/[\s,;]+/);
1188 var tabproduct = [];
1189 duplicatedbatchcode = [];
1195 textarray = textarray.filter(function(value){
1198 if(textarray.some((element) => element != "")){
1199 $(".qtydispatchinput
").each(function(){
1200 id = $(this).attr(\'id\');
1201 idarray = id.split(\'_\');
1202 idproduct = idarray[2];
1203 id = idarray[1] + \'_\' + idarray[2];
1204 console.log("Analyze the line
"+id+" in inventory, barcodemode=
"+barcodemode);
1205 warehouse = $("#entrepot_
"+id).val();
1206 console.log(warehouse);
1207 productbarcode = $("#product_
"+idproduct).attr(\'data-barcode\');
1208 console.log(productbarcode);
1209 productbatchcode = $("#lot_number_
"+id).val();
1210 if(productbatchcode == undefined){
1211 productbatchcode = "";
1213 console.log(productbatchcode);
1215 if (barcodemode != "barcodeforproduct
") {
1216 tabproduct.forEach(product=>{
1217 console.log("product.Batch=
"+product.Batch+" productbatchcode=
"+productbatchcode);
1218 if(product.Batch != "" && product.Batch == productbatchcode){
1219 console.log("duplicate batch code found
for batch code
"+productbatchcode);
1220 duplicatedbatchcode.push(productbatchcode);
1224 productinput = $("#qty_
"+id).val();
1225 if(productinput == ""){
1228 tabproduct.push({\'Id\':id,\'Warehouse\':warehouse,\'Barcode\':productbarcode,\'Batch\':productbatchcode,\'Qty\':productinput,\'fetched\':false});
1230 console.log("Loop on each record entered in the textarea
");
1232 textarray.forEach(function(element,index){
1233 console.log("Process record element=
"+element+" id=
"+id);
1234 var verify_batch = false;
1235 var verify_barcode = false;
1236 switch(barcodemode){
1237 case "barcodeforautodetect
":
1238 verify_barcode = barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,warehousetouse,selectaddorreplace,"barcode
",true);
1239 verify_batch = barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,warehousetouse,selectaddorreplace,"lotserial
",true);
1241 case "barcodeforproduct
":
1242 verify_barcode = barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,warehousetouse,selectaddorreplace,"barcode
");
1244 case "barcodeforlotserial
":
1245 verify_batch = barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,warehousetouse,selectaddorreplace,"lotserial
");
1248 alert(\''.dol_escape_js($langs->trans("ErrorWrongBarcodemode
")).' "\
'+barcodemode+\'"\');
1249 throw \''.dol_escape_js($langs->trans(
'ErrorWrongBarcodemode')).
' "\'+barcodemode+\'"\';
1252 if (verify_batch == false && verify_barcode == false) { /* If the 2 flags are false, not found error */
1253 errortab2.push(element);
1254 } else if (verify_batch == true && verify_barcode == true) { /* If the 2 flags are true, error: we don t know which one to take */
1255 errortab3.push(element);
1256 } else if (verify_batch == true) {
1257 console.log("element="+element);
1258 console.log(duplicatedbatchcode);
1259 if (duplicatedbatchcode.includes(element)) {
1260 errortab1.push(element);
1265 if (Object.keys(errortab1).length < 1 && Object.keys(errortab2).length < 1 && Object.keys(errortab3).length < 1) {
1266 tabproduct.forEach(product => {
1268 if(product.hasOwnProperty("reelqty")){
1269 idprod = $("td[data-idproduct=\'"+product.fk_product+"\']").attr("id");
1270 idproduct = idprod.split("_")[1];
1271 console.log("We create a new line for product_"+idproduct);
1272 if(product.Barcode != null){
1273 modedispatch = "dispatch";
1275 modedispatch = "batch";
1277 addDispatchLine(idproduct,modedispatch);
1278 console.log($("tr[name^=\'"+modedispatch+"_\'][name$=\'_"+idproduct+"\']"));
1279 nbrTrs = $("tr[name^=\'"+modedispatch+"_\'][name$=\'_"+idproduct+"\']").length;
1281 $("#qty_"+(nbrTrs-1)+"_"+idproduct).val(product.Qty);
1282 $("#entrepot_"+(nbrTrs-1)+"_"+idproduct).val(product.Warehouse);
1284 if(modedispatch == "batch"){
1285 $("#lot_number_"+(nbrTrs-1)+"_"+idproduct).val(product.Batch);
1289 console.log("We change #qty_"+product.Id +" to match input in scanner box");
1290 $("#qty_"+product.Id).val(product.Qty);
1294 jQuery("#scantoolmessage").text("'.
dol_escape_js($langs->transnoentities(
"QtyWasAddedToTheScannedBarcode")).
'\n");
1295 /* document.forms["formrecord"].submit(); */
1297 let stringerror = "";
1298 if (Object.keys(errortab1).length > 0) {
1299 stringerror += "<br>'.
dol_escape_js($langs->transnoentities(
'ErrorSameBatchNumber')).
': ";
1300 errortab1.forEach(element => {
1301 stringerror += (element + ", ")
1303 stringerror = stringerror.slice(0, -2); /* Remove last ", " */
1305 if (Object.keys(errortab2).length > 0) {
1306 stringerror += "<br>'.
dol_escape_js($langs->transnoentities(
'ErrorCantFindCodeInInventory')).
': ";
1307 errortab2.forEach(element => {
1308 stringerror += (element + ", ")
1310 stringerror = stringerror.slice(0, -2); /* Remove last ", " */
1312 if (Object.keys(errortab3).length > 0) {
1313 stringerror += "<br>'.
dol_escape_js($langs->transnoentities(
'ErrorCodeScannedIsBothProductAndSerial')).
': ";
1314 errortab3.forEach(element => {
1315 stringerror += (element + ", ")
1317 stringerror = stringerror.slice(0, -2); /* Remove last ", " */
1319 if (Object.keys(errortab4).length > 0) {
1320 stringerror += "<br>'.
dol_escape_js($langs->transnoentities(
'ErrorBarcodeNotFoundForProductWarehouse')).
': ";
1321 errortab4.forEach(element => {
1322 stringerror += (element + ", ")
1324 stringerror = stringerror.slice(0, -2); /* Remove last ", " */
1327 jQuery("#scantoolmessage").html(\''.
dol_escape_js($langs->transnoentities(
"ErrorOnElementsInventory")).
'\' + stringerror);
1335 function barcodeserialforproduct(tabproduct,index,element,barcodeproductqty,warehousetouse,selectaddorreplace,mode,autodetect=
false){
1336 BarcodeIsInProduct=0;
1339 tabproduct.forEach(product => {
1340 $.ajax({ url: \
''.DOL_URL_ROOT.
'/expedition/ajax/searchfrombarcode.php\',
1341 data: { "token":"'.
newToken().
'", "action":"existbarcode","fk_entrepot": warehousetouse, "barcode":element, "mode":mode},
1344 success: function(response) {
1345 if (response.status == "success"){
1346 console.log(response.message);
1348 newproductrow = response.object;
1351 if (mode!="lotserial" && autodetect==false && !errortab4.includes(element)){
1352 errortab4.push(element);
1353 console.error(response.message);
1357 error : function(output) {
1358 console.error("Error on barcodeserialforproduct function");
1361 console.log("Product "+(index+=1)+": "+element);
1362 if(mode == "barcode"){
1363 testonproduct = product.Barcode
1364 }else if (mode == "lotserial"){
1365 testonproduct = product.Batch
1367 testonwarehouse = product.Warehouse;
1368 if(testonproduct == element && testonwarehouse == warehousetouse){
1369 if(selectaddorreplace == "add"){
1370 productqty = parseInt(product.Qty,10);
1371 product.Qty = productqty + parseInt(barcodeproductqty,10);
1372 }else if(selectaddorreplace == "replace"){
1373 if(product.fetched == false){
1374 product.Qty = barcodeproductqty
1375 product.fetched=true
1377 productqty = parseInt(product.Qty,10);
1378 product.Qty = productqty + parseInt(barcodeproductqty,10);
1381 BarcodeIsInProduct+=1;
1384 if(BarcodeIsInProduct==0 && newproductrow!=0){
1385 tabproduct.push({\'Id\':tabproduct.length-1,\'Warehouse\':newproductrow.fk_warehouse,\'Barcode\':mode=="barcode"?element:null,\'Batch\':mode=="lotserial"?element:null,\'Qty\':barcodeproductqty,\'fetched\':true,\'reelqty\':newproductrow.reelqty,\'fk_product\':newproductrow.fk_product,\'mode\':mode});
1388 if(BarcodeIsInProduct > 0){
1396 include DOL_DOCUMENT_ROOT.
'/core/class/html.formother.class.php';
1398 print $formother->getHTMLScannerForm(
"barcodescannerjs",
'all', 1);
1402 print
'<script type="text/javascript">
1403 $(document).ready(function () {
1404 $("select[name=fk_default_warehouse]").change(function() {
1405 console.log("warehouse is modified");
1406 var fk_default_warehouse = $("option:selected", this).val();
1407 $("select[name^=entrepot_]").val(fk_default_warehouse).change();
1410 $("#autoreset").click(function() {
1411 console.log("we click on autoreset");
1412 $(".autoresettr").each(function(){
1413 id = $(this).attr("name");
1414 idtab = id.split("_");
1415 console.log("we process line "+id+" "+idtab);
1416 if ($(this).data("remove") == "clear") { /* data-remove=clear means that line qty must be cleared but line must not be removed */
1417 console.log("We clear the object to expected value")
1418 $("#qty_"+idtab[1]+"_"+idtab[2]).val("");
1420 qtyexpected = $("#qty_"+idtab[1]+"_"+idtab[2]).data("expected")
1421 console.log(qtyexpected);
1422 $("#qty_"+idtab[1]+"_"+idtab[2]).val(qtyexpected);
1423 qtydispatched = $("#qty_dispatched_0_"+idtab[2]).data("dispatched")
1424 $("#qty_dispatched_0_"+idtab[2]).val(qtydispatched);
1426 } else { /* data-remove=remove means that line must be removed */
1427 console.log("We remove the object")
1429 $("tr[name^=\'"+idtab[0]+"_\'][name$=\'_"+idtab[2]+"\']:last .splitbutton").show();
1435 $("#resetalltoexpected").click(function(){
1436 $(".qtydispatchinput").each(function(){
1437 console.log("We reset to expected "+$(this).attr("id")+" qty to dispatch");
1438 $(this).val($(this).data("expected"));
1443 $(".resetline").on("click", function(event) {
1444 event.preventDefault();
1445 id = $(this).attr("id");
1446 id = id.split("reset_");
1447 console.log("Reset trigger for id = qty_"+id[1]);
1448 $("#qty_"+id[1]).val("");
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Class to manage customers orders.
Class to manage warehouses.
const STATUS_DRAFT
Draft status.
Class 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_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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 '.
currentToken()
Return the value of token currently saved into session with name 'token'.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0, $attop=0)
Set event message in dol_events session object.
dol_now($mode='auto')
Return date for now.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='')
Return the value of a $_GET or $_POST supervariable, converted into float.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
treeview li table
No Email.
ui state ui widget content ui state ui widget header ui state a ui button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
$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.