From ca815ff9c6e03be4869e06f6b1306f44b535fb23 Mon Sep 17 00:00:00 2001 From: hystepik Date: Thu, 27 Apr 2023 14:56:27 +0200 Subject: [PATCH] working dispatchcard reception --- htdocs/core/lib/reception.lib.php | 7 + .../class/fournisseur.commande.class.php | 7 +- htdocs/fourn/js/lib_dispatch.js.php | 123 +- htdocs/langs/en_US/receptions.lang | 4 +- htdocs/reception/dispatch.php | 1135 +++++++++++++++++ 5 files changed, 1213 insertions(+), 63 deletions(-) create mode 100644 htdocs/reception/dispatch.php diff --git a/htdocs/core/lib/reception.lib.php b/htdocs/core/lib/reception.lib.php index e697908e8cb..16e036991f9 100644 --- a/htdocs/core/lib/reception.lib.php +++ b/htdocs/core/lib/reception.lib.php @@ -46,6 +46,13 @@ function reception_prepare_head(Reception $object) $head[$h][2] = 'reception'; $h++; + if ($object->statut == Reception::STATUS_DRAFT) { + $head[$h][0] = DOL_URL_ROOT."/reception/dispatch.php?id=".$object->id; + $head[$h][1] = $langs->trans("DispatchCard"); + $head[$h][2] = 'dispatch'; + $h++; + } + if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) { $objectsrc = $object; if ($object->origin == 'supplier_order' && $object->origin_id > 0) { diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index e3f8e3c5f81..738b7eb3dc2 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2110,9 +2110,10 @@ class CommandeFournisseur extends CommonOrder * @param string $batch Lot number * @param int $fk_commandefourndet Id of supplier order line * @param int $notrigger 1 = notrigger + * @param int $fk_reception Id of reception to link * @return int <0 if KO, >0 if OK */ - public function dispatchProduct($user, $product, $qty, $entrepot, $price = 0, $comment = '', $eatby = '', $sellby = '', $batch = '', $fk_commandefourndet = 0, $notrigger = 0) + public function dispatchProduct($user, $product, $qty, $entrepot, $price = 0, $comment = '', $eatby = '', $sellby = '', $batch = '', $fk_commandefourndet = 0, $notrigger = 0, $fk_reception = 0) { global $conf, $langs; @@ -2142,9 +2143,9 @@ class CommandeFournisseur extends CommonOrder $this->db->begin(); $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseur_dispatch"; - $sql .= " (fk_commande, fk_product, qty, fk_entrepot, fk_user, datec, fk_commandefourndet, status, comment, eatby, sellby, batch) VALUES"; + $sql .= " (fk_commande, fk_product, qty, fk_entrepot, fk_user, datec, fk_commandefourndet, status, comment, eatby, sellby, batch, fk_reception) VALUES"; $sql .= " ('".$this->id."','".$product."','".$qty."',".($entrepot > 0 ? "'".$entrepot."'" : "null").",'".$user->id."','".$this->db->idate($now)."','".$fk_commandefourndet."', ".$dispatchstatus.", '".$this->db->escape($comment)."', "; - $sql .= ($eatby ? "'".$this->db->idate($eatby)."'" : "null").", ".($sellby ? "'".$this->db->idate($sellby)."'" : "null").", ".($batch ? "'".$this->db->escape($batch)."'" : "null"); + $sql .= ($eatby ? "'".$this->db->idate($eatby)."'" : "null").", ".($sellby ? "'".$this->db->idate($sellby)."'" : "null").", ".($batch ? "'".$this->db->escape($batch)."'" : "null").", ".($fk_reception > 0 ? "'".$fk_reception."'" : "null"); $sql .= ")"; dol_syslog(get_class($this)."::dispatchProduct", LOG_DEBUG); diff --git a/htdocs/fourn/js/lib_dispatch.js.php b/htdocs/fourn/js/lib_dispatch.js.php index 7d711d3a19a..44a4df1161e 100644 --- a/htdocs/fourn/js/lib_dispatch.js.php +++ b/htdocs/fourn/js/lib_dispatch.js.php @@ -65,39 +65,36 @@ if (empty($dolibarr_nocache)) { * @param type string type of dispatch (batch = batch dispatch, dispatch = non batch dispatch) * @param mode string 'qtymissing' will create new line with qty missing, 'lessone' will keep 1 in old line and the rest in new one */ -function addDispatchLine(index, type, mode) -{ +function addDispatchLine(index, type, mode) { mode = mode || 'qtymissing' - console.log("fourn/js/lib_dispatch.js.php Split line type="+type+" index="+index+" mode="+mode); - var $row0 = $("tr[name='"+type+'_0_'+index+"']"); + console.log("fourn/js/lib_dispatch.js.php Split line type=" + type + " index=" + index + " mode=" + mode); + var $row0 = $("tr[name='" + type + '_0_' + index + "']"); var $dpopt = $row0.find('.hasDatepicker').first().datepicker('option', 'all'); // get current datepicker options to apply the same to the cloned datepickers var $row = $row0.clone(true); // clone first batch line to jQuery object - var nbrTrs = $("tr[name^='"+type+"_'][name$='_"+index+"']").length; // position of line for batch - var qtyOrdered = parseFloat($("#qty_ordered_0_"+index).val()); // Qty ordered is same for all rows - var qty = parseFloat($("#qty_"+(nbrTrs - 1)+"_"+index).val()); - var qtyDispatched; + var nbrTrs = $("tr[name^='" + type + "_'][name$='_" + index + "']").length; // position of line for batch + var qtyOrdered = parseFloat($("#qty_ordered_0_" + index).val()); // Qty ordered is same for all rows + var qty = parseFloat($("#qty_" + (nbrTrs - 1) + "_" + index).val()); + var qtyDispatched; - if (mode === 'lessone') - { - qtyDispatched = parseFloat($("#qty_dispatched_0_"+index).val()) + 1; + if (mode === 'lessone') { + qtyDispatched = parseFloat($("#qty_dispatched_0_" + index).val()) + 1; } - else - { - qtyDispatched = parseFloat($("#qty_dispatched_0_"+index).val()) + qty; + else { + qtyDispatched = parseFloat($("#qty_dispatched_0_" + index).val()) + qty; // If user did not reduced the qty to dispatch on old line, we keep only 1 on old line and the rest on new line if (qtyDispatched == qtyOrdered && qtyDispatched > 1) { - qtyDispatched = parseFloat($("#qty_dispatched_0_"+index).val()) + 1; + qtyDispatched = parseFloat($("#qty_dispatched_0_" + index).val()) + 1; mode = 'lessone'; } } - console.log("qtyDispatched="+qtyDispatched+" qtyOrdered="+qtyOrdered); + console.log("qtyDispatched=" + qtyDispatched + " qtyOrdered=" + qtyOrdered); if (qtyDispatched >= qtyOrdered || qtyOrdered <= 1) { window.alert("Remain quantity to dispatch is too low to be split"); } else if (qtyDispatched < qtyOrdered) { //replace tr suffix nbr - $row.html($row.html().replace(/_0_/g,"_"+nbrTrs+"_")); + $row.html($row.html().replace(/_0_/g, "_" + nbrTrs + "_")); // jquery's deep clone is incompatible with date pickers (the clone shares data with the original) // so we destroy and rebuild the new date pickers @@ -111,57 +108,63 @@ function addDispatchLine(index, type, mode) }, 0); //create new select2 to avoid duplicate id of cloned one - $row.find("select[name='"+'entrepot_'+nbrTrs+'_'+index+"']").select2(); + $row.find("select[name='" + 'entrepot_' + nbrTrs + '_' + index + "']").select2(); // TODO find solution to copy selected option to new select // TODO find solution to keep new tr's after page refresh //clear value $row.find("input[name^='qty']").val(''); //change name of new row - $row.attr('name',type+'_'+nbrTrs+'_'+index); + $row.attr('name', type + '_' + nbrTrs + '_' + index); //insert new row before last row - $("tr[name^='"+type+"_'][name$='_"+index+"']:last").after($row); + $("tr[name^='" + type + "_'][name$='_" + index + "']:last").after($row); //remove cloned select2 with duplicate id. - $("#s2id_entrepot_"+nbrTrs+'_'+index).detach(); // old way to find duplicated select2 component - $(".csswarehouse_"+nbrTrs+"_"+index+":first-child").parent("span.selection").parent(".select2").detach(); + $("#s2id_entrepot_" + nbrTrs + '_' + index).detach(); // old way to find duplicated select2 component + $(".csswarehouse_" + nbrTrs + "_" + index + ":first-child").parent("span.selection").parent(".select2").detach(); /* Suffix of lines are: _ trs.length _ index */ - $("#qty_"+nbrTrs+"_"+index).focus(); - $("#qty_dispatched_0_"+index).val(qtyDispatched); + $("#qty_" + nbrTrs + "_" + index).focus(); + $("#qty_dispatched_0_" + index).val(qtyDispatched); //hide all buttons then show only the last one - $("tr[name^='"+type+"_'][name$='_"+index+"'] .splitbutton").hide(); - $("tr[name^='"+type+"_'][name$='_"+index+"']:last .splitbutton").show(); + $("tr[name^='" + type + "_'][name$='_" + index + "'] .splitbutton").hide(); + $("tr[name^='" + type + "_'][name$='_" + index + "']:last .splitbutton").show(); - $("#reset_"+(nbrTrs)+"_"+index).click(function(){ + $("#reset_" + (nbrTrs) + "_" + index).click(function () { id = $(this).attr("id"); id = id.split("reset_"); idrow = id[1]; - idlast = $("tr[name^='"+type+"_'][name$='_"+index+"']:last .qtydispatchinput").attr("id"); - if (idlast == $("#qty_"+idrow).attr("id")) { - console.log("Remove trigger for tr name = "+type+"_"+idrow); - $('tr[name="'+type+'_'+idrow+'"').remove(); - $("tr[name^='"+type+"_'][name$='_"+index+"']:last .splitbutton").show(); + idlast = $("tr[name^='" + type + "_'][name$='_" + index + "']:last .qtydispatchinput").attr("id"); + if (idlast == $("#qty_" + idrow).attr("id")) { + console.log("Remove trigger for tr name = " + type + "_" + idrow); + $('tr[name="' + type + '_' + idrow + '"').remove(); + $("tr[name^='" + type + "_'][name$='_" + index + "']:last .splitbutton").show(); } else { - console.log("Reset trigger for id = #qty_"+idrow); - $("#qty_"+idrow).val(""); + console.log("Reset trigger for id = #qty_" + idrow); + $("#qty_" + idrow).val(""); } - });; + }); - if (mode === 'lessone') - { - qty = 1; // keep 1 in old line - $("#qty_"+(nbrTrs-1)+"_"+index).val(qty); - } - $("#qty_"+nbrTrs+"_"+index).val(qtyOrdered - qtyDispatched); + if (mode === 'lessone') + { + qty = 1; // keep 1 in old line + $("#qty_"+(nbrTrs-1)+"_"+index).val(qty); + } + $("#qty_" + nbrTrs + "_" + index).val(qtyOrdered - qtyDispatched); // Store arbitrary data for dispatch qty input field change event - $("#qty_"+(nbrTrs-1)+"_"+index).data('qty', qty); - $("#qty_"+(nbrTrs-1)+"_"+index).data('type', type); - $("#qty_"+(nbrTrs-1)+"_"+index).data('index', index); + $("#qty_" + (nbrTrs - 1) + "_" + index).data('qty', qty); + $("#qty_" + (nbrTrs - 1) + "_" + index).data('type', type); + $("#qty_" + (nbrTrs - 1) + "_" + index).data('index', index); // Update dispatched qty when value dispatch qty input field changed - $("#qty_"+(nbrTrs-1)+"_"+index).change(this.onChangeDispatchLineQty); + //$("#qty_" + (nbrTrs - 1) + "_" + index).change(this.onChangeDispatchLineQty); //set focus on lot of new line (if it exists) - $("#lot_number_"+(nbrTrs)+"_"+index).focus(); + $("#lot_number_" + (nbrTrs) + "_" + index).focus(); + //Clean bad values + $("tr[name^='" + type + "_'][name$='_" + index + "']:last").data("remove", "remove"); + $("#lot_number_" + (nbrTrs) + "_" + index).val("") + $("#idline_" + (nbrTrs) + "_" + index).val("-1") + $("#qty_" + (nbrTrs) + "_" + index).data('expected', "0"); + $("#lot_number_" + (nbrTrs) + "_" + index).removeAttr("disabled"); } } @@ -175,26 +178,28 @@ function addDispatchLine(index, type, mode) * element requires arbitrary data qty (value before change), type (type of dispatch) and index (index of product line) */ -function onChangeDispatchLineQty() { - var index = $(this).data('index'), - type = $(this).data('type'), - qty = parseFloat($(this).data('qty')), +function onChangeDispatchLineQty(element) { + var type = $(element).data('type'), + qty = parseFloat($(element).data('expected')), changedQty, nbrTrs, dispatchingQty, qtyOrdered, qtyDispatched; + id = $(element).attr("id"); + id = id.split("_"); + index = id[2]; if (index >= 0 && type && qty >= 0) { - nbrTrs = $("tr[name^='"+type+"_'][name$='_"+index+"']").length; - qtyChanged = parseFloat($(this).val()) - qty; // qty changed - qtyDispatching = parseFloat($("#qty_"+(nbrTrs-1)+"_"+index).val()); // qty currently being dispatched - qtyOrdered = parseFloat($("#qty_ordered_0_"+index).val()); // qty ordered - qtyDispatched = parseFloat($("#qty_dispatched_0_"+index).val()); // qty already dispatched + nbrTrs = $("tr[name^='" + type + "_'][name$='_" + index + "']").length; + qtyChanged = parseFloat($(element).val()) - qty; // qty changed + qtyDispatching = parseFloat($(element).val()); // qty currently being dispatched + qtyOrdered = parseFloat($("#qty_ordered_0_" + index).val()); // qty ordered + qtyDispatched = parseFloat($("#qty_dispatched_0_" + index).val()); // qty already dispatched - console.log("onChangeDispatchLineQty qtyChanged: " + qtyChanged + " qtyDispatching: " + qtyDispatching + " qtyOrdered: " + qtyOrdered + " qtyDispatched: "+ qtyDispatched); + console.log("onChangeDispatchLineQty qtyChanged: " + qtyChanged + " qtyDispatching: " + qtyDispatching + " qtyOrdered: " + qtyOrdered + " qtyDispatched: " + qtyDispatched); if ((qtyChanged) <= (qtyOrdered - (qtyDispatched + qtyDispatching))) { - $("#qty_dispatched_0_"+index).val(qtyDispatched + qtyChanged); + $("#qty_dispatched_0_" + index).val(qtyDispatched + qtyChanged); } else { - $(this).val($(this).data('qty')); + $(element).val($(element).data('expected')); } - $(this).data('qty', $(this).val()); + $(element).data('expected', $(element).val()); } } diff --git a/htdocs/langs/en_US/receptions.lang b/htdocs/langs/en_US/receptions.lang index 7324f14f2e0..43f1512ecef 100644 --- a/htdocs/langs/en_US/receptions.lang +++ b/htdocs/langs/en_US/receptions.lang @@ -51,4 +51,6 @@ NoMorePredefinedProductToDispatch=No more predefined products to dispatch ReceptionExist=A reception exists ReceptionBackToDraftInDolibarr=Reception %s back to draft ReceptionClassifyClosedInDolibarr=Reception %s classified Closed -ReceptionUnClassifyCloseddInDolibarr=Reception %s re-open \ No newline at end of file +ReceptionUnClassifyCloseddInDolibarr=Reception %s re-open +ResetQtyToDispatch=Reset all quantities to dispatch +ReceptionUpdated=Reception sucessfully updated \ No newline at end of file diff --git a/htdocs/reception/dispatch.php b/htdocs/reception/dispatch.php new file mode 100644 index 00000000000..a9c6c91d675 --- /dev/null +++ b/htdocs/reception/dispatch.php @@ -0,0 +1,1135 @@ + + * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2005 Eric Seigne + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2010-2021 Juanjo Menent + * Copyright (C) 2014 Cedric Gross + * Copyright (C) 2016 Florian Henry + * Copyright (C) 2017-2022 Ferran Marcet + * Copyright (C) 2018-2022 Frédéric France + * Copyright (C) 2019-2020 Christophe Battarel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/fourn/commande/dispatch.php + * \ingroup commande + * \brief Page to dispatch receiving + */ + +// Load Dolibarr environment +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/reception.lib.php'; + + +if (isModEnabled('project')) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +} + +// Load translation files required by the page +$langs->loadLangs(array("bills", "orders", "sendings", "companies", "deliveries", "products", "stocks", "receptions")); + +if (isModEnabled('productbatch')) { + $langs->load('productbatch'); +} + + // Security check +$id = GETPOST("id", 'int'); +$ref = GETPOST('ref'); +$lineid = GETPOST('lineid', 'int'); +$action = GETPOST('action', 'aZ09'); +$fk_default_warehouse = GETPOST('fk_default_warehouse', 'int'); +$cancel = GETPOST('cancel', 'alpha'); +$confirm = GETPOST('confirm', 'alpha'); + +if ($user->socid) { + $socid = $user->socid; +} + +$hookmanager->initHooks(array('ordersupplierdispatch')); + +// Recuperation de l'id de projet +$projectid = 0; +if (GETPOSTISSET("projectid")) { + $projectid = GETPOST("projectid", 'int'); +} + +$object = new Reception($db); + +if ($id > 0 || !empty($ref)) { + $result = $object->fetch($id, $ref); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } + $result = $object->fetch_thirdparty(); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } + if (!empty($object->origin)) { + $origin = $object->origin; + + $object->fetch_origin(); + $typeobject = $object->origin; + } + if ($origin == 'order_supplier' && $object->$typeobject->id && (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || isModEnabled("supplier_order"))) { + $origin_id = $object->$typeobject->id; + $objectsrc = new CommandeFournisseur($db); + $objectsrc->fetch($object->$typeobject->id); + } +} + +if (empty($conf->reception->enabled)) { + $permissiontoreceive = $user->rights->fournisseur->commande->receptionner; + $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))); +} else { + $permissiontoreceive = $user->rights->reception->creer; + $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))); +} + +// $id is id of a purchase order. +$result = restrictedArea($user, 'fournisseur', $object, 'reception'); + +if (!isModEnabled('stock')) { + accessforbidden(); +} + +$usercancreate = $user->rights->reception->creer; +$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +// Update a dispatched line +if ($action == 'updatelines' && $permissiontoreceive) { + $db->begin(); + $error = 0; + + $supplierorderdispatch = new CommandeFournisseurDispatch($db); + $pos = 0; + + foreach ($_POST as $key => $value) { + // without batch module enabled + $reg = array(); + if (preg_match('/^product_.*([0-9]+)_([0-9]+)$/i', $key, $reg)) { + $pos++; + if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) { + $modebatch = "barcode"; + } elseif (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) { // With batchmode enabled + $modebatch = "batch"; + } + + $numline = $pos; + if ($modebatch == "barcode") { + $prod = "product_".$reg[1].'_'.$reg[2]; + } else { + $prod = 'product_batch_'.$reg[1].'_'.$reg[2]; + } + $qty = "qty_".$reg[1].'_'.$reg[2]; + $ent = "entrepot_".$reg[1].'_'.$reg[2]; + $pu = "pu_".$reg[1].'_'.$reg[2]; // This is unit price including discount + $fk_commandefourndet = "fk_commandefourndet_".$reg[1].'_'.$reg[2]; + $idline = GETPOST("idline_".$reg[1].'_'.$reg[2]); + $lot = ''; + $dDLUO = ''; + $dDLC = ''; + if ($modebatch == "batch") { + $lot = GETPOST('lot_number_'.$reg[1].'_'.$reg[2]); + $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')); + $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')); + } + + if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { + if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) { + $dto = GETPOST("dto_".$reg[1].'_'.$reg[2], 'int'); + if (!empty($dto)) { + $unit_price = price2num(GETPOST("pu_".$reg[1]) * (100 - $dto) / 100, 'MU'); + } + $saveprice = "saveprice_".$reg[1].'_'.$reg[2]; + } + } + + // We ask to move a qty + if (($modebatch == "batch" && GETPOST($qty) > 0) || ($modebatch == "barcode" && GETPOST($qty) != 0)) { + if (!(GETPOST($ent, 'int') > 0)) { + dol_syslog('No dispatch for line '.$key.' as no warehouse was chosen.'); + $text = $langs->transnoentities('Warehouse').', '.$langs->transnoentities('Line').' '.($numline); + setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors'); + $error++; + } + + if (!$error) { + if ($idline > 0) { + $result = $supplierorderdispatch->fetch($idline); + if ($result < 0) { + setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors'); + $error++; + } else { + $qtystart = $supplierorderdispatch->qty; + $supplierorderdispatch->qty = GETPOST($qty); + $supplierorderdispatch->fk_entrepot = GETPOST($ent, 'int'); + if ($modebatch == "batch") { + $supplierorderdispatch->eatby = $dDLUO; + $supplierorderdispatch->sellby = $dDLC; + } + + $result = $supplierorderdispatch->update($user); + if ($result < 0) { + setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors'); + $error++; + } + + // If module stock is enabled and the stock increase is done on purchase order dispatching + if (!$error && GETPOST($ent, 'int') > 0 && isModEnabled('stock') && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) { + $mouv = new MouvementStock($db); + $product = GETPOST($prod, 'int'); + $entrepot = GETPOST($ent, 'int'); + $qtymouv = GETPOST($qty) - $qtystart; + $price = GETPOST($pu); + $comment = GETPOST('comment'); + $inventorycode = dol_print_date(dol_now(), 'dayhourlog'); + $now = dol_now(); + $eatby = ''; + $sellby = ''; + $batch = ''; + if ($modebatch == "batch") { + $eatby = $dDLUO; + $sellby = $dDLC; + $batch = $supplierorderdispatch->batch; + } + if ($product > 0) { + // $price should take into account discount (except if option STOCK_EXCLUDE_DISCOUNT_FOR_PMP is on) + $mouv->origin = $objectsrc; + $mouv->setOrigin($objectsrc->element, $objectsrc->id); + + // Method change if qty < 0 + if (!empty($conf->global->SUPPLIER_ORDER_ALLOW_NEGATIVE_QTY_FOR_SUPPLIER_ORDER_RETURN) && $qtymouv < 0) { + $result = $mouv->livraison($user, $product, $entrepot, $qtymouv*(-1), $price, $comment, $now, $eatby, $sellby, $batch, 0, $inventorycode); + } else { + $result = $mouv->reception($user, $product, $entrepot, $qtymouv, $price, $comment, $eatby, $sellby, $batch, '', 0, $inventorycode); + } + + if ($result < 0) { + setEventMessages($mouv->error, $mouv->errors, 'errors'); + $error++; + } + } + } + } + } else { + $result = $objectsrc->dispatchProduct($user, GETPOST($prod, 'int'), GETPOST($qty), GETPOST($ent, 'int'), GETPOST($pu), GETPOST('comment'), $dDLUO, $dDLC, $lot, GETPOST($fk_commandefourndet, 'int'), 0, $object->id); + if ($result < 0) { + setEventMessages($objectsrc->error, $objectsrc->errors, 'errors'); + $error++; + } + } + + if (!$error && !empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { + if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) { + $dto = price2num(GETPOST("dto_".$reg[1].'_'.$reg[2], 'int'), ''); + if (empty($dto)) { + $dto = 0; + } + + //update supplier price + if (GETPOSTISSET($saveprice)) { + // TODO Use class + $sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price"; + $sql .= " SET unitprice='".price2num(GETPOST($pu), 'MU')."'"; + $sql .= ", price=".price2num(GETPOST($pu), 'MU')."*quantity"; + $sql .= ", remise_percent = ".((float) $dto); + $sql .= " WHERE fk_soc=".((int) $object->socid); + $sql .= " AND fk_product=".((int) GETPOST($prod, 'int')); + + $resql = $db->query($sql); + } + } + } + } + } + } + } + if ($error > 0) { + $db->rollback(); + setEventMessages($error, $errors, 'errors'); + } else { + $db->commit(); + setEventMessages($langs->trans("ReceptionUpdated"), null); + } +} + + +/* + * View + */ + +$now = dol_now(); + +$form = new Form($db); +$formproduct = new FormProduct($db); +$warehouse_static = new Entrepot($db); +$supplierorderdispatch = new CommandeFournisseurDispatch($db); + +$title = $object->ref." - ".$langs->trans('OrderDispatch'); +$help_url = 'EN:Module_Suppliers_Orders|FR:CommandeFournisseur|ES:Módulo_Pedidos_a_proveedores'; +$morejs = array('/fourn/js/lib_dispatch.js.php'); + +llxHeader('', $title, $help_url, '', 0, 0, $morejs); + +if ($id > 0 || !empty($ref)) { + if (!empty($object->origin) && $object->origin_id > 0) { + $object->origin = 'CommandeFournisseur'; + $typeobject = $object->origin; + $origin = $object->origin; + $origin_id = $object->origin_id; + $object->fetch_origin(); // Load property $object->commande, $object->propal, ... + } + $soc = new Societe($db); + $soc->fetch($object->socid); + + $author = new User($db); + $author->fetch($object->user_author_id); + + $head = reception_prepare_head($object); + + $title = $langs->trans("SupplierOrder"); + print dol_get_fiche_head($head, 'dispatch', $langs->trans("Reception"), -1, 'dollyrevert'); + + + $formconfirm = ''; + + // Confirmation to delete line + if ($action == 'ask_deleteline') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); + } + + // Call Hook formConfirm + $parameters = array('lineid' => $lineid); + // Note that $action and $object may be modified by hook + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; + + // Reception card + $linkback = ''.$langs->trans("BackToList").''; + $morehtmlref = '
'; + // Ref customer reception + + $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->rights->reception->creer, 'string', '', 0, 1); + $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->rights->reception->creer, 'string', '', null, null, '', 1); + + // Thirdparty + $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); + // Project + if (!empty($conf->project->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
'; + if (0) { // Do not change on reception + $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); + if ($action != 'classify' && $permissiontoadd) { + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; + } + $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'); + } else { + if (!empty($objectsrc) && !empty($objectsrc->fk_project)) { + $proj = new Project($db); + $proj->fetch($objectsrc->fk_project); + $morehtmlref .= $proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title).''; + } + } + } + } + $morehtmlref .= '
'; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
'; + print '
'; + + print ''; + + // Linked documents + if ($typeobject == 'commande' && $object->$typeobject->id && isModEnabled('commande')) { + print ''; + print '\n"; + print ''; + } + if ($typeobject == 'propal' && $object->$typeobject->id && isModEnabled("propal")) { + print ''; + print '\n"; + print ''; + } + if ($typeobject == 'CommandeFournisseur' && $object->$typeobject->id && isModEnabled("propal")) { + print ''; + print '\n"; + print ''; + } + + // Date creation + print ''; + print '\n"; + print ''; + + // Delivery date planned + print ''; + print ''; + print '
'; + print $langs->trans("RefOrder").''; + print $objectsrc->getNomUrl(1, 'commande'); + print "
'; + print $langs->trans("RefProposal").''; + print $objectsrc->getNomUrl(1, 'reception'); + print "
'; + print $langs->trans("SupplierOrder").''; + print $objectsrc->getNomUrl(1, 'reception'); + print "
'.$langs->trans("DateCreation").''.dol_print_date($object->date_creation, "dayhour", "tzuserrel")."
'; + print ''; + print '
'; + print $langs->trans('DateDeliveryPlanned'); + print '
'; + print '
'; + print $object->date_delivery ? dol_print_date($object->date_delivery, 'dayhour') : ' '; + print '
'; + print '
'; + print ''.img_picto("", 'eraser', 'class="pictofixedwidth"').$langs->trans("ResetQtyToDispatch").''; + print ''.img_picto("", 'eraser', 'class="pictofixedwidth"').$langs->trans("Reset").''; + print '
'; + + print '
'; + $disabled = 0; // This is used to disable or not the bulk selection of target warehouse. No reason to have it disabled so forced to 0. + + if ($object->statut == Reception::STATUS_DRAFT) { + require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; + $formproduct = new FormProduct($db); + $formproduct->loadWarehouses(); + $entrepot = new Entrepot($db); + $listwarehouses = $entrepot->list_array(1); + + + print '
'; + + + print ''; + print ''; + print ''; + + + print '
'; + print ''; + + // Set $products_dispatched with qty dispatched for each product id + $products_dispatched = array(); + $sql = "SELECT l.rowid, cfd.fk_product, sum(cfd.qty) as qty"; + $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as cfd"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseurdet as l on l.rowid = cfd.fk_commandefourndet"; + $sql .= " WHERE cfd.fk_reception = ".((int) $object->id); + $sql .= " GROUP BY l.rowid, cfd.fk_product"; + + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + + if ($num) { + while ($i < $num) { + $objd = $db->fetch_object($resql); + $products_dispatched[$objd->rowid] = price2num($objd->qty, 5); + $i++; + } + } + $db->free($resql); + } + + //$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,"; + $sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, l.qty as qty,"; + $sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse"; + + // Enable hooks to alter the SQL query (SELECT) + $parameters = array(); + $reshook = $hookmanager->executeHooks( + 'printFieldListSelect', + $parameters, + $object, + $action + ); + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + $sql .= $hookmanager->resPrint; + + $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON l.fk_product=p.rowid"; + $sql .= " WHERE l.fk_commande = ".((int) $objectsrc->id); + if (empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + $sql .= " AND l.product_type = 0"; + } + + // Enable hooks to alter the SQL query (WHERE) + $parameters = array(); + $reshook = $hookmanager->executeHooks( + 'printFieldListWhere', + $parameters, + $object, + $action + ); + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + $sql .= $hookmanager->resPrint; + + //$sql .= " GROUP BY p.ref, p.label, p.tobatch, p.fk_default_warehouse, l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref"; // Calculation of amount dispatched is done per fk_product so we must group by fk_product + $sql .= " ORDER BY l.rang, p.ref, p.label"; + + $resql = $db->query($sql); + if ($resql) { + $num = $db->num_rows($resql); + $i = 0; + + if ($num) { + print ''; + + print ''; + if (isModEnabled('productbatch')) { + print ''; + if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + print ''; + } + if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + print ''; + } + } else { + print ''; + print ''; + print ''; + } + print ''; + print ''; + print ''; + print ' '; + + if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { + if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) { + print ''; + print ''; + print ''; + } + } + + print ''; + + // Enable hooks to append additional columns + $parameters = array(); + $reshook = $hookmanager->executeHooks( + 'printFieldListTitle', + $parameters, + $object, + $action + ); + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + print $hookmanager->resPrint; + + print "\n"; + } + + $nbfreeproduct = 0; // Nb of lins of free products/services + $nbproduct = 0; // Nb of predefined product lines to dispatch (already done or not) if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is off (default) + // or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on. + + $conf->cache['product'] = array(); + + while ($i < $num) { + $objp = $db->fetch_object($resql); + + // On n'affiche pas les produits libres + if (!$objp->fk_product > 0) { + $nbfreeproduct++; + } else { + $alreadydispatched = isset($products_dispatched[$objp->rowid])?$products_dispatched[$objp->rowid]:0; + $remaintodispatch = price2num($objp->qty, 5); // Calculation of dispatched + if ($remaintodispatch < 0 && empty($conf->global->SUPPLIER_ORDER_ALLOW_NEGATIVE_QTY_FOR_SUPPLIER_ORDER_RETURN)) { + $remaintodispatch = 0; + } + + if ($remaintodispatch || empty($conf->global->SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED)) { + $nbproduct++; + + // To show detail cref and description value, we must make calculation by cref + // print ($objp->cref?' ('.$objp->cref.')':''); + // if ($objp->description) print '
'.nl2br($objp->description); + $suffix = '_0_'.$i; + + print "\n"; + print ''."\n"; + // hidden fields for js function + print ''; + print ''; + print ''; + + if (empty($conf->cache['product'][$objp->fk_product])) { + $tmpproduct = new Product($db); + $tmpproduct->fetch($objp->fk_product); + $conf->cache['product'][$objp->fk_product] = $tmpproduct; + } else { + $tmpproduct = $conf->cache['product'][$objp->fk_product]; + } + + $linktoprod = $tmpproduct->getNomUrl(1); + $linktoprod .= ' - '.$objp->label."\n"; + + if (isModEnabled('productbatch')) { + if ($objp->tobatch) { + // Product + print '"; + print ''; + if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + print ''; + } + if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + print ''; + } + } else { + // Product + print '"; + print ''; + if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + print ''; + } + if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + print ''; + } + } + } else { + print '"; + } + + // Define unit price for PMP calculation + $up_ht_disc = $objp->subprice; + if (!empty($objp->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) { + $up_ht_disc = price2num($up_ht_disc * (100 - $objp->remise_percent) / 100, 'MU'); + } + + // Supplier ref + print ''; + + // Qty ordered + print ''; + + // Already dispatched + print ''; + + print ''; // Qty to dispatch + print ''; // Dispatch column + print ''; // Warehouse column + + $sql = "SELECT cfd.rowid, cfd.qty, cfd.fk_entrepot, cfd.batch, cfd.eatby, cfd.sellby, cfd.fk_product"; + $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as cfd"; + $sql .= " WHERE cfd.fk_commandefourndet = ".(int) $objp->rowid; + $resultsql = $db->query($sql); + $j = 0; + if ($resultsql) { + $numd = $db->num_rows($resultsql); + + while ($j < $numd) { + $suffix = "_".$j."_".$i; + $objd = $db->fetch_object($resultsql); + if (isModEnabled('productbatch') && !empty($objd->batch)) { + $type = 'batch'; + + // Enable hooks to append additional columns + $parameters = array( + // allows hook to distinguish between the rows with information and the rows with dispatch form input + 'is_information_row' => true, + 'j' => $j, + 'suffix' => $suffix, + 'objd' => $objd, + ); + $reshook = $hookmanager->executeHooks( + 'printFieldListValue', + $parameters, + $object, + $action + ); + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + print $hookmanager->resPrint; + + print ''; + + print ''; + print ''; + + print ''; + if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + print ''; + } + if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + print ''; + } + print ''; // Supplier ref + Qty ordered + qty already dispatched + } else { + $type = 'dispatch'; + $colspan = 7; + $colspan = (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) ? --$colspan : $colspan; + $colspan = (!empty($conf->global->PRODUCT_DISABLE_EATBY)) ? --$colspan : $colspan; + + // Enable hooks to append additional columns + $parameters = array( + // allows hook to distinguish between the rows with information and the rows with dispatch form input + 'is_information_row' => true, + 'j' => $j, + 'suffix' => $suffix, + 'objd' => $objd, + ); + $reshook = $hookmanager->executeHooks( + 'printFieldListValue', + $parameters, + $object, + $action + ); + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + print $hookmanager->resPrint; + + print ''; + + print ''; + print ''; + } + // Qty to dispatch + print ''; + print ''; + + if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { + if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) { + // Price + print ''; + + // Discount + print ''; + + // Save price + print ''; + } + } + + // Warehouse + print '\n"; + + // Enable hooks to append additional columns + $parameters = array( + 'is_information_row' => false, // this is a dispatch form row + 'i' => $i, + 'suffix' => $suffix, + 'objp' => $objp, + ); + $reshook = $hookmanager->executeHooks( + 'printFieldListValue', + $parameters, + $object, + $action + ); + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + print $hookmanager->resPrint; + + print "\n"; + $j++; + } + $suffix = "_".$j."_".$i; + } + if ($j == 0) { + if (isModEnabled('productbatch') && !empty($objp->batch)) { + $type = 'batch'; + + // Enable hooks to append additional columns + $parameters = array( + // allows hook to distinguish between the rows with information and the rows with dispatch form input + 'is_information_row' => true, + 'j' => $j, + 'suffix' => $suffix, + 'objp' => $objp, + ); + $reshook = $hookmanager->executeHooks( + 'printFieldListValue', + $parameters, + $object, + $action + ); + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + print $hookmanager->resPrint; + + print ''; + + print ''; + print ''; + + print ''; + if (empty($conf->global->PRODUCT_DISABLE_SELLBY)) { + print ''; + } + if (empty($conf->global->PRODUCT_DISABLE_EATBY)) { + print ''; + } + print ''; // Supplier ref + Qty ordered + qty already dispatched + } else { + $type = 'dispatch'; + $colspan = 7; + $colspan = (!empty($conf->global->PRODUCT_DISABLE_SELLBY)) ? --$colspan : $colspan; + $colspan = (!empty($conf->global->PRODUCT_DISABLE_EATBY)) ? --$colspan : $colspan; + + // Enable hooks to append additional columns + $parameters = array( + // allows hook to distinguish between the rows with information and the rows with dispatch form input + 'is_information_row' => true, + 'j' => $j, + 'suffix' => $suffix, + 'objp' => $objp, + ); + $reshook = $hookmanager->executeHooks( + 'printFieldListValue', + $parameters, + $object, + $action + ); + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + print $hookmanager->resPrint; + + print ''; + + print ''; + print ''; + } + // Qty to dispatch + print ''; + print ''; + + if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { + if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) { + // Price + print ''; + + // Discount + print ''; + + // Save price + print ''; + } + } + + // Warehouse + print '\n"; + + // Enable hooks to append additional columns + $parameters = array( + 'is_information_row' => false, // this is a dispatch form row + 'i' => $i, + 'suffix' => $suffix, + 'objp' => $objp, + ); + $reshook = $hookmanager->executeHooks( + 'printFieldListValue', + $parameters, + $object, + $action + ); + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + print $hookmanager->resPrint; + print "\n"; + } + } + } + $i++; + } + $db->free($resql); + } else { + dol_print_error($db); + } + + print "
'.$langs->trans("Description").''.$langs->trans("batch_number").''.$langs->trans("SellByDate").''.$langs->trans("EatByDate").''.$langs->trans("SupplierRef").''.$langs->trans("QtyOrdered").''.$langs->trans("QtyDispatchedShort").''.$langs->trans("QtyToDispatchShort"); + print ''.$langs->trans("Price").''.$langs->trans("ReductionShort").' (%)'.$langs->trans("UpdatePrice").''.$langs->trans("Warehouse"); + + // Select warehouse to force it everywhere + if (count($listwarehouses) > 1) { + print '
'.$langs->trans("ForceTo").' '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 1, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1); + } elseif (count($listwarehouses) == 1) { + print '
'.$langs->trans("ForceTo").' '.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1); + } + + print '
'; + print $linktoprod; + print "'; + print $linktoprod; + print "'; + print $langs->trans("ProductDoesNotUseBatchSerial"); + print ''; + print $linktoprod; + print "'.$objp->sref.''.$objp->qty.''.$alreadydispatched.''; + print ''; + print '
'; + print ''; + print ''; + print ''; + + print ''; + if (!empty($conf->global->SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT)) { // Not tested ! + print $langs->trans("BuyingPrice").': '; + } else { + print ''; + } + + print ''; + print ''; + print ''; + $dlcdatesuffix = !empty($objd->sellby) ? dol_stringtotime($objd->sellby) : dol_mktime(0, 0, 0, GETPOST('dlc'.$suffix.'month'), GETPOST('dlc'.$suffix.'day'), GETPOST('dlc'.$suffix.'year')); + print $form->selectDate($dlcdatesuffix, 'dlc'.$suffix, '', '', 1, ''); + print ''; + $dluodatesuffix = !empty($objd->eatby) ? dol_stringtotime($objd->eatby) : dol_mktime(0, 0, 0, GETPOST('dluo'.$suffix.'month'), GETPOST('dluo'.$suffix.'day'), GETPOST('dluo'.$suffix.'year')); + print $form->selectDate($dluodatesuffix, 'dluo'.$suffix, '', '', 1, ''); + print ' 
'; + print ''; + print ''; + print ''; + + print ''; + if (!empty($conf->global->SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT)) { // Not tested ! + print $langs->trans("BuyingPrice").': '; + } else { + print ''; + } + + print ''; + print ''.img_picto($langs->trans("Reset"), 'eraser', 'class="pictofixedwidth opacitymedium"').''; + print ''; + print ''; + if (isModEnabled('productbatch') && $objp->tobatch > 0) { + $type = 'batch'; + print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" '.($numd != $j+1 ? 'style="display:none"' : '').' onClick="addDispatchLine('.$i.', \''.$type.'\')"'); + } else { + $type = 'dispatch'; + print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" '.($numd != $j+1 ? 'style="display:none"' : '').' onClick="addDispatchLine('.$i.', \''.$type.'\')"'); + } + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (count($listwarehouses) > 1) { + print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ?GETPOST("entrepot".$suffix) : $objd->fk_entrepot, "entrepot".$suffix, '', 1, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix); + } elseif (count($listwarehouses) == 1) { + print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ?GETPOST("entrepot".$suffix) : $objd->fk_entrepot, "entrepot".$suffix, '', 0, 0, $objp->fk_product, '', 1, 0, null, 'csswarehouse'.$suffix); + } else { + $langs->load("errors"); + print $langs->trans("ErrorNoWarehouseDefined"); + } + print "
'; + print ''; + print ''; + print ''; + + print ''; + if (!empty($conf->global->SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT)) { // Not tested ! + print $langs->trans("BuyingPrice").': '; + } else { + print ''; + } + + print ''; + print ''; + print ''; + $dlcdatesuffix = dol_mktime(0, 0, 0, GETPOST('dlc'.$suffix.'month'), GETPOST('dlc'.$suffix.'day'), GETPOST('dlc'.$suffix.'year')); + print $form->selectDate($dlcdatesuffix, 'dlc'.$suffix, '', '', 1, ''); + print ''; + $dluodatesuffix = dol_mktime(0, 0, 0, GETPOST('dluo'.$suffix.'month'), GETPOST('dluo'.$suffix.'day'), GETPOST('dluo'.$suffix.'year')); + print $form->selectDate($dluodatesuffix, 'dluo'.$suffix, '', '', 1, ''); + print ' 
'; + print ''; + print ''; + print ''; + + print ''; + if (!empty($conf->global->SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT)) { // Not tested ! + print $langs->trans("BuyingPrice").': '; + } else { + print ''; + } + + print ''; + print ''.img_picto($langs->trans("Reset"), 'eraser', 'class="pictofixedwidth opacitymedium"').''; + print ''; + print ''; + if (isModEnabled('productbatch') && $objp->tobatch > 0) { + $type = 'batch'; + print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine('.$i.', \''.$type.'\')"'); + } else { + $type = 'dispatch'; + print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine('.$i.', \''.$type.'\')"'); + } + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (count($listwarehouses) > 1) { + 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); + } elseif (count($listwarehouses) == 1) { + 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); + } else { + $langs->load("errors"); + print $langs->trans("ErrorNoWarehouseDefined"); + } + print "
\n"; + print '
'; + + if ($nbproduct) { + $checkboxlabel = $langs->trans("CloseReceivedSupplierOrdersAutomatically", $langs->transnoentitiesnoconv('StatusOrderReceivedAll')); + + print '
'; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been + // modified by hook + if (empty($reshook)) { + if (empty($conf->reception->enabled)) { + print $langs->trans("Comment").' : '; + print 'trans("DispatchSupplierOrder", $object->ref); + // print ' / '.$object->ref_supplier; // Not yet available + print '" class="flat">
'; + + print ' '.$checkboxlabel; + } + + $dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive") : $langs->trans("CreateReception"); + + print '
'; + print ''; + } + print '
'; + } + + // Message if nothing to dispatch + if (!$nbproduct) { + print "
\n"; + if (empty($conf->global->SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED)) { + print '
'.$langs->trans("NoPredefinedProductToDispatch").'
'; // No predefined line at all + } else { + print '
'.$langs->trans("NoMorePredefinedProductToDispatch").'
'; // No predefined line that remain to be dispatched. + } + } + + print '
'; + } + + print dol_get_fiche_end(); + + // traitement entrepot par défaut + print ''; +} + +// End of page +llxFooter(); +$db->close();