dolibarr 25.0.0-alpha
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 if ($objp->tobatch == 2) {
1044 // Product managed with unique serial numbers: allow to enter several serial numbers at once (one line per serial)
1045 print img_picto($langs->trans('EnterMultipleSerialNumbers'), 'barcode', 'class="splitbutton marginleftonly" onClick="addDispatchLinesFromSerialList('.$i.', \''.$type.'\')"');
1046 }
1047 } else {
1048 $type = 'dispatch';
1049 print img_picto($langs->trans('AddStockLocationLine'), 'split', 'class="splitbutton" onClick="addDispatchLine('.$i.', \''.$type.'\')"');
1050 }
1051 print '</td>';
1052
1053 if (getDolGlobalString('SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT')) {
1054 if (!isModEnabled("multicurrency") && empty($conf->dynamicprices->enabled)) {
1055 // Price
1056 print '<td class="right">';
1057 print '<input id="pu'.$suffix.'" name="pu'.$suffix.'" type="text" size="8" value="'.price((GETPOST('pu'.$suffix) != '' ? price2num(GETPOST('pu'.$suffix)) : $up_ht_disc)).'">';
1058 print '</td>';
1059
1060 // Discount
1061 print '<td class="right">';
1062 print '<input id="dto'.$suffix.'" name="dto'.$suffix.'" type="text" size="8" value="'.(GETPOST('dto'.$suffix) != '' ? GETPOST('dto'.$suffix) : '').'">';
1063 print '</td>';
1064
1065 // Save price
1066 print '<td class="center">';
1067 print '<input class="flat checkformerge" type="checkbox" name="saveprice'.$suffix.'" value="'.(GETPOST('saveprice'.$suffix) != '' ? GETPOST('saveprice'.$suffix) : '').'">';
1068 print '</td>';
1069 }
1070 }
1071
1072 // Warehouse
1073 print '<td class="right">';
1074 if (count($listwarehouses) > 1) {
1075 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);
1076 } elseif (count($listwarehouses) == 1) {
1077 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);
1078 } else {
1079 $langs->load("errors");
1080 print $langs->trans("ErrorNoWarehouseDefined");
1081 }
1082 print "</td>\n";
1083
1084 // Enable hooks to append additional columns
1085 $parameters = array(
1086 'is_information_row' => false, // this is a dispatch form row
1087 'i' => $i,
1088 'suffix' => $suffix,
1089 'objp' => $objp,
1090 );
1091 $reshook = $hookmanager->executeHooks(
1092 'printFieldListValue',
1093 $parameters,
1094 $object,
1095 $action
1096 );
1097 if ($reshook < 0) {
1098 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1099 }
1100 print $hookmanager->resPrint;
1101
1102 print "</tr>\n";
1103 }
1104 }
1105 $i++;
1106 }
1107 $db->free($resql);
1108 } else {
1109 dol_print_error($db);
1110 }
1111
1112 print "</table>\n";
1113 print '</div>';
1114
1115 if ($nbproduct) {
1116 $checkboxlabel = $langs->trans("CloseReceivedSupplierOrdersAutomatically", $langs->transnoentitiesnoconv('StatusOrderReceivedAll'));
1117
1118 print '<div class="center">';
1119 $parameters = array();
1120 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1121 // modified by hook
1122 if (empty($reshook)) {
1123 if (empty($conf->reception->enabled)) {
1124 print $langs->trans("Comment").' : ';
1125 print '<input type="text" class="minwidth400" maxlength="128" name="comment" value="';
1126 print GETPOSTISSET("comment") ? GETPOST("comment") : $langs->trans("DispatchSupplierOrder", $object->ref);
1127 // print ' / '.$object->ref_supplier; // Not yet available
1128 print '" class="flat"><br>';
1129
1130 print '<input type="checkbox" checked="checked" name="closeopenorder"> '.$checkboxlabel;
1131 }
1132
1133 $dispatchBt = empty($conf->reception->enabled) ? $langs->trans("Receive") : $langs->trans("CreateReception");
1134
1135 print '<br>';
1136 print '<input type="hidden" name="backtopageforcancel" value="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'">';
1137 print '<input type="submit" class="button" name="dispatch" value="'.dol_escape_htmltag($dispatchBt).'"';
1138 $disabled = 0;
1139 if (!$permissiontoreceive) {
1140 $disabled = 1;
1141 }
1142 if (count($listwarehouses) <= 0) {
1143 $disabled = 1;
1144 }
1145 if ($disabled) {
1146 print ' disabled';
1147 }
1148
1149 print '>';
1150 }
1151 print '</div>';
1152 }
1153
1154 // Message if nothing to dispatch
1155 if (!$nbproduct) {
1156 print "<br>\n";
1157 if (!getDolGlobalString('SUPPLIER_ORDER_DISABLE_STOCK_DISPATCH_WHEN_TOTAL_REACHED')) {
1158 print '<div class="opacitymedium">'.$langs->trans("NoPredefinedProductToDispatch").'</div>'; // No predefined line at all
1159 } else {
1160 print '<div class="opacitymedium">'.$langs->trans("NoMorePredefinedProductToDispatch").'</div>'; // No predefined line that remain to be dispatched.
1161 }
1162 }
1163
1164 print '</form>';
1165 }
1166
1167 print dol_get_fiche_end();
1168
1169 // default warehouse processing
1170 print '<script type="text/javascript">
1171 $(document).ready(function () {
1172 $("select[name=fk_default_warehouse]").change(function() {
1173 var fk_default_warehouse = $("option:selected", this).val();
1174 $("select[name^=entrepot_]").val(fk_default_warehouse).change();
1175 });
1176
1177 $(".auto-fill-qty").on("click touchstart", function(e){
1178 e.preventDefault();
1179 $("input[name="+$(this).data("rowname")+"]").val($(this).data("value")).trigger("change");
1180 });
1181
1182 $("#autoreset").click(function() {
1183 $(".qtydispatchinput").each(function(){
1184 id = $(this).attr("id");
1185 idtab = id.split("_");
1186 if(idtab[1] == 0){
1187 console.log(idtab);
1188 $(this).val("");
1189 $("#qty_dispatched_0_"+idtab[2]).val("0");
1190 } else {
1191 obj = $(this).parent().parent();
1192 nameobj = obj.attr("name");
1193 nametab = nameobj.split("_");
1194 obj.remove();
1195 $("tr[name^=\'"+nametab[0]+"_\'][name$=\'_"+nametab[2]+"\']:last .splitbutton").show();
1196 }
1197 });
1198 });
1199
1200 $(".resetline").click(function(e){
1201 e.preventDefault();
1202 id = $(this).attr("id");
1203 id = id.split("reset_");
1204 console.log("Reset trigger for id = qty_"+id[1]);
1205 $("#qty_"+id[1]).val("");
1206 });
1207 });
1208 </script>';
1209
1210 // List of lines already dispatched
1211 $sql = "SELECT p.rowid as pid, p.ref, p.label,";
1212 $sql .= " e.rowid as warehouse_id, e.ref as entrepot,";
1213 $sql .= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status, cfd.datec";
1214 $sql .= " ,cd.rowid, cd.subprice";
1215 if (isModEnabled('reception')) {
1216 $sql .= ", cfd.fk_reception, r.date_delivery";
1217 }
1218 $sql .= " FROM ".MAIN_DB_PREFIX."product as p,";
1219 $sql .= " ".MAIN_DB_PREFIX."receptiondet_batch as cfd";
1220 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseurdet as cd ON cd.rowid = cfd.fk_elementdet";
1221 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e ON cfd.fk_entrepot = e.rowid";
1222 if (isModEnabled('reception')) {
1223 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."reception as r ON cfd.fk_reception = r.rowid";
1224 }
1225 $sql .= " WHERE cfd.fk_element = ".((int) $object->id);
1226 $sql .= " AND cfd.fk_product = p.rowid";
1227 $sql .= " ORDER BY cfd.rowid ASC";
1228
1229 $resql = $db->query($sql);
1230 if ($resql) {
1231 $num = $db->num_rows($resql);
1232 $i = 0;
1233
1234 if ($num > 0) {
1235 print "<br>\n";
1236
1237 print load_fiche_titre($langs->trans("ReceivingForSameOrder"));
1238
1239 print '<div class="div-table-responsive">';
1240 print '<table id="dispatch_received_products" class="noborder centpercent">';
1241
1242 print '<tr class="liste_titre">';
1243 // Reception ref
1244 if (isModEnabled("reception")) {
1245 print '<td>'.$langs->trans("Reception").'</td>';
1246 }
1247 // Product
1248 print '<td>'.$langs->trans("Product").'</td>';
1249 print '<td class="center">'.$langs->trans("DateCreation").'</td>';
1250 print '<td class="center">'.$langs->trans("DateDeliveryPlanned").'</td>';
1251 if (isModEnabled('productbatch')) {
1252 print '<td class="dispatch_batch_number_title">'.$langs->trans("batch_number").'</td>';
1253 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1254 print '<td class="dispatch_dlc_title">'.$langs->trans("SellByDate").'</td>';
1255 }
1256 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1257 print '<td class="dispatch_dluo_title">'.$langs->trans("EatByDate").'</td>';
1258 }
1259 }
1260 print '<td class="right">'.$langs->trans("QtyDispatched").'</td>';
1261 print '<td>'.$langs->trans("Warehouse").'</td>';
1262 print '<td>'.$langs->trans("Comment").'</td>';
1263
1264 // Status
1265 if (getDolGlobalString('SUPPLIER_ORDER_USE_DISPATCH_STATUS') && !isModEnabled("reception")) {
1266 print '<td class="center" colspan="2">'.$langs->trans("Status").'</td>';
1267 } elseif (isModEnabled("reception")) {
1268 print '<td class="center"></td>';
1269 }
1270
1271 print '<td class="center" colspan="2"></td>';
1272
1273 print "</tr>\n";
1274
1275
1276 while ($i < $num) {
1277 $objp = $db->fetch_object($resql);
1278
1279 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1280 print '<form name="editdispatchedlines" id="editdispatchedlines" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'#line_'.GETPOSTINT('lineid').'" method="POST">
1281 <input type="hidden" name="token" value="'.newToken().'">
1282 <input type="hidden" name="action" value="updateline">
1283 <input type="hidden" name="mode" value="">
1284 <input type="hidden" name="lineid" value="'.$objp->dispatchlineid.'">';
1285 }
1286
1287 print '<tr class="oddeven" id="line_'.$objp->dispatchlineid.'" >';
1288
1289 // Reception ref
1290 $reception = null;
1291 if (isModEnabled("reception")) {
1292 print '<td class="nowraponall">';
1293 if (!empty($objp->fk_reception)) {
1294 if (empty($conf->cache['reception'][$objp->fk_reception])) {
1295 $reception = new Reception($db);
1296 $reception->fetch($objp->fk_reception);
1297 $conf->cache['reception'][$objp->fk_reception] = $reception;
1298 } else {
1299 $reception = $conf->cache['reception'][$objp->fk_reception];
1300 }
1301 print $reception->getNomUrl(1);
1302 }
1303
1304 print "</td>";
1305 }
1306
1307 // Product
1308 print '<td class="tdoverflowmax150">';
1309 if (empty($conf->cache['product'][$objp->fk_product])) {
1310 $tmpproduct = new Product($db);
1311 $tmpproduct->fetch($objp->fk_product);
1312 $conf->cache['product'][$objp->fk_product] = $tmpproduct;
1313 } else {
1314 $tmpproduct = $conf->cache['product'][$objp->fk_product];
1315 }
1316 print $tmpproduct->getNomUrl(1);
1317 print ' - '.$objp->label;
1318 print "</td>\n";
1319
1320 // Date creation
1321 print '<td class="center">'.dol_print_date($db->jdate($objp->datec), 'day').'</td>';
1322
1323 // Date delivery of reception
1324 if (isModEnabled('reception')) {
1325 print '<td class="center">';
1326 if (!empty($objp->date_delivery)) {
1327 print dol_print_date($db->jdate($objp->date_delivery), 'day');
1328 }
1329 print '</td>';
1330 } else {
1331 print '<td class="center"></td>';
1332 }
1333
1334 // Batch / Eat by / Sell by
1335 if (isModEnabled('productbatch')) {
1336 if ($objp->batch) {
1337 include_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
1338 $lotcachekey = $objp->pid.'_'.$objp->batch;
1339 if (empty($conf->cache['productlot'][$lotcachekey])) {
1340 $lot = new Productlot($db);
1341 $lot->fetch(0, $objp->pid, $objp->batch);
1342 $conf->cache['productlot'][$lotcachekey] = $lot;
1343 } else {
1344 $lot = $conf->cache['productlot'][$lotcachekey];
1345 }
1346 print '<td class="dispatch_batch_number" data-col="batch" data-batch="' . dolPrintHTMLForAttribute($objp->batch) . '" data-productid="' . $objp->fk_product . '" >'.$lot->getNomUrl(1).'</td>';
1347 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1348 print '<td class="dispatch_dlc">'.dol_print_date($lot->sellby, 'day').'</td>';
1349 }
1350 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1351 print '<td class="dispatch_dluo">'.dol_print_date($lot->eatby, 'day').'</td>';
1352 }
1353 } else {
1354 print '<td class="dispatch_batch_number" data-col="batch" data-batch="" data-productid="' . $objp->fk_product . '" ></td>';
1355 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1356 print '<td class="dispatch_dlc"></td>';
1357 }
1358 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1359 print '<td class="dispatch_dluo"></td>';
1360 }
1361 }
1362 }
1363
1364 // Qty
1365 print '<td class="right">';
1366 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1367 print '<input style="width: 50px;" type="text" min="1" name="qty" value="'.$objp->qty.'" />';
1368 } else {
1369 print $objp->qty;
1370 }
1371 print '<input type="hidden" name="price" value="'.$objp->subprice.'" />';
1372 print '</td>';
1373 // Warehouse
1374 print '<td class="tdoverflowmax150">';
1375 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1376 $warehouse_id = GETPOSTINT("fk_entrepot") ? GETPOSTINT("fk_entrepot") : ($objp->warehouse_id ? $objp->warehouse_id : '');
1377 if (count($listwarehouses) > 1) {
1378 print $formproduct->selectWarehouses($warehouse_id, "fk_entrepot", '', 1, 0, $objp->fk_product, '', 1, 1, array(), 'csswarehouse');
1379 } elseif (count($listwarehouses) == 1) {
1380 print $formproduct->selectWarehouses($warehouse_id, "fk_entrepot", '', 0, 0, $objp->fk_product, '', 1, 1, array(), 'csswarehouse');
1381 } else {
1382 $langs->load("errors");
1383 print $langs->trans("ErrorNoWarehouseDefined");
1384 }
1385 } else {
1386 $warehouse_static->id = $objp->warehouse_id;
1387 $warehouse_static->label = $objp->entrepot;
1388 print $warehouse_static->getNomUrl(1);
1389 }
1390 print '</td>';
1391
1392 // Comment
1393 print '<td class="tdoverflowmax300" style="white-space: pre;">'.$objp->comment.'</td>';
1394
1395 // Status
1396 if (getDolGlobalString('SUPPLIER_ORDER_USE_DISPATCH_STATUS') && !isModEnabled("reception")) {
1397 print '<td class="right">';
1398 $supplierorderdispatch->status = (empty($objp->status) ? 0 : $objp->status);
1399 // print $supplierorderdispatch->status;
1400 print $supplierorderdispatch->getLibStatut(5);
1401 print '</td>';
1402
1403 // Add button to check/uncheck dispatching
1404 print '<td class="center">';
1405 if (!$permissiontocontrol) {
1406 if (empty($objp->status)) {
1407 print '<a class="button buttonRefused" href="#">'.$langs->trans("Approve").'</a>';
1408 print '<a class="button buttonRefused" href="#">'.$langs->trans("Deny").'</a>';
1409 } else {
1410 print '<a class="button buttonRefused" href="#">'.$langs->trans("Disapprove").'</a>';
1411 print '<a class="button buttonRefused" href="#">'.$langs->trans("Deny").'</a>';
1412 }
1413 } else {
1414 $disabled = '';
1415 if ($object->status == $object::STATUS_RECEIVED_COMPLETELY) {
1416 $disabled = 1;
1417 }
1418 if (empty($objp->status)) {
1419 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=checkdispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Approve").'</a>';
1420 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=denydispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Deny").'</a>';
1421 }
1422 if ($objp->status == 1) {
1423 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=uncheckdispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Reinit").'</a>';
1424 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=denydispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Deny").'</a>';
1425 }
1426 if ($objp->status == 2) {
1427 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=uncheckdispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Reinit").'</a>';
1428 print '<a class="button'.($disabled ? ' buttonRefused' : '').'" href="'.$_SERVER["PHP_SELF"]."?id=".$id."&action=checkdispatchline&token=".newToken()."&lineid=".$objp->dispatchlineid.'">'.$langs->trans("Approve").'</a>';
1429 }
1430 }
1431 print '</td>';
1432 } elseif (isModEnabled("reception")) {
1433 print '<td class="right">';
1434 if ($reception !== null && !empty($reception->id)) {
1435 print $reception->getLibStatut(5);
1436 }
1437 print '</td>';
1438 }
1439
1440 // Action
1441 if ($action != 'editline' || $lineid != $objp->dispatchlineid) {
1442 if (($reception === null) || empty($reception->id) || ($reception->statut == Reception::STATUS_DRAFT)) { // only allow edit on draft reception
1443 print '<td class="linecoledit center">';
1444 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&token='.newToken().'&lineid='.$objp->dispatchlineid.'#line_'.$objp->dispatchlineid.'">';
1445 print img_edit();
1446 print '</a>';
1447 print '</td>';
1448
1449 print '<td class="linecoldelete center">';
1450 print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=ask_deleteline&token='.newToken().'&lineid='.$objp->dispatchlineid.'#dispatch_received_products">';
1451 print img_delete();
1452 print '</a>';
1453 print '</td>';
1454 } else {
1455 print '<td></td><td></td>';
1456 }
1457 } else {
1458 print '<td class="center valignmiddle">';
1459 print '<input type="submit" class="button button-save" id="savelinebutton" name="save" value="'.$langs->trans("Save").'" />';
1460 print '</td>';
1461 print '<td class="center valignmiddle">';
1462 print '<input type="submit" class="button button-cancel" id="cancellinebutton" name="cancel" value="'.$langs->trans("Cancel").'" />';
1463 print '</td>';
1464 }
1465
1466
1467 print "</tr>\n";
1468 if ($action == 'editline' && $lineid == $objp->dispatchlineid) {
1469 print '</form>';
1470 }
1471
1472 $i++;
1473 }
1474 $db->free($resql);
1475
1476 print "</table>\n";
1477 print '</div>';
1478 }
1479 } else {
1480 dol_print_error($db);
1481 }
1482}
1483
1484// End of page
1485llxFooter();
1486$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:
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...
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.
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).
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.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
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.
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.
Definition html.lib.php:540
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Definition html.lib.php:181
$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.