dolibarr 21.0.0-beta
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003-2008 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2005-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Simon TOSSER <simon@kornog-computing.com>
5 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
6 * Copyright (C) 2011-2017 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2013 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
10 * Copyright (C) 2014-2017 Francis Appels <francis.appels@yahoo.com>
11 * Copyright (C) 2015 Claudio Aschieri <c.aschieri@19.coop>
12 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
13 * Copyright (C) 2016 Yasser Carreón <yacasia@gmail.com>
14 * Copyright (C) 2018 Quentin Vial-Gouteyron <quentin.vial-gouteyron@atm-consulting.fr>
15 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
16 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 3 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program. If not, see <https://www.gnu.org/licenses/>.
30 */
31
38// Load Dolibarr environment
39require '../main.inc.php';
40require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
41require_once DOL_DOCUMENT_ROOT.'/reception/class/reception.class.php';
42require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
43require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
44require_once DOL_DOCUMENT_ROOT.'/core/lib/reception.lib.php';
45require_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
46require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
48require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
49require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
50if (isModEnabled("product") || isModEnabled("service")) {
51 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
52}
53if (isModEnabled("propal")) {
54 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
55}
56require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
57require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php';
58if (isModEnabled('productbatch')) {
59 require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
60}
61if (isModEnabled('project')) {
62 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
63 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
64}
73$langs->loadLangs(array("receptions", "companies", "bills", 'deliveries', 'orders', 'stocks', 'other', 'propal', 'sendings'));
74
75if (isModEnabled('incoterm')) {
76 $langs->load('incoterm');
77}
78if (isModEnabled('productbatch')) {
79 $langs->load('productbatch');
80}
81
82$origin = GETPOST('origin', 'alpha') ? GETPOST('origin', 'alpha') : 'reception'; // Example: commande, propal
83$origin_id = GETPOSTINT('id') ? GETPOSTINT('id') : '';
84$id = $origin_id;
85if (empty($origin_id)) {
86 $origin_id = GETPOSTINT('origin_id'); // Id of order or propal
87}
88if (empty($origin_id)) {
89 $origin_id = GETPOSTINT('object_id'); // Id of order or propal
90}
91if (empty($origin_id)) {
92 $origin_id = GETPOSTINT('originid'); // Id of order or propal
93}
94$ref = GETPOST('ref', 'alpha');
95$line_id = GETPOSTINT('lineid') ? GETPOSTINT('lineid') : 0;
96$facid = GETPOSTINT('facid');
97
98$action = GETPOST('action', 'alpha');
99//Select mail models is same action as presend
100if (GETPOST('modelselected')) {
101 $action = 'presend';
102}
103$confirm = GETPOST('confirm', 'alpha');
104$cancel = GETPOST('cancel', 'alpha');
105$backtopage = GETPOST('backtopage', 'alpha');
106$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
107
108//PDF
109$hidedetails = (GETPOSTINT('hidedetails') ? GETPOSTINT('hidedetails') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0));
110$hidedesc = (GETPOSTINT('hidedesc') ? GETPOSTINT('hidedesc') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0));
111$hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0));
112
113$object = new Reception($db);
114$objectorder = new CommandeFournisseur($db);
115$extrafields = new ExtraFields($db);
116
117// fetch optionals attributes and labels
118$extrafields->fetch_name_optionals_label($object->table_element);
119$extrafields->fetch_name_optionals_label($object->table_element_line);
120$extrafields->fetch_name_optionals_label($objectorder->table_element_line);
121
122// Load object. Make an object->fetch
123include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'
124
125// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
126$hookmanager->initHooks(array('receptioncard', 'globalcard'));
127
128$date_delivery = dol_mktime(GETPOSTINT('date_deliveryhour'), GETPOSTINT('date_deliverymin'), 0, GETPOSTINT('date_deliverymonth'), GETPOSTINT('date_deliveryday'), GETPOSTINT('date_deliveryyear'));
129
130if ($id > 0 || !empty($ref)) {
131 $object->fetch($id, $ref);
132 $object->fetch_thirdparty();
133
134 $typeobject = '';
135 if (!empty($object->origin)) {
136 $origin = $object->origin;
137 $typeobject = $object->origin;
138
139 $object->fetch_origin();
140 }
141
142 // Set $origin_id and $objectsrc
143 if (($origin == 'order_supplier' || $origin == 'supplier_order') && is_object($object->origin_object) && isModEnabled("supplier_order")) {
144 $origin_id = $object->origin_object->id;
145 $objectsrc = $object->origin_object;
146 }
147}
148
149// Security check
150$socid = '';
151if ($user->socid) {
152 $socid = $user->socid;
153}
154
155// TODO Test on reception module on only
156if (isModEnabled("reception") || $origin == 'reception' || empty($origin)) {
157 $result = restrictedArea($user, 'reception', $object->id);
158} else {
159 // We do not use the reception module, so we test permission on the supplier orders
160 if ($origin == 'supplierorder' || $origin == 'order_supplier') {
161 $result = restrictedArea($user, 'fournisseur', $origin_id, 'commande_fournisseur', 'commande');
162 } elseif (!$user->hasRight($origin, 'lire') && !$user->hasRight($origin, 'read')) {
164 }
165}
166
167if (isModEnabled("reception")) {
168 $permissiontoread = $user->hasRight('reception', 'lire');
169 $permissiontoadd = $user->hasRight('reception', 'creer');
170 $permissiondellink = $user->hasRight('reception', 'creer'); // Used by the include of actions_dellink.inc.php
171 $permissiontovalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'creer')) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'reception_advance', 'validate')));
172 $permissiontodelete = $user->hasRight('reception', 'supprimer');
173} else {
174 $permissiontoread = $user->hasRight('fournisseur', 'commande', 'receptionner');
175 $permissiontoadd = $user->hasRight('fournisseur', 'commande', 'receptionner');
176 $permissiondellink = $user->hasRight('fournisseur', 'commande', 'receptionner'); // Used by the include of actions_dellink.inc.php
177 $permissiontovalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('fournisseur', 'commande', 'receptionner')) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('fournisseur', 'commande_advance', 'check')));
178 $permissiontodelete = $user->hasRight('fournisseur', 'commande', 'receptionner');
179}
180
181$error = 0;
182
183
184/*
185 * Actions
186 */
187
188$parameters = array();
189$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
190if ($reshook < 0) {
191 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
192}
193
194if (empty($reshook)) {
195 /*
196 $backurlforlist = DOL_URL_ROOT.'/reception/list.php';
197
198 if (empty($backtopage) || ($cancel && empty($id))) {
199 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
200 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
201 $backtopage = $backurlforlist;
202 } else {
203 $backtopage = dol_buildpath('/mymodule/myobject_card.php', 1).'?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
204 }
205 }
206 }
207 */
208
209 if ($cancel) {
210 if (!empty($backtopageforcancel)) {
211 header("Location: ".$backtopageforcancel);
212 exit;
213 } elseif (!empty($backtopage)) {
214 header("Location: ".$backtopage);
215 exit;
216 }
217
218 $action = '';
219 }
220
221 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be 'include', not 'include_once'
222
223 // Reopen
224 if ($action == 'reopen' && $permissiontoadd) { // Test on permissions not required here
225 $result = $object->reOpen();
226 }
227
228 // Confirm back to draft status
229 if ($action == 'modif' && $permissiontoadd) {
230 $result = $object->setDraft($user);
231 if ($result >= 0) {
232 // Define output language
233 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
234 $outputlangs = $langs;
235 $newlang = '';
236 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
237 $newlang = GETPOST('lang_id', 'aZ09');
238 }
239 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
240 $newlang = $object->thirdparty->default_lang;
241 }
242 if (!empty($newlang)) {
243 $outputlangs = new Translate("", $conf);
244 $outputlangs->setDefaultLang($newlang);
245 }
246 $model = $object->model_pdf;
247 $ret = $object->fetch($id); // Reload to get new records
248 $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
249 }
250 } else {
251 setEventMessages($object->error, $object->errors, 'errors');
252 }
253 }
254
255 // Set incoterm
256 if ($action == 'set_incoterms' && isModEnabled('incoterm') && $permissiontoadd) {
257 $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms'));
258 }
259
260 if ($action == 'setref_supplier' && $permissiontoadd) {
261 if ($result < 0) {
262 setEventMessages($object->error, $object->errors, 'errors');
263 }
264
265 $result = $object->setValueFrom('ref_supplier', GETPOST('ref_supplier', 'alpha'), '', null, 'text', '', $user, 'RECEPTION_MODIFY');
266 if ($result < 0) {
267 setEventMessages($object->error, $object->errors, 'errors');
268 $action = 'editref_supplier';
269 } else {
270 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
271 exit;
272 }
273 }
274
275 if ($action == 'update_extras' && $permissiontoadd) {
276 $object->oldcopy = dol_clone($object, 2);
277
278 // Fill array 'array_options' with data from update form
279 $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
280 if ($ret < 0) {
281 $error++;
282 }
283
284 if (!$error) {
285 // Actions on extra fields
286 $result = $object->insertExtraFields('RECEPTION_MODIFY');
287 if ($result < 0) {
288 setEventMessages($object->error, $object->errors, 'errors');
289 $error++;
290 }
291 }
292
293 if ($error) {
294 $action = 'edit_extras';
295 }
296 }
297
298 // Create reception
299 if ($action == 'add' && $permissiontoadd) {
300 $error = 0;
301
302 $db->begin();
303
304 $object->note = GETPOST('note', 'alpha');
305 $object->note_private = GETPOST('note', 'alpha');
306 $object->origin = $origin;
307 $object->origin_id = $origin_id;
308 $object->fk_project = GETPOSTINT('projectid');
309 $object->weight = GETPOSTINT('weight') == '' ? null : GETPOSTINT('weight');
310 $object->trueHeight = GETPOSTINT('trueHeight') == '' ? null : GETPOSTINT('trueHeight');
311 $object->trueWidth = GETPOSTINT('trueWidth') == '' ? null : GETPOSTINT('trueWidth');
312 $object->trueDepth = GETPOSTINT('trueDepth') == '' ? null : GETPOSTINT('trueDepth');
313 $object->size_units = GETPOSTINT('size_units');
314 $object->weight_units = GETPOSTINT('weight_units');
315
316 // On va boucler sur chaque ligne du document d'origine pour completer object reception
317 // avec info diverses + qte a livrer
318
319 if ($object->origin == "supplierorder") {
320 $object->origin = 'order_supplier';
321 $classname = 'CommandeFournisseur';
322 } else {
323 $classname = ucfirst($object->origin);
324 }
325 $objectsrc = new $classname($db);
326 $objectsrc->fetch($object->origin_id);
327
328 $object->socid = $objectsrc->socid;
329 $object->ref_supplier = GETPOST('ref_supplier', 'alpha');
330 $object->model_pdf = GETPOST('model');
331 $object->date_delivery = $date_delivery; // Date delivery planned
332 $object->fk_delivery_address = $objectsrc->fk_delivery_address;
333 $object->shipping_method_id = GETPOSTINT('shipping_method_id');
334 $object->tracking_number = GETPOST('tracking_number', 'alpha');
335 $object->note_private = GETPOST('note_private', 'restricthtml');
336 $object->note_public = GETPOST('note_public', 'restricthtml');
337 $object->fk_incoterms = GETPOSTINT('incoterm_id');
338 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
339
340 $batch_line = array();
341 $stockLine = array();
342 $array_options = array();
343
344 $totalqty = 0;
345
346 $num = 0;
347 foreach ($_POST as $key => $value) {
348 // without batch module enabled
349
350 if (strpos($key, 'qtyasked') !== false) {
351 $num++;
352 }
353 }
354
355 // Loop lines to calculate $totalqty
356 for ($i = 1; $i <= $num; $i++) {
357 $idl = "idl".$i; // id line source
358
359 //$sub_qty = array();
360 //$subtotalqty = 0;
361
362 //$j = 0;
363 //$batch = "batchl".$i."_0";
364 //$stockLocation = "ent1".$i."_0";
365 $qty = "qtyl".$i; // qty
366
367 //reception line for product with no batch management and no multiple stock location
368 if (GETPOST($qty, 'alpha') > 0) {
369 $totalqty += price2num(GETPOST($qty, 'alpha'), 'MS');
370 }
371
372 // Extrafields
373 $array_options[$i] = $extrafields->getOptionalsFromPost($object->table_element_line, $i);
374 }
375
376
377 if ($totalqty > 0) { // There is at least one thing to ship
378 for ($i = 1; $i <= $num; $i++) {
379 $idl = "idl".$i; // id line source
380 $lineToTest = '';
381 $lineId = GETPOSTINT($idl);
382 foreach ($objectsrc->lines as $linesrc) {
383 if ($linesrc->id == $lineId) {
384 $lineToTest = $linesrc;
385 break;
386 }
387 }
388 if (empty($lineToTest)) {
389 continue;
390 }
391 $qty = "qtyl".$i;
392 $comment = "comment".$i;
393 // EATBY <-> DLUO and SELLBY <-> DLC, see productbatch.class.php
394 $eatby = "dluo".$i;
395 $sellby = "dlc".$i;
396 $batch = "batch".$i;
397 $cost_price = "cost_price".$i;
398
399 //var_dump(GETPOST("productl".$i, 'int').' '.GETPOST('entl'.$i, 'int').' '.GETPOST($idl, 'int').' '.GETPOST($qty, 'int').' '.GETPOST($batch, 'alpha'));
400
401 //if (GETPOST($qty, 'int') > 0 || (GETPOST($qty, 'int') == 0 && getDolGlobalString('RECEPTION_GETS_ALL_ORDER_PRODUCTS')) || (GETPOST($qty, 'int') < 0 && getDolGlobalString('RECEPTION_ALLOW_NEGATIVE_QTY'))) {
402 if (GETPOSTFLOAT($qty) > 0 || (GETPOSTFLOAT($qty) == 0 && getDolGlobalString('RECEPTION_GETS_ALL_ORDER_PRODUCTS'))) {
403 $ent = "entl".$i;
404 $idl = "idl".$i;
405
406 $entrepot_id = is_numeric(GETPOST($ent)) ? GETPOSTINT($ent) : GETPOSTINT('entrepot_id');
407
408 /*
409 if (!empty($lineToTest)) {
410 $fk_product = $lineToTest->fk_product;
411 } else {
412 $fk_product = $linesrc->fk_product;
413 }*/
414 $fk_product = GETPOSTINT("productl".$i);
415
416 if ($entrepot_id < 0) {
417 $entrepot_id = '';
418 }
419 if (!($fk_product > 0) && !getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
420 $entrepot_id = 0;
421 }
422
423 $eatby = GETPOST($eatby, 'alpha');
424 $sellby = GETPOST($sellby, 'alpha');
425 $eatbydate = str_replace('/', '-', $eatby);
426 $sellbydate = str_replace('/', '-', $sellby);
427
428 if (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
429 $ret = $object->addline($entrepot_id, GETPOSTINT($idl), price2num(GETPOST($qty), 'MS'), $array_options[$i], GETPOST($comment), strtotime($eatbydate), strtotime($sellbydate), GETPOST($batch), GETPOSTFLOAT($cost_price, 'MU'));
430 } else {
431 $ret = $object->addline($entrepot_id, GETPOSTINT($idl), price2num(GETPOST($qty), 'MS'), $array_options[$i], GETPOST($comment), strtotime($eatbydate), strtotime($sellbydate), GETPOST($batch));
432 }
433 if ($ret < 0) {
434 setEventMessages($object->error, $object->errors, 'errors');
435 $error++;
436 }
437 }
438 }
439
440 // Fill array 'array_options' with data from add form
441 $ret = $extrafields->setOptionalsFromPost(null, $object);
442 if ($ret < 0) {
443 $error++;
444 }
445 if (!$error) {
446 $ret = $object->create($user); // This create reception (like Odoo picking) and line of receptions. Stock movement will when validating reception.
447
448 if ($ret <= 0) {
449 setEventMessages($object->error, $object->errors, 'errors');
450 $error++;
451 } else {
452 // Define output language
453 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
454 $object->fetch_thirdparty();
455 $outputlangs = $langs;
456 $newlang = '';
457 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
458 $newlang = GETPOST('lang_id', 'aZ09');
459 }
460 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
461 $newlang = $object->thirdparty->default_lang;
462 }
463 if (!empty($newlang)) {
464 $outputlangs = new Translate("", $conf);
465 $outputlangs->setDefaultLang($newlang);
466 }
467 $model = $object->model_pdf;
468 $ret = $object->fetch($object->id); // Reload to get new records
469
470 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
471 if ($result < 0) {
472 dol_print_error($db, $object->error, $object->errors);
473 }
474 }
475 }
476 }
477 } else {
478 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("QtyToReceive").'/'.$langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
479 $error++;
480 }
481
482 if (!$error) {
483 $db->commit();
484 header("Location: card.php?id=".$object->id);
485 exit;
486 } else {
487 $db->rollback();
488 //$_GET["commande_id"] = GETPOSTINT('commande_id');
489 $action = 'create';
490 }
491 } elseif ($action == 'confirm_valid' && $confirm == 'yes' && $permissiontovalidate) {
492 $object->fetch_thirdparty();
493
494 $result = $object->valid($user);
495
496 if ($result < 0) {
497 $langs->load("errors");
498 setEventMessages($langs->trans($object->error), null, 'errors');
499 } else {
500 // Define output language
501 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
502 $outputlangs = $langs;
503 $newlang = '';
504 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
505 $newlang = GETPOST('lang_id', 'aZ09');
506 }
507 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
508 $newlang = $object->thirdparty->default_lang;
509 }
510 if (!empty($newlang)) {
511 $outputlangs = new Translate("", $conf);
512 $outputlangs->setDefaultLang($newlang);
513 }
514 $model = $object->model_pdf;
515 $ret = $object->fetch($id); // Reload to get new records
516
517 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
518 if ($result < 0) {
519 dol_print_error($db, $object->error, $object->errors);
520 }
521 }
522 }
523 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) {
524 $result = $object->delete($user);
525 if ($result > 0) {
526 header("Location: ".DOL_URL_ROOT.'/reception/index.php');
527 exit;
528 } else {
529 setEventMessages($object->error, $object->errors, 'errors');
530 }
531
532 // TODO add alternative status
533 /*} elseif ($action == 'reopen' && ($user->hasRights('reception', 'creer') || $user->hasRights('reception', 'reception_advance', 'validate'))) {
534 $result = $object->setStatut(0);
535 if ($result < 0) {
536 setEventMessages($object->error, $object->errors, 'errors');
537 }*/
538 } elseif ($action == 'setdate_livraison' && $permissiontoadd) {
539 $datedelivery = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
540
541 $object->fetch($id);
542 $result = $object->setDeliveryDate($user, $datedelivery);
543 if ($result < 0) {
544 setEventMessages($object->error, $object->errors, 'errors');
545 }
546 } elseif (($action == 'settracking_number' || $action == 'settracking_url'
547 || $action == 'settrueWeight'
548 || $action == 'settrueWidth'
549 || $action == 'settrueHeight'
550 || $action == 'settrueDepth'
551 || $action == 'setshipping_method_id') && $permissiontoadd) {
552 // Action update
553 $error = 0;
554
555 if ($action == 'settracking_number') { // Test on permission to add
556 $object->tracking_number = trim(GETPOST('tracking_number', 'alpha'));
557 }
558 if ($action == 'settracking_url') { // Test on permission to add
559 $object->tracking_url = trim(GETPOST('tracking_url', 'restricthtml'));
560 }
561 if ($action == 'settrueWeight') { // Test on permission to add
562 $object->trueWeight = GETPOSTINT('trueWeight');
563 $object->weight_units = GETPOSTINT('weight_units');
564 }
565 if ($action == 'settrueWidth') { // Test on permission to add
566 $object->trueWidth = GETPOSTINT('trueWidth');
567 }
568 if ($action == 'settrueHeight') { // Test on permission to add
569 $object->trueHeight = GETPOSTINT('trueHeight');
570 $object->size_units = GETPOSTINT('size_units');
571 }
572 if ($action == 'settrueDepth') { // Test on permission to add
573 $object->trueDepth = GETPOSTINT('trueDepth');
574 }
575 if ($action == 'setshipping_method_id') { // Test on permission to add
576 $object->shipping_method_id = GETPOSTINT('shipping_method_id');
577 }
578
579 if (!$error) {
580 if ($object->update($user) >= 0) {
581 header("Location: card.php?id=".$object->id);
582 exit;
583 }
584 setEventMessages($object->error, $object->errors, 'errors');
585 }
586
587 $action = "";
588 } elseif ($action == 'builddoc' && $permissiontoread) {
589 // Build document
590 // En get ou en post
591 // Save last template used to generate document
592 if (GETPOST('model')) {
593 $object->setDocModel($user, GETPOST('model', 'alpha'));
594 }
595
596 // Define output language
597 $outputlangs = $langs;
598 $newlang = '';
599 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
600 $newlang = GETPOST('lang_id', 'aZ09');
601 }
602 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
603 $newlang = $reception->thirdparty->default_lang;
604 }
605 if (!empty($newlang)) {
606 $outputlangs = new Translate("", $conf);
607 $outputlangs->setDefaultLang($newlang);
608 }
609 $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
610 if ($result <= 0) {
611 setEventMessages($object->error, $object->errors, 'errors');
612 $action = '';
613 }
614 } elseif ($action == 'remove_file' && $permissiontoadd) {
615 // Delete file in doc form
616 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
617
618 $upload_dir = $conf->reception->dir_output;
619 $file = $upload_dir.'/'.GETPOST('file');
620 $ret = dol_delete_file($file, 0, 0, 0, $object);
621 if ($ret) {
622 setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
623 } else {
624 setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
625 }
626 } elseif ($action == 'classifybilled' && $permissiontoadd) {
627 $result = $object->setBilled();
628 if ($result >= 0) {
629 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
630 exit();
631 } else {
632 setEventMessages($object->error, $object->errors, 'errors');
633 $action = '';
634 }
635 } elseif ($action == 'classifyclosed' && $permissiontoread) {
636 $result = $object->setClosed();
637 if ($result >= 0) {
638 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
639 exit();
640 } else {
641 setEventMessages($object->error, $object->errors, 'errors');
642 $action = '';
643 }
644 } elseif ($action == 'deleteline' && !empty($line_id) && $permissiontoread) {
645 // delete a line
646 $lines = $object->lines;
647 $line = new CommandeFournisseurDispatch($db);
648
649 $num_prod = count($lines);
650 for ($i = 0; $i < $num_prod; $i++) {
651 if ($lines[$i]->id == $line_id) {
652 // delete single warehouse line
653 $line->id = $line_id;
654 if (!$error && $line->delete($user) < 0) {
655 $error++;
656 }
657 }
658 unset($_POST["lineid"]);
659 }
660
661 if (!$error) {
662 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
663 exit();
664 } else {
665 setEventMessages($line->error, $line->errors, 'errors');
666 }
667 } elseif ($action == 'updateline' && GETPOST('save') && $permissiontoadd) {
668 // Update a line
669 // Clean parameters
670 $qty = 0;
671 $entrepot_id = 0;
672 $batch_id = 0;
673
674 $lines = $object->lines;
675 $num_prod = count($lines);
676 for ($i = 0; $i < $num_prod; $i++) {
677 if ($lines[$i]->id == $line_id) { // we have found line to update
678 $line = new CommandeFournisseurDispatch($db);
679 $line->fetch($line_id);
680 // Extrafields Lines
681 $extrafields->fetch_name_optionals_label($object->table_element_line);
682 $line->array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
683
684
685 $line->fk_product = $lines[$i]->fk_product;
686
687
688 if ($lines[$i]->fk_product > 0) {
689 // single warehouse reception line
690 $stockLocation = "entl".$line_id;
691 $qty = "qtyl".$line_id;
692 $comment = "comment".$line_id;
693
694
695 $line->id = $line_id;
696 $line->fk_entrepot = GETPOSTINT($stockLocation);
697 $line->qty = GETPOSTINT($qty);
698 $line->comment = GETPOST($comment, 'alpha');
699
700 if (isModEnabled('productbatch')) {
701 $batch = "batch".$line_id;
702 $dlc = "dlc".$line_id;
703 $dluo = "dluo".$line_id;
704 // EATBY <-> DLUO
705 $eatby = GETPOST($dluo, 'alpha');
706 $eatbydate = str_replace('/', '-', $eatby);
707 // SELLBY <-> DLC
708 $sellby = GETPOST($dlc, 'alpha');
709 $sellbydate = str_replace('/', '-', $sellby);
710 $line->batch = GETPOST($batch, 'alpha');
711 $line->eatby = strtotime($eatbydate);
712 $line->sellby = strtotime($sellbydate);
713 }
714
715 if ($line->update($user) < 0) {
716 setEventMessages($line->error, $line->errors, 'errors');
717 $error++;
718 }
719 } else { // Product no predefined
720 $qty = "qtyl".$line_id;
721 $line->id = $line_id;
722 $line->qty = GETPOSTINT($qty);
723 $line->fk_entrepot = 0;
724 if ($line->update($user) < 0) {
725 setEventMessages($line->error, $line->errors, 'errors');
726 $error++;
727 }
728 unset($_POST[$qty]);
729 }
730 }
731 }
732
733 unset($_POST["lineid"]);
734
735 if (!$error) {
736 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
737 // Define output language
738 $outputlangs = $langs;
739 $newlang = '';
740 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
741 $newlang = GETPOST('lang_id', 'aZ09');
742 }
743 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
744 $newlang = $object->thirdparty->default_lang;
745 }
746 if (!empty($newlang)) {
747 $outputlangs = new Translate("", $conf);
748 $outputlangs->setDefaultLang($newlang);
749 }
750
751 $ret = $object->fetch($object->id); // Reload to get new records
752 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
753 }
754 } else {
755 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To reshow the record we edit
756 exit();
757 }
758 } elseif ($action == 'updateline' && $permissiontoadd && GETPOST('cancel', 'alpha') == $langs->trans("Cancel")) {
759 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To reshow the record we edit
760 exit();
761 }
762
763 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
764
765 // Actions to send emails
766 if (empty($id)) {
767 $id = $facid;
768 }
769 $triggersendname = 'RECEPTION_SENTBYMAIL';
770 $paramname = 'id';
771 $mode = 'emailfromreception';
772 $autocopy = 'MAIN_MAIL_AUTOCOPY_RECEPTION_TO';
773 $trackid = 'rec'.$object->id;
774 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
775}
776
777
778/*
779 * View
780 */
781
782$title = $object->ref.' - '.$langs->trans('Reception');
783
784llxHeader('', $title, 'Reception', '', 0, 0, '', '', '', 'mod-reception page-card');
785
786$form = new Form($db);
787$formfile = new FormFile($db);
788$formproduct = new FormProduct($db);
789if (isModEnabled('project')) {
790 $formproject = new FormProjets($db);
791}
792
793$product_static = new Product($db);
794$reception_static = new Reception($db);
795$warehousestatic = new Entrepot($db);
796
797if ($action == 'create2') {
798 print load_fiche_titre($langs->trans("CreateReception"), '', 'dollyrevert');
799
800 print '<br>'.$langs->trans("ReceptionCreationIsDoneFromOrder");
801 $action = '';
802 $id = '';
803 $ref = '';
804}
805
806// Mode creation.
807if ($action == 'create') {
808 $recept = new Reception($db);
809
810 print load_fiche_titre($langs->trans("CreateReception"));
811 if (!$origin) {
812 setEventMessages($langs->trans("ErrorBadParameters"), null, 'errors');
813 }
814
815 if ($origin) {
816 if ($origin == 'supplierorder') {
817 $classname = 'CommandeFournisseur';
818 } else {
819 $classname = ucfirst($origin);
820 }
821
822 $objectsrc = new $classname($db);
823 if ($objectsrc->fetch($origin_id)) { // This include the fetch_lines
824 $soc = new Societe($db);
825 $soc->fetch($objectsrc->socid);
826
827 $author = new User($db);
828 $author->fetch($objectsrc->user_author_id);
829
830 if (isModEnabled('stock')) {
831 $entrepot = new Entrepot($db);
832 }
833
834 print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
835 print '<input type="hidden" name="token" value="'.newToken().'">';
836 print '<input type="hidden" name="action" value="add">';
837 print '<input type="hidden" name="origin" value="'.$origin.'">';
838 print '<input type="hidden" name="origin_id" value="'.$objectsrc->id.'">';
839 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
840 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
841 if (GETPOSTINT('entrepot_id')) {
842 print '<input type="hidden" name="entrepot_id" value="'.GETPOSTINT('entrepot_id').'">';
843 }
844
845 print dol_get_fiche_head();
846
847 print '<table class="border centpercent">';
848
849 // Ref
850 print '<tr><td class="titlefieldcreate fieldrequired">';
851 if ($origin == 'supplierorder' && isModEnabled("supplier_order")) {
852 print $langs->trans("RefOrder").'</td><td colspan="3"><a href="'.DOL_URL_ROOT.'/fourn/commande/card.php?id='.$objectsrc->id.'">'.img_object($langs->trans("ShowOrder"), 'order').' '.$objectsrc->ref;
853 }
854 if ($origin == 'propal' && isModEnabled("propal")) {
855 print $langs->trans("RefProposal").'</td><td colspan="3"><a href="'.DOL_URL_ROOT.'/comm/card.php?id='.$objectsrc->id.'">'.img_object($langs->trans("ShowProposal"), 'propal').' '.$objectsrc->ref;
856 }
857 print '</a></td>';
858 print "</tr>\n";
859
860 // Ref client
861 print '<tr><td>';
862 if ($origin == 'supplier_order') {
863 print $langs->trans('SupplierOrder');
864 } else {
865 print $langs->trans('RefSupplier');
866 }
867 print '</td><td colspan="3">';
868 print '<input type="text" name="ref_supplier" value="'.$objectsrc->ref_supplier.'" />';
869 print '</td>';
870 print '</tr>';
871
872 // Tiers
873 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Company').'</td>';
874 print '<td colspan="3">'.$soc->getNomUrl(1).'</td>';
875 print '</tr>';
876
877 // Project
878 if (isModEnabled('project')) {
879 $projectid = GETPOSTINT('projectid') ? GETPOSTINT('projectid') : 0;
880 if (empty($projectid) && !empty($objectsrc->fk_project)) {
881 $projectid = $objectsrc->fk_project;
882 }
883 if ($origin == 'project') {
884 $projectid = ($originid ? $originid : 0);
885 }
886
887 $langs->load("projects");
888 print '<tr>';
889 print '<td>'.$langs->trans("Project").'</td><td colspan="2">';
890 print img_picto('', 'project', 'class="paddingright"');
891 print $formproject->select_projects((!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $soc->id : -1), $projectid, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1, 0, 'maxwidth500');
892 print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$soc->id.'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
893 print '</td>';
894 print '</tr>';
895 }
896
897 // Date delivery planned
898 print '<tr><td>'.$langs->trans("DateDeliveryPlanned").'</td>';
899 print '<td colspan="3">';
900 $date_delivery = ($date_delivery ? $date_delivery : $objectsrc->delivery_date); // $date_delivery comes from GETPOST
901 print $form->selectDate($date_delivery ? $date_delivery : -1, 'date_delivery', 1, 1, 1);
902 print "</td>\n";
903 print '</tr>';
904
905 // Note Public
906 print '<tr><td>'.$langs->trans("NotePublic").'</td>';
907 print '<td colspan="3">';
908 $doleditor = new DolEditor('note_public', $objectsrc->note_public, '', 60, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
909 print $doleditor->Create(1);
910 print "</td></tr>";
911
912 // Note Private
913 if ($objectsrc->note_private && !$user->socid) {
914 print '<tr><td>'.$langs->trans("NotePrivate").'</td>';
915 print '<td colspan="3">';
916 $doleditor = new DolEditor('note_private', $objectsrc->note_private, '', 60, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
917 print $doleditor->Create(1);
918 print "</td></tr>";
919 }
920
921 // Weight
922 print '<tr><td>';
923 print $langs->trans("Weight");
924 print '</td><td colspan="3"><input name="weight" size="4" value="'.GETPOSTINT('weight').'"> ';
925 $text = $formproduct->selectMeasuringUnits("weight_units", "weight", GETPOSTINT('weight_units'), 0, 2);
926 $htmltext = $langs->trans("KeepEmptyForAutoCalculation");
927 print $form->textwithpicto($text, $htmltext);
928 print '</td></tr>';
929 // Dim
930 print '<tr><td>';
931 print $langs->trans("Width").' x '.$langs->trans("Height").' x '.$langs->trans("Depth");
932 print ' </td><td colspan="3"><input name="trueWidth" size="4" value="'.GETPOSTINT('trueWidth').'">';
933 print ' x <input name="trueHeight" size="4" value="'.GETPOSTINT('trueHeight').'">';
934 print ' x <input name="trueDepth" size="4" value="'.GETPOSTINT('trueDepth').'">';
935 print ' ';
936 $text = $formproduct->selectMeasuringUnits("size_units", "size", GETPOSTINT('size_units'), 0, 2);
937 $htmltext = $langs->trans("KeepEmptyForAutoCalculation");
938 print $form->textwithpicto($text, $htmltext);
939 print '</td></tr>';
940
941 // Delivery method
942 print "<tr><td>".$langs->trans("ReceptionMethod")."</td>";
943 print '<td colspan="3">';
944 $recept->fetch_delivery_methods();
945 print $form->selectarray("shipping_method_id", $recept->meths, GETPOSTINT('shipping_method_id'), 1, 0, 0, "", 1);
946 if ($user->admin) {
947 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
948 }
949 print "</td></tr>\n";
950
951 // Tracking number
952 print "<tr><td>".$langs->trans("TrackingNumber")."</td>";
953 print '<td colspan="3">';
954 print '<input name="tracking_number" size="20" value="'.GETPOST('tracking_number', 'alpha').'">';
955 print "</td></tr>\n";
956
957 // Other attributes
958 $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"', 'cols' => '3', 'socid' => $socid);
959 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $recept, $action); // Note that $action and $objectsrc may have been modified by hook
960 print $hookmanager->resPrint;
961
962 // Here $object can be of an object Reception
963 $extrafields->fetch_name_optionals_label($object->table_element);
964 if (empty($reshook) && !empty($extrafields->attributes[$object->table_element]['label'])) {
965 // copy from order
966 if ($objectsrc->fetch_optionals() > 0) {
967 $recept->array_options = array_merge($recept->array_options, $objectsrc->array_options);
968 }
969 print $recept->showOptionals($extrafields, 'create', $parameters);
970 }
971
972 // Incoterms
973 if (isModEnabled('incoterm')) {
974 print '<tr>';
975 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $objectsrc->label_incoterms, 1).'</label></td>';
976 print '<td colspan="3" class="maxwidthonsmartphone">';
977 print $form->select_incoterms((!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : ''), (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : ''));
978 print '</td></tr>';
979 }
980
981 // Document model
982 include_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
984
985 if (is_countable($list) && count($list) > 1) {
986 print "<tr><td>".$langs->trans("DefaultModel")."</td>";
987 print '<td colspan="3">';
988 print $form->selectarray('model', $list, getDolGlobalString('RECEPTION_ADDON_PDF'));
989 print "</td></tr>\n";
990 }
991
992 print "</table>";
993
994 print dol_get_fiche_end();
995
996 // Number of lines show on the reception card
997 $numAsked = 0;
998
1003 $suffix2numAsked = array();
1004 $dispatchLines = array();
1005
1006 foreach ($_POST as $key => $value) {
1007 // If create form is coming from the button "Create Reception" of previous page
1008
1009 // without batch module enabled or product with no lot/serial
1010 $reg = array();
1011 if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
1012 $numAsked++;
1013 $paramSuffix = $reg[1] . '_' . $reg[2];
1014 $suffix2numAsked[$paramSuffix] = $numAsked;
1015
1016 // $numline=$reg[2] + 1; // line of product
1017 $numline = $numAsked;
1018
1019 $prod = "product_" . $paramSuffix;
1020 $qty = "qty_" . $paramSuffix;
1021 $ent = "entrepot_" . $paramSuffix;
1022 $pu = "pu_" . $paramSuffix; // This is unit price including discount
1023 $fk_commandefourndet = "fk_commandefourndet_" . $paramSuffix;
1024 $dispatchLines[$numAsked] = array('paramSuffix' => $paramSuffix, 'prod' => GETPOSTINT($prod), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOSTINT($ent), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST('comment'), 'fk_commandefourndet' => GETPOSTINT($fk_commandefourndet));
1025 }
1026
1027 // with batch module enabled and product with lot/serial
1028 if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
1029 $numAsked++;
1030 $paramSuffix = $reg[1] . '_' . $reg[2];
1031 $suffix2numAsked[$paramSuffix] = $numAsked;
1032
1033 // eat-by date dispatch
1034 // $numline=$reg[2] + 1; // line of product
1035 $numline = $numAsked;
1036
1037 $prod = 'product_batch_' . $paramSuffix;
1038 $qty = 'qty_' . $paramSuffix;
1039 $ent = 'entrepot_' . $paramSuffix;
1040 $pu = 'pu_' . $paramSuffix;
1041 $lot = 'lot_number_' . $paramSuffix;
1042 $dDLUO = dol_mktime(12, 0, 0, GETPOSTINT('dluo_'.$paramSuffix.'month'), GETPOSTINT('dluo_'.$paramSuffix.'day'), GETPOSTINT('dluo_'.$paramSuffix.'year'));
1043 $dDLC = dol_mktime(12, 0, 0, GETPOSTINT('dlc_'.$paramSuffix.'month'), GETPOSTINT('dlc_'.$paramSuffix.'day'), GETPOSTINT('dlc_'.$paramSuffix.'year'));
1044 $fk_commandefourndet = 'fk_commandefourndet_'.$paramSuffix;
1045 $dispatchLines[$numAsked] = array('paramSuffix' => $paramSuffix, 'prod' => GETPOSTINT($prod), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOSTINT($ent), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST('comment'), 'fk_commandefourndet' => GETPOSTINT($fk_commandefourndet), 'DLC' => $dDLC, 'DLUO' => $dDLUO, 'lot' => GETPOST($lot));
1046 }
1047
1048 // If create form is coming from same page, it means that post was sent but an error occurred
1049 if (preg_match('/^productl([0-9]+)$/i', $key, $reg)) {
1050 $numAsked++;
1051 $paramSuffix = $reg[1];
1052 $suffix2numAsked[$paramSuffix] = $numAsked;
1053
1054 // eat-by date dispatch
1055 // $numline=$reg[2] + 1; // line of product
1056 $numline = $numAsked;
1057
1058 $prod = 'productid'.$paramSuffix;
1059 $comment = 'comment'.$paramSuffix;
1060 $qty = 'qtyl'.$paramSuffix;
1061 $ent = 'entl'.$paramSuffix;
1062 $pu = 'pul'.$paramSuffix;
1063 $lot = 'batch'.$paramSuffix;
1064 $dDLUO = dol_mktime(12, 0, 0, GETPOSTINT('dluo'.$paramSuffix.'month'), GETPOSTINT('dluo'.$paramSuffix.'day'), GETPOSTINT('dluo'.$paramSuffix.'year'));
1065 $dDLC = dol_mktime(12, 0, 0, GETPOSTINT('dlc'.$paramSuffix.'month'), GETPOSTINT('dlc'.$paramSuffix.'day'), GETPOSTINT('dlc'.$paramSuffix.'year'));
1066 $fk_commandefourndet = 'fk_commandefournisseurdet'.$paramSuffix;
1067 $dispatchLines[$numAsked] = array('prod' => GETPOSTINT($prod), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOSTINT($ent), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST($comment), 'fk_commandefourndet' => GETPOSTINT($fk_commandefourndet), 'DLC' => $dDLC, 'DLUO' => $dDLUO, 'lot' => GETPOSTINT($lot));
1068 }
1069 }
1070
1071 // If extrafield values are passed in the HTTP query, assign them to the correct dispatch line
1072 // Note that if an extrafield with the same name exists in the origin supplier order line, the value
1073 // from the HTTP query will be ignored
1074 foreach ($suffix2numAsked as $suffix => $n) {
1075 $dispatchLines[$n]['array_options'] = $extrafields->getOptionalsFromPost('receptiondet_batch', '_' . $suffix, '');
1076 }
1077
1078 print '<script type="text/javascript">
1079 jQuery(document).ready(function() {
1080 jQuery("#autofill").click(function(event) {
1081 event.preventDefault();';
1082 $i = 1;
1083 while ($i <= $numAsked) {
1084 print 'jQuery("#qtyl'.$i.'").val(jQuery("#qtyasked'.$i.'").val() - jQuery("#qtydelivered'.$i.'").val());'."\n";
1085 $i++;
1086 }
1087 print '});
1088 jQuery("#autoreset").click(function(event) {
1089 event.preventDefault();';
1090 $i = 1;
1091 while ($i <= $numAsked) {
1092 print 'jQuery("#qtyl'.$i.'").val(0);'."\n";
1093 $i++;
1094 }
1095 print '});
1096 });
1097 </script>';
1098
1099 print '<br>';
1100
1101 print '<table class="noborder centpercent">';
1102
1103 // Load receptions already done for same order
1104 $objectsrc->loadReceptions();
1105
1106 if ($numAsked) {
1107 print '<tr class="liste_titre">';
1108 print '<td>'.$langs->trans("Description").'</td>';
1109 print '<td>'.$langs->trans("Comment").'</td>';
1110 print '<td class="center">'.$langs->trans("QtyOrdered").'</td>';
1111 print '<td class="center">'.$langs->trans("QtyReceived").'</td>';
1112 print '<td class="center">'.$langs->trans("QtyToReceive");
1113 if (getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
1114 print '<td>'.$langs->trans("BuyingPrice").'</td>';
1115 }
1116 if (!isModEnabled('productbatch')) {
1117 print ' <br><center><a href="#" id="autofill"><span class="fas fa-fill pictofixedwidth" style=""></span> '.$langs->trans("Fill").'</a>';
1118 print ' &nbsp; &nbsp; <a href="#" id="autoreset"><span class="fas fa-eraser pictofixedwidth" style=""></span>'.$langs->trans("Reset").'</a></center><br>';
1119 }
1120 print '</td>';
1121 if (isModEnabled('stock')) {
1122 print '<td class="left">'.$langs->trans("Warehouse").' ('.$langs->trans("Stock").')</td>';
1123 }
1124 if (isModEnabled('productbatch')) {
1125 print '<td class="left">'.$langs->trans("batch_number").'</td>';
1126 if (!getDolGlobalInt('PRODUCT_DISABLE_SELLBY')) {
1127 print '<td class="left">'.$langs->trans("SellByDate").'</td>';
1128 }
1129 if (!getDolGlobalInt('PRODUCT_DISABLE_EATBY')) {
1130 print '<td class="left">'.$langs->trans("EatByDate").'</td>';
1131 }
1132 }
1133 print "</tr>\n";
1134 }
1135
1136 // $objectsrc->lines contains the line of the purchase order
1137 // $dispatchLines is list of lines with dispatching detail (with product, qty and warehouse). One purchase order line may have n of this dispatch lines.
1138
1139 $arrayofpurchaselinealreadyoutput = array();
1140
1141 // $_POST contains fk_commandefourndet_X_Y where Y is num of product line and X is number of split lines
1142 $indiceAsked = 1;
1143 while ($indiceAsked <= $numAsked) { // Loop on $dispatchLines. Warning: $dispatchLines must be sorted by fk_commandefourndet (it is a regroupment key on output)
1144 $product = new Product($db);
1145
1146 // We search the purchase order line that is linked to the dispatchLines
1147 foreach ($objectsrc->lines as $supplierLine) {
1148 if ($dispatchLines[$indiceAsked]['fk_commandefourndet'] == $supplierLine->id) {
1149 $line = $supplierLine;
1150 break;
1151 }
1152 }
1153
1154 // Show product and description
1155 $type = $line->product_type ? $line->product_type : $line->fk_product_type;
1156 // Try to enhance type detection using date_start and date_end for free lines where type
1157 // was not saved.
1158 if (!empty($line->date_start)) {
1159 $type = 1;
1160 }
1161 if (!empty($line->date_end)) {
1162 $type = 1;
1163 }
1164
1165 print '<!-- line fk_commandefourndet='.$line->id.' for product='.$line->fk_product.' -->'."\n";
1166 print '<tr class="oddeven">'."\n";
1167
1168 // Product label
1169 if ($line->fk_product > 0) { // If predefined product
1170 $product->fetch($line->fk_product);
1171 $product->load_stock('warehouseopen'); // Load all $product->stock_warehouse[idwarehouse]->detail_batch
1172 //var_dump($product->stock_warehouse[1]);
1173 //var_dump($dispatchLines[$indiceAsked]);
1174
1175 print '<td>';
1176 print '<a name="'.$line->id.'"></a>'; // ancre pour retourner sur la ligne
1177
1178 print '<input type="hidden" name="productl'.$indiceAsked.'" value="'.$line->fk_product.'">';
1179
1180 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1181 print '<input type="hidden" name="productid'.$indiceAsked.'" value="'.$line->fk_product.'">';
1182
1183 // Show product and description
1184 $product_static = $product;
1185
1186 $text = $product_static->getNomUrl(1);
1187 $text .= ' - '.(!empty($line->label) ? $line->label : $line->product_label);
1188 $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($line->desc));
1189 print $form->textwithtooltip($text, $description, 3, '', '', $i);
1190
1191 // Show range
1192 print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end));
1193
1194 // Add description in form
1195 if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
1196 print ($line->desc && $line->desc != $line->product_label) ? '<br>'.dol_htmlentitiesbr($line->desc) : '';
1197 }
1198 }
1199 print '</td>';
1200 } else {
1201 print "<td>";
1202 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1203 if ($type == 1) {
1204 $text = img_object($langs->trans('Service'), 'service');
1205 } else {
1206 $text = img_object($langs->trans('Product'), 'product');
1207 }
1208
1209 if (!empty($line->label)) {
1210 $text .= ' <strong>'.$line->label.'</strong>';
1211 print $form->textwithtooltip($text, $line->desc, 3, '', '', $i);
1212 } else {
1213 print $text.' '.nl2br($line->desc);
1214 }
1215
1216 // Show range
1217 print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end));
1218 }
1219 print "</td>\n";
1220 }
1221
1222 // Comment
1223 //$defaultcomment = 'Line create from order line id '.$line->id;
1224 $defaultcomment = $dispatchLines[$indiceAsked]['comment'];
1225 print '<td>';
1226 print '<input type="text" class="maxwidth100" name="comment'.$indiceAsked.'" value="'.$defaultcomment.'">';
1227 print '</td>';
1228
1229 // Qty in source purchase order line
1230 print '<td class="center">';
1231 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1232 print $line->qty;
1233 }
1234 print '<input type="hidden" name="fk_commandefournisseurdet'.$indiceAsked.'" value="'.$line->id.'">';
1235 print '<input type="hidden" name="pul'.$indiceAsked.'" value="'.$line->pu_ht.'">';
1236 print '<input name="qtyasked'.$indiceAsked.'" id="qtyasked'.$indiceAsked.'" type="hidden" value="'.$line->qty.'">';
1237 print '</td>';
1238 $qtyProdCom = $line->qty;
1239
1240 // Qty already received
1241 print '<td class="center">';
1242 $quantityDelivered = $objectsrc->receptions[$line->id];
1243 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1244 print $quantityDelivered;
1245 }
1246 print '<input name="qtydelivered'.$indiceAsked.'" id="qtydelivered'.$indiceAsked.'" type="hidden" value="'.$quantityDelivered.'">';
1247 print '</td>';
1248
1249
1250 if ($line->product_type == 1 && !getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1251 $quantityToBeDelivered = 0;
1252 } else {
1253 $quantityToBeDelivered = $dispatchLines[$indiceAsked]['qty'];
1254 }
1255 $warehouse_id = $dispatchLines[$indiceAsked]['ent'];
1256
1257
1258 $warehouseObject = null;
1259 if (isModEnabled('stock')) {
1260 // If warehouse was already selected or if product is not a predefined, we go into this part with no multiwarehouse selection
1261 print '<!-- Case warehouse already known or product not a predefined product -->';
1262 if (array_key_exists($dispatchLines[$indiceAsked]['ent'], $product->stock_warehouse)) {
1263 $stock = +$product->stock_warehouse[$dispatchLines[$indiceAsked]['ent']]->real; // Convert to number
1264 }
1265 $deliverableQty = $dispatchLines[$indiceAsked]['qty'];
1266 $cost_price = $dispatchLines[$indiceAsked]['pu'];
1267
1268 // Quantity to send
1269 print '<td class="center">';
1270 if ($line->product_type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1271 if (GETPOSTINT('qtyl'.$indiceAsked)) {
1272 $defaultqty = GETPOSTINT('qtyl'.$indiceAsked);
1273 }
1274 print '<input name="idl'.$indiceAsked.'" type="hidden" value="'.$line->id.'">';
1275 print '<input class="right" name="qtyl'.$indiceAsked.'" id="qtyl'.$indiceAsked.'" type="text" size="4" value="'.$deliverableQty.'">';
1276 } else {
1277 print $langs->trans("NA");
1278 }
1279 print '</td>';
1280
1281 if (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
1282 print '<td>';
1283 print '<input class="width75 right" name="cost_price'.$indiceAsked.'" id="cost_price'.$indiceAsked.'" value="'.$cost_price.'">';
1284 print '</td>';
1285 }
1286
1287 // Stock
1288 if (isModEnabled('stock')) {
1289 print '<td class="left">';
1290 if ($line->product_type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) { // Type of product need stock change ?
1291 // Show warehouse combo list
1292 $ent = "entl".$indiceAsked;
1293 $idl = "idl".$indiceAsked;
1294 $tmpentrepot_id = is_numeric(GETPOST($ent)) ? GETPOSTINT($ent) : $warehouse_id;
1295 if ($line->fk_product > 0) {
1296 print '<!-- Show warehouse selection -->';
1297 print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 0, 0, $line->fk_product, '', 1);
1298 }
1299 } else {
1300 print $langs->trans("Service");
1301 }
1302 print '</td>';
1303 }
1304
1305 if (isModEnabled('productbatch')) {
1306 if (!empty($product->status_batch)) {
1307 print '<td><input name="batch'.$indiceAsked.'" value="'.$dispatchLines[$indiceAsked]['lot'].'"></td>';
1308 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1309 print '<td class="nowraponall">';
1310 print $form->selectDate($dispatchLines[$indiceAsked]['DLC'], 'dlc'.$indiceAsked, 0, 0, 1, "");
1311 print '</td>';
1312 }
1313 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1314 print '<td class="nowraponall">';
1315 print $form->selectDate($dispatchLines[$indiceAsked]['DLUO'], 'dluo'.$indiceAsked, 0, 0, 1, "");
1316 print '</td>';
1317 }
1318 } else {
1319 print '<td colspan="3"></td>';
1320 }
1321 }
1322 }
1323
1324 $arrayofpurchaselinealreadyoutput[$line->id] = $line->id;
1325
1326 print "</tr>\n";
1327
1328 // Display lines for extrafields of the Reception line
1329 // $line is a 'CommandeFournisseurLigne', $dispatchLines contains values of Reception lines so properties of CommandeFournisseurDispatch
1330 if (!empty($extrafields)) {
1331 $colspan = 5;
1332 if (isModEnabled('productbatch')) {
1333 $colspan += 2;
1334 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1335 $colspan += 1;
1336 }
1337 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1338 $colspan += 1;
1339 }
1340 }
1341 $recLine = new CommandeFournisseurDispatch($db);
1342
1343 $srcLine = new CommandeFournisseurLigne($db);
1344 $srcLine->id = $line->id;
1345 $srcLine->fetch_optionals(); // fetch extrafields also available in orderline
1346
1347 if (empty($recLine->array_options) && !empty($dispatchLines[$indiceAsked]['array_options'])) {
1348 $recLine->array_options = $dispatchLines[$indiceAsked]['array_options'];
1349 }
1350 $recLine->array_options = array_merge($recLine->array_options, $srcLine->array_options);
1351
1352 print $recLine->showOptionals($extrafields, 'edit', array('style' => 'class="oddeven"', 'colspan' => $colspan), $indiceAsked, '', 1);
1353 }
1354
1355 $indiceAsked++;
1356 }
1357
1358 print "</table>";
1359
1360 print '<br>';
1361
1362 print $form->buttonsSaveCancel("Create");
1363
1364 print '</form>';
1365
1366 print '<br>';
1367 } else {
1368 dol_print_error($db);
1369 }
1370 }
1371} elseif ($id || $ref) {
1372 /* *************************************************************************** */
1373 /* */
1374 /* Edit and view mode */
1375 /* */
1376 /* *************************************************************************** */
1377 $lines = $object->lines;
1378
1379 $num_prod = count($lines);
1380 $indiceAsked = 0;
1381
1382 if ($object->id <= 0) {
1383 print $langs->trans("NoRecordFound");
1384 llxFooter();
1385 exit;
1386 }
1387
1388 if (!empty($object->origin) && $object->origin_id > 0) {
1389 $object->origin = 'CommandeFournisseur';
1390 $typeobject = $object->origin;
1391 $origin = $object->origin;
1392 $origin_id = $object->origin_id;
1393 $object->fetch_origin(); // Load property $object->origin_object, $object->commande, $object->propal, ...
1394 }
1395
1396 $soc = new Societe($db);
1397 $soc->fetch($object->socid);
1398
1399 $res = $object->fetch_optionals();
1400
1402 print dol_get_fiche_head($head, 'reception', $langs->trans("Reception"), -1, 'dollyrevert');
1403
1404 $formconfirm = '';
1405
1406 // Confirm deletion
1407 if ($action == 'delete') {
1408 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('DeleteReception'), $langs->trans("ConfirmDeleteReception", $object->ref), 'confirm_delete', '', 0, 1);
1409 }
1410
1411 // Confirmation validation
1412 if ($action == 'valid') {
1413 $objectref = substr($object->ref, 1, 4);
1414 if ($objectref == 'PROV') {
1415 $numref = $object->getNextNumRef($soc);
1416 } else {
1417 $numref = $object->ref;
1418 }
1419
1420 $text = $langs->trans("ConfirmValidateReception", $numref);
1421 if (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION')) {
1422 $text .= '<br>'.img_picto('', 'movement', 'class="pictofixedwidth"').$langs->trans("StockMovementWillBeRecorded").'.';
1423 } elseif (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
1424 $text .= '<br>'.img_picto('', 'movement', 'class="pictofixedwidth"').$langs->trans("StockMovementNotYetRecorded").'.';
1425 }
1426
1427 if (isModEnabled('notification')) {
1428 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
1429 $notify = new Notify($db);
1430 $text .= '<br>';
1431 $text .= $notify->confirmMessage('RECEPTION_VALIDATE', $object->socid, $object);
1432 }
1433
1434 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('ValidateReception'), $text, 'confirm_valid', '', 0, 1, 250);
1435 }
1436
1437 // Confirm cancellation
1438 if ($action == 'annuler') {
1439 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('CancelReception'), $langs->trans("ConfirmCancelReception", $object->ref), 'confirm_cancel', '', 0, 1);
1440 }
1441
1442 if (!$formconfirm) {
1443 $parameters = array('formConfirm' => $formconfirm);
1444 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1445 if (empty($reshook)) {
1446 $formconfirm .= $hookmanager->resPrint;
1447 } elseif ($reshook > 0) {
1448 $formconfirm = $hookmanager->resPrint;
1449 }
1450 }
1451
1452 // Print form confirm
1453 print $formconfirm;
1454
1455
1456 // Calculate totalWeight and totalVolume for all products
1457 // by adding weight and volume of each product line.
1458 $tmparray = $object->getTotalWeightVolume();
1459 $totalWeight = $tmparray['weight'];
1460 $totalVolume = $tmparray['volume'];
1461
1462
1463 if ($typeobject == 'commande' && $object->origin_object->id && isModEnabled('order')) {
1464 $objectsrc = new Commande($db);
1465 $objectsrc->fetch($object->origin_object->id);
1466 }
1467 if ($typeobject == 'propal' && $object->origin_object->id && isModEnabled("propal")) {
1468 $objectsrc = new Propal($db);
1469 $objectsrc->fetch($object->origin_object->id);
1470 }
1471 if ($typeobject == 'CommandeFournisseur' && $object->origin_object->id && isModEnabled("supplier_order")) {
1472 $objectsrc = new CommandeFournisseur($db);
1473 $objectsrc->fetch($object->origin_object->id);
1474 }
1475 // Reception card
1476 $linkback = '<a href="'.DOL_URL_ROOT.'/reception/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1477 $morehtmlref = '<div class="refidno">';
1478 // Ref customer reception
1479
1480 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('reception', 'creer'), 'string', '', 0, 1);
1481 $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('reception', 'creer'), 'string', '', null, null, '', 1);
1482
1483 // Thirdparty
1484 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
1485 // Project
1486 if (isModEnabled('project')) {
1487 $langs->load("projects");
1488 $morehtmlref .= '<br>';
1489 if (0) { // Do not change on reception
1490 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
1491 if ($action != 'classify' && $permissiontoadd) {
1492 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
1493 }
1494 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $object->socid : -1), $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
1495 } else {
1496 if (!empty($objectsrc) && !empty($objectsrc->fk_project)) {
1497 $proj = new Project($db);
1498 $proj->fetch($objectsrc->fk_project);
1499 $morehtmlref .= $proj->getNomUrl(1);
1500 if ($proj->title) {
1501 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
1502 }
1503 }
1504 }
1505 }
1506 $morehtmlref .= '</div>';
1507
1508 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
1509
1510
1511 print '<div class="fichecenter">';
1512 print '<div class="fichehalfleft">';
1513 print '<div class="underbanner clearboth"></div>';
1514
1515 print '<table class="border centpercent tableforfield">';
1516
1517 // Linked documents
1518 if ($typeobject == 'commande' && $object->origin_object->id && isModEnabled('order')) {
1519 print '<tr><td>';
1520 print $langs->trans("RefOrder").'</td>';
1521 print '<td colspan="3">';
1522 print $objectsrc->getNomUrl(1, 'commande');
1523 print "</td>\n";
1524 print '</tr>';
1525 }
1526 if ($typeobject == 'propal' && $object->origin_object->id && isModEnabled("propal")) {
1527 print '<tr><td>';
1528 print $langs->trans("RefProposal").'</td>';
1529 print '<td colspan="3">';
1530 print $objectsrc->getNomUrl(1, 'reception');
1531 print "</td>\n";
1532 print '</tr>';
1533 }
1534 if ($typeobject == 'CommandeFournisseur' && $object->origin_object->id && isModEnabled("propal")) {
1535 print '<tr><td>';
1536 print $langs->trans("SupplierOrder").'</td>';
1537 print '<td colspan="3">';
1538 print $objectsrc->getNomUrl(1, 'reception');
1539 print "</td>\n";
1540 print '</tr>';
1541 }
1542
1543 // Date creation
1544 print '<tr><td class="titlefield">'.$langs->trans("DateCreation").'</td>';
1545 print '<td colspan="3">'.dol_print_date($object->date_creation, "dayhour", "tzuserrel")."</td>\n";
1546 print '</tr>';
1547
1548 // Delivery date planned
1549 print '<tr><td height="10">';
1550 print '<table class="nobordernopadding" width="100%"><tr><td>';
1551 print $langs->trans('DateDeliveryPlanned');
1552 print '</td>';
1553
1554 if ($action != 'editdate_livraison' && $permissiontoadd) {
1555 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editdate_livraison&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetDeliveryDate'), 1).'</a></td>';
1556 }
1557 print '</tr></table>';
1558 print '</td><td colspan="2">';
1559 if ($action == 'editdate_livraison') {
1560 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
1561 print '<input type="hidden" name="token" value="'.newToken().'">';
1562 print '<input type="hidden" name="action" value="setdate_livraison">';
1563 print $form->selectDate($object->date_delivery ? $object->date_delivery : -1, 'liv_', 1, 1, 0, "setdate_livraison", 1, 0);
1564 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
1565 print '</form>';
1566 } else {
1567 print $object->date_delivery ? dol_print_date($object->date_delivery, 'dayhour') : '&nbsp;';
1568 }
1569 print '</td>';
1570 print '</tr>';
1571
1572 // Weight
1573 print '<tr><td>';
1574 print $form->editfieldkey("Weight", 'trueWeight', $object->trueWeight, $object, $user->hasRight('reception', 'creer'));
1575 print '</td><td colspan="3">';
1576
1577 if ($action == 'edittrueWeight') {
1578 print '<form name="settrueweight" action="'.$_SERVER["PHP_SELF"].'" method="post">';
1579 print '<input name="action" value="settrueWeight" type="hidden">';
1580 print '<input name="id" value="'.$object->id.'" type="hidden">';
1581 print '<input type="hidden" name="token" value="'.newToken().'">';
1582 print '<input id="trueWeight" name="trueWeight" value="'.$object->trueWeight.'" type="text">';
1583 print $formproduct->selectMeasuringUnits("weight_units", "weight", $object->weight_units, 0, 2);
1584 print ' <input class="button" name="modify" value="'.$langs->trans("Modify").'" type="submit">';
1585 print ' <input class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'" type="submit">';
1586 print '</form>';
1587 } else {
1588 print $object->trueWeight;
1589 print ($object->trueWeight && $object->weight_units != '') ? ' '.measuringUnitString(0, "weight", $object->weight_units) : '';
1590 }
1591
1592 // Calculated
1593 if ($totalWeight > 0) {
1594 if (!empty($object->trueWeight)) {
1595 print ' ('.$langs->trans("SumOfProductWeights").': ';
1596 }
1597 print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, getDolGlobalInt('MAIN_WEIGHT_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_WEIGHT_DEFAULT_UNIT', 'no'));
1598 if (!empty($object->trueWeight)) {
1599 print ')';
1600 }
1601 }
1602 print '</td></tr>';
1603
1604 // Width
1605 print '<tr><td>'.$form->editfieldkey("Width", 'trueWidth', $object->trueWidth, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
1606 print $form->editfieldval("Width", 'trueWidth', $object->trueWidth, $object, $user->hasRight('reception', 'creer'));
1607 print ($object->trueWidth && $object->width_units != '') ? ' '.measuringUnitString(0, "size", $object->width_units) : '';
1608 print '</td></tr>';
1609
1610 // Height
1611 print '<tr><td>'.$form->editfieldkey("Height", 'trueHeight', $object->trueHeight, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
1612 if ($action == 'edittrueHeight') {
1613 print '<form name="settrueHeight" action="'.$_SERVER["PHP_SELF"].'" method="post">';
1614 print '<input name="action" value="settrueHeight" type="hidden">';
1615 print '<input name="id" value="'.$object->id.'" type="hidden">';
1616 print '<input type="hidden" name="token" value="'.newToken().'">';
1617 print '<input id="trueHeight" name="trueHeight" value="'.$object->trueHeight.'" type="text">';
1618 print $formproduct->selectMeasuringUnits("size_units", "size", $object->size_units, 0, 2);
1619 print ' <input class="button" name="modify" value="'.$langs->trans("Modify").'" type="submit">';
1620 print ' <input class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'" type="submit">';
1621 print '</form>';
1622 } else {
1623 print $object->trueHeight;
1624 print ($object->trueHeight && $object->height_units != '') ? ' '.measuringUnitString(0, "size", $object->height_units) : '';
1625 }
1626
1627 print '</td></tr>';
1628
1629 // Depth
1630 print '<tr><td>'.$form->editfieldkey("Depth", 'trueDepth', $object->trueDepth, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
1631 print $form->editfieldval("Depth", 'trueDepth', $object->trueDepth, $object, $user->hasRight('reception', 'creer'));
1632 print ($object->trueDepth && $object->depth_units != '') ? ' '.measuringUnitString(0, "size", $object->depth_units) : '';
1633 print '</td></tr>';
1634
1635 // Volume
1636 print '<tr><td>';
1637 print $langs->trans("Volume");
1638 print '</td>';
1639 print '<td colspan="3">';
1640 $calculatedVolume = 0;
1641 $volumeUnit = 0;
1642 if ($object->trueWidth && $object->trueHeight && $object->trueDepth) {
1643 $calculatedVolume = ($object->trueWidth * $object->trueHeight * $object->trueDepth);
1644 $volumeUnit = $object->size_units * 3;
1645 }
1646 // If reception volume not defined we use sum of products
1647 if ($calculatedVolume > 0) {
1648 if ($volumeUnit < 50) {
1649 print showDimensionInBestUnit($calculatedVolume, $volumeUnit, "volume", $langs, getDolGlobalInt('MAIN_VOLUME_DEFAULT_ROUND', -1), getDolGlobalString("MAIN_VOLUME_DEFAULT_UNIT", 'no'));
1650 } else {
1651 print $calculatedVolume.' '.measuringUnitString(0, "volume", (string) $volumeUnit);
1652 }
1653 }
1654 if ($totalVolume > 0) {
1655 if ($calculatedVolume) {
1656 print ' ('.$langs->trans("SumOfProductVolumes").': ';
1657 }
1658 print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, getDolGlobalInt('MAIN_VOLUME_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_VOLUME_DEFAULT_UNIT', 'no'));
1659 //if (empty($calculatedVolume)) print ' ('.$langs->trans("Calculated").')';
1660 if ($calculatedVolume) {
1661 print ')';
1662 }
1663 }
1664 print "</td>\n";
1665 print '</tr>';
1666
1667 // Other attributes
1668 $cols = 2;
1669
1670 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1671
1672 print '</table>';
1673
1674 print '</div>';
1675 print '<div class="fichehalfright">';
1676 print '<div class="underbanner clearboth"></div>';
1677
1678 print '<table class="border centpercent tableforfield">';
1679
1680 // Reception method
1681 print '<tr><td height="10">';
1682 print '<table class="nobordernopadding centpercent"><tr><td>';
1683 print $langs->trans('ReceptionMethod');
1684 print '</td>';
1685
1686 if ($action != 'editshipping_method_id' && $permissiontoadd) {
1687 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editshipping_method_id&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetReceptionMethod'), 1).'</a></td>';
1688 }
1689 print '</tr></table>';
1690 print '</td><td colspan="2">';
1691 if ($action == 'editshipping_method_id') {
1692 print '<form name="setshipping_method_id" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
1693 print '<input type="hidden" name="token" value="'.newToken().'">';
1694 print '<input type="hidden" name="action" value="setshipping_method_id">';
1695 $object->fetch_delivery_methods();
1696 print $form->selectarray("shipping_method_id", $object->meths, $object->shipping_method_id, 1, 0, 0, "", 1);
1697 if ($user->admin) {
1698 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1699 }
1700 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
1701 print '</form>';
1702 } else {
1703 if ($object->shipping_method_id > 0) {
1704 // Get code using getLabelFromKey
1705 $code = $langs->getLabelFromKey($db, $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code');
1706 print $langs->trans("SendingMethod".strtoupper($code));
1707 }
1708 }
1709 print '</td>';
1710 print '</tr>';
1711
1712 // Tracking Number
1713 print '<tr><td class="titlefield">'.$form->editfieldkey("TrackingNumber", 'tracking_number', $object->tracking_number, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
1714 print $form->editfieldval("TrackingNumber", 'tracking_number', $object->tracking_url, $object, $user->hasRight('reception', 'creer'), 'safehtmlstring', $object->tracking_number);
1715 print '</td></tr>';
1716
1717 // Incoterms
1718 if (isModEnabled('incoterm')) {
1719 print '<tr><td>';
1720 print '<table width="100%" class="nobordernopadding"><tr><td>';
1721 print $langs->trans('IncotermLabel');
1722 print '<td><td class="right">';
1723 if ($user->hasRight('reception', 'creer')) {
1724 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/reception/card.php?id='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
1725 } else {
1726 print '&nbsp;';
1727 }
1728 print '</td></tr></table>';
1729 print '</td>';
1730 print '<td colspan="3">';
1731 if ($action != 'editincoterm') {
1732 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
1733 } else {
1734 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
1735 }
1736 print '</td></tr>';
1737 }
1738
1739 print "</table>";
1740
1741 print '</div>';
1742 print '</div>';
1743
1744 print '<div class="clearboth"></div>';
1745
1746
1747 // Lines of products
1748 if ($action == 'editline') {
1749 print '<form name="updateline" id="updateline" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;lineid='.$line_id.'" method="POST">
1750 <input type="hidden" name="token" value="' . newToken().'">
1751 <input type="hidden" name="action" value="updateline">
1752 <input type="hidden" name="mode" value="">
1753 <input type="hidden" name="id" value="' . $object->id.'">';
1754 }
1755 print '<br><br>';
1756
1757 print '<div class="div-table-responsive-no-min">';
1758 print '<table id="tablelines" class="noborder centpercent">';
1759 print '<thead>';
1760 print '<tr class="liste_titre">';
1761 // #
1762 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
1763 print '<td width="5" class="center">&nbsp;</td>';
1764 }
1765 // Product/Service
1766 print '<td>'.$langs->trans("Products").'</td>';
1767 // Comment
1768 print '<td>'.$langs->trans("Comment").'</td>';
1769 // Qty
1770 print '<td class="center">'.$langs->trans("QtyOrdered").'</td>';
1771 if ($origin && $origin_id > 0) {
1772 print '<td class="center">'.$langs->trans("QtyInOtherReceptions").'</td>';
1773 }
1774 if ($action == 'editline') {
1775 $editColspan = 3;
1776 if (!isModEnabled('stock')) {
1777 $editColspan--;
1778 }
1779 if (empty($conf->productbatch->enabled)) {
1780 $editColspan--;
1781 }
1782 print '<td class="center" colspan="'.$editColspan.'">';
1783 if ($object->statut <= 1) {
1784 print $langs->trans("QtyToReceive").' - ';
1785 } else {
1786 print $langs->trans("QtyReceived").' - ';
1787 }
1788 if (isModEnabled('stock')) {
1789 print $langs->trans("WarehouseTarget").' - ';
1790 }
1791 if (isModEnabled('productbatch')) {
1792 print $langs->trans("Batch");
1793 }
1794 print '</td>';
1795 } else {
1796 $statusreceived = $object::STATUS_CLOSED;
1797 if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION")) {
1798 $statusreceived = $object::STATUS_VALIDATED;
1799 }
1800 if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION_CLOSE")) {
1801 $statusreceived = $object::STATUS_CLOSED;
1802 }
1803 if ($object->statut < $statusreceived) {
1804 print '<td class="center">'.$langs->trans("QtyToReceive").'</td>';
1805 } else {
1806 print '<td class="center">'.$langs->trans("QtyReceived").'</td>';
1807 }
1808 if (isModEnabled('stock')) {
1809 print '<td class="left">'.$langs->trans("WarehouseTarget").'</td>';
1810 }
1811
1812 if (isModEnabled('productbatch')) {
1813 print '<td class="left">'.$langs->trans("Batch").'</td>';
1814 }
1815 }
1816 print '<td class="center">'.$langs->trans("CalculatedWeight").'</td>';
1817 print '<td class="center">'.$langs->trans("CalculatedVolume").'</td>';
1818 //print '<td class="center">'.$langs->trans("Size").'</td>';
1819 if ($object->statut == 0) {
1820 print '<td class="linecoledit"></td>';
1821 print '<td class="linecoldelete" width="10"></td>';
1822 }
1823 print "</tr>\n";
1824 print '</thead>';
1825
1826 $var = false;
1827
1828 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
1829 $object->fetch_thirdparty();
1830 $outputlangs = $langs;
1831 $newlang = '';
1832 if (empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1833 $newlang = GETPOST('lang_id', 'aZ09');
1834 }
1835 if (empty($newlang)) {
1836 $newlang = $object->thirdparty->default_lang;
1837 }
1838 if (!empty($newlang)) {
1839 $outputlangs = new Translate("", $conf);
1840 $outputlangs->setDefaultLang($newlang);
1841 }
1842 }
1843
1844 // Get list of products already sent for same source object into $alreadysent
1845 $alreadysent = array();
1846
1847 $origin = 'commande_fournisseur';
1848
1849 if ($origin && $origin_id > 0) {
1850 $sql = "SELECT obj.rowid, obj.fk_product, obj.label, obj.description, obj.product_type as fk_product_type, obj.qty as qty_asked, obj.date_start, obj.date_end";
1851 $sql .= ", ed.rowid as receptionline_id, ed.qty, ed.fk_reception as reception_id, ed.fk_entrepot";
1852 $sql .= ", e.rowid as reception_id, e.ref as reception_ref, e.date_creation, e.date_valid, e.date_delivery, e.date_reception";
1853 //if (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY')) $sql .= ", l.rowid as livraison_id, l.ref as livraison_ref, l.date_delivery, ld.qty as qty_received";
1854 $sql .= ', p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tobatch as product_tobatch';
1855 $sql .= ', p.description as product_desc';
1856 $sql .= " FROM ".MAIN_DB_PREFIX."receptiondet_batch as ed";
1857 $sql .= ", ".MAIN_DB_PREFIX."reception as e";
1858 $sql .= ", ".MAIN_DB_PREFIX.$origin."det as obj";
1859 //if (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY')) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."delivery as l ON l.fk_reception = e.rowid LEFT JOIN ".MAIN_DB_PREFIX."deliverydet as ld ON ld.fk_delivery = l.rowid AND obj.rowid = ld.fk_origin_line";
1860 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON obj.fk_product = p.rowid";
1861 $sql .= " WHERE e.entity IN (".getEntity('reception').")";
1862 $sql .= " AND obj.fk_commande = ".((int) $origin_id);
1863 $sql .= " AND obj.rowid = ed.fk_elementdet";
1864 $sql .= " AND ed.fk_reception = e.rowid";
1865 $sql .= " AND ed.fk_reception !=".((int) $object->id);
1866 //if ($filter) $sql.= $filter;
1867 $sql .= " ORDER BY obj.fk_product";
1868
1869 dol_syslog("get list of reception lines", LOG_DEBUG);
1870 $resql = $db->query($sql);
1871 if ($resql) {
1872 $num = $db->num_rows($resql);
1873 $i = 0;
1874
1875 while ($i < $num) {
1876 $obj = $db->fetch_object($resql);
1877 if ($obj) {
1878 // $obj->rowid is rowid in $origin."det" table
1879 $alreadysent[$obj->rowid][$obj->receptionline_id] = array('reception_ref' => $obj->reception_ref, 'reception_id' => $obj->reception_id, 'warehouse' => $obj->fk_entrepot, 'qty' => $obj->qty, 'date_valid' => $obj->date_valid, 'date_delivery' => $obj->date_delivery);
1880 }
1881 $i++;
1882 }
1883 }
1884 //var_dump($alreadysent);
1885 }
1886
1887 $arrayofpurchaselinealreadyoutput = array();
1888
1889 // Loop on each product to send/sent. Warning: $lines must be sorted by ->fk_commandefourndet (it is a regroupment key on output)
1890 print '<tbody>';
1891 for ($i = 0; $i < $num_prod; $i++) {
1892 print '<!-- origin line id = '.(!empty($lines[$i]->origin_line_id) ? $lines[$i]->origin_line_id : 0).' -->'; // id of order line
1893 print '<tr class="oddeven" id="row-'.$lines[$i]->id.'" data-id="'.$lines[$i]->id.'" data-element="'.$lines[$i]->element.'">';
1894
1895 // #
1896 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
1897 print '<td class="center">'.($i + 1).'</td>';
1898 }
1899
1900 // Predefined product or service
1901 if ($lines[$i]->fk_product > 0) {
1902 // Define output language
1903 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
1904 $prod = new Product($db);
1905 $prod->fetch($lines[$i]->fk_product);
1906 $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["label"])) ? $prod->multilangs[$outputlangs->defaultlang]["label"] : $lines[$i]->product->label;
1907 } else {
1908 $label = (!empty($lines[$i]->product->label) ? $lines[$i]->product->label : $lines[$i]->product->product_label);
1909 }
1910
1911 print '<td class="linecoldescription">';
1912 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
1913 $text = $lines[$i]->product->getNomUrl(1);
1914 $text .= ' - '.$label;
1915 $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($lines[$i]->product->description));
1916 print $form->textwithtooltip($text, $description, 3, '', '', $i);
1917 print_date_range(!empty($lines[$i]->date_start) ? $lines[$i]->date_start : 0, !empty($lines[$i]->date_end) ? $lines[$i]->date_end : 0);
1918 if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
1919 print (!empty($lines[$i]->product->description) && $lines[$i]->description != $lines[$i]->product->description) ? '<br>'.dol_htmlentitiesbr($lines[$i]->description) : '';
1920 }
1921 }
1922 print "</td>\n";
1923 } else {
1924 print '<td class="linecoldescription">';
1925 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
1926 if ($lines[$i]->product_type == Product::TYPE_SERVICE) {
1927 $text = img_object($langs->trans('Service'), 'service');
1928 } else {
1929 $text = img_object($langs->trans('Product'), 'product');
1930 }
1931
1932 if (!empty($lines[$i]->label)) {
1933 $text .= ' <strong>'.$lines[$i]->label.'</strong>';
1934 print $form->textwithtooltip($text, $lines[$i]->description, 3, '', '', $i);
1935 } else {
1936 print $text.' '.nl2br($lines[$i]->description);
1937 }
1938
1939 print_date_range($lines[$i]->date_start, $lines[$i]->date_end);
1940 }
1941 print "</td>\n";
1942 }
1943
1944 if ($action == 'editline' && $lines[$i]->id == $line_id) {
1945 print '<td><input name="comment'.$line_id.'" id="comment'.$line_id.'" value="'.dol_escape_htmltag($lines[$i]->comment).'"></td>';
1946 } else {
1947 print '<td style="white-space: pre-wrap; max-width: 200px;">'.dol_escape_htmltag($lines[$i]->comment).'</td>';
1948 }
1949
1950
1951 // Qty ordered
1952 print '<td class="center linecolqty">';
1953 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
1954 print $lines[$i]->qty_asked;
1955 }
1956 print '</td>';
1957
1958 // Qty in other receptions (with reception and warehouse used)
1959 if ($origin && $origin_id > 0) {
1960 print '<td class="center nowrap linecolqtyinotherreceptions">';
1961 $htmltooltip = '';
1962 $qtyalreadyreceived = 0;
1963 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
1964 foreach ($alreadysent as $key => $val) {
1965 if ($lines[$i]->fk_commandefourndet == $key) {
1966 $j = 0;
1967 foreach ($val as $receptionline_id => $receptionline_var) {
1968 if ($receptionline_var['reception_id'] == $lines[$i]->fk_reception) {
1969 continue; // We want to show only "other receptions"
1970 }
1971
1972 $j++;
1973 if ($j > 1) {
1974 $htmltooltip .= '<br>';
1975 }
1976 $reception_static->fetch($receptionline_var['reception_id']);
1977 $htmltooltip .= $reception_static->getNomUrl(1, 0, 0, 0, 1);
1978 $htmltooltip .= ' - '.$receptionline_var['qty'];
1979
1980 $htmltext = $langs->trans("DateValidation").' : '.(empty($receptionline_var['date_valid']) ? $langs->trans("Draft") : dol_print_date($receptionline_var['date_valid'], 'dayhour'));
1981 if (isModEnabled('stock') && $receptionline_var['warehouse'] > 0) {
1982 $warehousestatic->fetch($receptionline_var['warehouse']);
1983 $htmltext .= '<br>'.$langs->trans("From").' : '.$warehousestatic->getNomUrl(1, '', 0, 1);
1984 }
1985 $htmltooltip .= ' '.$form->textwithpicto('', $htmltext, 1);
1986
1987 $qtyalreadyreceived += $receptionline_var['qty'];
1988 }
1989 if ($j) {
1990 $htmltooltip = $langs->trans("QtyInOtherReceptions").'...<br><br>'.$htmltooltip.'<br><input type="submit" name="dummyhiddenbuttontogetfocus" style="display:none" autofocus>';
1991 }
1992 }
1993 }
1994 }
1995 print $form->textwithpicto($qtyalreadyreceived, $htmltooltip, 1, 'info', '', 0, 3, 'tooltip'.$lines[$i]->id);
1996 print '</td>';
1997 }
1998
1999 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2000 // edit mode
2001 print '<td colspan="'.$editColspan.'" class="center"><table class="nobordernopadding">';
2002 if (isModEnabled('stock')) {
2003 if ($lines[$i]->fk_product > 0) {
2004 print '<!-- case edit 1 -->';
2005 print '<tr>';
2006 // Qty to receive or received
2007 print '<td><input name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty.'"></td>';
2008 // Warehouse source
2009 print '<td>'.$formproduct->selectWarehouses($lines[$i]->fk_entrepot, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1).'</td>';
2010 // Batch number management
2011 if ($conf->productbatch->enabled && !empty($lines[$i]->product->status_batch)) {
2012 print '<td class="nowraponall left"><input name="batch'.$line_id.'" id="batch'.$line_id.'" type="text" value="'.$lines[$i]->batch.'"><br>';
2013 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
2014 print $langs->trans('SellByDate').' : ';
2015 print $form->selectDate($lines[$i]->sellby, 'dlc'.$line_id, 0, 0, 1, "").'</br>';
2016 }
2017 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
2018 print $langs->trans('EatByDate').' : ';
2019 print $form->selectDate($lines[$i]->eatby, 'dluo'.$line_id, 0, 0, 1, "");
2020 }
2021 print '</td>';
2022 }
2023 print '</tr>';
2024 } else {
2025 print '<!-- case edit 2 -->';
2026 print '<tr>';
2027 // Qty to receive or received
2028 print '<td><input name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty.'"></td>';
2029 // Warehouse source
2030 print '<td></td>';
2031 // Batch number management
2032 print '<td></td>';
2033 print '</tr>';
2034 }
2035 }
2036 print '</table></td>';
2037 } else {
2038 // Qty to receive or received
2039 print '<td class="center linecolqtytoreceive">'.$lines[$i]->qty.'</td>';
2040
2041 // Warehouse source
2042 if (isModEnabled('stock')) {
2043 if ($lines[$i]->fk_entrepot > 0) {
2044 $entrepot = new Entrepot($db);
2045 $entrepot->fetch($lines[$i]->fk_entrepot);
2046
2047 print '<td class="left tdoverflowmax150" title="'.dol_escape_htmltag($entrepot->label).'">';
2048 print $entrepot->getNomUrl(1);
2049 print '</td>';
2050 } else {
2051 print '<td></td>';
2052 }
2053 }
2054
2055 // Batch number management
2056 if (isModEnabled('productbatch')) {
2057 if (isset($lines[$i]->batch)) {
2058 print '<!-- Detail of lot -->';
2059 print '<td class="linecolbatch nowrap">';
2060 $detail = $langs->trans("NA");
2061 if ($lines[$i]->product->status_batch > 0 && $lines[$i]->fk_product > 0) {
2062 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
2063 $productlot = new Productlot($db);
2064 $reslot = $productlot->fetch(0, $lines[$i]->fk_product, $lines[$i]->batch);
2065 if ($reslot > 0) {
2066 $detail = $productlot->getNomUrl(1);
2067 } else {
2068 // lot is not created and info is only in reception lines
2069 $batchinfo = $langs->trans("Batch").': '.$lines[$i]->batch;
2070 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
2071 $batchinfo .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($lines[$i]->sellby, "day");
2072 }
2073 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
2074 $batchinfo .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($lines[$i]->eatby, "day");
2075 }
2076 $detail = $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"), $batchinfo);
2077 }
2078 }
2079 print $detail . '</td>';
2080 } else {
2081 print '<td></td>';
2082 }
2083 }
2084 }
2085
2086 // Weight
2087 print '<td class="center linecolweight">';
2088 if (!empty($lines[$i]->fk_product_type) && $lines[$i]->fk_product_type == Product::TYPE_PRODUCT) {
2089 print $lines[$i]->product->weight * $lines[$i]->qty.' '.measuringUnitString(0, "weight", $lines[$i]->product->weight_units);
2090 } else {
2091 print '&nbsp;';
2092 }
2093 print '</td>';
2094
2095 // Volume
2096 print '<td class="center linecolvolume">';
2097 if (!empty($lines[$i]->fk_product_type) && $lines[$i]->fk_product_type == Product::TYPE_PRODUCT) {
2098 print $lines[$i]->product->volume * $lines[$i]->qty.' '.measuringUnitString(0, "volume", $lines[$i]->product->volume_units);
2099 } else {
2100 print '&nbsp;';
2101 }
2102 print '</td>';
2103
2104
2105 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2106 print '<td class="center valignmiddle" colspan="2">';
2107 print '<input type="submit" class="button small button-save" id="savelinebutton marginbottomonly" name="save" value="'.$langs->trans("Save").'"><br>';
2108 print '<input type="submit" class="button small button-cancel" id="cancellinebutton" name="cancel" value="'.$langs->trans("Cancel").'"><br>';
2109 print '</td>';
2110 } elseif ($object->statut == Reception::STATUS_DRAFT) {
2111 // edit-delete buttons
2112 print '<td class="linecoledit center">';
2113 print '<a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&token='.newToken().'&lineid='.$lines[$i]->id.'">'.img_edit().'</a>';
2114 print '</td>';
2115 print '<td class="linecoldelete" width="10">';
2116 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deleteline&token='.newToken().'&lineid='.$lines[$i]->id.'">'.img_delete().'</a>';
2117 print '</td>';
2118
2119 // Display lines extrafields
2120 if (!empty($rowExtrafieldsStart)) {
2121 print $rowExtrafieldsStart;
2122 print $rowExtrafieldsView;
2123 print $rowEnd;
2124 }
2125 }
2126 print "</tr>";
2127
2128 $arrayofpurchaselinealreadyoutput[$lines[$i]->fk_commandefourndet] = $lines[$i]->fk_commandefourndet;
2129
2130 // Display lines extrafields
2131 $extralabelslines = $extrafields->attributes[$lines[$i]->table_element];
2132 if (!empty($extralabelslines) && is_array($extralabelslines) && count($extralabelslines) > 0) {
2133 $colspan = 8;
2134 if (isModEnabled('stock')) {
2135 $colspan++;
2136 }
2137 if (isModEnabled('productbatch')) {
2138 $colspan++;
2139 }
2140
2141 $line = new CommandeFournisseurDispatch($db);
2142 $line->id = $lines[$i]->id;
2143 $line->fetch_optionals();
2144
2145 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2146 print $line->showOptionals($extrafields, 'edit', array('colspan' => $colspan), '');
2147 } else {
2148 print $line->showOptionals($extrafields, 'view', array('colspan' => $colspan), '');
2149 }
2150 }
2151 }
2152 print '</tbody>';
2153
2154 // TODO Show also lines ordered but not delivered
2155
2156 print "</table>\n";
2157 print '</div>';
2158
2159
2160 print dol_get_fiche_end();
2161
2162
2163 $object->fetchObjectLinked($object->id, $object->element);
2164
2165
2166 /*
2167 * Boutons actions
2168 */
2169
2170 if (($user->socid == 0) && ($action != 'presend')) {
2171 print '<div class="tabsAction">';
2172
2173 $parameters = array();
2174 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2175 if (empty($reshook)) {
2176 if ($object->statut == Reception::STATUS_DRAFT && $num_prod > 0) {
2177 if ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'creer'))
2178 || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'reception_advance', 'validate'))) {
2179 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken().'">'.$langs->trans("Validate").'</a>';
2180 } else {
2181 print '<a class="butActionRefused" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Validate").'</a>';
2182 }
2183 }
2184 // Back to draft
2185 if ($object->statut == Reception::STATUS_VALIDATED && $user->hasRight('reception', 'creer')) {
2186 print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=modif&token='.newToken().'">'.$langs->trans('SetToDraft').'</a></div>';
2187 }
2188
2189 // TODO add alternative status
2190 // 0=draft, 1=validated, 2=billed, we miss a status "delivered" (only available on order)
2191 if ($object->statut == Reception::STATUS_CLOSED && $user->hasRight('reception', 'creer')) {
2192 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("ReOpen").'</a>';
2193 }
2194
2195 // Send
2196 if (empty($user->socid)) {
2197 if ($object->statut > 0) {
2198 if (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('reception', 'reception_advance', 'send')) {
2199 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendByMail').'</a>';
2200 } else {
2201 print '<a class="butActionRefused" href="#">'.$langs->trans('SendByMail').'</a>';
2202 }
2203 }
2204 }
2205
2206 // Create bill
2207 if (isModEnabled("supplier_invoice") && ($object->statut == Reception::STATUS_VALIDATED || $object->statut == Reception::STATUS_CLOSED)) {
2208 if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight('supplier_invoice', 'creer')) {
2209 if (getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0') {
2210 print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->socid.'">'.$langs->trans("CreateBill").'</a>';
2211 }
2212 }
2213 }
2214
2215
2216 // Set Billed and Closed
2217 if ($object->statut == Reception::STATUS_VALIDATED) {
2218 if ($user->hasRight('reception', 'creer') && $object->statut > 0) {
2219 if (!$object->billed && getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0') {
2220 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled&token='.newToken().'">'.$langs->trans('ClassifyBilled').'</a>';
2221 }
2222 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifyclosed&token='.newToken().'">'.$langs->trans("Close").'</a>';
2223 }
2224 }
2225
2226 if ($user->hasRight('reception', 'supprimer')) {
2227 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'">'.$langs->trans("Delete").'</a>';
2228 }
2229 }
2230
2231 print '</div>';
2232 }
2233
2234
2235 /*
2236 * Documents generated
2237 */
2238
2239 if ($action != 'presend' && $action != 'editline') {
2240 print '<div class="fichecenter"><div class="fichehalfleft">';
2241
2242 $objectref = dol_sanitizeFileName($object->ref);
2243 $filedir = $conf->reception->dir_output."/".$objectref;
2244
2245 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2246
2247 $genallowed = $user->hasRight('reception', 'lire');
2248 $delallowed = $user->hasRight('reception', 'creer');
2249
2250 print $formfile->showdocuments('reception', $objectref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang);
2251
2252 // Show links to link elements
2253 //$tmparray = $form->showLinkToObjectBlock($object, null, array('order'), 1);
2254 $somethingshown = $form->showLinkedObjectBlock($object, '');
2255
2256 print '</div><div class="fichehalfright">';
2257
2258 print '</div></div>';
2259 }
2260
2261 // Presend form
2262 $modelmail = 'shipping_send';
2263 $defaulttopic = 'SendReceptionRef';
2264 $diroutput = $conf->reception->dir_output;
2265 $trackid = 'rec'.$object->id;
2266
2267 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2268}
2269
2270
2271llxFooter();
2272
2273$db->close();
$id
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
Class to manage table ReceptionLineBatch.
Class to manage predefined suppliers products.
Class to manage line orders.
Class to manage customers orders.
Class to manage a WYSIWYG editor.
Class to manage warehouses.
Class to manage standard extra fields.
Class to offer components to list and upload files.
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 building of HTML components.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
Class to manage the table of subscription to notifications.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class with list of lots and properties.
Class to manage projects.
Class to manage proposals.
Class to manage receptions.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
llxFooter()
Footer empty.
Definition document.php:107
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
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...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round=-1, $forceunitoutput='no', $use_short_label=0)
Output a dimension with best unit.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
print_date_range($date_start, $date_end, $format='', $outputlangs=null)
Format output for start and end date.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='')
Return the value of a $_GET or $_POST supervariable, converted into float.
dol_clone($object, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
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...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
measuringUnitString($unitid, $measuring_style='', $unitscale='', $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
reception_prepare_head(Reception $object)
Prepare array with list of tabs.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.