dolibarr 24.0.2
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-2023 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-2026 Frédéric France <frederic.france@free.fr>
11 * Copyright (C) 2019-2020 Christophe Battarel <christophe@altairis.fr>
12 * Copyright (C) 2024-2026 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';
36
45require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php';
46require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
48require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
49require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php';
50require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
51require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
52require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
53
54if (isModEnabled('project')) {
55 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
56}
57
58// Load translation files required by the page
59$langs->loadLangs(array("bills", "orders", "sendings", "companies", "products", "stocks", "receptions"));
60
61if (isModEnabled('productbatch')) {
62 $langs->load('productbatch');
63}
64
65// Security check
66$id = GETPOSTINT("id");
67$ref = GETPOST('ref');
68$lineid = GETPOSTINT('lineid');
69$action = GETPOST('action', 'aZ09');
70$fk_default_warehouse = GETPOSTINT('fk_default_warehouse');
71$cancel = GETPOST('cancel', 'alpha');
72$confirm = GETPOST('confirm', 'alpha');
73
74if ($user->isExternalUser()) {
75 $socid = $user->isExternalUser();
76}
77
78$hookmanager->initHooks(array('ordersupplierdispatch'));
79
80// Get id of project
81$projectid = 0;
82if (GETPOSTISSET("projectid")) {
83 $projectid = GETPOSTINT("projectid");
84}
85
87
88if ($id > 0 || !empty($ref)) {
89 $result = $object->fetch($id, $ref);
90 if ($result < 0) {
91 setEventMessages($object->error, $object->errors, 'errors');
92 }
93 $result = $object->fetch_thirdparty();
94 if ($result < 0) {
95 setEventMessages($object->error, $object->errors, 'errors');
96 }
97}
98
99if (empty($conf->reception->enabled)) {
100 $permissiontoreceive = $user->hasRight("fournisseur", "commande", "receptionner");
101 $permissiontocontrol = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight("fournisseur", "commande", "receptionner")) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight("fournisseur", "commande_advance", "check")));
102} else {
103 $permissiontoreceive = $user->hasRight("reception", "creer");
104 $permissiontocontrol = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight("reception", "creer")) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight("reception", "reception_advance", "validate")));
105}
106
107// $id is id of a purchase order.
108$result = restrictedArea($user, 'fournisseur', $object, 'commande_fournisseur', 'commande');
109
110if (!isModEnabled('stock')) {
112}
113
114$usercancreate = ($user->hasRight("fournisseur", "commande", "creer") || $user->hasRight("supplier_order", "creer"));
115$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php
116
117
118/*
119 * Actions
120 */
121
122$error = 0;
123$errors = [];
124$parameters = array();
125$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
126if ($reshook < 0) {
127 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
128}
129
130// Actions on an existing dispatch line: the line must be a line of the purchase order of the page
131if (in_array($action, ['checkdispatchline', 'uncheckdispatchline', 'denydispatchline', 'confirm_deleteline', 'updateline'])) {
132 $tmpdispatchline = new CommandeFournisseurDispatch($db);
133 if ($tmpdispatchline->fetch($lineid) <= 0 || (int) $tmpdispatchline->fk_element !== (int) $object->id) {
134 setEventMessages($langs->trans('ErrorRecordNotFound'), null, 'errors');
135 $action = '';
136 }
137}
138
139if ($action == 'checkdispatchline' && $permissiontocontrol) {
140 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
141
142 $db->begin();
143
144 $result = $supplierorderdispatch->fetch($lineid);
145 if (!$result) {
146 $error++;
147 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
148 $action = '';
149 }
150
151 if (!$error) {
152 $result = $supplierorderdispatch->setStatut(1);
153 if ($result < 0) {
154 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
155 $error++;
156 $action = '';
157 }
158 }
159
160 if (!$error) {
161 $result = $object->calcAndSetStatusDispatch($user);
162 if ($result < 0) {
163 setEventMessages($object->error, $object->errors, 'errors');
164 $error++;
165 $action = '';
166 }
167 }
168 if (!$error) {
169 $db->commit();
170 } else {
171 $db->rollback();
172 }
173}
174
175if ($action == 'uncheckdispatchline' && $permissiontocontrol) {
176 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
177
178 $db->begin();
179
180 $result = $supplierorderdispatch->fetch($lineid);
181 if (!$result) {
182 $error++;
183 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
184 $action = '';
185 }
186
187 if (!$error) {
188 $result = $supplierorderdispatch->setStatut(0);
189 if ($result < 0) {
190 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
191 $error++;
192 $action = '';
193 }
194 }
195 if (!$error) {
196 $result = $object->calcAndSetStatusDispatch($user);
197 if ($result < 0) {
198 setEventMessages($object->error, $object->errors, 'errors');
199 $error++;
200 $action = '';
201 }
202 }
203 if (!$error) {
204 $db->commit();
205 } else {
206 $db->rollback();
207 }
208}
209
210if ($action == 'denydispatchline' && $permissiontocontrol) {
211 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
212
213 $db->begin();
214
215 $result = $supplierorderdispatch->fetch($lineid);
216 if (!$result) {
217 $error++;
218 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
219 $action = '';
220 }
221
222 if (!$error) {
223 $result = $supplierorderdispatch->setStatut(2);
224 if ($result < 0) {
225 setEventMessages($supplierorderdispatch->error, $supplierorderdispatch->errors, 'errors');
226 $error++;
227 $action = '';
228 }
229 }
230 if (!$error) {
231 $result = $object->calcAndSetStatusDispatch($user);
232 if ($result < 0) {
233 setEventMessages($object->error, $object->errors, 'errors');
234 $error++;
235 $action = '';
236 }
237 }
238 if (!$error) {
239 $db->commit();
240 } else {
241 $db->rollback();
242 }
243}
244
245$saveprice = "savepriceIsNotSet";
246if ($action == 'dispatch' && $permissiontoreceive) {
247 $notrigger = 0;
248
249 $db->begin();
250
251 $pos = 0;
252 $comment = (string) GETPOST('comment', 'alpha');
253
254 foreach ($_POST as $key => $value) {
255 // without batch module enabled
256 $reg = array();
257 if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
258 $pos++;
259
260 // $numline=$reg[2] + 1; // line of product
261 $numline = $pos;
262 $prod = "product_".$reg[1].'_'.$reg[2];
263 $qty = "qty_".$reg[1].'_'.$reg[2];
264 $ent = "entrepot_".$reg[1].'_'.$reg[2];
265 if (empty(GETPOST($ent))) {
266 $ent = $fk_default_warehouse;
267 }
268 $pu = "pu_".$reg[1].'_'.$reg[2]; // This is unit price including discount
269 $fk_commandefourndet = "fk_commandefourndet_".$reg[1].'_'.$reg[2];
270
271 if (getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
272 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
273 $dto = GETPOSTINT("dto_".$reg[1].'_'.$reg[2]);
274 if (!empty($dto)) {
275 $unit_price = price2num((float) GETPOST("pu_".$reg[1]) * (100 - $dto) / 100, 'MU');
276 }
277 $saveprice = "saveprice_".$reg[1].'_'.$reg[2];
278 }
279 }
280
281 // We ask to move a qty
282 $qtytomove = GETPOSTFLOAT($qty);
283 $puformove = GETPOSTFLOAT($pu);
284 if ($qtytomove != 0) {
285 if (!(GETPOSTINT($ent) > 0)) {
286 dol_syslog('No dispatch for line '.$key.' as no warehouse was chosen.');
287 $text = $langs->transnoentities('Warehouse').', '.$langs->transnoentities('Line').' '.($numline);
288 setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
289 $error++;
290 }
291
292 if (!$error) {
293 $result = $object->dispatchProduct($user, GETPOSTINT($prod), $qtytomove, GETPOSTINT($ent), $puformove, GETPOST('comment'), '', '', '', GETPOSTINT($fk_commandefourndet), $notrigger);
294 if ($result < 0) {
295 setEventMessages($object->error, $object->errors, 'errors');
296 $error++;
297 }
298
299 if (!$error && getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
300 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
301 $dto = price2num(GETPOST("dto_".$reg[1].'_'.$reg[2]), '');
302 if (empty($dto)) {
303 $dto = 0;
304 }
305
306 //update supplier price
307 if (GETPOSTISSET($saveprice)) {
308 // TODO Use class
309 $sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price";
310 $sql .= " SET unitprice='".price2num(GETPOST($pu), 'MU')."'";
311 $sql .= ", price=".price2num(GETPOST($pu), 'MU')."*quantity";
312 $sql .= ", remise_percent = ".((float) $dto);
313 $sql .= " WHERE fk_soc=".((int) $object->socid);
314 $sql .= " AND fk_product=".(GETPOSTINT($prod));
315
316 $resql = $db->query($sql);
317 }
318 }
319 }
320 }
321 }
322 }
323 // with batch module enabled
324 if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
325 $pos++;
326
327 // eat-by date dispatch
328 // $numline=$reg[2] + 1; // line of product
329 $numline = $pos;
330 $prod = 'product_batch_'.$reg[1].'_'.$reg[2];
331 $qty = 'qty_'.$reg[1].'_'.$reg[2];
332 $ent = 'entrepot_'.$reg[1].'_'.$reg[2];
333 $pu = 'pu_'.$reg[1].'_'.$reg[2];
334 $fk_commandefourndet = 'fk_commandefourndet_'.$reg[1].'_'.$reg[2];
335 $lot = 'lot_number_'.$reg[1].'_'.$reg[2];
336 $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'));
337 $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'));
338
339 $fk_commandefourndet = 'fk_commandefourndet_'.$reg[1].'_'.$reg[2];
340
341 if (getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
342 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
343 $dto = GETPOSTFLOAT("dto_".$reg[1].'_'.$reg[2]);
344 if (!empty($dto)) {
345 $unit_price = price2num((float) GETPOST("pu_".$reg[1]) * (100 - $dto) / 100, 'MU');
346 }
347 $saveprice = "saveprice_".$reg[1].'_'.$reg[2];
348 }
349 }
350
351 // We ask to move a qty
352 $qtytomove = GETPOSTFLOAT($qty);
353 $puformove = GETPOSTFLOAT($pu);
354 if ($qtytomove > 0) {
355 $productId = GETPOSTINT($prod);
356
357 if (!(GETPOSTINT($ent) > 0)) {
358 dol_syslog('No dispatch for line '.$key.' as no warehouse was chosen.');
359 $text = $langs->transnoentities('Warehouse').', '.$langs->transnoentities('Line').' '.($numline).'-'.((int) $reg[1] + 1);
360 setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
361 $error++;
362 }
363
364 // check sell-by / eat-by date is mandatory
365 /* Not required. Mandatory is checked when we insert the lot. Once lot has been recorded and is known, user can just enter the lot/serial
366 $errorMsgArr = Productlot::checkSellOrEatByMandatoryFromProductIdAndDates($productId, $dDLC, $dDLUO);
367 if (!(GETPOST($lot, 'alpha')) || !empty($errorMsgArr)) {
368 dol_syslog('No dispatch for line '.$key.' as serial/eat-by/sellby date are not set');
369 $text = $langs->transnoentities('atleast1batchfield').', '.$langs->transnoentities('Line').' '.($numline).'-'.($reg[1] + 1);
370 setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
371 $error++;
372 }*/
373 if (!GETPOST($lot, 'alpha') && !$dDLUO && !$dDLC) {
374 dol_syslog('No dispatch for line '.$key.' as serial/eat-by/sellby date are not set');
375 $text = $langs->transnoentities('atleast1batchfield').', '.$langs->transnoentities('Line').' '.($numline).'-'.((int) $reg[1] + 1);
376 setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
377 $error++;
378 }
379
380 if (!$error) {
381 $result = $object->dispatchProduct($user, $productId, $qtytomove, GETPOSTINT($ent), $puformove, GETPOST('comment'), $dDLUO, $dDLC, GETPOST($lot, 'alpha'), GETPOSTINT($fk_commandefourndet), $notrigger);
382 if ($result < 0) {
383 setEventMessages($object->error, $object->errors, 'errors');
384 $error++;
385 }
386
387 if (!$error && getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
388 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
389 $dto = GETPOSTFLOAT("dto_".$reg[1].'_'.$reg[2]);
390 //update supplier price
391 if (GETPOSTISSET($saveprice)) {
392 // TODO Use class
393 $sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price";
394 $sql .= " SET unitprice = ".price2num(GETPOST($pu), 'MU', 2);
395 $sql .= ", price = ".price2num(GETPOST($pu), 'MU', 2)." * quantity";
396 $sql .= ", remise_percent = ".price2num((empty($dto) ? 0 : $dto), 3, 2);
397 $sql .= " WHERE fk_soc = ".((int) $object->socid);
398 $sql .= " AND fk_product=".((int) $productId);
399
400 $resql = $db->query($sql);
401 }
402 }
403 }
404 }
405 }
406 }
407 }
408
409 if (!$error) {
410 $result = $object->calcAndSetStatusDispatch($user, GETPOST('closeopenorder') ? 1 : 0, GETPOST('comment'));
411 if ($result < 0) {
412 setEventMessages($object->error, $object->errors, 'errors');
413 $error++;
414 }
415 }
416
417 if ($result >= 0 && !$error) {
418 $db->commit();
419
420 setEventMessages($langs->trans("ReceptionsRecorded"), null, 'mesgs');
421
422 header("Location: dispatch.php?id=".$id);
423 exit();
424 } else {
425 $db->rollback();
426 }
427}
428
429$batch = '';
430$eatby = null;
431$sellby = 0;
432$qty = 0;
433$price = '0';
434$entrepot = 0;
435$product = 0;
436
437// Remove a dispatched line
438if ($action == 'confirm_deleteline' && $confirm == 'yes' && $permissiontoreceive) {
439 $db->begin();
440
441 $comment = '';
442
443 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
444 $result = $supplierorderdispatch->fetch($lineid);
445 if ($result > 0) {
446 $qty = $supplierorderdispatch->qty;
447 $entrepot = $supplierorderdispatch->fk_entrepot;
448 $product = $supplierorderdispatch->fk_product;
449 $price = price2num(GETPOST('price', 'alpha'), 'MU');
450 $comment = $supplierorderdispatch->comment;
451 $eatby = $supplierorderdispatch->eatby;
452 $sellby = $supplierorderdispatch->sellby;
453 $batch = $supplierorderdispatch->batch;
454
455 $result = $supplierorderdispatch->delete($user);
456 }
457 if ($result < 0) {
458 $errors = $object->errors;
459 $error++;
460 } else {
461 // If module stock is enabled and the stock increase is done on purchase order dispatching
462 if ($entrepot > 0 && isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') && empty($supplierorderdispatch->fk_reception)) {
463 $mouv = new MouvementStock($db);
464 if ($product > 0) {
465 $mouv->origin = &$object;
466 $mouv->setOrigin($object->element, $object->id);
467 $result = $mouv->livraison($user, $product, $entrepot, $qty, (float) $price, (string) $comment, '', (int) $eatby, (int) $sellby, $batch);
468 if ($result < 0) {
469 $errors = $mouv->errors;
470 $error++;
471 }
472 }
473 }
474 }
475 if ($error > 0) {
476 $db->rollback();
477 setEventMessages(null, $errors, 'errors');
478 } else {
479 $db->commit();
480 }
481}
482
483// Update a dispatched line
484if ($action == 'updateline' && $permissiontoreceive && empty($cancel)) {
485 $db->begin();
486
487 $comment = '';
488
489 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
490 $result = $supplierorderdispatch->fetch($lineid);
491 if ($result > 0) {
492 $qty = $supplierorderdispatch->qty;
493 $entrepot = $supplierorderdispatch->fk_entrepot;
494 $product = $supplierorderdispatch->fk_product;
495 $price = GETPOSTFLOAT('price');
496 $comment = $supplierorderdispatch->comment;
497 $eatby = $supplierorderdispatch->eatby;
498 $sellby = $supplierorderdispatch->sellby;
499 $batch = $supplierorderdispatch->batch;
500
501 $supplierorderdispatch->qty = GETPOSTFLOAT('qty', 'MS');
502 $supplierorderdispatch->fk_entrepot = GETPOSTINT('fk_entrepot');
503 $result = $supplierorderdispatch->update($user);
504 }
505 if ($result < 0) {
506 $error++;
507 $errors = $supplierorderdispatch->errors;
508 } else {
509 // If module stock is enabled and the stock increase is done on purchase order dispatching
510 if ($entrepot > 0 && isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER')) {
511 $mouv = new MouvementStock($db);
512 if ($product > 0) {
513 $mouv->origin = &$object;
514 $mouv->setOrigin($object->element, $object->id);
515 $result = $mouv->livraison($user, $product, $entrepot, $qty, $price, (string) $comment, '', (int) $eatby, (int) $sellby, $batch);
516 if ($result < 0) {
517 $errors = $mouv->errors;
518 $error++;
519 } else {
520 $mouv->origin = &$object;
521 $result = $mouv->reception($user, $product, $supplierorderdispatch->fk_entrepot, $supplierorderdispatch->qty, $price, (string) $comment, (int) $eatby, (int) $sellby, $batch);
522 if ($result < 0) {
523 $errors = $mouv->errors;
524 $error++;
525 }
526 }
527 }
528 }
529 }
530 if ($error > 0) {
531 $db->rollback();
532 setEventMessages($langs->trans("Error"), $errors, 'errors');
533 } else {
534 $db->commit();
535 }
536}
537
538
539/*
540 * View
541 */
542
543$now = dol_now();
544
545$form = new Form($db);
546$formproduct = new FormProduct($db);
547$warehouse_static = new Entrepot($db);
548$supplierorderdispatch = new CommandeFournisseurDispatch($db);
549
550$title = $object->ref." - ".$langs->trans('OrderDispatch');
551$help_url = 'EN:Module_Suppliers_Orders|FR:CommandeFournisseur|ES:Módulo_Pedidos_a_proveedores';
552$morejs = array('/fourn/js/lib_dispatch.js.php');
553
554llxHeader('', $title, $help_url, '', 0, 0, $morejs, '', '', 'mod-supplier-order page-card_dispatch');
555
556if ($id > 0 || !empty($ref)) {
557 $soc = new Societe($db);
558 $soc->fetch($object->socid);
559
560 $author = new User($db);
561 $author->fetch($object->user_author_id);
562
563 $head = ordersupplier_prepare_head($object);
564
565 $title = $langs->trans("SupplierOrder");
566 print dol_get_fiche_head($head, 'dispatch', $title, -1, 'order');
567
568 $formconfirm = '';
569
570 // Confirmation to delete line
571 if ($action == 'ask_deleteline') {
572 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
573 }
574
575 // Call Hook formConfirm
576 $parameters = array('lineid' => $lineid);
577 // Note that $action and $object may be modified by hook
578 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
579 if (empty($reshook)) {
580 $formconfirm .= $hookmanager->resPrint;
581 } elseif ($reshook > 0) {
582 $formconfirm = $hookmanager->resPrint;
583 }
584
585 // Print form confirm
586 print $formconfirm;
587
588 // Supplier order card
589
590 $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php'.(!empty($socid) ? '?socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
591
592 $morehtmlref = '<div class="refidno">';
593 // Ref supplier
594 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', 0, 1);
595 $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, 0, 'string', '', null, null, '', 1);
596 // Thirdparty
597 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
598 // Project
599 if (isModEnabled('project')) {
600 $langs->load("projects");
601 $morehtmlref .= '<br>';
602 if (0) { // @phpstan-ignore-line
603 $caneditproject = false; // For static analysis
604 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
605 if ($action != 'classify' && $caneditproject) {
606 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
607 }
608 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $object->socid : -1), (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
609 } else {
610 if (!empty($object->fk_project)) {
611 $proj = new Project($db);
612 $proj->fetch($object->fk_project);
613 $morehtmlref .= $proj->getNomUrl(1);
614 if ($proj->title) {
615 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
616 }
617 }
618 }
619 }
620 $morehtmlref .= '</div>';
621
622
623 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
624
625
626 print '<div class="fichecenter">';
627 print '<div class="underbanner clearboth"></div>';
628
629 print '<table class="border tableforfield" width="100%">';
630
631 // Date
632 if ($object->methode_commande_id > 0) {
633 print '<tr><td class="titlefield">'.$langs->trans("Date").'</td><td>';
634 if ($object->date_commande) {
635 print dol_print_date($object->date_commande, "dayhour")."\n";
636 }
637 print "</td></tr>";
638
639 if ($object->methode_commande) {
640 print '<tr><td>'.$langs->trans("Method").'</td><td>'.$object->getInputMethod().'</td></tr>';
641 }
642 }
643
644 // Author
645 print '<tr><td class="titlefield">'.$langs->trans("AuthorRequest").'</td>';
646 print '<td>'.$author->getNomUrl(-1, '', 0, 0, 0).'</td>';
647 print '</tr>';
648
649 $parameters = array();
650 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
651
652 print "</table>";
653
654 print '</div>';
655
656 // if ($mesg) print $mesg;
657 print '<br>';
658
659 $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.
660
661 // Line of orders
663 print '<br><span class="opacitymedium">'.$langs->trans("OrderStatusNotReadyToDispatch").'</span>';
664 }
665
666
667 print '<br>';
668
669 $listwarehouses = array();
670
674 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
675 $formproduct = new FormProduct($db);
676 $formproduct->loadWarehouses();
677 $entrepot = new Entrepot($db);
678 $listwarehouses = $entrepot->list_array(1);
679
680
681 if (empty($conf->reception->enabled)) {
682 print '<form method="POST" action="dispatch.php?id='.$object->id.'">';
683 } else {
684 print '<form method="post" action="'.dol_buildpath('/reception/card.php', 1).'?originid='.$object->id.'&origin=supplierorder">';
685 }
686
687 print '<input type="hidden" name="token" value="'.newToken().'">';
688 if (empty($conf->reception->enabled)) {
689 print '<input type="hidden" name="action" value="dispatch">';
690 } else {
691 print '<input type="hidden" name="action" value="create">';
692 }
693
694 print '<div class="div-table-responsive-no-min">';
695 print '<table class="noborder centpercent">';
696
697 // Set $products_dispatched with qty dispatched for each product id
698 $products_dispatched = array();
699 $sql = "SELECT l.rowid, cfd.fk_product, sum(cfd.qty) as qty";
700 $sql .= " FROM ".MAIN_DB_PREFIX."receptiondet_batch as cfd";
701 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseurdet as l on l.rowid = cfd.fk_elementdet";
702 $sql .= " WHERE cfd.fk_element = ".((int) $object->id);
703 $sql .= " GROUP BY l.rowid, cfd.fk_product";
704
705 $resql = $db->query($sql);
706 if ($resql) {
707 $num = $db->num_rows($resql);
708 $i = 0;
709
710 if ($num) {
711 while ($i < $num) {
712 $objd = $db->fetch_object($resql);
713 $products_dispatched[$objd->rowid] = price2num($objd->qty, 'MS');
714 $i++;
715 }
716 }
717 $db->free($resql);
718 }
719
720 //$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,";
721 $sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, l.qty as qty,";
722 $sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse";
723
724 // Enable hooks to alter the SQL query (SELECT)
725 $parameters = array();
726 $reshook = $hookmanager->executeHooks(
727 'printFieldListSelect',
728 $parameters,
729 $object,
730 $action
731 );
732 if ($reshook < 0) {
733 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
734 }
735 $sql .= $hookmanager->resPrint;
736
737 $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l";
738 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON l.fk_product=p.rowid";
739 $sql .= " WHERE l.fk_commande = ".((int) $object->id);
740 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
741 $sql .= " AND l.product_type = 0";
742 }
743
744 // Enable hooks to alter the SQL query (WHERE)
745 $parameters = array();
746 $reshook = $hookmanager->executeHooks(
747 'printFieldListWhere',
748 $parameters,
749 $object,
750 $action
751 );
752 if ($reshook < 0) {
753 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
754 }
755 $sql .= $hookmanager->resPrint;
756
757 //$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
758 $sql .= " ORDER BY l.rang, p.ref, p.label";
759
760 // Nb of predefined product lines to dispatch (already done or not) if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is off (default)
761 // or nb of line that remain to dispatch if SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED is on.
762 $nbproduct = 0;
763
764 $resql = $db->query($sql);
765 if ($resql) {
766 $num = $db->num_rows($resql);
767 $i = 0;
768
769 if ($num) {
770 print '<tr class="liste_titre">';
771
772 print '<td>'.$langs->trans("Description").'</td>';
773 if (isModEnabled('productbatch')) {
774 print '<td class="dispatch_batch_number_title">'.$langs->trans("batch_number").'</td>';
775 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
776 print '<td class="dispatch_dlc_title">'.$langs->trans("SellByDate").'</td>';
777 }
778 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
779 print '<td class="dispatch_dluo_title">'.$langs->trans("EatByDate").'</td>';
780 }
781 } else {
782 print '<td></td>';
783 print '<td></td>';
784 print '<td></td>';
785 }
786 print '<td class="right">'.$langs->trans("SupplierRef").'</td>';
787 print '<td class="right">'.$langs->trans("QtyOrdered").'</td>';
788 print '<td class="right">'.$langs->trans("QtyDispatchedShort").'</td>';
789 print ' <td class="right">'.$langs->trans("QtyToDispatchShort");
790 print '<br><a href="#" id="autoreset">'.img_picto($langs->trans("Reset"), 'eraser', 'class="pictofixedwidth opacitymedium"').$langs->trans("Reset").'</a></td>';
791 print '<td width="32"></td>';
792
793 if (getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
794 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
795 print '<td class="right">'.$langs->trans("Price").'</td>';
796 print '<td class="right">'.$langs->trans("ReductionShort").' (%)</td>';
797 print '<td class="right">'.$langs->trans("UpdatePrice").'</td>';
798 }
799 }
800
801 print '<td align="right">'.$langs->trans("Warehouse");
802
803 // Select warehouse to force it everywhere
804 if (count($listwarehouses) > 1) {
805 print '<br>'.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, $langs->trans("ForceTo"), 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1);
806 } elseif (count($listwarehouses) == 1) {
807 print '<br>'.$form->selectarray('fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0, '', 0, 0, $disabled, '', 'minwidth100 maxwidth300', 1);
808 }
809
810 print '</td>';
811
812 // Enable hooks to append additional columns
813 $parameters = array();
814 $reshook = $hookmanager->executeHooks(
815 'printFieldListTitle',
816 $parameters,
817 $object,
818 $action
819 );
820 if ($reshook < 0) {
821 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
822 }
823 print $hookmanager->resPrint;
824
825 print "</tr>\n";
826 }
827
828 $nbfreeproduct = 0; // Nb of lines of free products/services
829
830 $conf->cache['product'] = array();
831
832 // Loop on each source order line (may be more or less than current number of lines in llx_commande_fournisseurdet)
833 while ($i < $num) {
834 $objp = $db->fetch_object($resql);
835
836 // We don't display free products
837 if (!$objp->fk_product > 0) {
838 $nbfreeproduct++;
839 } else {
840 $alreadydispatched = isset($products_dispatched[$objp->rowid]) ? $products_dispatched[$objp->rowid] : 0;
841 $remaintodispatch = price2num($objp->qty - ((float) $alreadydispatched), 5); // Calculation of dispatched
842 if ($remaintodispatch < 0 && !getDolGlobalString('SUPPLIER_ORDER_ALLOW_NEGATIVE_QTY_FOR_SUPPLIER_ORDER_RETURN')) {
843 $remaintodispatch = 0;
844 }
845
846 if ($remaintodispatch || !getDolGlobalString('SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED')) {
847 $nbproduct++;
848
849 // To show detail cref and description value, we must make calculation by cref
850 // print ($objp->cref?' ('.$objp->cref.')':'');
851 // if ($objp->description) print '<br>'.nl2br($objp->description);
852 $suffix = '_0_'.$i;
853
854 print "\n";
855 print '<!-- Line to dispatch '.$suffix.' -->'."\n";
856 // hidden fields for js function
857 print '<input id="qty_ordered'.$suffix.'" type="hidden" value="'.$objp->qty.'">';
858 print '<input id="qty_dispatched'.$suffix.'" type="hidden" value="'.(float) $alreadydispatched.'">';
859 print '<tr class="oddeven">';
860
861 if (empty($conf->cache['product'][$objp->fk_product])) {
862 $tmpproduct = new Product($db);
863 $tmpproduct->fetch($objp->fk_product);
864 $conf->cache['product'][$objp->fk_product] = $tmpproduct;
865 } else {
866 $tmpproduct = $conf->cache['product'][$objp->fk_product];
867 }
868
869 $linktoprod = $tmpproduct->getNomUrl(1);
870 $linktoprod .= ' - '.$objp->label."\n";
871
872 if (isModEnabled('productbatch')) {
873 if ($objp->tobatch) {
874 // Product
875 print '<td>';
876 print $linktoprod;
877 print "</td>";
878 print '<td class="dispatch_batch_number"></td>';
879 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
880 print '<td class="dispatch_dlc"></td>';
881 }
882 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
883 print '<td class="dispatch_dluo"></td>';
884 }
885 } else {
886 // Product
887 print '<td>';
888 print $linktoprod;
889 print "</td>";
890 print '<td class="dispatch_batch_number">';
891 print '<span class="opacitymedium small">'.$langs->trans("ProductDoesNotUseBatchSerial").'</small>';
892 print '</td>';
893 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
894 print '<td class="dispatch_dlc"></td>';
895 }
896 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
897 print '<td class="dispatch_dluo"></td>';
898 }
899 }
900 } else {
901 print '<td colspan="4">';
902 print $linktoprod;
903 print "</td>";
904 }
905
906 // Define unit price for PMP calculation
907 $up_ht_disc = $objp->subprice;
908 if (!empty($objp->remise_percent) && !getDolGlobalString('STOCK_EXCLUDE_DISCOUNT_FOR_PMP')) {
909 $up_ht_disc = price2num($up_ht_disc * (100 - $objp->remise_percent) / 100, 'MU');
910 }
911
912 // Supplier ref
913 print '<td class="right">'.$objp->sref.'</td>';
914
915 // Qty ordered
916 print '<td class="right">'.$objp->qty.'</td>';
917
918 // Already dispatched
919 print '<td class="right">'.$alreadydispatched.'</td>';
920
921 if (isModEnabled('productbatch') && $objp->tobatch > 0) {
922 $type = 'batch';
923 print '<td class="right">';
924 print '</td>'; // Qty to dispatch
925 print '<td>';
926 //print img_picto($langs->trans('AddDispatchBatchLine'), 'split', 'class="splitbutton" onClick="addDispatchLine(' . $i . ',\'' . $type . '\')"');
927 print '</td>'; // Dispatch column
928 print '<td></td>'; // Warehouse column
929
930 // Enable hooks to append additional columns
931 $parameters = array(
932 // allows hook to distinguish between the rows with information and the rows with dispatch form input
933 'is_information_row' => true,
934 'i' => $i,
935 'suffix' => $suffix,
936 'objp' => $objp,
937 );
938 $reshook = $hookmanager->executeHooks(
939 'printFieldListValue',
940 $parameters,
941 $object,
942 $action
943 );
944 if ($reshook < 0) {
945 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
946 }
947 print $hookmanager->resPrint;
948
949 print '</tr>';
950
951 print '<tr class="oddeven" name="'.$type.$suffix.'">';
952 print '<td>';
953 print '<input name="fk_commandefourndet'.$suffix.'" type="hidden" value="'.$objp->rowid.'">';
954 print '<input name="product_batch'.$suffix.'" type="hidden" value="'.$objp->fk_product.'">';
955
956 print '<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
957 if (getDolGlobalString('SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT')) { // Not tested !
958 print $langs->trans("BuyingPrice").': <input class="maxwidth75" name="pu'.$suffix.'" type="text" value="'.price($up_ht_disc).'">';
959 } else {
960 print '<input class="maxwidth75" name="pu'.$suffix.'" type="hidden" value="'.price($up_ht_disc).'">';
961 }
962
963 print '</td>';
964
965 print '<td>';
966 print '<input type="text" class="inputlotnumber quatrevingtquinzepercent" id="lot_number'.$suffix.'" name="lot_number'.$suffix.'" value="'.GETPOST('lot_number'.$suffix).'">';
967 print '</td>';
968 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
969 print '<td class="nowraponall">';
970 $dlcdatesuffix = dol_mktime(0, 0, 0, GETPOSTINT('dlc'.$suffix.'month'), GETPOSTINT('dlc'.$suffix.'day'), GETPOSTINT('dlc'.$suffix.'year'));
971 print $form->selectDate($dlcdatesuffix, 'dlc'.$suffix, 0, 0, 1, '');
972 print '</td>';
973 }
974 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
975 print '<td class="nowraponall">';
976 $dluodatesuffix = dol_mktime(0, 0, 0, GETPOSTINT('dluo'.$suffix.'month'), GETPOSTINT('dluo'.$suffix.'day'), GETPOSTINT('dluo'.$suffix.'year'));
977 print $form->selectDate($dluodatesuffix, 'dluo'.$suffix, 0, 0, 1, '');
978 print '</td>';
979 }
980 print '<td colspan="3">&nbsp;</td>'; // Supplier ref + Qty ordered + qty already dispatched
981 } else {
982 $type = 'dispatch';
983 $colspan = 7;
984 $colspan = (getDolGlobalString('PRODUCT_DISABLE_SELLBY')) ? --$colspan : $colspan;
985 $colspan = (getDolGlobalString('PRODUCT_DISABLE_EATBY')) ? --$colspan : $colspan;
986 print '<td class="right">';
987 print '</td>'; // Qty to dispatch
988 print '<td>';
989 //print img_picto($langs->trans('AddStockLocationLine'), 'split', 'class="splitbutton" onClick="addDispatchLine(' . $i . ',\'' . $type . '\')"');
990 print '</td>'; // Dispatch column
991 print '<td></td>'; // Warehouse column
992
993 // Enable hooks to append additional columns
994 $parameters = array(
995 // allows hook to distinguish between the rows with information and the rows with dispatch form input
996 'is_information_row' => true,
997 'i' => $i,
998 'suffix' => $suffix,
999 'objp' => $objp,
1000 );
1001 $reshook = $hookmanager->executeHooks(
1002 'printFieldListValue',
1003 $parameters,
1004 $object,
1005 $action
1006 );
1007 if ($reshook < 0) {
1008 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1009 }
1010 print $hookmanager->resPrint;
1011
1012 print '</tr>';
1013
1014 print '<tr class="oddeven" name="'.$type.$suffix.'">';
1015 print '<td colspan="'.$colspan.'">';
1016 print '<input name="fk_commandefourndet'.$suffix.'" type="hidden" value="'.$objp->rowid.'">';
1017 print '<input name="product'.$suffix.'" type="hidden" value="'.$objp->fk_product.'">';
1018
1019 print '<!-- This is a up (may include discount or not depending on STOCK_EXCLUDE_DISCOUNT_FOR_PMP. will be used for PMP calculation) -->';
1020 if (getDolGlobalString('SUPPLIER_ORDER_EDIT_BUYINGPRICE_DURING_RECEIPT')) { // Not tested !
1021 print $langs->trans("BuyingPrice").': <input class="maxwidth75" name="pu'.$suffix.'" type="text" value="'.price2num($up_ht_disc, 'MU').'">';
1022 } else {
1023 print '<input class="maxwidth75" name="pu'.$suffix.'" type="hidden" value="'.price2num($up_ht_disc, 'MU').'">';
1024 }
1025
1026 print '</td>';
1027 }
1028
1029 // Qty to dispatch
1030 print '<td class="right nowrap">';
1031 if ($remaintodispatch > 0) {
1032 $btnLabel = $langs->trans("Fill").' : '.$remaintodispatch;
1033 print '<button class="auto-fill-qty btn-low-emphasis --btn-icon" data-rowname="qty'.$suffix.'" data-value="'.$remaintodispatch.'" title="'.dol_escape_htmltag($btnLabel).'" aria-label="'.dol_escape_htmltag($btnLabel).'" >'.img_picto($btnLabel, 'fa-arrow-right', 'aria-hidden="true"', 0, 0, 1).'</button>';
1034 }
1035 print '<input id="qty'.$suffix.'" name="qty'.$suffix.'" type="number" step="any" class="width75 right qtydispatchinput" value="'.(GETPOSTISSET('qty'.$suffix) ? GETPOSTINT('qty'.$suffix) : (!getDolGlobalString('SUPPLIER_ORDER_DISPATCH_FORCE_QTY_INPUT_TO_ZERO') ? $remaintodispatch : 0)).'">';
1036 print '<button class="resetline btn-low-emphasis --btn-icon" id="reset'.$suffix.'" title="'.dol_escape_htmltag($langs->trans("Reset")).'" >'.img_picto($langs->trans("Reset"), 'eraser', 'aria-hidden="true"', 0, 0, 1).'</button>';
1037 print '</td>';
1038
1039 print '<td>';
1040 if (isModEnabled('productbatch') && $objp->tobatch > 0) {
1041 $type = 'batch';
1042 print img_picto($langs->trans('AddStockLocationLine'), 'split', 'class="splitbutton" onClick="addDispatchLine('.$i.', \''.$type.'\')"');
1043 } else {
1044 $type = 'dispatch';
1045 print img_picto($langs->trans('AddStockLocationLine'), 'split', 'class="splitbutton" onClick="addDispatchLine('.$i.', \''.$type.'\')"');
1046 }
1047 print '</td>';
1048
1049 if (getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
1050 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
1051 // Price
1052 print '<td class="right">';
1053 print '<input id="pu'.$suffix.'" name="pu'.$suffix.'" type="text" size="8" value="'.price((GETPOST('pu'.$suffix) != '' ? price2num(GETPOST('pu'.$suffix)) : $up_ht_disc)).'">';
1054 print '</td>';
1055
1056 // Discount
1057 print '<td class="right">';
1058 print '<input id="dto'.$suffix.'" name="dto'.$suffix.'" type="text" size="8" value="'.(GETPOST('dto'.$suffix) != '' ? GETPOST('dto'.$suffix) : '').'">';
1059 print '</td>';
1060
1061 // Save price
1062 print '<td class="center">';
1063 print '<input class="flat checkformerge" type="checkbox" name="saveprice'.$suffix.'" value="'.(GETPOST('saveprice'.$suffix) != '' ? GETPOST('saveprice'.$suffix) : '').'">';
1064 print '</td>';
1065 }
1066 }
1067
1068 // Warehouse
1069 print '<td class="right">';
1070 if (count($listwarehouses) > 1) {
1071 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);
1072 } elseif (count($listwarehouses) == 1) {
1073 print $formproduct->selectWarehouses(GETPOST("entrepot".$suffix) ? GETPOST("entrepot".$suffix) : ($objp->fk_default_warehouse ? $objp->fk_default_warehouse : ''), "entrepot".$suffix, '', 0, 0, $objp->fk_product, '', 1, 0, array(), 'csswarehouse'.$suffix);
1074 } else {
1075 $langs->load("errors");
1076 print $langs->trans("ErrorNoWarehouseDefined");
1077 }
1078 print "</td>\n";
1079
1080 // Enable hooks to append additional columns
1081 $parameters = array(
1082 'is_information_row' => false, // this is a dispatch form row
1083 'i' => $i,
1084 'suffix' => $suffix,
1085 'objp' => $objp,
1086 );
1087 $reshook = $hookmanager->executeHooks(
1088 'printFieldListValue',
1089 $parameters,
1090 $object,
1091 $action
1092 );
1093 if ($reshook < 0) {
1094 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1095 }
1096 print $hookmanager->resPrint;
1097
1098 print "</tr>\n";
1099 }
1100 }
1101 $i++;
1102 }
1103 $db->free($resql);
1104 } else {
1105 dol_print_error($db);
1106 }
1107
1108 print "</table>\n";
1109 print '</div>';
1110
1111 if ($nbproduct) {
1112 $checkboxlabel = $langs->trans("CloseReceivedSupplierOrdersAutomatically", $langs->transnoentitiesnoconv('StatusOrderReceivedAll'));
1113
1114 print '<div class="center">';
1115 $parameters = array();
1116 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1117 // modified by hook
1118 if (empty($reshook)) {
1119 if (empty($conf->reception->enabled)) {
1120 print $langs->trans("Comment").' : ';
1121 print '<input type="text" class="minwidth400" maxlength="128" name="comment" value="';
1122 print GETPOSTISSET("comment") ? GETPOST("comment") : $langs->trans("DispatchSupplierOrder", $object->ref);
1123 // print ' / '.$object->ref_supplier; // Not yet available
1124 print '" class="flat"><br>';
1125
1126 print '<input type="checkbox" checked="checked" name="closeopenorder"> '.$checkboxlabel;
1127 }
1128
1129 $dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive") : $langs->trans("CreateReception");
1130
1131 print '<br>';
1132 print '<input type="hidden" name="backtopageforcancel" value="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'">';
1133 print '<input type="submit" class="button" name="dispatch" value="'.dol_escape_htmltag($dispatchBt).'"';
1134 $disabled = 0;
1135 if (!$permissiontoreceive) {
1136 $disabled = 1;
1137 }
1138 if (count($listwarehouses) <= 0) {
1139 $disabled = 1;
1140 }
1141 if ($disabled) {
1142 print ' disabled';
1143 }
1144
1145 print '>';
1146 }
1147 print '</div>';
1148 }
1149
1150 // Message if nothing to dispatch
1151 if (!$nbproduct) {
1152 print "<br>\n";
1153 if (!getDolGlobalString('SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED')) {
1154 print '<div class="opacitymedium">'.$langs->trans("NoPredefinedProductToDispatch").'</div>'; // No predefined line at all
1155 } else {
1156 print '<div class="opacitymedium">'.$langs->trans("NoMorePredefinedProductToDispatch").'</div>'; // No predefined line that remain to be dispatched.
1157 }
1158 }
1159
1160 print '</form>';
1161 }
1162
1163 print dol_get_fiche_end();
1164
1165 // default warehouse processing
1166 print '<script type="text/javascript">
1167 $(document).ready(function () {
1168 $("select[name=fk_default_warehouse]").change(function() {
1169 var fk_default_warehouse = $("option:selected", this).val();
1170 $("select[name^=entrepot_]").val(fk_default_warehouse).change();
1171 });
1172
1173 $(".auto-fill-qty").on("click touchstart", function(e){
1174 e.preventDefault();
1175 $("input[name="+$(this).data("rowname")+"]").val($(this).data("value")).trigger("change");
1176 });
1177
1178 $("#autoreset").click(function() {
1179 $(".qtydispatchinput").each(function(){
1180 id = $(this).attr("id");
1181 idtab = id.split("_");
1182 if(idtab[1] == 0){
1183 console.log(idtab);
1184 $(this).val("");
1185 $("#qty_dispatched_0_"+idtab[2]).val("0");
1186 } else {
1187 obj = $(this).parent().parent();
1188 nameobj = obj.attr("name");
1189 nametab = nameobj.split("_");
1190 obj.remove();
1191 $("tr[name^=\'"+nametab[0]+"_\'][name$=\'_"+nametab[2]+"\']:last .splitbutton").show();
1192 }
1193 });
1194 });
1195
1196 $(".resetline").click(function(e){
1197 e.preventDefault();
1198 id = $(this).attr("id");
1199 id = id.split("reset_");
1200 console.log("Reset trigger for id = qty_"+id[1]);
1201 $("#qty_"+id[1]).val("");
1202 });
1203 });
1204 </script>';
1205
1206 // List of lines already dispatched
1207 $sql = "SELECT p.rowid as pid, p.ref, p.label,";
1208 $sql .= " e.rowid as warehouse_id, e.ref as entrepot,";
1209 $sql .= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status, cfd.datec";
1210 $sql .= " ,cd.rowid, cd.subprice";
1211 if (isModEnabled('reception')) {
1212 $sql .= ", cfd.fk_reception, r.date_delivery";
1213 }
1214 $sql .= " FROM ".MAIN_DB_PREFIX."product as p,";
1215 $sql .= " ".MAIN_DB_PREFIX."receptiondet_batch as cfd";
1216 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseurdet as cd ON cd.rowid = cfd.fk_elementdet";
1217 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e ON cfd.fk_entrepot = e.rowid";
1218 if (isModEnabled('reception')) {
1219 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."reception as r ON cfd.fk_reception = r.rowid";
1220 }
1221 $sql .= " WHERE cfd.fk_element = ".((int) $object->id);
1222 $sql .= " AND cfd.fk_product = p.rowid";
1223 $sql .= " ORDER BY cfd.rowid ASC";
1224
1225 $resql = $db->query($sql);
1226 if ($resql) {
1227 $num = $db->num_rows($resql);
1228 $i = 0;
1229
1230 if ($num > 0) {
1231 print "<br>\n";
1232
1233 print load_fiche_titre($langs->trans("ReceivingForSameOrder"));
1234
1235 print '<div class="div-table-responsive">';
1236 print '<table id="dispatch_received_products" class="noborder centpercent">';
1237
1238 print '<tr class="liste_titre">';
1239 // Reception ref
1240 if (isModEnabled("reception")) {
1241 print '<td>'.$langs->trans("Reception").'</td>';
1242 }
1243 // Product
1244 print '<td>'.$langs->trans("Product").'</td>';
1245 print '<td class="center">'.$langs->trans("DateCreation").'</td>';
1246 print '<td class="center">'.$langs->trans("DateDeliveryPlanned").'</td>';
1247 if (isModEnabled('productbatch')) {
1248 print '<td class="dispatch_batch_number_title">'.$langs->trans("batch_number").'</td>';
1249 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1250 print '<td class="dispatch_dlc_title">'.$langs->trans("SellByDate").'</td>';
1251 }
1252 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1253 print '<td class="dispatch_dluo_title">'.$langs->trans("EatByDate").'</td>';
1254 }
1255 }
1256 print '<td class="right">'.$langs->trans("QtyDispatched").'</td>';
1257 print '<td>'.$langs->trans("Warehouse").'</td>';
1258 print '<td>'.$langs->trans("Comment").'</td>';
1259
1260 // Status
1261 if (getDolGlobalString('SUPPLIER_ORDER_USE_DISPATCH_STATUS') && !isModEnabled("reception")) {
1262 print '<td class="center" colspan="2">'.$langs->trans("Status").'</td>';
1263 } elseif (isModEnabled("reception")) {
1264 print '<td class="center"></td>';
1265 }
1266
1267 print '<td class="center" colspan="2"></td>';
1268
1269 print "</tr>\n";
1270
1271
1272 while ($i < $num) {
1273 $objp = $db->fetch_object($resql);
1274
1275 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1276 print '<form name="editdispatchedlines" id="editdispatchedlines" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'#line_'.GETPOSTINT('lineid').'" method="POST">
1277 <input type="hidden" name="token" value="'.newToken().'">
1278 <input type="hidden" name="action" value="updateline">
1279 <input type="hidden" name="mode" value="">
1280 <input type="hidden" name="lineid" value="'.$objp->dispatchlineid.'">';
1281 }
1282
1283 print '<tr class="oddeven" id="line_'.$objp->dispatchlineid.'" >';
1284
1285 // Reception ref
1286 $reception = null;
1287 if (isModEnabled("reception")) {
1288 print '<td class="nowraponall">';
1289 if (!empty($objp->fk_reception)) {
1290 $reception = new Reception($db);
1291 $reception->fetch($objp->fk_reception);
1292 print $reception->getNomUrl(1);
1293 }
1294
1295 print "</td>";
1296 }
1297
1298 // Product
1299 print '<td class="tdoverflowmax150">';
1300 if (empty($conf->cache['product'][$objp->fk_product])) {
1301 $tmpproduct = new Product($db);
1302 $tmpproduct->fetch($objp->fk_product);
1303 $conf->cache['product'][$objp->fk_product] = $tmpproduct;
1304 } else {
1305 $tmpproduct = $conf->cache['product'][$objp->fk_product];
1306 }
1307 print $tmpproduct->getNomUrl(1);
1308 print ' - '.$objp->label;
1309 print "</td>\n";
1310
1311 // Date creation
1312 print '<td class="center">'.dol_print_date($db->jdate($objp->datec), 'day').'</td>';
1313
1314 // Date delivery of reception
1315 if (isModEnabled('reception')) {
1316 print '<td class="center">';
1317 if (!empty($objp->date_delivery)) {
1318 print dol_print_date($db->jdate($objp->date_delivery), 'day');
1319 }
1320 print '</td>';
1321 } else {
1322 print '<td class="center"></td>';
1323 }
1324
1325 // Batch / Eat by / Sell by
1326 if (isModEnabled('productbatch')) {
1327 if ($objp->batch) {
1328 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
1329 $lot = new Productlot($db);
1330 $lot->fetch(0, $objp->pid, $objp->batch);
1331 print '<td class="dispatch_batch_number" data-col="batch" data-batch="' . dolPrintHTMLForAttribute($objp->batch) . '" data-productid="' . $objp->fk_product . '" >'.$lot->getNomUrl(1).'</td>';
1332 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1333 print '<td class="dispatch_dlc">'.dol_print_date($lot->sellby, 'day').'</td>';
1334 }
1335 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1336 print '<td class="dispatch_dluo">'.dol_print_date($lot->eatby, 'day').'</td>';
1337 }
1338 } else {
1339 print '<td class="dispatch_batch_number" data-col="batch" data-batch="" data-productid="' . $objp->fk_product . '" ></td>';
1340 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1341 print '<td class="dispatch_dlc"></td>';
1342 }
1343 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1344 print '<td class="dispatch_dluo"></td>';
1345 }
1346 }
1347 }
1348
1349 // Qty
1350 print '<td class="right">';
1351 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1352 print '<input style="width: 50px;" type="text" min="1" name="qty" value="'.$objp->qty.'" />';
1353 } else {
1354 print $objp->qty;
1355 }
1356 print '<input type="hidden" name="price" value="'.$objp->subprice.'" />';
1357 print '</td>';
1358 // Warehouse
1359 print '<td class="tdoverflowmax150">';
1360 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1361 $warehouse_id = GETPOSTINT("fk_entrepot") ? GETPOSTINT("fk_entrepot") : ($objp->warehouse_id ? $objp->warehouse_id : '');
1362 if (count($listwarehouses) > 1) {
1363 print $formproduct->selectWarehouses($warehouse_id, "fk_entrepot", '', 1, 0, $objp->fk_product, '', 1, 1, array(), 'csswarehouse');
1364 } elseif (count($listwarehouses) == 1) {
1365 print $formproduct->selectWarehouses($warehouse_id, "fk_entrepot", '', 0, 0, $objp->fk_product, '', 1, 1, array(), 'csswarehouse');
1366 } else {
1367 $langs->load("errors");
1368 print $langs->trans("ErrorNoWarehouseDefined");
1369 }
1370 } else {
1371 $warehouse_static->id = $objp->warehouse_id;
1372 $warehouse_static->label = $objp->entrepot;
1373 print $warehouse_static->getNomUrl(1);
1374 }
1375 print '</td>';
1376
1377 // Comment
1378 print '<td class="tdoverflowmax300" style="white-space: pre;">'.$objp->comment.'</td>';
1379
1380 // Status
1381 if (getDolGlobalString('SUPPLIER_ORDER_USE_DISPATCH_STATUS') && !isModEnabled("reception")) {
1382 print '<td class="right">';
1383 $supplierorderdispatch->status = (empty($objp->status) ? 0 : $objp->status);
1384 // print $supplierorderdispatch->status;
1385 print $supplierorderdispatch->getLibStatut(5);
1386 print '</td>';
1387
1388 // Add button to check/uncheck dispatching
1389 print '<td class="center">';
1390 if (!$permissiontocontrol) {
1391 if (empty($objp->status)) {
1392 print '<a class="button buttonRefused" href="#">'.$langs->trans("Approve").'</a>';
1393 print '<a class="button buttonRefused" href="#">'.$langs->trans("Deny").'</a>';
1394 } else {
1395 print '<a class="button buttonRefused" href="#">'.$langs->trans("Disapprove").'</a>';
1396 print '<a class="button buttonRefused" href="#">'.$langs->trans("Deny").'</a>';
1397 }
1398 } else {
1399 $disabled = '';
1400 if ($object->status == $object::STATUS_RECEIVED_COMPLETELY) {
1401 $disabled = 1;
1402 }
1403 if (empty($objp->status)) {
1404 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=checkdispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Approve").'</a>';
1405 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=denydispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Deny").'</a>';
1406 }
1407 if ($objp->status == 1) {
1408 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=uncheckdispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Reinit").'</a>';
1409 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=denydispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Deny").'</a>';
1410 }
1411 if ($objp->status == 2) {
1412 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=uncheckdispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Reinit").'</a>';
1413 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=checkdispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Approve").'</a>';
1414 }
1415 }
1416 print '</td>';
1417 } elseif (isModEnabled("reception")) {
1418 print '<td class="right">';
1419 if ($reception !== null && !empty($reception->id)) {
1420 print $reception->getLibStatut(5);
1421 }
1422 print '</td>';
1423 }
1424
1425 // Action
1426 if ($action != 'editline' || $lineid != $objp->dispatchlineid) {
1427 if (($reception === null) || empty($reception->id) || ($reception->statut == Reception::STATUS_DRAFT)) { // only allow edit on draft reception
1428 print '<td class="linecoledit center">';
1429 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&token='.newToken().'&lineid='.$objp->dispatchlineid.'#line_'.$objp->dispatchlineid.'">';
1430 print img_edit();
1431 print '</a>';
1432 print '</td>';
1433
1434 print '<td class="linecoldelete center">';
1435 print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=ask_deleteline&token='.newToken().'&lineid='.$objp->dispatchlineid.'#dispatch_received_products">';
1436 print img_delete();
1437 print '</a>';
1438 print '</td>';
1439 } else {
1440 print '<td></td><td></td>';
1441 }
1442 } else {
1443 print '<td class="center valignmiddle">';
1444 print '<input type="submit" class="button button-save" id="savelinebutton" name="save" value="'.$langs->trans("Save").'" />';
1445 print '</td>';
1446 print '<td class="center valignmiddle">';
1447 print '<input type="submit" class="button button-cancel" id="cancellinebutton" name="cancel" value="'.$langs->trans("Cancel").'" />';
1448 print '</td>';
1449 }
1450
1451
1452 print "</tr>\n";
1453 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1454 print '</form>';
1455 }
1456
1457 $i++;
1458 }
1459 $db->free($resql);
1460
1461 print "</table>\n";
1462 print '</div>';
1463 }
1464 } else {
1466 }
1467}
1468
1469// End of page
1470llxFooter();
1471$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
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:73
Class to manage table ReceptionLineBatch.
Class to manage predefined suppliers products.
const STATUS_RECEIVED_PARTIALLY
Received partially.
const STATUS_CANCELED
Order canceled.
const STATUS_RECEIVED_COMPLETELY
Received completely.
const STATUS_ORDERSENT
Order sent, shipment on process.
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 stock movements.
Class to manage products or services.
Class with list of lots and properties.
Class to manage projects.
Class to manage receptions.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
ordersupplier_prepare_head(CommandeFournisseur $object)
Prepare array with list of tabs.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
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.
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, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
dolPrintHTMLForAttribute($s, $escapeonlyhtmltags=0, $allowothertags=array())
Return a string ready to be output into an HTML attribute (alt, title, data-html, ....
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
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.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
multi select button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
treeview li table
No Email.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
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.