dolibarr 21.0.0-beta
dispatch.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Eric Seigne <eric.seigne@ryxeo.com>
5 * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2010-2021 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2014 Cedric Gross <c.gross@kreiz-it.fr>
8 * Copyright (C) 2016 Florian Henry <florian.henry@atm-consulting.fr>
9 * Copyright (C) 2017-2022 Ferran Marcet <fmarcet@2byte.es>
10 * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
11 * Copyright (C) 2019-2020 Christophe Battarel <christophe@altairis.fr>
12 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27
34// Load Dolibarr environment
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/reception.lib.php';
44require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
45
54// Load translation files required by the page
55$langs->loadLangs(array("bills", "orders", "sendings", "companies", "deliveries", "products", "stocks", "receptions"));
56
57if (isModEnabled('productbatch')) {
58 $langs->load('productbatch');
59}
60
61// Security check
62$id = GETPOSTINT("id");
63$ref = GETPOST('ref');
64$lineid = GETPOSTINT('lineid');
65$action = GETPOST('action', 'aZ09');
66$fk_default_warehouse = GETPOSTINT('fk_default_warehouse');
67$cancel = GETPOST('cancel', 'alpha');
68$confirm = GETPOST('confirm', 'alpha');
69
70$error = 0;
71$errors = array();
72
73if ($user->socid) {
74 $socid = $user->socid;
75}
76
77$hookmanager->initHooks(array('ordersupplierdispatch'));
78
79// Recuperation de l'id de projet
80$projectid = 0;
81if (GETPOSTISSET("projectid")) {
82 $projectid = GETPOSTINT("projectid");
83}
84
85$object = new Reception($db);
86
87if ($id > 0 || !empty($ref)) {
88 $result = $object->fetch($id, $ref);
89 if ($result < 0) {
90 setEventMessages($object->error, $object->errors, 'errors');
91 }
92 $result = $object->fetch_thirdparty();
93 if ($result < 0) {
94 setEventMessages($object->error, $object->errors, 'errors');
95 }
96 if (!empty($object->origin)) {
97 $origin = $object->origin;
98 $typeobject = $object->origin;
99
100 $object->fetch_origin();
101 }
102 if ($origin == 'order_supplier' && $object->origin_object->id && (isModEnabled("fournisseur") && !getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') || isModEnabled("supplier_order"))) {
103 $origin_id = $object->origin_object->id;
104 $objectsrc = new CommandeFournisseur($db);
105 $objectsrc->fetch($origin_id);
106 }
107}
108
109if (empty($conf->reception->enabled)) {
110 $permissiontoreceive = $user->hasRight('fournisseur', 'commande', 'receptionner');
111 $permissiontocontrol = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('fournisseur', 'commande', 'receptionner')) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('fournisseur', 'commande_advance', 'check')));
112} else {
113 $permissiontoreceive = $user->hasRight('reception', 'creer');
114 $permissiontocontrol = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'creer')) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'reception_advance', 'validate')));
115}
116
117// $id is id of a reception
118$result = restrictedArea($user, 'reception', $object->id);
119
120if (!isModEnabled('stock')) {
121 accessforbidden('Module stock disabled');
122}
123
124$usercancreate = $user->hasRight('reception', 'creer');
125$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php
126
127
128/*
129 * Actions
130 */
131
132$parameters = array();
133$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
134if ($reshook < 0) {
135 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
136}
137
138// Update a dispatched line
139if ($action == 'updatelines' && $permissiontoreceive) {
140 $db->begin();
141 $error = 0;
142
143 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
144 $pos = 0;
145
146 foreach ($_POST as $key => $value) {
147 // without batch module enabled
148 $reg = array();
149 if (preg_match('/^product_.*([0-9]+)_([0-9]+)$/i', $key, $reg)) {
150 $pos++;
151 if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
152 $modebatch = "barcode";
153 } elseif (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) { // With batchmode enabled
154 $modebatch = "batch";
155 }
156
157 $numline = $pos;
158 if ($modebatch == "barcode") {
159 $prod = "product_".$reg[1].'_'.$reg[2];
160 } else {
161 $prod = 'product_batch_'.$reg[1].'_'.$reg[2];
162 }
163 $qty = "qty_".$reg[1].'_'.$reg[2];
164 $ent = "entrepot_".$reg[1].'_'.$reg[2];
165 $pu = "pu_".$reg[1].'_'.$reg[2]; // This is unit price including discount
166 $fk_commandefourndet = "fk_commandefourndet_".$reg[1].'_'.$reg[2];
167 $idline = GETPOST("idline_".$reg[1].'_'.$reg[2]);
168 $lot = '';
169 $dDLUO = '';
170 $dDLC = '';
171 if ($modebatch == "batch") {
172 $lot = GETPOST('lot_number_'.$reg[1].'_'.$reg[2]);
173 $dDLUO = dol_mktime(12, 0, 0, GETPOSTINT('dluo_'.$reg[1].'_'.$reg[2].'month'), GETPOSTINT('dluo_'.$reg[1].'_'.$reg[2].'day'), GETPOSTINT('dluo_'.$reg[1].'_'.$reg[2].'year'));
174 $dDLC = dol_mktime(12, 0, 0, GETPOSTINT('dlc_'.$reg[1].'_'.$reg[2].'month'), GETPOSTINT('dlc_'.$reg[1].'_'.$reg[2].'day'), GETPOSTINT('dlc_'.$reg[1].'_'.$reg[2].'year'));
175 }
176
177 if (getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
178 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
179 $dto = GETPOSTINT("dto_".$reg[1].'_'.$reg[2]);
180 if (!empty($dto)) {
181 $unit_price = (float) price2num(GETPOSTFLOAT("pu_".$reg[1]) * (100 - $dto) / 100, 'MU');
182 }
183 $saveprice = "saveprice_".$reg[1].'_'.$reg[2];
184 }
185 }
186
187 // We ask to move a qty
188 if (($modebatch == "batch" && GETPOST($qty) > 0) || ($modebatch == "barcode" && GETPOST($qty) != 0)) {
189 if (!(GETPOSTINT($ent) > 0)) {
190 dol_syslog('No dispatch for line '.$key.' as no warehouse was chosen.');
191 $text = $langs->transnoentities('Warehouse').', '.$langs->transnoentities('Line').' '.($numline);
192 setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
193 $error++;
194 }
195
196 if (!$error) {
197 if ($idline > 0) {
198 $result = $supplierorderdispatch->fetch($idline);
199 if ($result < 0) {
200 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
201 $error++;
202 } else {
203 $qtystart = $supplierorderdispatch->qty;
204 $supplierorderdispatch->qty = (float) price2num(GETPOST($qty));
205 $supplierorderdispatch->fk_entrepot = GETPOSTINT($ent);
206 if ($modebatch == "batch") {
207 $supplierorderdispatch->eatby = $dDLUO;
208 $supplierorderdispatch->sellby = $dDLC;
209 }
210
211 $result = $supplierorderdispatch->update($user);
212 if ($result < 0) {
213 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
214 $error++;
215 }
216
217 // If module stock is enabled and the stock decrease is done on edition of this page
218 /*
219 if (!$error && GETPOST($ent, 'int') > 0 && isModEnabled('stock') && !empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER)) {
220 $mouv = new MouvementStock($db);
221 $product = GETPOST($prod, 'int');
222 $entrepot = GETPOST($ent, 'int');
223 $qtymouv = GETPOST($qty) - $qtystart;
224 $price = GETPOST($pu);
225 $comment = GETPOST('comment');
226 $inventorycode = dol_print_date(dol_now(), 'dayhourlog');
227 $now = dol_now();
228 $eatby = '';
229 $sellby = '';
230 $batch = '';
231 if ($modebatch == "batch") {
232 $eatby = $dDLUO;
233 $sellby = $dDLC;
234 $batch = $supplierorderdispatch->batch;
235 }
236 if ($product > 0) {
237 // $price should take into account discount (except if option STOCK_EXCLUDE_DISCOUNT_FOR_PMP is on)
238 $mouv->origin = $objectsrc;
239 $mouv->setOrigin($objectsrc->element, $objectsrc->id);
240
241 // Method change if qty < 0
242 if (!empty($conf->global->SUPPLIER_ORDER_ALLOW_NEGATIVE_QTY_FOR_SUPPLIER_ORDER_RETURN) && $qtymouv < 0) {
243 $result = $mouv->livraison($user, $product, $entrepot, $qtymouv*(-1), $price, $comment, $now, $eatby, $sellby, $batch, 0, $inventorycode);
244 } else {
245 $result = $mouv->reception($user, $product, $entrepot, $qtymouv, $price, $comment, $eatby, $sellby, $batch, '', 0, $inventorycode);
246 }
247
248 if ($result < 0) {
249 setEventMessages($mouv->error, $mouv->errors, 'errors');
250 $error++;
251 }
252 }
253 }
254 */
255 }
256 } else {
257 $result = $objectsrc->dispatchProduct($user, GETPOSTINT($prod), GETPOST($qty), GETPOSTINT($ent), GETPOST($pu), GETPOST('comment'), $dDLUO, $dDLC, $lot, GETPOSTINT($fk_commandefourndet), 0, $object->id);
258 if ($result < 0) {
259 setEventMessages($objectsrc->error, $objectsrc->errors, 'errors');
260 $error++;
261 }
262 }
263
264 if (!$error && getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
265 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
266 $dto = price2num(GETPOSTINT("dto_".$reg[1].'_'.$reg[2]), '');
267 if (empty($dto)) {
268 $dto = 0;
269 }
270
271 //update supplier price
272 if (GETPOSTISSET($saveprice)) {
273 // TODO Use class
274 $sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price";
275 $sql .= " SET unitprice='".price2num(GETPOST($pu), 'MU')."'";
276 $sql .= ", price=".price2num(GETPOST($pu), 'MU')."*quantity";
277 $sql .= ", remise_percent = ".((float) $dto);
278 $sql .= " WHERE fk_soc=".((int) $object->socid);
279 $sql .= " AND fk_product=".(GETPOSTINT($prod));
280
281 $resql = $db->query($sql);
282 }
283 }
284 }
285 }
286 }
287 }
288 }
289 if ($error > 0) {
290 $db->rollback();
291 setEventMessages($langs->trans("Error"), $errors, 'errors');
292 } else {
293 $db->commit();
294 setEventMessages($langs->trans("ReceptionUpdated"), null);
295
296 header("Location: ".DOL_URL_ROOT.'/reception/dispatch.php?id='.$object->id);
297 exit;
298 }
299}
300
301
302/*
303 * View
304 */
305
306$now = dol_now();
307
308$form = new Form($db);
309$formproduct = new FormProduct($db);
310$warehouse_static = new Entrepot($db);
311$supplierorderdispatch = new CommandeFournisseurDispatch($db);
312
313$title = $object->ref." - ".$langs->trans('ReceptionDistribution');
314$help_url = 'EN:Module_Suppliers_Orders|FR:CommandeFournisseur|ES:Módulo_Pedidos_a_proveedores';
315$morejs = array('/fourn/js/lib_dispatch.js.php');
316$numline = 0;
317
318llxHeader('', $title, $help_url, '', 0, 0, $morejs, '', '', 'mod-reception page-card_dispatch');
319
320if ($id > 0 || !empty($ref)) {
321 if (!empty($object->origin) && $object->origin_id > 0) {
322 $object->origin = 'CommandeFournisseur';
323 $typeobject = $object->origin;
324 $origin = $object->origin;
325 $origin_id = $object->origin_id;
326 $object->fetch_origin(); // Load property $object->origin_object, $object->commande, $object->propal, ...
327 }
328 $soc = new Societe($db);
329 $soc->fetch($object->socid);
330
331 $author = new User($db);
332 $author->fetch($object->user_author_id);
333
334 $head = reception_prepare_head($object);
335
336 $title = $langs->trans("SupplierOrder");
337 print dol_get_fiche_head($head, 'dispatch', $langs->trans("Reception"), -1, 'dollyrevert');
338
339
340 $formconfirm = '';
341
342 // Confirmation to delete line
343 if ($action == 'ask_deleteline') {
344 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
345 }
346
347 // Call Hook formConfirm
348 $parameters = array('lineid' => $lineid);
349 // Note that $action and $object may be modified by hook
350 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
351 if (empty($reshook)) {
352 $formconfirm .= $hookmanager->resPrint;
353 } elseif ($reshook > 0) {
354 $formconfirm = $hookmanager->resPrint;
355 }
356
357 // Print form confirm
358 print $formconfirm;
359
360 // Reception card
361 $linkback = '<a href="'.DOL_URL_ROOT.'/reception/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
362 $morehtmlref = '<div class="refidno">';
363 // Ref customer reception
364
365 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('reception', 'creer'), 'string', '', 0, 1);
366 $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('reception', 'creer'), 'string', '', null, null, '', 1);
367
368 // Thirdparty
369 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
370 // Project
371 if (isModEnabled('project')) {
372 $langs->load("projects");
373 $morehtmlref .= '<br>';
374 if (0) { // Do not change on reception
375 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
376 if ($action != 'classify' && $permissiontoadd) {
377 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
378 }
379 $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');
380 } else {
381 if (!empty($objectsrc) && !empty($objectsrc->fk_project)) {
382 $proj = new Project($db);
383 $proj->fetch($objectsrc->fk_project);
384 $morehtmlref .= $proj->getNomUrl(1);
385 if ($proj->title) {
386 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
387 }
388 }
389 }
390 }
391 $morehtmlref .= '</div>';
392
393 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
394
395
396 print '<div class="fichecenter">';
397 print '<div class="underbanner clearboth"></div>';
398
399 print '<table class="border tableforfield" width="100%">';
400
401 // Linked documents
402 if ($typeobject == 'commande' && $object->origin_object->id && isModEnabled('order')) {
403 print '<tr><td>';
404 print $langs->trans("RefOrder").'</td>';
405 print '<td colspan="3">';
406 print $objectsrc->getNomUrl(1, 'commande');
407 print "</td>\n";
408 print '</tr>';
409 }
410 if ($typeobject == 'propal' && $object->origin_object->id && isModEnabled("propal")) {
411 print '<tr><td>';
412 print $langs->trans("RefProposal").'</td>';
413 print '<td colspan="3">';
414 print $objectsrc->getNomUrl(1, 'reception');
415 print "</td>\n";
416 print '</tr>';
417 }
418 if ($typeobject == 'CommandeFournisseur' && $object->origin_object->id && isModEnabled("propal")) {
419 print '<tr><td>';
420 print $langs->trans("SupplierOrder").'</td>';
421 print '<td colspan="3">';
422 print $objectsrc->getNomUrl(1, 'reception');
423 print "</td>\n";
424 print '</tr>';
425 }
426
427 // Date creation
428 print '<tr><td class="titlefield">'.$langs->trans("DateCreation").'</td>';
429 print '<td colspan="3">'.dol_print_date($object->date_creation, "dayhour", "tzuserrel")."</td>\n";
430 print '</tr>';
431
432 // Delivery date planned
433 print '<tr><td height="10">';
434 print '<table class="nobordernopadding" width="100%"><tr><td>';
435 print $langs->trans('DateDeliveryPlanned');
436 print '</td>';
437 print '</tr></table>';
438 print '</td><td colspan="2">';
439 print $object->date_delivery ? dol_print_date($object->date_delivery, 'dayhour') : '&nbsp;';
440 print '</td>';
441 print '</tr>';
442 print '</table>';
443
444 print '<br><br><center>';
445 print '<a href="#" id="resetalltoexpected" class="marginrightonly paddingright marginleftonly paddingleft">'.img_picto("", 'autofill', 'class="pictofixedwidth"').$langs->trans("RestoreWithCurrentQtySaved").'</a></td>';
446 // Link to clear qty
447 print '<a href="#" id="autoreset" class="marginrightonly paddingright marginleftonly paddingleft">'.img_picto("", 'eraser', 'class="pictofixedwidth"').$langs->trans("ClearQtys").'</a></td>';
448 print '<center>';
449
450 print '<br>';
451 $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.
452
453 if ($object->statut == Reception::STATUS_DRAFT || ($object->statut == Reception::STATUS_VALIDATED && !getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION'))) {
454 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
455 $formproduct = new FormProduct($db);
456 $formproduct->loadWarehouses();
457 $entrepot = new Entrepot($db);
458 $listwarehouses = $entrepot->list_array(1);
459
460 print '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
461
462 print '<input type="hidden" name="token" value="'.newToken().'">';
463 print '<input type="hidden" name="action" value="updatelines">';
464 print '<input type="hidden" name="id" value="'.$object->id.'">';
465
466 print '<div class="div-table-responsive-no-min">';
467 print '<table class="noborder centpercent">';
468
469 // Get list of lines from the original Order into $products_dispatched with qty dispatched for each product id
470 $products_dispatched = array();
471 $sql = "SELECT l.rowid, cfd.fk_product, sum(cfd.qty) as qty";
472 $sql .= " FROM ".MAIN_DB_PREFIX."receptiondet_batch as cfd";
473 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."receptiondet_batch as l on l.rowid = cfd.fk_elementdet";
474 $sql .= " WHERE cfd.fk_reception = ".((int) $object->id);
475 $sql .= " GROUP BY l.rowid, cfd.fk_product";
476
477 $resql = $db->query($sql);
478 if ($resql) {
479 $num = $db->num_rows($resql);
480 $i = 0;
481
482 if ($num) {
483 while ($i < $num) {
484 $objd = $db->fetch_object($resql);
485 $products_dispatched[$objd->rowid] = price2num($objd->qty, 'MS');
486 $i++;
487 }
488 }
489 $db->free($resql);
490 }
491
492
493 //$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,";
494 $sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, l.qty as qty,";
495 $sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse";
496 // Enable hooks to alter the SQL query (SELECT)
497 $parameters = array();
498 $reshook = $hookmanager->executeHooks(
499 'printFieldListSelect',
500 $parameters,
501 $object,
502 $action
503 );
504 if ($reshook < 0) {
505 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
506 }
507 $sql .= $hookmanager->resPrint;
508 $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l";
509 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON l.fk_product=p.rowid";
510 $sql .= " WHERE l.fk_commande = ".((int) $objectsrc->id);
511 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
512 $sql .= " AND l.product_type = 0";
513 }
514 // Enable hooks to alter the SQL query (WHERE)
515 $parameters = array();
516 $reshook = $hookmanager->executeHooks(
517 'printFieldListWhere',
518 $parameters,
519 $object,
520 $action
521 );
522 if ($reshook < 0) {
523 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
524 }
525 $sql .= $hookmanager->resPrint;
526
527 //$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
528 $sql .= " ORDER BY l.rang, p.ref, p.label";
529
530 $resql = $db->query($sql);
531 if ($resql) {
532 $num = $db->num_rows($resql);
533 $i = 0;
534
535 if ($num) {
536 print '<tr class="liste_titre">';
537
538 print '<td>'.$langs->trans("Description").'</td>';
539 if (isModEnabled('productbatch')) {
540 print '<td class="dispatch_batch_number_title">'.$langs->trans("batch_number").'</td>';
541 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
542 print '<td class="dispatch_dlc_title">'.$langs->trans("SellByDate").'</td>';
543 }
544 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
545 print '<td class="dispatch_dluo_title">'.$langs->trans("EatByDate").'</td>';
546 }
547 } else {
548 print '<td></td>';
549 print '<td></td>';
550 print '<td></td>';
551 }
552 print '<td class="right">'.$langs->trans("SupplierRef").'</td>';
553 print '<td class="right">'.$langs->trans("QtyOrdered").'</td>';
554 if ($object->status == Reception::STATUS_DRAFT) {
555 print '<td class="right">'.$langs->trans("QtyToReceive"); // Qty to dispatch (sum for all lines of batch detail if there is)
556 } else {
557 print '<td class="right">'.$langs->trans("QtyDispatchedShort").'</td>';
558 }
559 print '<td class="right">'.$langs->trans("Details");
560 print '<td width="32"></td>';
561
562 if (getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
563 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
564 print '<td class="right">'.$langs->trans("Price").'</td>';
565 print '<td class="right">'.$langs->trans("ReductionShort").' (%)</td>';
566 print '<td class="right">'.$langs->trans("UpdatePrice").'</td>';
567 }
568 }
569
570 print '<td align="right">'.$langs->trans("Warehouse");
571
572 // Select warehouse to force it everywhere
573 if (count($listwarehouses) > 1) {
574 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);
575 } elseif (count($listwarehouses) == 1) {
576 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);
577 }
578
579 print '</td>';
580
581 // Enable hooks to append additional columns
582 $parameters = array();
583 $reshook = $hookmanager->executeHooks(
584 'printFieldListTitle',
585 $parameters,
586 $object,
587 $action
588 );
589 if ($reshook < 0) {
590 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
591 }
592 print $hookmanager->resPrint;
593
594 print "</tr>\n";
595 }
596
597 $nbfreeproduct = 0; // Nb of lines of free products/services
598 $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)
599 // or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on.
600
601 $conf->cache['product'] = array();
602
603 // Loop on each source order line (may be more or less than current number of lines in llx_commande_fournisseurdet)
604 while ($i < $num) {
605 $objp = $db->fetch_object($resql);
606
607 // On n'affiche pas les produits libres
608 if (!$objp->fk_product > 0) {
609 $nbfreeproduct++;
610 } else {
611 $alreadydispatched = isset($products_dispatched[$objp->rowid]) ? $products_dispatched[$objp->rowid] : 0;
612 $remaintodispatch = price2num($objp->qty, 5); // Calculation of dispatched
613 if ($remaintodispatch < 0 && !getDolGlobalString('SUPPLIER_ORDER_ALLOW_NEGATIVE_QTY_FOR_SUPPLIER_ORDER_RETURN')) {
614 $remaintodispatch = 0;
615 }
616
617 if ($remaintodispatch || !getDolGlobalString('SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED')) {
618 $nbproduct++;
619
620 // To show detail cref and description value, we must make calculation by cref
621 // print ($objp->cref?' ('.$objp->cref.')':'');
622 // if ($objp->description) print '<br>'.nl2br($objp->description);
623 $suffix = '_0_'.$i;
624
625 print "\n";
626 print '<!-- Line to dispatch '.$suffix.' -->'."\n";
627 // hidden fields for js function
628 print '<input id="qty_ordered'.$suffix.'" type="hidden" value="'.$objp->qty.'">';
629 print '<input id="qty_dispatched'.$suffix.'" type="hidden" data-dispatched="'.((float) $alreadydispatched).'" value="'.(float) $alreadydispatched.'">';
630 print '<tr class="oddeven">';
631
632 if (empty($conf->cache['product'][$objp->fk_product])) {
633 $tmpproduct = new Product($db);
634 $tmpproduct->fetch($objp->fk_product);
635 $conf->cache['product'][$objp->fk_product] = $tmpproduct;
636 } else {
637 $tmpproduct = $conf->cache['product'][$objp->fk_product];
638 }
639
640 $linktoprod = $tmpproduct->getNomUrl(1);
641 $linktoprod .= ' - '.$objp->label."\n";
642
643 if (isModEnabled('productbatch')) {
644 if ($objp->tobatch) {
645 // Product
646 print '<td>';
647 print $linktoprod;
648 print "</td>";
649 print '<td class="dispatch_batch_number"></td>';
650 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
651 print '<td class="dispatch_dlc"></td>';
652 }
653 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
654 print '<td class="dispatch_dluo"></td>';
655 }
656 } else {
657 // Product
658 print '<td>';
659 print $linktoprod;
660 print "</td>";
661 print '<td class="dispatch_batch_number">';
662 print '<span class="opacitymedium small">'.$langs->trans("ProductDoesNotUseBatchSerial").'</small>';
663 print '</td>';
664 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
665 print '<td class="dispatch_dlc"></td>';
666 }
667 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
668 print '<td class="dispatch_dluo"></td>';
669 }
670 }
671 } else {
672 print '<td colspan="4">';
673 print $linktoprod;
674 print "</td>";
675 }
676
677 // Define unit price for PMP calculation
678 $up_ht_disc = $objp->subprice;
679 if (!empty($objp->remise_percent) && !getDolGlobalString('STOCK_EXCLUDE_DISCOUNT_FOR_PMP')) {
680 $up_ht_disc = price2num($up_ht_disc * (100 - $objp->remise_percent) / 100, 'MU');
681 }
682
683 // Supplier ref
684 print '<td class="right">'.$objp->sref.'</td>';
685
686 // Qty ordered
687 print '<td class="right">'.$objp->qty.'</td>';
688
689 // Already dispatched
690 print '<td class="right">'.$alreadydispatched.'</td>';
691
692 print '<td class="right">';
693 print '</td>'; // Qty to dispatch
694 print '<td>';
695 print '</td>'; // Dispatch column
696 print '<td></td>'; // Warehouse column
697
698 $sql = "SELECT cfd.rowid, cfd.qty, cfd.fk_entrepot, cfd.batch, cfd.eatby, cfd.sellby, cfd.fk_product";
699 $sql .= " FROM ".MAIN_DB_PREFIX."receptiondet_batch as cfd";
700 $sql .= " WHERE cfd.fk_reception = ".((int) $object->id);
701 $sql .= " AND cfd.fk_element = ".((int) $objectsrc->id);
702 $sql .= " AND cfd.fk_elementdet = ".(int) $objp->rowid;
703
704 //print $sql;
705 $resultsql = $db->query($sql);
706 $j = 0;
707 if ($resultsql) {
708 $numd = $db->num_rows($resultsql);
709
710 while ($j < $numd) {
711 $suffix = "_".$j."_".$i;
712 $objd = $db->fetch_object($resultsql);
713
714 if (isModEnabled('productbatch') && (!empty($objd->batch) || (is_null($objd->batch) && $tmpproduct->status_batch > 0))) {
715 $type = 'batch';
716
717 // Enable hooks to append additional columns
718 $parameters = array(
719 // allows hook to distinguish between the rows with information and the rows with dispatch form input
720 'is_information_row' => true,
721 'j' => $j,
722 'suffix' => $suffix,
723 'objd' => $objd,
724 );
725 $reshook = $hookmanager->executeHooks(
726 'printFieldListValue',
727 $parameters,
728 $object,
729 $action
730 );
731 if ($reshook < 0) {
732 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
733 }
734 print $hookmanager->resPrint;
735
736 print '</tr>';
737
738 print '<!-- line for batch '.$numline.' -->';
739 print '<tr class="oddeven autoresettr" name="'.$type.$suffix.'" data-remove="clear">';
740 print '<td>';
741 print '<input id="fk_commandefourndet'.$suffix.'" name="fk_commandefourndet'.$suffix.'" type="hidden" value="'.$objp->rowid.'">';
742 print '<input id="idline'.$suffix.'" name="idline'.$suffix.'" type="hidden" value="'.$objd->rowid.'">';
743 print '<input name="product_batch'.$suffix.'" type="hidden" value="'.$objd->fk_product.'">';
744
745 print '<!-- This is a U.P. (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
746 if (getDolGlobalString('SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT')) { // Not tested !
747 print $langs->trans("BuyingPrice").': <input class="maxwidth75" name="pu'.$suffix.'" type="text" value="'.price2num($up_ht_disc, 'MU').'">';
748 } else {
749 print '<input class="maxwidth75" name="pu'.$suffix.'" type="hidden" value="'.price2num($up_ht_disc, 'MU').'">';
750 }
751
752 print '</td>';
753
754 print '<td>';
755 print '<input disabled="" type="text" class="inputlotnumber quatrevingtquinzepercent" id="lot_number'.$suffix.'" name="lot_number'.$suffix.'" value="'.(GETPOSTISSET('lot_number'.$suffix) ? GETPOST('lot_number'.$suffix) : $objd->batch).'">';
756 print '</td>';
757 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
758 print '<td class="nowraponall">';
759 $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'));
760 print $form->selectDate($dlcdatesuffix, 'dlc'.$suffix, 0, 0, 1, '');
761 print '</td>';
762 }
763 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
764 print '<td class="nowraponall">';
765 $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'));
766 print $form->selectDate($dluodatesuffix, 'dluo'.$suffix, 0, 0, 1, '');
767 print '</td>';
768 }
769 print '<td colspan="3">&nbsp;</td>'; // Supplier ref + Qty ordered + qty already dispatched
770 } else {
771 $type = 'dispatch';
772 $colspan = 7;
773 $colspan = (getDolGlobalString('PRODUCT_DISABLE_SELLBY')) ? --$colspan : $colspan;
774 $colspan = (getDolGlobalString('PRODUCT_DISABLE_EATBY')) ? --$colspan : $colspan;
775
776 // Enable hooks to append additional columns
777 $parameters = array(
778 // allows hook to distinguish between the rows with information and the rows with dispatch form input
779 'is_information_row' => true,
780 'j' => $j,
781 'suffix' => $suffix,
782 'objd' => $objd,
783 );
784 $reshook = $hookmanager->executeHooks(
785 'printFieldListValue',
786 $parameters,
787 $object,
788 $action
789 );
790 if ($reshook < 0) {
791 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
792 }
793 print $hookmanager->resPrint;
794
795 print '</tr>';
796
797 print '<!-- line no batch '.$numline.' -->';
798 print '<tr class="oddeven autoresettr" name="'.$type.$suffix.'" data-remove="clear">';
799 print '<td colspan="'.$colspan.'">';
800 print '<input id="fk_commandefourndet'.$suffix.'" name="fk_commandefourndet'.$suffix.'" type="hidden" value="'.$objp->rowid.'">';
801 print '<input id="idline'.$suffix.'" name="idline'.$suffix.'" type="hidden" value="'.$objd->rowid.'">';
802 print '<input name="product'.$suffix.'" type="hidden" value="'.$objd->fk_product.'">';
803
804 print '<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
805 if (getDolGlobalString('SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT')) { // Not tested !
806 print $langs->trans("BuyingPrice").': <input class="maxwidth75" name="pu'.$suffix.'" type="text" value="'.price2num($up_ht_disc, 'MU').'">';
807 } else {
808 print '<input class="maxwidth75" name="pu'.$suffix.'" type="hidden" value="'.price2num($up_ht_disc, 'MU').'">';
809 }
810
811 print '</td>';
812 }
813 // Qty to dispatch
814 print '<td class="right">';
815 print '<a href="#" id="reset'.$suffix.'" class="resetline">'.img_picto($langs->trans("Reset"), 'eraser', 'class="pictofixedwidth opacitymedium"').'</a>';
816 print '<input id="qty'.$suffix.'" onchange="onChangeDispatchLineQty($(this))" name="qty'.$suffix.'" data-type="'.$type.'" data-index="'.$i.'" class="width50 right qtydispatchinput" value="'.(GETPOSTISSET('qty'.$suffix) ? GETPOSTINT('qty'.$suffix) : $objd->qty).'" data-expected="'.$objd->qty.'">';
817 print '</td>';
818 print '<td>';
819 if (isModEnabled('productbatch') && $objp->tobatch > 0) {
820 $type = 'batch';
821 print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" '.($numd != $j + 1 ? 'style="display:none"' : '').' onClick="addDispatchLine('.$i.', \''.$type.'\')"');
822 } else {
823 $type = 'dispatch';
824 print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" '.($numd != $j + 1 ? 'style="display:none"' : '').' onClick="addDispatchLine('.$i.', \''.$type.'\')"');
825 }
826
827 print '</td>';
828
829 if (getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
830 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
831 // Price
832 print '<td class="right">';
833 print '<input id="pu'.$suffix.'" name="pu'.$suffix.'" type="text" size="8" value="'.price((GETPOST('pu'.$suffix) != '' ? price2num(GETPOST('pu'.$suffix)) : $up_ht_disc)).'">';
834 print '</td>';
835
836 // Discount
837 print '<td class="right">';
838 print '<input id="dto'.$suffix.'" name="dto'.$suffix.'" type="text" size="8" value="'.(GETPOST('dto'.$suffix) != '' ? GETPOST('dto'.$suffix) : '').'">';
839 print '</td>';
840
841 // Save price
842 print '<td class="center">';
843 print '<input class="flat checkformerge" type="checkbox" name="saveprice'.$suffix.'" value="'.(GETPOST('saveprice'.$suffix) != '' ? GETPOST('saveprice'.$suffix) : '').'">';
844 print '</td>';
845 }
846 }
847
848 // Warehouse
849 print '<td class="right">';
850 if (count($listwarehouses) > 1) {
851 print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ? GETPOST("entrepot".$suffix) : $objd->fk_entrepot, "entrepot".$suffix, '', 1, 0, $objp->fk_product, '', 1, 0, array(), 'csswarehouse'.$suffix);
852 } elseif (count($listwarehouses) == 1) {
853 print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ? GETPOST("entrepot".$suffix) : $objd->fk_entrepot, "entrepot".$suffix, '', 0, 0, $objp->fk_product, '', 1, 0, array(), 'csswarehouse'.$suffix);
854 } else {
855 $langs->load("errors");
856 print $langs->trans("ErrorNoWarehouseDefined");
857 }
858 print "</td>\n";
859
860 // Enable hooks to append additional columns
861 $parameters = array(
862 'is_information_row' => false, // this is a dispatch form row
863 'i' => $i,
864 'suffix' => $suffix,
865 'objp' => $objp,
866 );
867 $reshook = $hookmanager->executeHooks(
868 'printFieldListValue',
869 $parameters,
870 $object,
871 $action
872 );
873 if ($reshook < 0) {
874 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
875 }
876 print $hookmanager->resPrint;
877
878 print "</tr>\n";
879 $j++;
880
881 $numline++;
882 }
883 $suffix = "_".$j."_".$i;
884 }
885
886 if ($j == 0) {
887 if (isModEnabled('productbatch') && !empty($objp->tobatch)) {
888 $type = 'batch';
889
890 // Enable hooks to append additional columns
891 $parameters = array(
892 // allows hook to distinguish between the rows with information and the rows with dispatch form input
893 'is_information_row' => true,
894 'j' => $j,
895 'suffix' => $suffix,
896 'objp' => $objp,
897 );
898 $reshook = $hookmanager->executeHooks(
899 'printFieldListValue',
900 $parameters,
901 $object,
902 $action
903 );
904 if ($reshook < 0) {
905 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
906 }
907 print $hookmanager->resPrint;
908
909 print '</tr>';
910
911 print '<!-- line for batch '.$numline.' (not dispatched line yet for this order line) -->';
912 print '<tr class="oddeven autoresettr" name="'.$type.$suffix.'">';
913 print '<td>';
914 print '<input id="fk_commandefourndet'.$suffix.'" name="fk_commandefourndet'.$suffix.'" type="hidden" value="'.$objp->rowid.'">';
915 print '<input id="idline'.$suffix.'" name="idline'.$suffix.'" type="hidden" value="-1">';
916 print '<input name="product_batch'.$suffix.'" type="hidden" value="'.$objp->fk_product.'">';
917
918 print '<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
919 if (getDolGlobalString('SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT')) { // Not tested !
920 print $langs->trans("BuyingPrice").': <input class="maxwidth75" name="pu'.$suffix.'" type="text" value="'.price2num($up_ht_disc, 'MU').'">';
921 } else {
922 print '<input class="maxwidth75" name="pu'.$suffix.'" type="hidden" value="'.price2num($up_ht_disc, 'MU').'">';
923 }
924
925 print '</td>';
926
927 print '<td>';
928 print '<input type="text" class="inputlotnumber quatrevingtquinzepercent" id="lot_number'.$suffix.'" name="lot_number'.$suffix.'" value="'.GETPOST('lot_number'.$suffix).'">';
929 print '</td>';
930 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
931 print '<td class="nowraponall">';
932 $dlcdatesuffix = dol_mktime(0, 0, 0, GETPOST('dlc'.$suffix.'month'), GETPOST('dlc'.$suffix.'day'), GETPOST('dlc'.$suffix.'year'));
933 print $form->selectDate($dlcdatesuffix, 'dlc'.$suffix, 0, 0, 1, '');
934 print '</td>';
935 }
936 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
937 print '<td class="nowraponall">';
938 $dluodatesuffix = dol_mktime(0, 0, 0, GETPOST('dluo'.$suffix.'month'), GETPOST('dluo'.$suffix.'day'), GETPOST('dluo'.$suffix.'year'));
939 print $form->selectDate($dluodatesuffix, 'dluo'.$suffix, 0, 0, 1, '');
940 print '</td>';
941 }
942 print '<td colspan="3">&nbsp;</td>'; // Supplier ref + Qty ordered + qty already dispatched
943 } else {
944 $type = 'dispatch';
945 $colspan = 7;
946 $colspan = (getDolGlobalString('PRODUCT_DISABLE_SELLBY')) ? --$colspan : $colspan;
947 $colspan = (getDolGlobalString('PRODUCT_DISABLE_EATBY')) ? --$colspan : $colspan;
948
949 // Enable hooks to append additional columns
950 $parameters = array(
951 // allows hook to distinguish between the rows with information and the rows with dispatch form input
952 'is_information_row' => true,
953 'j' => $j,
954 'suffix' => $suffix,
955 'objp' => $objp,
956 );
957 $reshook = $hookmanager->executeHooks(
958 'printFieldListValue',
959 $parameters,
960 $object,
961 $action
962 );
963 if ($reshook < 0) {
964 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
965 }
966 print $hookmanager->resPrint;
967
968 print '</tr>';
969
970 print '<!-- line no batch '.$numline.' (not dispatched line yet for this order line) -->';
971 print '<tr class="oddeven autoresettr" name="'.$type.$suffix.'" data-remove="clear">';
972 print '<td colspan="'.$colspan.'">';
973 print '<input id="fk_commandefourndet'.$suffix.'" name="fk_commandefourndet'.$suffix.'" type="hidden" value="'.$objp->rowid.'">';
974 print '<input id="idline'.$suffix.'" name="idline'.$suffix.'" type="hidden" value="-1">';
975 print '<input name="product'.$suffix.'" type="hidden" value="'.$objp->fk_product.'">';
976
977 print '<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
978 if (getDolGlobalString('SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT')) { // Not tested !
979 print $langs->trans("BuyingPrice").': <input class="maxwidth75" name="pu'.$suffix.'" data-type="text" value="'.price2num($up_ht_disc, 'MU').'">';
980 } else {
981 print '<input class="maxwidth75" name="pu'.$suffix.'" type="hidden" value="'.price2num($up_ht_disc, 'MU').'">';
982 }
983
984 print '</td>';
985 }
986 // Qty to dispatch
987 print '<td class="right">';
988 print '<a href="#" id="reset'.$suffix.'" class="resetline">'.img_picto($langs->trans("Reset"), 'eraser', 'class="pictofixedwidth opacitymedium"').'</a>';
989 print '<input id="qty'.$suffix.'" onchange="onChangeDispatchLineQty($(this))" name="qty'.$suffix.'" data-index="'.$i.'" data-type="text" class="width50 right qtydispatchinput" value="'.(GETPOSTISSET('qty'.$suffix) ? GETPOSTINT('qty'.$suffix) : (!getDolGlobalString('SUPPLIER_ORDER_DISPATCH_FORCE_QTY_INPUT_TO_ZERO') ? $remaintodispatch : 0)).'" data-expected="'.$remaintodispatch.'">';
990 print '</td>';
991 print '<td>';
992 if (isModEnabled('productbatch') && $objp->tobatch > 0) {
993 $type = 'batch';
994 print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine('.$i.', \''.$type.'\')"');
995 } else {
996 $type = 'dispatch';
997 print img_picto($langs->trans('AddStockLocationLine'), 'split.png', 'class="splitbutton" onClick="addDispatchLine('.$i.', \''.$type.'\')"');
998 }
999
1000 print '</td>';
1001
1002 if (getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
1003 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
1004 // Price
1005 print '<td class="right">';
1006 print '<input id="pu'.$suffix.'" name="pu'.$suffix.'" type="text" size="8" value="'.price((GETPOST('pu'.$suffix) != '' ? price2num(GETPOST('pu'.$suffix)) : $up_ht_disc)).'">';
1007 print '</td>';
1008
1009 // Discount
1010 print '<td class="right">';
1011 print '<input id="dto'.$suffix.'" name="dto'.$suffix.'" type="text" size="8" value="'.(GETPOST('dto'.$suffix) != '' ? GETPOST('dto'.$suffix) : '').'">';
1012 print '</td>';
1013
1014 // Save price
1015 print '<td class="center">';
1016 print '<input class="flat checkformerge" type="checkbox" name="saveprice'.$suffix.'" value="'.(GETPOST('saveprice'.$suffix) != '' ? GETPOST('saveprice'.$suffix) : '').'">';
1017 print '</td>';
1018 }
1019 }
1020
1021 // Warehouse
1022 print '<td class="right">';
1023 if (count($listwarehouses) > 1) {
1024 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);
1025 } elseif (count($listwarehouses) == 1) {
1026 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);
1027 } else {
1028 $langs->load("errors");
1029 print $langs->trans("ErrorNoWarehouseDefined");
1030 }
1031 print "</td>\n";
1032
1033 // Enable hooks to append additional columns
1034 $parameters = array(
1035 'is_information_row' => false, // this is a dispatch form row
1036 'i' => $i,
1037 'suffix' => $suffix,
1038 'objp' => $objp,
1039 );
1040 $reshook = $hookmanager->executeHooks(
1041 'printFieldListValue',
1042 $parameters,
1043 $object,
1044 $action
1045 );
1046 if ($reshook < 0) {
1047 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1048 }
1049 print $hookmanager->resPrint;
1050 print "</tr>\n";
1051 }
1052 }
1053 }
1054 $i++;
1055 }
1056 $db->free($resql);
1057 } else {
1058 dol_print_error($db);
1059 }
1060
1061 print "</table>\n";
1062 print '</div>';
1063
1064 if ($nbproduct) {
1065 print '<div class="center">';
1066 $parameters = array();
1067 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1068 // modified by hook
1069 if (empty($reshook)) {
1070 /*$checkboxlabel = $langs->trans("CloseReceivedSupplierOrdersAutomatically", $langs->transnoentitiesnoconv('StatusOrderReceivedAll'));
1071
1072 if (empty($conf->reception->enabled)) {
1073 print $langs->trans("Comment").' : ';
1074 print '<input type="text" class="minwidth400" maxlength="128" name="comment" value="';
1075 print GETPOSTISSET("comment") ? GETPOST("comment") : $langs->trans("DispatchSupplierOrder", $object->ref);
1076 // print ' / '.$object->ref_supplier; // Not yet available
1077 print '" class="flat"><br>';
1078
1079 print '<input type="checkbox" checked="checked" name="closeopenorder"> '.$checkboxlabel;
1080 }
1081
1082 $dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive") : $langs->trans("CreateReception");
1083
1084 print '<br>';
1085 */
1086
1087 print '<input type="submit" id="submitform" class="button" name="dispatch" value="'.$langs->trans("Save").'"';
1088 $disabled = 0;
1089 if (!$permissiontoreceive) {
1090 $disabled = 1;
1091 }
1092 if (count($listwarehouses) <= 0) {
1093 $disabled = 1;
1094 }
1095 if ($disabled) {
1096 print ' disabled';
1097 }
1098
1099 print '>';
1100 }
1101 print '</div>';
1102 }
1103
1104 // Message if nothing to dispatch
1105 if (!$nbproduct) {
1106 print "<br>\n";
1107 if (!getDolGlobalString('SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED')) {
1108 print '<div class="opacitymedium">'.$langs->trans("NoPredefinedProductToDispatch").'</div>'; // No predefined line at all
1109 } else {
1110 print '<div class="opacitymedium">'.$langs->trans("NoMorePredefinedProductToDispatch").'</div>'; // No predefined line that remain to be dispatched.
1111 }
1112 }
1113
1114 print '</form>';
1115 }
1116
1117 print dol_get_fiche_end();
1118
1119 // traitement entrepot par défaut
1120 print '<script type="text/javascript">
1121 $(document).ready(function () {
1122 $("select[name=fk_default_warehouse]").change(function() {
1123 var fk_default_warehouse = $("option:selected", this).val();
1124 $("select[name^=entrepot_]").val(fk_default_warehouse).change();
1125 });
1126
1127 $("#autoreset").click(function() {
1128 $(".autoresettr").each(function(){
1129 id = $(this).attr("name");
1130 idtab = id.split("_");
1131 if ($(this).data("remove") == "clear"){
1132 console.log("We clear the object to expected value")
1133 $("#qty_"+idtab[1]+"_"+idtab[2]).val("");
1134 /*
1135 qtyexpected = $("#qty_"+idtab[1]+"_"+idtab[2]).data("expected")
1136 console.log(qtyexpected);
1137 $("#qty_"+idtab[1]+"_"+idtab[2]).val(qtyexpected);
1138 qtydispatched = $("#qty_dispatched_0_"+idtab[2]).data("dispatched")
1139 $("#qty_dispatched_0_"+idtab[2]).val(qtydispatched);
1140 */
1141 } else {
1142 console.log("We remove the object")
1143 $(this).remove();
1144 $("tr[name^=\'"+idtab[0]+"_\'][name$=\'_"+idtab[2]+"\']:last .splitbutton").show();
1145 }
1146 });
1147 return false;
1148 });
1149
1150 $("#resetalltoexpected").click(function(){
1151 $(".qtydispatchinput").each(function(){
1152 console.log("We reset to expected "+$(this).attr("id")+" qty to dispatch");
1153 $(this).val($(this).data("expected"));
1154 });
1155 return false;
1156 });
1157
1158 $(".resetline").click(function(e){
1159 e.preventDefault();
1160 id = $(this).attr("id");
1161 id = id.split("reset_");
1162 console.log("Reset trigger for id = qty_"+id[1]);
1163 $("#qty_"+id[1]).val("");
1164 return false;
1165 });
1166 });
1167 </script>';
1168}
1169
1170// End of page
1171llxFooter();
1172$db->close();
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
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.
Definition wrapper.php:71
Class to manage table ReceptionLineBatch.
Class to manage predefined suppliers products.
Class to manage comment.
Class to manage warehouses.
Class to manage generation of HTML components Only common components must be here.
Class with static methods for building HTML components related to products Only components common to ...
Class to manage products or services.
Class to manage projects.
Class to manage receptions.
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...
Definition date.lib.php:431
llxFooter()
Footer empty.
Definition document.php:107
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)
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 '.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
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.
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...
Definition member.php:79
reception_prepare_head(Reception $object)
Prepare array with list of tabs.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:152
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.