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