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