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