dolibarr 25.0.0-alpha
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003-2008 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2005-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Simon TOSSER <simon@kornog-computing.com>
5 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
6 * Copyright (C) 2011-2017 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2013 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
10 * Copyright (C) 2014-2017 Francis Appels <francis.appels@yahoo.com>
11 * Copyright (C) 2015 Claudio Aschieri <c.aschieri@19.coop>
12 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
13 * Copyright (C) 2016 Yasser Carreón <yacasia@gmail.com>
14 * Copyright (C) 2018 Quentin Vial-Gouteyron <quentin.vial-gouteyron@atm-consulting.fr>
15 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
16 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
17 * Copyright (C) 2025 Nick Fragoulis
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 3 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program. If not, see <https://www.gnu.org/licenses/>.
31 */
32
39// Load Dolibarr environment
40require '../main.inc.php';
49require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
50require_once DOL_DOCUMENT_ROOT.'/reception/class/reception.class.php';
51require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
52require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
53require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
54require_once DOL_DOCUMENT_ROOT.'/core/lib/reception.lib.php';
55require_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
56require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
57require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
58require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
59require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
60if (isModEnabled("product") || isModEnabled("service")) {
61 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
62}
63if (isModEnabled("propal")) {
64 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
65}
66require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
67require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.orderline.class.php';
68require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php';
69if (isModEnabled('productbatch')) {
70 require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
71}
72if (isModEnabled('project')) {
73 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
74 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
75}
76
77$langs->loadLangs(array("receptions", "companies", "bills", 'orders', 'stocks', 'other', 'propal', 'sendings'));
78
79if (isModEnabled('incoterm')) {
80 $langs->load('incoterm');
81}
82if (isModEnabled('productbatch')) {
83 $langs->load('productbatch');
84}
85
86$origin = GETPOST('origin', 'alpha'); // Example: commande, propal
87$origin_id = GETPOSTINT('origin_id') ? GETPOSTINT('id') : '';
88$id = GETPOSTINT('id');
89if (empty($origin_id) && !empty($origin)) {
90 $origin_id = GETPOSTINT('origin_id'); // Id of order or propal
91}
92if (empty($origin_id) && !empty($origin)) {
93 $origin_id = GETPOSTINT('object_id'); // Id of order or propal
94}
95if (empty($origin_id) && !empty($origin)) {
96 $origin_id = GETPOSTINT('originid'); // Id of order or propal
97}
98$ref = GETPOST('ref', 'alpha');
99$line_id = GETPOSTINT('lineid') ? GETPOSTINT('lineid') : 0;
100$facid = GETPOSTINT('facid');
101$socid = GETPOSTINT('socid');
102$action = GETPOST('action', 'alpha');
103//Select mail models is same action as presend
104if (GETPOST('modelselected')) {
105 $action = 'presend';
106}
107$confirm = GETPOST('confirm', 'alpha');
108$cancel = GETPOST('cancel', 'alpha');
109$backtopage = GETPOST('backtopage', 'alpha');
110$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
111
112$contactid = GETPOSTINT('contactid');
113$projectid = GETPOSTINT('projectid');
114
115
116$cancel = GETPOST('cancel', 'alpha');
117$rank = (GETPOSTINT('rank') > 0) ? GETPOSTINT('rank') : -1;
118$lineid = GETPOSTINT('lineid');
119$backtopage = GETPOST('backtopage', 'alpha');
120//PDF
121$hidedetails = (GETPOSTINT('hidedetails') ? GETPOSTINT('hidedetails') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0));
122$hidedesc = (GETPOSTINT('hidedesc') ? GETPOSTINT('hidedesc') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0));
123$hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0));
124
125$object = new Reception($db);
126$objectorder = new CommandeFournisseur($db);
127$extrafields = new ExtraFields($db);
128
129// fetch optionals attributes and labels
130$extrafields->fetch_name_optionals_label($object->table_element);
131$extrafields->fetch_name_optionals_label($object->table_element_line);
132$extrafields->fetch_name_optionals_label($objectorder->table_element_line);
133
134// Load object. Make an object->fetch
135include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'
136
137// Restore $origin and $origin_id from the loaded object when the request only carried the
138// reception id (e.g. the line edit form on an existing reception posts action=updateline
139// and id=N but no origin field). Without this, the action handler below sees $origin
140// empty and silently skips both its standalone and its origin branches, so updates to
141// quantity, comment, batch and extrafields on an existing line are not persisted
142// (see issue #38386, regression from PR #36134).
143// The restore is gated on $object->origin_id > 0 so standalone receptions, which have
144// no upstream origin, are not affected: $origin stays empty and the standalone branch
145// of the updateline handler is still selected.
146if ($object->origin_id > 0) {
147 if (empty($origin)) {
148 if (!empty($object->origin_type)) {
149 $origin = $object->origin_type;
150 } elseif (is_string($object->origin) && $object->origin !== '') {
151 $origin = (string) $object->origin;
152 }
153 }
154 if (empty($origin_id)) {
155 $origin_id = $object->origin_id;
156 }
157}
158
159// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
160$hookmanager->initHooks(array('receptioncard', 'globalcard'));
161
162$date_delivery = dol_mktime(GETPOSTINT('date_deliveryhour'), GETPOSTINT('date_deliverymin'), 0, GETPOSTINT('date_deliverymonth'), GETPOSTINT('date_deliveryday'), GETPOSTINT('date_deliveryyear'));
163$date_reception = dol_mktime(GETPOSTINT('date_receptionhour'), GETPOSTINT('date_receptionmin'), 0, GETPOSTINT('date_receptionmonth'), GETPOSTINT('date_receptionday'), GETPOSTINT('date_receptionyear'));
164
165// Security check
166if ($user->socid) {
167 $socid = $user->socid;
168}
169$result = restrictedArea($user, 'reception', $object->id, '');
170// TODO Test on reception module on only
171if (isModEnabled("reception") || $origin == 'reception' || empty($origin)) {
172 $result = restrictedArea($user, 'reception', $object->id);
173} else {
174 // We do not use the reception module, so we test permission on the supplier orders
175 if ($origin == 'supplierorder' || $origin == 'order_supplier') {
176 $result = restrictedArea($user, 'fournisseur', $origin_id, 'commande_fournisseur', 'commande');
177 } elseif (!$user->hasRight($origin, 'lire') && !$user->hasRight($origin, 'read')) {
179 }
180}
181
182if (isModEnabled("reception")) {
183 $permissiontoread = $user->hasRight('reception', 'lire');
184 $permissiontoadd = $user->hasRight('reception', 'creer');
185 $permissiontoedit = $user->hasRight('reception', 'creer'); // Used by the include of actions_lineupdown.inc.php
186 $permissiondellink = $user->hasRight('reception', 'creer'); // Used by the include of actions_dellink.inc.php
187 $permissiontovalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'creer')) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'reception_advance', 'validate')));
188 $permissiontodelete = $user->hasRight('reception', 'supprimer');
189} else {
190 $permissiontoread = $user->hasRight('fournisseur', 'commande', 'receptionner');
191 $permissiontoadd = $user->hasRight('fournisseur', 'commande', 'receptionner');
192 $permissiondellink = $user->hasRight('fournisseur', 'commande', 'receptionner'); // Used by the include of actions_dellink.inc.php
193 $permissiontovalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('fournisseur', 'commande', 'receptionner')) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('fournisseur', 'commande_advance', 'check')));
194 $permissiontodelete = $user->hasRight('fournisseur', 'commande', 'receptionner');
195}
196$permissiontoeditextra = $permissiontoadd;
197if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
198 // For action 'update_extras' there is a specific permission set for the attribute to update
199 $permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
200}
201
202$editColspan = 0;
203$objectsrc = null;
204$typeobject = null;
205$ref_customer = null;
206$shipping_method_id = null;
207$warehouse_id = null;
208$note_public = null;
209$note_private = null;
210
211
212/*
213 * Actions
214 */
215
216$error = 0;
217$parameters = array();
218$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
219if ($reshook < 0) {
220 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
221}
222
223if (empty($reshook)) {
224 $backurlforlist = DOL_URL_ROOT.'/reception/list.php';
225
226 if (empty($backtopage) || ($cancel && empty($id))) {
227 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
228 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
229 $backtopage = $backurlforlist;
230 } else {
231 $backtopage = DOL_URL_ROOT.'/reception/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
232 }
233 }
234 }
235
236 if ($cancel) {
237 if (!empty($backtopageforcancel)) {
238 header("Location: ".$backtopageforcancel);
239 exit;
240 } elseif (!empty($backtopage)) {
241 header("Location: ".$backtopage);
242 exit;
243 }
244
245 $action = '';
246 }
247
248 if ($cancel) {
249 if (!$origin) {
250 $action = '';
251 $object->fetch($object->id); // show reception also after canceling modification
252 }
253 }
254
255 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be 'include', not 'include_once'
256
257 // Reopen
258 if ($action == 'reopen' && $permissiontoadd) { // Test on permissions not required here
259 $result = $object->reOpen();
260 if ($result < 0) {
261 setEventMessages($object->error, $object->errors, 'errors');
262 }
263 }
264
265 // Confirm back to draft status
266 if ($action == 'modif' && $permissiontoadd) {
267 $result = $object->setDraft($user);
268 if ($result >= 0) {
269 // Define output language
270 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
271 $outputlangs = $langs;
272 $newlang = '';
273 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
274 $newlang = GETPOST('lang_id', 'aZ09');
275 }
276 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
277 $newlang = $object->thirdparty->default_lang;
278 }
279 if (!empty($newlang)) {
280 $outputlangs = new Translate("", $conf);
281 $outputlangs->setDefaultLang($newlang);
282 }
283 $model = $object->model_pdf;
284 $ret = $object->fetch($id); // Reload to get new records
285 $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
286 }
287 } else {
288 setEventMessages($object->error, $object->errors, 'errors');
289 }
290 }
291
292 // Set incoterm
293 if ($action == 'set_incoterms' && isModEnabled('incoterm') && $permissiontoadd) {
294 $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms'));
295 }
296
297 if ($action == 'setref_supplier' && $permissiontoadd) {
298 if ($result < 0) {
299 setEventMessages($object->error, $object->errors, 'errors');
300 }
301
302 $result = $object->setValueFrom('ref_supplier', GETPOST('ref_supplier', 'alpha'), '', null, 'text', '', $user, 'RECEPTION_MODIFY');
303 if ($result < 0) {
304 setEventMessages($object->error, $object->errors, 'errors');
305 $action = 'editref_supplier';
306 } else {
307 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
308 exit;
309 }
310 }
311
312 if ($action == 'update_extras' && $permissiontoeditextra) {
313 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
314
315 $attribute_name = GETPOST('attribute', 'aZ09');
316
317 // Fill array 'array_options' with data from update form
318 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
319 if ($ret < 0) {
320 $error++;
321 }
322
323 if (!$error) {
324 $result = $object->updateExtraField($attribute_name, 'RECEPTION_MODIFY');
325 if ($result < 0) {
326 setEventMessages($object->error, $object->errors, 'errors');
327 $error++;
328 }
329 }
330
331 if ($error) {
332 $action = 'edit_extras';
333 }
334 }
335
336 // Create reception
337 if ($action == 'add' && $permissiontoadd) {
338 $db->begin();
339
340 if (!$error && !$origin && getDolGlobalString('RECEPTION_STANDALONE')) {
341 if (GETPOSTINT('socid') < 1) {
342 $error++;
343 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ThirdParty")), null, 'errors');
344 $action = 'create';
345 }
346
347 $object->socid = GETPOSTINT('socid');
348 $object->fetch_thirdparty();
349 $object->note = GETPOST('note', 'alpha');
350 $object->note_private = GETPOST('note', 'alpha');
351 $object->origin = $origin; // deprecated
352 $object->origin_type = $origin;
353 $object->origin_id = $origin_id;
354 $object->fk_project = GETPOSTINT('projectid');
355 $object->weight = GETPOSTINT('weight') == '' ? null : GETPOSTINT('weight');
356 $object->trueHeight = GETPOSTINT('trueHeight') == '' ? null : GETPOSTINT('trueHeight');
357 $object->trueWidth = GETPOSTINT('trueWidth') == '' ? null : GETPOSTINT('trueWidth');
358 $object->trueDepth = GETPOSTINT('trueDepth') == '' ? null : GETPOSTINT('trueDepth');
359 $object->size_units = GETPOSTINT('size_units');
360 $object->weight_units = GETPOSTINT('weight_units');
361 $object->ref_supplier = GETPOST('ref_supplier', 'alpha');
362 $object->model_pdf = GETPOST('model');
363 $object->date_delivery = $date_delivery; // Date delivery planned
364 $object->date_reception = $date_reception;
365 $object->shipping_method_id = GETPOSTINT('shipping_method_id');
366 $object->tracking_number = GETPOST('tracking_number', 'alpha');
367 $object->note_private = GETPOST('note_private', 'restricthtml');
368 $object->note_public = GETPOST('note_public', 'restricthtml');
369 $object->fk_incoterms = GETPOSTINT('incoterm_id');
370 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
371
372 $product = new Product($db);
373
374 // Fill array 'array_options' with data from add form
375 $ret = $extrafields->setOptionalsFromPost(null, $object);
376 if ($ret < 0) {
377 $error++;
378 }
379
380 if (!$error) {
381 $ret = $object->create($user);
382 if ($ret <= 0) {
383 setEventMessages($object->error, $object->errors, 'errors');
384 $error++;
385 }
386 }
387 }
388 if ($origin && $origin_id > 0) {
389 $object->note = GETPOST('note', 'alpha');
390 $object->note_private = GETPOST('note', 'alpha');
391 $object->origin = $origin;
392 $object->origin_type = $origin;
393 $object->origin_id = $origin_id;
394 $object->fk_project = GETPOSTINT('projectid');
395 $object->weight = GETPOST('weight') == '' ? null : GETPOSTINT('weight');
396 $object->trueHeight = GETPOST('trueHeight') == '' ? null : GETPOSTINT('trueHeight');
397 $object->trueWidth = GETPOST('trueWidth') == '' ? null : GETPOSTINT('trueWidth');
398 $object->trueDepth = GETPOST('trueDepth') == '' ? null : GETPOSTINT('trueDepth');
399 $object->size_units = GETPOSTINT('size_units');
400 $object->weight_units = GETPOSTINT('weight_units');
401
402 $object->ref_supplier = GETPOST('ref_supplier', 'alpha');
403 $object->model_pdf = GETPOST('model');
404 $object->date_delivery = $date_delivery; // Date delivery planned
405 $object->date_reception = $date_reception;
406 $object->shipping_method_id = GETPOSTINT('shipping_method_id');
407 $object->tracking_number = GETPOST('tracking_number', 'alpha');
408 $object->note_private = GETPOST('note_private', 'restricthtml');
409 $object->note_public = GETPOST('note_public', 'restricthtml');
410 $object->fk_incoterms = GETPOSTINT('incoterm_id');
411 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
412
413 if ($object->origin == "supplierorder") {
414 $object->origin = 'order_supplier';
415 $object->origin_type = 'order_supplier';
416 $classname = 'CommandeFournisseur';
417 } else {
418 $classname = ucfirst($object->origin_type);
419 }
420 $objectsrc = new $classname($db);
421 $objectsrc->fetch($object->origin_id);
422
423 $object->socid = $objectsrc->socid;
424
425 $product = new Product($db);
426 $batch_line = array();
427 $stockLine = array();
428 $array_options = array();
429
430 $totalqty = 0;
431
432 $num = 0;
433 foreach ($_POST as $key => $value) {
434 // without batch module enabled
435
436 if (strpos($key, 'qtyasked') !== false) {
437 $num++;
438 }
439 }
440
441 // Loop lines to calculate $totalqty
442 for ($i = 1; $i <= $num; $i++) {
443 $idl = "idl".$i; // id line source
444
445 //$sub_qty = array();
446 //$subtotalqty = 0;
447
448 //$j = 0;
449 //$batch = "batchl".$i."_0";
450 //$stockLocation = "ent1".$i."_0";
451 $qty = "qtyl".$i; // qty
452
453 //reception line for product with no batch management and no multiple stock location
454 if (GETPOST($qty, 'alpha') > 0) {
455 $totalqty += price2num(GETPOST($qty, 'alpha'), 'MS');
456 }
457
458 // Extrafields
459 $array_options[$i] = $extrafields->getOptionalsFromPost($object->table_element_line, (string) $i);
460 }
461
462
463 if ($totalqty > 0) { // There is at least one thing to ship
464 for ($i = 1; $i <= $num; $i++) {
465 $idl = "idl".$i; // id line source
466 $lineToTest = '';
467 $lineId = GETPOSTINT($idl);
468 foreach ($objectsrc->lines as $linesrc) {
469 if ($linesrc->id == $lineId) {
470 $lineToTest = $linesrc;
471 break;
472 }
473 }
474 if (empty($lineToTest)) {
475 continue;
476 }
477 $qty = "qtyl".$i;
478 $comment = "comment".$i;
479 // EATBY <-> DLUO and SELLBY <-> DLC, see productbatch.class.php
480 $eatby = "dluo".$i;
481 $sellby = "dlc".$i;
482 $batch = "batch".$i;
483 $cost_price = "cost_price".$i;
484
485 //var_dump(GETPOST("productl".$i, 'int').' '.GETPOST('entl'.$i, 'int').' '.GETPOST($idl, 'int').' '.GETPOST($qty, 'int').' '.GETPOST($batch, 'alpha'));
486
487 //if (GETPOST($qty, 'int') > 0 || (GETPOST($qty, 'int') == 0 && getDolGlobalString('RECEPTION_GETS_ALL_ORDER_PRODUCTS')) || (GETPOST($qty, 'int') < 0 && getDolGlobalString('RECEPTION_ALLOW_NEGATIVE_QTY'))) {
488 if (GETPOSTFLOAT($qty) > 0 || (GETPOSTFLOAT($qty) == 0 && getDolGlobalString('RECEPTION_GETS_ALL_ORDER_PRODUCTS'))) {
489 $ent = "entl".$i;
490 $idl = "idl".$i;
491
492 $entrepot_id = is_numeric(GETPOST($ent)) ? GETPOSTINT($ent) : GETPOSTINT('entrepot_id');
493
494 /*
495 if (!empty($lineToTest)) {
496 $fk_product = $lineToTest->fk_product;
497 } else {
498 $fk_product = $linesrc->fk_product;
499 }*/
500 $fk_product = GETPOSTINT("productl".$i);
501
502 if ($entrepot_id < 0) {
503 $entrepot_id = '';
504 }
505 if (!($fk_product > 0) && !getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
506 $entrepot_id = 0;
507 }
508
509 $eatby = GETPOST($eatby, 'alpha');
510 $sellby = GETPOST($sellby, 'alpha');
511 $eatbydate = str_replace('/', '-', $eatby);
512 $sellbydate = str_replace('/', '-', $sellby);
513
514 if (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
515 $ret = $object->addline($entrepot_id, GETPOSTINT($idl), (float) price2num(GETPOST($qty), 'MS'), $array_options[$i], GETPOST($comment), strtotime($eatbydate), strtotime($sellbydate), GETPOST($batch), GETPOSTFLOAT($cost_price, 'MU'));
516 } else {
517 $ret = $object->addline($entrepot_id, GETPOSTINT($idl), (float) price2num(GETPOST($qty), 'MS'), $array_options[$i], GETPOST($comment), strtotime($eatbydate), strtotime($sellbydate), GETPOST($batch));
518 }
519 if ($ret < 0) {
520 setEventMessages($object->error, $object->errors, 'errors');
521 $error++;
522 }
523 }
524 }
525
526 // Fill array 'array_options' with data from add form
527 $ret = $extrafields->setOptionalsFromPost(null, $object);
528 if ($ret < 0) {
529 $error++;
530 }
531 if (!$error) {
532 $ret = $object->create($user); // This create reception (like Odoo picking) and line of receptions. Stock movement will when validating reception.
533
534 if ($ret <= 0) {
535 setEventMessages($object->error, $object->errors, 'errors');
536 $error++;
537 } else {
538 // Define output language
539 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
540 $object->fetch_thirdparty();
541 $outputlangs = $langs;
542 $newlang = '';
543 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
544 $newlang = GETPOST('lang_id', 'aZ09');
545 }
546 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
547 $newlang = $object->thirdparty->default_lang;
548 }
549 if (!empty($newlang)) {
550 $outputlangs = new Translate("", $conf);
551 $outputlangs->setDefaultLang($newlang);
552 }
553 $model = $object->model_pdf;
554 $ret = $object->fetch($object->id); // Reload to get new records
555
556 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
557 if ($result < 0) {
558 dol_print_error($db, $object->error, $object->errors);
559 }
560 }
561 }
562 }
563 } else {
564 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("QtyToReceive").'/'.$langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
565 $error++;
566 }
567 }
568 if (!$error) {
569 $db->commit();
570 header("Location: card.php?id=" . $object->id);
571 exit;
572 } else {
573 $db->rollback();
574 //$_GET["commande_id"] = GETPOSTINT('commande_id');
575 $action = 'create';
576 }
577 } elseif ($action == 'confirm_valid' && $confirm == 'yes' && $permissiontovalidate) {
578 $object->fetch_thirdparty();
579
580 $result = $object->valid($user);
581
582 if ($result < 0) {
583 $langs->load("errors");
584 setEventMessages($langs->trans($object->error), null, 'errors');
585 } else {
586 // Define output language
587 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
588 $outputlangs = $langs;
589 $newlang = '';
590 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
591 $newlang = GETPOST('lang_id', 'aZ09');
592 }
593 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
594 $newlang = $object->thirdparty->default_lang;
595 }
596 if (!empty($newlang)) {
597 $outputlangs = new Translate("", $conf);
598 $outputlangs->setDefaultLang($newlang);
599 }
600 $model = $object->model_pdf;
601 $ret = $object->fetch($id); // Reload to get new records
602
603 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
604 if ($result < 0) {
605 dol_print_error($db, $object->error, $object->errors);
606 }
607 }
608 }
609 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) {
610 $result = $object->delete($user);
611 if ($result > 0) {
612 header("Location: ".DOL_URL_ROOT.'/reception/index.php');
613 exit;
614 } else {
615 setEventMessages($object->error, $object->errors, 'errors');
616 }
617
618 // TODO add alternative status
619 /*} elseif ($action == 'reopen' && ($user->hasRights('reception', 'creer') || $user->hasRights('reception', 'reception_advance', 'validate'))) {
620 $result = $object->setStatut(Reception::STATUS_DRAFT);
621 if ($result < 0) {
622 setEventMessages($object->error, $object->errors, 'errors');
623 }*/
624 } elseif ($action == 'setdate_livraison' && $permissiontoadd) {
625 $datedelivery = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
626
627 $object->fetch($id);
628 $result = $object->setDeliveryDate($user, $datedelivery);
629 if ($result < 0) {
630 setEventMessages($object->error, $object->errors, 'errors');
631 }
632 } elseif ($action == 'setdate_reception' && $user->hasRight('reception', 'creer')) {
633 $datereception = dol_mktime(GETPOSTINT('recep_hour'), GETPOSTINT('recep_min'), 0, GETPOSTINT('recep_month'), GETPOSTINT('recep_day'), GETPOSTINT('recep_year'));
634
635 $object->fetch($id);
636 $result = $object->setReceptionDate($user, $datereception);
637 if ($result < 0) {
638 setEventMessages($object->error, $object->errors, 'errors');
639 }
640 } elseif ($action == 'confirm_deleteline' && $confirm == 'yes' && $permissiontoadd) {
641 // Remove a product line
642 $result = $object->deleteLine($user, $lineid);
643 if ($result > 0) {
644 // reorder lines
645 $object->line_order(true);
646 // Define output language
647 $outputlangs = $langs;
648 $newlang = '';
649 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
650 $newlang = GETPOST('lang_id', 'aZ09');
651 }
652 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
653 $newlang = $object->thirdparty->default_lang;
654 }
655 if (!empty($newlang)) {
656 $outputlangs = new Translate("", $conf);
657 $outputlangs->setDefaultLang($newlang);
658 }
659 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
660 $ret = $object->fetch($object->id); // Reload to get new records
661 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
662 }
663
664 header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
665 exit;
666 } else {
667 setEventMessages($object->error, $object->errors, 'errors');
668 }
669 } elseif (in_array($action, array('settracking_number', 'settracking_url', 'settrueWeight', 'settrueWidth', 'settrueHeight', 'settrueDepth', 'setshipping_method_id')) && $permissiontoadd) {
670 // Action update
671 $error = 0;
672
673 if ($action == 'settracking_number') { // Test on permission already done
674 $object->tracking_number = trim(GETPOST('tracking_number', 'alpha'));
675 }
676 if ($action == 'settracking_url') { // Test on permission already done
677 $object->tracking_url = trim(GETPOST('tracking_url', 'restricthtml'));
678 }
679 if ($action == 'settrueWeight') { // Test on permission already done
680 $object->trueWeight = GETPOST('trueWeight');
681 $object->weight_units = GETPOSTINT('weight_units');
682 }
683 if ($action == 'settrueWidth') { // Test on permission already done
684 $object->trueWidth = GETPOST('trueWidth');
685 }
686 if ($action == 'settrueHeight') { // Test on permission already done
687 $object->trueHeight = GETPOST('trueHeight');
688 $object->size_units = GETPOSTINT('size_units');
689 }
690 if ($action == 'settrueDepth') { // Test on permission already done
691 $object->trueDepth = GETPOST('trueDepth');
692 }
693 if ($action == 'setshipping_method_id') { // Test on permission already done
694 $object->shipping_method_id = GETPOSTINT('shipping_method_id');
695 }
696
697 if ($object->update($user) >= 0) {
698 header("Location: card.php?id=" . $object->id);
699 exit;
700 }
701 setEventMessages($object->error, $object->errors, 'errors');
702
703 $action = "";
704 } elseif ($action == 'builddoc' && $permissiontoread) {
705 // Build document
706 // En get ou en post
707 // Save last template used to generate document
708 if (GETPOST('model')) {
709 $object->setDocModel($user, GETPOST('model', 'alpha'));
710 }
711
712 // Define output language
713 $outputlangs = $langs;
714 $newlang = '';
715 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
716 $newlang = GETPOST('lang_id', 'aZ09');
717 }
718 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
719 $newlang = $object->thirdparty->default_lang;
720 }
721 if (!empty($newlang)) {
722 $outputlangs = new Translate("", $conf);
723 $outputlangs->setDefaultLang($newlang);
724 }
725 $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
726 if ($result <= 0) {
727 setEventMessages($object->error, $object->errors, 'errors');
728 $action = '';
729 }
730 } elseif ($action == 'remove_file' && $permissiontoadd) {
731 // Delete file in doc form
732 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
733
734 $upload_dir = $conf->reception->dir_output;
735 $file = $upload_dir.'/'.GETPOST('file');
736 $ret = dol_delete_file($file, 1, 0, 0, $object);
737 if ($ret) {
738 setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
739 } else {
740 setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
741 }
742 } elseif ($action == 'classifybilled' && $permissiontoadd) {
743 $result = $object->setBilled();
744 if ($result >= 0) {
745 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
746 exit();
747 } else {
748 setEventMessages($object->error, $object->errors, 'errors');
749 $action = '';
750 }
751 } elseif ($action == 'classifyclosed' && $permissiontoread) {
752 $result = $object->setClosed();
753 if ($result >= 0) {
754 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
755 exit();
756 } else {
757 setEventMessages($object->error, $object->errors, 'errors');
758 $action = '';
759 }
760 } elseif ($action == 'deleteline' && !empty($line_id) && $permissiontoread) {
761 // delete a line
762 $lines = $object->lines;
763 $line = new CommandeFournisseurDispatch($db);
764
765 $num_prod = count($lines);
766 for ($i = 0; $i < $num_prod; $i++) {
767 if ($lines[$i]->id == $line_id) {
768 // delete single warehouse line
769 $line->id = $line_id;
770 if (!$error && $line->delete($user) < 0) {
771 $error++;
772 }
773 }
774 unset($_POST["lineid"]);
775 }
776
777 if (!$error) {
778 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
779 exit();
780 } else {
781 setEventMessages($line->error, $line->errors, 'errors');
782 }
783 } elseif ($action == 'updateline' && GETPOST('save') && $permissiontoadd) {
784 if (!$origin && getDolGlobalString('RECEPTION_STANDALONE')) {
785 // Update a line
786 // Clean parameters
787
788 if (!$object->fetch($id) > 0) {
790 }
791 $object->fetch_thirdparty();
792
793 $qty = GETPOST('qty', 'alpha');
794 $description = '';
795 $element_type = 'reception';
796 $fk_unit = '';
797 $fk_product = 0;
798 $rang = 0;
799
800 // Extrafields
801 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
802 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
803 // Unset extrafield
804 if (is_array($extralabelsline)) {
805 // Get extra fields
806 foreach ($extralabelsline as $key => $value) {
807 unset($_POST["options_" . $key]);
808 }
809 }
810
811 $receptionline = new ReceptionLineBatch($db);
812 $receptionline->fetch(GETPOSTINT('lineid'));
813
814
815 if (!$error) {
816 $result = $object->updatelinefree(GETPOSTINT('lineid'), (float) $qty, $element_type, $fk_product, GETPOSTINT('units'), $rang, $description, 0, $array_options);
817
818 if ($result >= 0) {
819 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
820 // Define output language
821 $outputlangs = $langs;
822 $newlang = '';
823 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
824 $newlang = GETPOST('lang_id', 'aZ09');
825 }
826 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
827 $newlang = $object->thirdparty->default_lang;
828 }
829 if (!empty($newlang)) {
830 $outputlangs = new Translate("", $conf);
831 $outputlangs->setDefaultLang($newlang);
832 $outputlangs->load('products');
833 }
834
835 $ret = $object->fetch($object->id); // Reload to get new records
836 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
837 }
838 unset($_POST['qty']);
839 unset($_POST['units']);
840 } else {
841 setEventMessages($object->error, $object->errors, 'errors');
842 }
843 }
844 } elseif ($origin && $origin_id > 0) {
845 // Update a line
846 // Clean parameters
847 $qty = 0;
848 $entrepot_id = 0;
849 $batch_id = 0;
850
851 $lines = $object->lines;
852 $num_prod = count($lines);
853 for ($i = 0; $i < $num_prod; $i++) {
854 if ($lines[$i]->id == $line_id) { // we have found line to update
855 $line = new CommandeFournisseurDispatch($db);
856 $line->fetch($line_id);
857 // Extrafields Lines
858 $extrafields->fetch_name_optionals_label($object->table_element_line);
859 $line->array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
860
861 $line->fk_product = $lines[$i]->fk_product;
862
863 if ($lines[$i]->fk_product > 0) {
864 // single warehouse reception line
865 $stockLocation = "entl".$line_id;
866 $qty = "qtyl".$line_id;
867 $comment = "comment".$line_id;
868
869 $line->id = $line_id;
870 $line->fk_entrepot = GETPOSTINT($stockLocation);
871 $line->qty = GETPOSTFLOAT($qty, 'MS');
872 $line->comment = GETPOST($comment, 'alpha');
873
874 if (isModEnabled('productbatch')) {
875 $batch = "batch".$line_id;
876 $dlc = "dlc".$line_id;
877 $dluo = "dluo".$line_id;
878 // EATBY <-> DLUO
879 $eatby = GETPOST($dluo, 'alpha');
880 $eatbydate = str_replace('/', '-', $eatby);
881 // SELLBY <-> DLC
882 $sellby = GETPOST($dlc, 'alpha');
883 $sellbydate = str_replace('/', '-', $sellby);
884 $line->batch = GETPOST($batch, 'alpha');
885 $line->eatby = strtotime($eatbydate);
886 $line->sellby = strtotime($sellbydate);
887 }
888
889 if ($line->update($user) < 0) {
890 setEventMessages($line->error, $line->errors, 'errors');
891 $error++;
892 }
893 } else { // Product no predefined
894 $qty = "qtyl".$line_id;
895 $line->id = $line_id;
896 $line->qty = GETPOSTFLOAT($qty, 'MS');
897 $line->fk_entrepot = 0;
898 if ($line->update($user) < 0) {
899 setEventMessages($line->error, $line->errors, 'errors');
900 $error++;
901 }
902 unset($_POST[$qty]);
903 }
904 }
905 }
906
907 unset($_POST["lineid"]);
908
909 if (!$error) {
910 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
911 // Define output language
912 $outputlangs = $langs;
913 $newlang = '';
914 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
915 $newlang = GETPOST('lang_id', 'aZ09');
916 }
917 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
918 $newlang = $object->thirdparty->default_lang;
919 }
920 if (!empty($newlang)) {
921 $outputlangs = new Translate("", $conf);
922 $outputlangs->setDefaultLang($newlang);
923 }
924
925 $ret = $object->fetch($object->id); // Reload to get new records
926 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
927 }
928
929 // Redirect after the successful save so the page leaves edit mode and the
930 // updated values are read back from DB, matching the cancel path below
931 // and the header-data save handlers (see issue #38386).
932 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id);
933 exit();
934 } else {
935 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To reshow the record we edit
936 exit();
937 }
938 }
939 } elseif ($action == 'updateline' && $permissiontoadd && GETPOST('cancel', 'alpha') == $langs->trans("Cancel")) {
940 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To reshow the record we edit
941 exit();
942 } elseif ($action == 'addline' && !$origin && getDolGlobalString('RECEPTION_STANDALONE') && $permissiontoadd) { // Add a new line
943 $langs->load('errors');
944 $error = 0;
945 $line_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
946 $predef = '';
947 $description = '';
948 $fk_elementdet = '';
949 $element_type = 'reception';
950 $fk_unit = '';
951 $idprod = 0;
952 $fk_product = 0;
953 $fk_entrepot = '';
954 $rang = '';
955 $prod_entry_mode = GETPOST('prod_entry_mode', 'aZ09');
956 if ($prod_entry_mode == 'free') {
957 $idprod = 0;
958 } else {
959 $idprod = GETPOSTINT('idprod');
960 if (getDolGlobalString('MAIN_DISABLE_FREE_LINES') && $idprod <= 0) {
961 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
962 $error++;
963 }
964 }
965
966 $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2);
967
968 // Extrafields
969 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
970 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
971 // Unset extrafield
972 if (is_array($extralabelsline)) {
973 // Get extra fields
974 foreach ($extralabelsline as $key => $value) {
975 unset($_POST["options_".$key]);
976 }
977 }
978
979 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) {
980 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
981 $error++;
982 }
983
984 if ($qty == '') {
985 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
986 $error++;
987 }
988 if ($qty < 0) {
989 setEventMessages($langs->trans('FieldCannotBeNegative', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
990 $error++;
991 }
992 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($line_desc)) {
993 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
994 $error++;
995 }
996
997 if (!$error && isModEnabled('variants') && $prod_entry_mode != 'free') {
998 if ($combinations = GETPOST('combinations', 'array')) {
999 // Check if there is a product with the given combination
1000 $prodcomb = new ProductCombination($db);
1001
1002 if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
1003 $idprod = $res->fk_product_child;
1004 $fk_product = $idprod; // Update $fk_product with the fetched child product
1005 } else {
1006 setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
1007 $error++;
1008 }
1009 }
1010 }
1011
1012 if (!$error && ($qty >= 0) && (!empty($line_desc) || (!empty($idprod) && $idprod > 0))) {
1013 // Clean parameters
1014 if (!empty($idprod) && $idprod > 0) {
1015 $prod = new Product($db);
1016 $prod->fetch($idprod);
1017 $desc = $prod->label;
1018 $description = $desc;
1019 // Define output language
1020 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
1021 $outputlangs = $langs;
1022 $newlang = '';
1023 if (GETPOST('lang_id', 'aZ09')) {
1024 $newlang = GETPOST('lang_id', 'aZ09');
1025 }
1026 if (empty($newlang)) {
1027 $newlang = $object->thirdparty->default_lang;
1028 }
1029 if (!empty($newlang)) {
1030 $outputlangs = new Translate("", $conf);
1031 $outputlangs->setDefaultLang($newlang);
1032 }
1033
1034 $description = (!empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description;
1035 } else {
1036 $description = $prod->description;
1037 }
1038 if (getDolGlobalInt('PRODUIT_AUTOFILL_DESC') == 0) {
1039 $description = dol_concatdesc($desc, $line_desc, false, getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION') ? true : false);
1040 } else {
1041 $description = $line_desc;
1042 }
1043
1044 // Add custom code and origin country into description
1045 if (!getDolGlobalString('MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE') && (!empty($prod->customcode) || !empty($prod->country_code))) {
1046 $tmptxt = '(';
1047 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
1048 $outputlangs = $langs;
1049 $newlang = '';
1050 if (GETPOST('lang_id', 'alpha')) {
1051 $newlang = GETPOST('lang_id', 'alpha');
1052 }
1053 if (empty($newlang)) {
1054 $newlang = $object->thirdparty->default_lang;
1055 }
1056 if (!empty($newlang)) {
1057 $outputlangs = new Translate("", $conf);
1058 $outputlangs->setDefaultLang($newlang);
1059 $outputlangs->load('products');
1060 }
1061 if (!empty($prod->customcode)) {
1062 $tmptxt .= $outputlangs->transnoentitiesnoconv("CustomsCode").': '.$prod->customcode;
1063 }
1064 if (!empty($prod->customcode) && !empty($prod->country_code)) {
1065 $tmptxt .= ' - ';
1066 }
1067 if (!empty($prod->country_code)) {
1068 $tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, '', $db, $outputlangs, 0);
1069 }
1070 } else {
1071 if (!empty($prod->customcode)) {
1072 $tmptxt .= $langs->transnoentitiesnoconv("CustomsCode").': '.$prod->customcode;
1073 }
1074 if (!empty($prod->customcode) && !empty($prod->country_code)) {
1075 $tmptxt .= ' - ';
1076 }
1077 if (!empty($prod->country_code)) {
1078 $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, '', $db, $langs, 0);
1079 }
1080 }
1081 $tmptxt .= ')';
1082 $description = dol_concatdesc($desc, $tmptxt);
1083 }
1084 $type = $prod->type;
1085 $fk_unit = $prod->fk_unit;
1086 } else {
1087 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1088 $desc = $line_desc;
1089 $type = GETPOST('type');
1090 $fk_unit = GETPOST('units', 'alpha');
1091 $description = $desc;
1092 $fk_elementdet = '';
1093 }
1094 $desc = dol_htmlcleanlastbr($desc);
1095
1096 if (!$error) {
1097 // Insert line
1098 $result = $object->addlinefree((float) $qty, $element_type, $idprod, $fk_unit, min($rank, count($object->lines) + 1), $description, $array_options);
1099
1100 if ($result > 0) {
1101 $ret = $object->fetch($object->id); // Reload to get new records
1102 $object->fetch_thirdparty();
1103 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1104 // Define output language
1105 $outputlangs = $langs;
1106 $newlang = GETPOST('lang_id', 'alpha');
1107 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1108 $newlang = $object->thirdparty->default_lang;
1109 }
1110 if (!empty($newlang)) {
1111 $outputlangs = new Translate("", $conf);
1112 $outputlangs->setDefaultLang($newlang);
1113 }
1114 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1115 }
1116 } else {
1117 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To redisplay the form being edited
1118 exit();
1119 }
1120 }
1121 }
1122 }
1123
1124 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
1125
1126 // Actions to send emails
1127 if (empty($id)) {
1128 $id = $facid;
1129 }
1130 $triggersendname = 'RECEPTION_SENTBYMAIL';
1131 $paramname = 'id';
1132 $mode = 'emailfromreception';
1133 $autocopy = 'MAIN_MAIL_AUTOCOPY_RECEPTION_TO';
1134 $trackid = 'rec'.$object->id;
1135 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1136}
1137
1138
1139/*
1140 * View
1141 */
1142
1143$title = $object->ref.' - '.$langs->trans('Reception');
1144if ($action == 'create') {
1145 $title = $langs->trans("NewReception");
1146}
1147llxHeader('', $title, 'Reception', '', 0, 0, '', '', '', 'mod-reception page-card');
1148
1149$form = new Form($db);
1150$formfile = new FormFile($db);
1151$formproduct = new FormProduct($db);
1152$formproject = null;
1153if (isModEnabled('project')) {
1154 $formproject = new FormProjets($db);
1155} else {
1156 $formproject = null;
1157}
1158
1159$product_static = new Product($db);
1160$reception_static = new Reception($db);
1161$warehousestatic = new Entrepot($db);
1162
1163if ($action == 'create' && $origin != 'supplierorder' && !getDolGlobalString('RECEPTION_STANDALONE')) {
1164 print load_fiche_titre($langs->trans("CreateReception"), '', 'dollyrevert');
1165
1166 print '<br>'.$langs->trans("ReceptionCreationIsDoneFromOrder");
1167 $action = '';
1168 $id = '';
1169 $ref = '';
1170}
1171
1172// Mode creation.
1173if ($action == 'create' && $permissiontoadd) {
1174 $recept = new Reception($db);
1175
1176 print load_fiche_titre($langs->trans("NewReception"), '', 'dollyrevert');
1177 if (empty($origin) && getDolGlobalString('RECEPTION_STANDALONE')) {
1178 $soc = new Societe($db);
1179 if ($socid > 0) {
1180 $res = $soc->fetch($socid);
1181 }
1182
1183 $note_private = $object->getDefaultCreateValueFor('note_private');
1184 $note_public = $object->getDefaultCreateValueFor('note_public');
1185
1186 print '<form name="crea_reception" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
1187 print '<input type="hidden" name="token" value="' . newToken() . '">';
1188 print '<input type="hidden" name="action" value="add">';
1189 print '<input type="hidden" name="changecompany" value="0">'; // will be set to 1 by javascript so we know post is done after a company change
1190 print '<input type="hidden" name="originid" value="' . $id . '">';
1191 print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
1192
1193 print dol_get_fiche_head([]);
1194
1195 print '<table class="border centpercent">';
1196
1197
1198 // Thirdparty
1199 print '<tr>';
1200 print '<td class="fieldrequired">' . $langs->trans('ThirdParty') . '</td>';
1201 if ($socid > 0) {
1202 print '<td>';
1203 print $soc->getNomUrl(1);
1204 print '<input type="hidden" name="socid" value="' . $soc->id . '">';
1205 print '</td>';
1206 } else {
1207 print '<td class="valuefieldcreate">';
1208 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, array(), 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
1209 // reload page to retrieve customer information
1210 if (!getDolGlobalString('RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED')) {
1211 print '<script>
1212 $(document).ready(function() {
1213 $("#socid").change(function() {
1214 console.log("We have changed the company - Reload page");
1215 var socid = $(this).val();
1216 // reload page
1217 $("input[name=action]").val("create");
1218 $("input[name=changecompany]").val("1");
1219 $("form[name=crea_reception]").submit();
1220 });
1221 });
1222 </script>';
1223 }
1224 print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&client=3&fournisseur=0&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddThirdParty").'"></span></a>';
1225 print '</td>';
1226 }
1227 print '</tr>'."\n";
1228
1229 // Project
1230 if (isModEnabled('project') && is_object($formproject)) {
1231 $projectid = GETPOSTINT('projectid');
1232 if (empty($projectid) && !empty($object->fk_project)) {
1233 $projectid = (int) $object->fk_project;
1234 }
1235 $langs->load("projects");
1236 print '<tr>';
1237 print '<td>' . $langs->trans("Project") . '</td><td colspan="2">';
1238 print img_picto('', 'project', 'class="pictofixedwidth"');
1239 print $formproject->select_projects($soc->id, $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 1, 0, 'widthcentpercentminusxx');
1240 print ' <a class="paddingleft" 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"></span></a>';
1241 print '</td>';
1242 print '</tr>';
1243 }
1244
1245 // Reception Date
1246 print '<tr><td>'.$langs->trans("DateReception").'</td>';
1247 print '<td colspan="3">';
1248 print img_picto('', 'action', 'class="pictofixedwidth"');
1249 $date_reception = ($date_reception ? $date_reception : $object->date_reception); // $date_reception comes from GETPOST
1250 print $form->selectDate($date_reception ? $date_reception : -1, 'date_reception', 1, 1, 1);
1251 print "</td>\n";
1252 print '</tr>';
1253
1254 // Date delivery planned
1255 print '<tr><td>'.$langs->trans("DateDeliveryPlanned").'</td>';
1256 print '<td colspan="3">';
1257 print img_picto('', 'action', 'class="pictofixedwidth"');
1258 $date_delivery = ($date_delivery ? $date_delivery : $object->delivery_date); // $date_delivery comes from GETPOST
1259 print $form->selectDate($date_delivery ? $date_delivery : -1, 'date_delivery', 1, 1, 1);
1260 print "</td>\n";
1261 print '</tr>';
1262
1263 // Weight
1264 print '<tr><td>';
1265 print $langs->trans("Weight");
1266 print '</td><td colspan="3">';
1267 print img_picto('', 'fa-balance-scale', 'class="pictofixedwidth"');
1268 print '<input name="weight" size="4" value="'.GETPOST('weight').'"> ';
1269 $text = $formproduct->selectMeasuringUnits("weight_units", "weight", (string) GETPOSTINT('weight_units'), 0, 2);
1270 $htmltext = $langs->trans("KeepEmptyForAutoCalculation");
1271 print $form->textwithpicto($text, $htmltext);
1272 print '</td></tr>';
1273
1274 // Dim
1275 print '<tr><td>';
1276 print $langs->trans("Width").' x '.$langs->trans("Height").' x '.$langs->trans("Depth");
1277 print ' </td><td colspan="3">';
1278 print img_picto('', 'fa-ruler', 'class="pictofixedwidth"');
1279 print '<input name="sizeW" size="4" value="'.GETPOST('sizeW').'">';
1280 print ' x <input name="sizeH" size="4" value="'.GETPOST('sizeH').'">';
1281 print ' x <input name="sizeS" size="4" value="'.GETPOST('sizeS').'">';
1282 print ' ';
1283 $text = $formproduct->selectMeasuringUnits("size_units", "size", (string) GETPOSTINT('size_units'), 0, 2);
1284 $htmltext = $langs->trans("KeepEmptyForAutoCalculation");
1285 print $form->textwithpicto($text, $htmltext);
1286 print '</td></tr>';
1287
1288 // Delivery method
1289 print "<tr><td>".$langs->trans("ReceptionMethod")."</td>";
1290 print '<td colspan="3">';
1291 $recept->fetch_delivery_methods();
1292 print $form->selectarray("shipping_method_id", $recept->meths, GETPOSTINT('shipping_method_id'), 1, 0, 0, "", 1);
1293 if ($user->admin) {
1294 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1295 }
1296 print "</td></tr>\n";
1297
1298 // Tracking number
1299 print "<tr><td>".$langs->trans("TrackingNumber")."</td>";
1300 print '<td colspan="3">';
1301 print img_picto('', 'barcode', 'class="pictofixedwidth"');
1302 print '<input name="tracking_number" size="20" value="'.GETPOST('tracking_number', 'alpha').'">';
1303 print "</td></tr>\n";
1304
1305 // Here $object can be of an object Reception
1306 $extrafields->fetch_name_optionals_label($object->table_element);
1307 if (empty($reshook) && !empty($extrafields->attributes[$object->table_element]['label'])) {
1308 if ($object->fetch_optionals() > 0) {
1309 $recept->array_options = array_merge($recept->array_options, $object->array_options);
1310 }
1311 print $recept->showOptionals($extrafields, 'create', $parameters);
1312 }
1313
1314 // Incoterms
1315 if (isModEnabled('incoterm')) {
1316 print '<tr>';
1317 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $object->label_incoterms, 1).'</label></td>';
1318 print '<td colspan="3" class="maxwidthonsmartphone">';
1319 print img_picto('', 'incoterm', 'class="pictofixedwidth"');
1320 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''));
1321 print '</td></tr>';
1322 }
1323
1324 // Template to use by default
1326 if (is_countable($list) && count($list) > 0) {
1327 print '<tr><td>'.$langs->trans('Model').'</td>';
1328 print '<td colspan="2">';
1329 print img_picto('', 'pdf', 'class="pictofixedwidth"');
1330 include_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
1331 print $form->selectarray('model', $list, getDolGlobalString('RECEPTION_ADDON_PDF'), 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1);
1332 print "</td></tr>";
1333 }
1334
1335 // Note Public
1336 $htmltext = '';
1337 print '<tr>';
1338 print '<td class="tdtop">';
1339 print $form->textwithpicto($langs->trans('NotePublic'), $htmltext);
1340 print '</td>';
1341 print '<td valign="top" colspan="2">';
1342 $doleditor = new DolEditor('note_public', (string) $note_public, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
1343 print $doleditor->Create(1);
1344
1345 // Note Private
1346 if (!$user->socid) {
1347 print '<tr>';
1348 print '<td class="tdtop">';
1349 print $form->textwithpicto($langs->trans('NotePrivate'), $htmltext);
1350 print '</td>';
1351 print '<td valign="top" colspan="2">';
1352 $doleditor = new DolEditor('note_private', (string) $note_private, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
1353 print $doleditor->Create(1);
1354 print "</td></tr>";
1355 }
1356
1357 print "</table>\n";
1358
1359 print dol_get_fiche_end();
1360
1361 print $form->buttonsSaveCancel("CreateDraft");
1362
1363 print "</form>\n";
1364 } elseif ($origin) {
1365 if ($origin == 'supplierorder') {
1366 $classname = 'CommandeFournisseur';
1367 } else {
1368 $classname = ucfirst($origin);
1369 }
1370
1371 $objectsrc = new $classname($db);
1372 if ($objectsrc->fetch($origin_id)) { // This include the fetch_lines
1373 $soc = new Societe($db);
1374 $soc->fetch($objectsrc->socid);
1375
1376 $author = new User($db);
1377 $author->fetch($objectsrc->user_author_id);
1378
1379 if (isModEnabled('stock')) {
1380 $entrepot = new Entrepot($db);
1381 }
1382
1383 print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
1384 print '<input type="hidden" name="token" value="'.newToken().'">';
1385 print '<input type="hidden" name="action" value="add">';
1386 print '<input type="hidden" name="origin" value="'.$origin.'">';
1387 print '<input type="hidden" name="origin_id" value="'.$objectsrc->id.'">';
1388 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
1389 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1390 if (GETPOSTINT('entrepot_id')) {
1391 print '<input type="hidden" name="entrepot_id" value="'.GETPOSTINT('entrepot_id').'">';
1392 }
1393
1394 print dol_get_fiche_head();
1395
1396 print '<table class="border centpercent">';
1397
1398 // Ref
1399 print '<tr><td class="titlefieldcreate fieldrequired">';
1400 if ($origin == 'supplierorder' && isModEnabled("supplier_order")) {
1401 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;
1402 }
1403 if ($origin == 'propal' && isModEnabled("propal")) {
1404 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;
1405 }
1406 print '</a></td>';
1407 print "</tr>\n";
1408
1409 // Ref client
1410 print '<tr><td>';
1411 if ($origin == 'supplier_order') {
1412 print $langs->trans('SupplierOrder');
1413 } else {
1414 print $langs->trans('RefSupplier');
1415 }
1416 print '</td><td colspan="3">';
1417 print '<input type="text" name="ref_supplier" value="'.$objectsrc->ref_supplier.'" />';
1418 print '</td>';
1419 print '</tr>';
1420
1421 // Thirdparty provider
1422 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Company').'</td>';
1423 print '<td colspan="3">'.$soc->getNomUrl(1).'</td>';
1424 print '</tr>';
1425
1426 // Project
1427 if (isModEnabled('project') && $formproject !== null) {
1428 $projectid = GETPOSTINT('projectid') ? GETPOSTINT('projectid') : 0;
1429 if (empty($projectid) && !empty($objectsrc->fk_project)) {
1430 $projectid = $objectsrc->fk_project;
1431 }
1432 if ($origin == 'project') {
1433 $projectid = ($origin_id ? $origin_id : 0);
1434 }
1435
1436 $langs->load("projects");
1437 print '<tr>';
1438 print '<td>'.$langs->trans("Project").'</td><td colspan="2">';
1439 print img_picto('', 'project', 'class="paddingright"');
1440 print $formproject->select_projects((!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $soc->id : -1), (string) $projectid, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1, 0, 'maxwidth500');
1441 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>';
1442 print '</td>';
1443 print '</tr>';
1444 }
1445
1446 // Reception Date
1447 print '<tr><td>'.$langs->trans("DateReception").'</td>';
1448 print '<td colspan="3">';
1449 print img_picto('', 'action', 'class="pictofixedwidth"');
1450 $date_reception = ($date_reception ? $date_reception : $object->date_reception); // $date_reception comes from GETPOST
1451 print $form->selectDate($date_reception ? $date_reception : -1, 'date_reception', 1, 1, 1);
1452 print "</td>\n";
1453 print '</tr>';
1454
1455 // Date delivery planned
1456 print '<tr><td>'.$langs->trans("DateDeliveryPlanned").'</td>';
1457 print '<td colspan="3">';
1458 print img_picto('', 'action', 'class="pictofixedwidth"');
1459 $date_delivery = ($date_delivery ? $date_delivery : $objectsrc->delivery_date); // $date_delivery comes from GETPOST
1460 print $form->selectDate($date_delivery ? $date_delivery : -1, 'date_delivery', 1, 1, 1);
1461 print "</td>\n";
1462 print '</tr>';
1463
1464 // Note Public
1465 print '<tr><td>'.$langs->trans("NotePublic").'</td>';
1466 print '<td colspan="3">';
1467 $doleditor = new DolEditor('note_public', $objectsrc->note_public, '', 60, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
1468 print $doleditor->Create(1);
1469 print "</td></tr>";
1470
1471 // Note Private
1472 if ($objectsrc->note_private && !$user->socid) {
1473 print '<tr><td>'.$langs->trans("NotePrivate").'</td>';
1474 print '<td colspan="3">';
1475 $doleditor = new DolEditor('note_private', $objectsrc->note_private, '', 60, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
1476 print $doleditor->Create(1);
1477 print "</td></tr>";
1478 }
1479
1480 // Weight
1481 print '<tr><td>';
1482 print $langs->trans("Weight");
1483 print '</td><td colspan="3"><input name="weight" size="4" value="'.GETPOST('weight').'"> ';
1484 $text = $formproduct->selectMeasuringUnits("weight_units", "weight", (string) GETPOSTINT('weight_units'), 0, 2);
1485 $htmltext = $langs->trans("KeepEmptyForAutoCalculation");
1486 print $form->textwithpicto($text, $htmltext);
1487 print '</td></tr>';
1488 // Dim
1489 print '<tr><td>';
1490 print $langs->trans("Width").' x '.$langs->trans("Height").' x '.$langs->trans("Depth");
1491 print ' </td><td colspan="3"><input name="trueWidth" size="4" value="'.GETPOST('trueWidth').'">';
1492 print ' x <input name="trueHeight" size="4" value="'.GETPOST('trueHeight').'">';
1493 print ' x <input name="trueDepth" size="4" value="'.GETPOST('trueDepth').'">';
1494 print ' ';
1495 $text = $formproduct->selectMeasuringUnits("size_units", "size", (string) GETPOSTINT('size_units'), 0, 2);
1496 $htmltext = $langs->trans("KeepEmptyForAutoCalculation");
1497 print $form->textwithpicto($text, $htmltext);
1498 print '</td></tr>';
1499
1500 // Delivery method
1501 print "<tr><td>".$langs->trans("ReceptionMethod")."</td>";
1502 print '<td colspan="3">';
1503 $recept->fetch_delivery_methods();
1504 print $form->selectarray("shipping_method_id", $recept->meths, GETPOSTINT('shipping_method_id'), 1, 0, 0, "", 1);
1505 if ($user->admin) {
1506 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1507 }
1508 print "</td></tr>\n";
1509
1510 // Tracking number
1511 print "<tr><td>".$langs->trans("TrackingNumber")."</td>";
1512 print '<td colspan="3">';
1513 print '<input name="tracking_number" size="20" value="'.GETPOST('tracking_number', 'alpha').'">';
1514 print "</td></tr>\n";
1515
1516 // Other attributes
1517 $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"', 'cols' => '3', 'socid' => $socid);
1518 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $recept, $action); // Note that $action and $objectsrc may have been modified by hook
1519 print $hookmanager->resPrint;
1520
1521 // Here $object can be of an object Reception
1522 $extrafields->fetch_name_optionals_label($object->table_element);
1523 if (empty($reshook) && !empty($extrafields->attributes[$object->table_element]['label'])) {
1524 // copy from order
1525 if ($objectsrc->fetch_optionals() > 0) {
1526 $recept->array_options = array_merge($recept->array_options, $objectsrc->array_options);
1527 }
1528 print $recept->showOptionals($extrafields, 'create', $parameters);
1529 }
1530
1531 // Incoterms
1532 if (isModEnabled('incoterm')) {
1533 print '<tr>';
1534 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $objectsrc->label_incoterms, 1).'</label></td>';
1535 print '<td colspan="3" class="maxwidthonsmartphone">';
1536 print $form->select_incoterms((!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : ''), (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : ''));
1537 print '</td></tr>';
1538 }
1539
1540 // Document model
1541 include_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
1543
1544 if (is_array($list) && count($list) > 1) {
1545 print "<tr><td>".$langs->trans("DefaultModel")."</td>";
1546 print '<td colspan="3">';
1547 print $form->selectarray('model', $list, getDolGlobalString('RECEPTION_ADDON_PDF'));
1548 print "</td></tr>\n";
1549 }
1550
1551 print "</table>";
1552
1553 print dol_get_fiche_end();
1554
1555 // Number of lines show on the reception card
1556 $numAsked = 0;
1557
1562 $suffix2numAsked = array();
1563 $dispatchLines = array();
1564
1565 foreach ($_POST as $key => $value) {
1566 // If create form is coming from the button "Create Reception" of previous page
1567
1568 // without batch module enabled or product with no lot/serial
1569 $reg = array();
1570 if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
1571 $numAsked++;
1572 $paramSuffix = $reg[1] . '_' . $reg[2];
1573 $suffix2numAsked[$paramSuffix] = $numAsked;
1574
1575 // $numline=$reg[2] + 1; // line of product
1576 $numline = $numAsked;
1577
1578 $prod = "product_" . $paramSuffix;
1579 $qty = "qty_" . $paramSuffix;
1580 $ent = "entrepot_" . $paramSuffix;
1581 $pu = "pu_" . $paramSuffix; // This is unit price including discount
1582 $fk_commandefourndet = "fk_commandefourndet_" . $paramSuffix;
1583 $dispatchLines[$numAsked] = array('paramSuffix' => $paramSuffix, 'prod' => GETPOSTINT($prod), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOSTINT($ent), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST('comment'), 'fk_commandefourndet' => GETPOSTINT($fk_commandefourndet));
1584 }
1585
1586 // with batch module enabled and product with lot/serial
1587 if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
1588 $numAsked++;
1589 $paramSuffix = $reg[1] . '_' . $reg[2];
1590 $suffix2numAsked[$paramSuffix] = $numAsked;
1591
1592 // eat-by date dispatch
1593 // $numline=$reg[2] + 1; // line of product
1594 $numline = $numAsked;
1595
1596 $prod = 'product_batch_' . $paramSuffix;
1597 $qty = 'qty_' . $paramSuffix;
1598 $ent = 'entrepot_' . $paramSuffix;
1599 $pu = 'pu_' . $paramSuffix;
1600 $lot = 'lot_number_' . $paramSuffix;
1601 $dDLUO = dol_mktime(12, 0, 0, GETPOSTINT('dluo_'.$paramSuffix.'month'), GETPOSTINT('dluo_'.$paramSuffix.'day'), GETPOSTINT('dluo_'.$paramSuffix.'year'));
1602 $dDLC = dol_mktime(12, 0, 0, GETPOSTINT('dlc_'.$paramSuffix.'month'), GETPOSTINT('dlc_'.$paramSuffix.'day'), GETPOSTINT('dlc_'.$paramSuffix.'year'));
1603 $fk_commandefourndet = 'fk_commandefourndet_'.$paramSuffix;
1604 $dispatchLines[$numAsked] = array('paramSuffix' => $paramSuffix, 'prod' => GETPOSTINT($prod), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOSTINT($ent), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST('comment'), 'fk_commandefourndet' => GETPOSTINT($fk_commandefourndet), 'DLC' => $dDLC, 'DLUO' => $dDLUO, 'lot' => GETPOST($lot));
1605 }
1606
1607 // If create form is coming from same page, it means that post was sent but an error occurred
1608 if (preg_match('/^productl([0-9]+)$/i', $key, $reg)) {
1609 $numAsked++;
1610 $paramSuffix = $reg[1];
1611 $suffix2numAsked[$paramSuffix] = $numAsked;
1612
1613 // eat-by date dispatch
1614 // $numline=$reg[2] + 1; // line of product
1615 $numline = $numAsked;
1616
1617 $prod = 'productid'.$paramSuffix;
1618 $comment = 'comment'.$paramSuffix;
1619 $qty = 'qtyl'.$paramSuffix;
1620 $ent = 'entl'.$paramSuffix;
1621 $pu = 'pul'.$paramSuffix;
1622 $lot = 'batch'.$paramSuffix;
1623 $dDLUO = dol_mktime(12, 0, 0, GETPOSTINT('dluo'.$paramSuffix.'month'), GETPOSTINT('dluo'.$paramSuffix.'day'), GETPOSTINT('dluo'.$paramSuffix.'year'));
1624 $dDLC = dol_mktime(12, 0, 0, GETPOSTINT('dlc'.$paramSuffix.'month'), GETPOSTINT('dlc'.$paramSuffix.'day'), GETPOSTINT('dlc'.$paramSuffix.'year'));
1625 $fk_commandefourndet = 'fk_commandefournisseurdet'.$paramSuffix;
1626 $dispatchLines[$numAsked] = array('prod' => GETPOSTINT($prod), 'qty' => price2num(GETPOST($qty), 'MS'), 'ent' => GETPOSTINT($ent), 'pu' => price2num(GETPOST($pu), 'MU'), 'comment' => GETPOST($comment), 'fk_commandefourndet' => GETPOSTINT($fk_commandefourndet), 'DLC' => $dDLC, 'DLUO' => $dDLUO, 'lot' => GETPOSTINT($lot));
1627 }
1628 }
1629
1630 // If extrafield values are passed in the HTTP query, assign them to the correct dispatch line
1631 // Note that if an extrafield with the same name exists in the origin supplier order line, the value
1632 // from the HTTP query will be ignored
1633 foreach ($suffix2numAsked as $suffix => $n) {
1634 $dispatchLines[$n]['array_options'] = $extrafields->getOptionalsFromPost('receptiondet_batch', '_' . $suffix, '');
1635 }
1636
1637 $reshook = $hookmanager->executeHooks('dataProcessing', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1638 if ($reshook < 0) {
1639 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1640 } elseif (empty($reshook)) {
1641 // Only merge if resArray is a valid, non-empty array
1642 if (is_array($hookmanager->resArray) && !empty($hookmanager->resArray)) {
1643 // Check if the merge would overwrite valid data with NULL
1644 $tempMerged = array_merge($dispatchLines, $hookmanager->resArray);
1645
1646 // Sanity check: ensure our existing keys are still valid arrays
1647 $corrupted = false;
1648 foreach ($dispatchLines as $idx => $val) {
1649 if (!is_array($tempMerged[$idx]) || !isset($tempMerged[$idx]['fk_commandefourndet'])) {
1650 $corrupted = true;
1651 break;
1652 }
1653 }
1654
1655 if (!$corrupted) {
1656 $dispatchLines = $tempMerged;
1657 } else {
1658 // If merge corrupted data, ignore the hook result and keep original
1659 error_log("WARNING: Hook dataProcessing returned invalid data, ignoring merge.");
1660 }
1661 }
1662 } elseif ($reshook > 0) {
1663 // $resArray starts from [0], we need $dispatchLines to start from [1], so we shift it
1664 $dispatchLines = $hookmanager->resArray;
1665 array_unshift($dispatchLines, null);
1666 unset($dispatchLines[0]);
1667 $numAsked = count($dispatchLines);
1668 }
1669
1670 print '<script type="text/javascript">
1671 jQuery(document).ready(function() {
1672 jQuery("#autofill").click(function(event) {
1673 event.preventDefault();';
1674 $i = 1;
1675 while ($i <= $numAsked) {
1676 print 'jQuery("#qtyl'.$i.'").val(jQuery("#qtyasked'.$i.'").val() - jQuery("#qtydelivered'.$i.'").val());'."\n";
1677 $i++;
1678 }
1679 print '});
1680 jQuery("#autoreset").click(function(event) {
1681 event.preventDefault();';
1682 $i = 1;
1683 while ($i <= $numAsked) {
1684 print 'jQuery("#qtyl'.$i.'").val(0);'."\n";
1685 $i++;
1686 }
1687 print '});
1688 });
1689 </script>';
1690
1691 print '<br>';
1692
1693 print '<table class="noborder centpercent">';
1694
1695 // Load receptions already done for same order
1696 $objectsrc->loadReceptions();
1697
1698 if ($numAsked) {
1699 print '<tr class="liste_titre">';
1700 print '<td>'.$langs->trans("Description").'</td>';
1701 print '<td>'.$langs->trans("Comment").'</td>';
1702 print '<td class="center">'.$langs->trans("QtyOrdered").'</td>';
1703 print '<td class="center">'.$langs->trans("QtyReceived").'</td>';
1704 print '<td class="center">'.$langs->trans("QtyToReceive");
1705 if (getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
1706 print '<td>'.$langs->trans("BuyingPrice").'</td>';
1707 }
1708 if (!isModEnabled('productbatch')) {
1709 print ' <br><center><a href="#" id="autofill"><span class="fas fa-fill pictofixedwidth" style=""></span> '.$langs->trans("Fill").'</a>';
1710 print ' &nbsp; &nbsp; <a href="#" id="autoreset"><span class="fas fa-eraser pictofixedwidth" style=""></span>'.$langs->trans("Reset").'</a></center><br>';
1711 }
1712 print '</td>';
1713 if (isModEnabled('stock')) {
1714 print '<td class="left">'.$langs->trans("Warehouse").' ('.$langs->trans("Stock").')</td>';
1715 }
1716 if (isModEnabled('productbatch')) {
1717 print '<td class="left">'.$langs->trans("batch_number").'</td>';
1718 if (!getDolGlobalInt('PRODUCT_DISABLE_SELLBY')) {
1719 print '<td class="left">'.$langs->trans("SellByDate").'</td>';
1720 }
1721 if (!getDolGlobalInt('PRODUCT_DISABLE_EATBY')) {
1722 print '<td class="left">'.$langs->trans("EatByDate").'</td>';
1723 }
1724 }
1725
1726 $parameters = array();
1727 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1728 if ($reshook < 0) {
1729 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1730 } else {
1731 print $hookmanager->resPrint;
1732 }
1733 print "</tr>\n";
1734 }
1735
1736 // $objectsrc->lines contains the line of the purchase order
1737 // $dispatchLines is an array with dispatching detail (with product, qty, warehouse and fk_commandefourndet). One purchase order line may have n of this dispatch lines.
1738
1739 $arrayofpurchaselinealreadyoutput = array();
1740
1741 // $_POST contains fk_commandefourndet_X_Y where Y is num of product line and X is number of split lines
1742 $indiceAsked = 1;
1743 while ($indiceAsked <= $numAsked) { // Loop on $dispatchLines. Warning: $dispatchLines must be sorted by fk_commandefourndet (it is a regroupment key on output)
1744 $product = new Product($db);
1745 $line = new CommandeFournisseurLigne($db); // By default
1746
1747 // We search the purchase order line that is linked to the dispatchLines
1748 foreach ($objectsrc->lines as $supplierLine) {
1749 if ($dispatchLines[$indiceAsked]['fk_commandefourndet'] == $supplierLine->id) {
1750 $line = $supplierLine;
1751 break;
1752 }
1753 }
1754
1755 // Now $line can be CommandeFournisseurLigne but could be other type of line.
1756
1757 // Show product and description
1758 $type = $line->product_type ? $line->product_type : $line->fk_product_type;
1759 // Try to enhance type detection using date_start and date_end for free lines where type was not saved.
1760 if (!empty($line->date_start)) {
1761 $type = 1;
1762 }
1763 if (!empty($line->date_end)) {
1764 $type = 1;
1765 }
1766
1767 print '<!-- line fk_commandefourndet='.$line->id.' for product='.$line->fk_product.' -->'."\n";
1768 print '<tr class="oddeven">'."\n";
1769
1770 // Product label
1771 if ($line->fk_product > 0) { // If predefined product
1772 $product->fetch($line->fk_product);
1773 $product->load_stock('warehouseopen'); // Load all $product->stock_warehouse[idwarehouse]->detail_batch
1774 //var_dump($product->stock_warehouse[1]);
1775 //var_dump($dispatchLines[$indiceAsked]);
1776
1777 print '<td>';
1778 print '<a name="'.$line->id.'"></a>'; // Anchor to return to the line
1779
1780 print '<input type="hidden" name="productl'.$indiceAsked.'" value="'.$line->fk_product.'">';
1781
1782 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1783 print '<input type="hidden" name="productid'.$indiceAsked.'" value="'.$line->fk_product.'">';
1784
1785 // Show product and description
1786 $product_static = $product;
1787
1788 $text = $product_static->getNomUrl(1);
1789 $text .= ' - '.(!empty($line->label) ? $line->label : $line->product_label);
1790 $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($line->desc));
1791 print $form->textwithtooltip($text, $description, 3, 0, '', (string) $i);
1792
1793 // Show range
1794 print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end));
1795
1796 // Add description in form
1797 if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
1798 print ($line->desc && $line->desc != $line->product_label) ? '<br>'.dol_htmlentitiesbr($line->desc) : '';
1799 }
1800 }
1801 print '</td>';
1802 } else {
1803 print "<td>";
1804 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1805 if ($type == 1) {
1806 $text = img_object($langs->trans('Service'), 'service');
1807 } else {
1808 $text = img_object($langs->trans('Product'), 'product');
1809 }
1810
1811 if (!empty($line->label)) {
1812 $text .= ' <strong>'.$line->label.'</strong>';
1813 print $form->textwithtooltip($text, $line->desc, 3, 0, '', (string) $i);
1814 } else {
1815 print $text.' '.nl2br($line->desc);
1816 }
1817
1818 // Show range
1819 print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end));
1820 }
1821 print "</td>\n";
1822 }
1823
1824 // Comment
1825 //$defaultcomment = 'Line create from order line id '.$line->id;
1826 $defaultcomment = $dispatchLines[$indiceAsked]['comment'];
1827 print '<td>';
1828 print '<input type="text" class="maxwidth100" name="comment'.$indiceAsked.'" value="'.$defaultcomment.'">';
1829 print '</td>';
1830
1831 // Qty in source purchase order line
1832 print '<td class="center">';
1833 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1834 print $line->qty;
1835 }
1836 print '<input type="hidden" name="fk_commandefournisseurdet'.$indiceAsked.'" value="'.$line->id.'">';
1837 print '<input type="hidden" name="pul'.$indiceAsked.'" value="'.$line->subprice.'">';
1838 print '<input name="qtyasked'.$indiceAsked.'" id="qtyasked'.$indiceAsked.'" type="hidden" value="'.$line->qty.'">';
1839 print '</td>';
1840 $qtyProdCom = $line->qty;
1841
1842 // Qty already received
1843 print '<td class="center">';
1844 $quantityDelivered = isset($objectsrc->receptions[$line->id]) ? $objectsrc->receptions[$line->id] : 0;
1845 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1846 print $quantityDelivered;
1847 }
1848 print '<input name="qtydelivered'.$indiceAsked.'" id="qtydelivered'.$indiceAsked.'" type="hidden" value="'.$quantityDelivered.'">';
1849 print '</td>';
1850
1851
1852 if ($line->product_type == 1 && !getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1853 $quantityToBeDelivered = 0;
1854 } else {
1855 $quantityToBeDelivered = $dispatchLines[$indiceAsked]['qty'];
1856 }
1857 $warehouse_id = $dispatchLines[$indiceAsked]['ent'];
1858
1859
1860 $warehouseObject = null;
1861 if (isModEnabled('stock')) {
1862 // If warehouse was already selected or if product is not a predefined, we go into this part with no multiwarehouse selection
1863 print '<!-- Case warehouse already known or product not a predefined product -->';
1864 if (array_key_exists($dispatchLines[$indiceAsked]['ent'], $product->stock_warehouse)) {
1865 $stock = +$product->stock_warehouse[$dispatchLines[$indiceAsked]['ent']]->real; // Convert to number
1866 }
1867 $deliverableQty = $dispatchLines[$indiceAsked]['qty'];
1868 $cost_price = $dispatchLines[$indiceAsked]['pu'];
1869
1870 // Quantity to send
1871 print '<td class="center">';
1872 if ($line->product_type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1873 if (GETPOSTINT('qtyl'.$indiceAsked)) {
1874 $defaultqty = GETPOSTINT('qtyl'.$indiceAsked);
1875 }
1876 print '<input name="idl'.$indiceAsked.'" type="hidden" value="'.$line->id.'">';
1877 print '<input class="right" name="qtyl'.$indiceAsked.'" id="qtyl'.$indiceAsked.'" type="text" size="4" value="'.$deliverableQty.'">';
1878 } else {
1879 print $langs->trans("NA");
1880 }
1881 print '</td>';
1882
1883 if (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
1884 print '<td>';
1885 print '<input class="width75 right" name="cost_price'.$indiceAsked.'" id="cost_price'.$indiceAsked.'" value="'.price($cost_price).'">';
1886 print '</td>';
1887 }
1888
1889 // Stock
1890 if (isModEnabled('stock')) {
1891 print '<td class="left">';
1892 if ($line->product_type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) { // Type of product need stock change ?
1893 // Show warehouse combo list
1894 $ent = "entl".$indiceAsked;
1895 $idl = "idl".$indiceAsked;
1896 $tmpentrepot_id = is_numeric(GETPOST($ent)) ? GETPOSTINT($ent) : $warehouse_id;
1897 if ($line->fk_product > 0) {
1898 print '<!-- Show warehouse selection -->';
1899 print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 0, 0, $line->fk_product, '', 1);
1900 }
1901 } else {
1902 print $langs->trans("Service");
1903 }
1904 print '</td>';
1905 }
1906
1907 if (isModEnabled('productbatch')) {
1908 if (!empty($product->status_batch)) {
1909 print '<td><input name="batch'.$indiceAsked.'" value="'.$dispatchLines[$indiceAsked]['lot'].'"></td>';
1910 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1911 print '<td class="nowraponall">';
1912 print $form->selectDate($dispatchLines[$indiceAsked]['DLC'], 'dlc'.$indiceAsked, 0, 0, 1, "");
1913 print '</td>';
1914 }
1915 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1916 print '<td class="nowraponall">';
1917 print $form->selectDate($dispatchLines[$indiceAsked]['DLUO'], 'dluo'.$indiceAsked, 0, 0, 1, "");
1918 print '</td>';
1919 }
1920 } else {
1921 print '<td colspan="3"></td>';
1922 }
1923 }
1924
1925 $parameters = array();
1926 $parameters['dispatchLine'] = $dispatchLines[$indiceAsked];
1927 $parameters['indiceAsked'] = $indiceAsked;
1928 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1929 if ($reshook < 0) {
1930 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1931 } else {
1932 print $hookmanager->resPrint;
1933 }
1934 }
1935
1936 $arrayofpurchaselinealreadyoutput[$line->id] = $line->id;
1937
1938 print "</tr>\n";
1939
1940 // Display lines for extrafields of the Reception line
1941 // $line is a 'CommandeFournisseurLigne', $dispatchLines contains values of Reception lines so properties of CommandeFournisseurDispatch
1942 if (!empty($extrafields)) {
1943 $colspan = 5;
1944 if (isModEnabled('productbatch')) {
1945 $colspan += 2;
1946 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1947 $colspan += 1;
1948 }
1949 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1950 $colspan += 1;
1951 }
1952 }
1953 $recLine = new CommandeFournisseurDispatch($db);
1954
1955 $srcLine = new CommandeFournisseurLigne($db);
1956 $srcLine->id = $line->id;
1957 $srcLine->fetch_optionals(); // fetch extrafields also available in orderline
1958
1959 if (empty($recLine->array_options) && !empty($dispatchLines[$indiceAsked]['array_options'])) {
1960 $recLine->array_options = $dispatchLines[$indiceAsked]['array_options'];
1961 }
1962 $recLine->array_options = array_merge($recLine->array_options, $srcLine->array_options);
1963
1964 print $recLine->showOptionals($extrafields, 'edit', array('style' => 'class="oddeven"', 'colspan' => $colspan), (string) $indiceAsked, '', '1');
1965 }
1966
1967 $indiceAsked++;
1968 }
1969
1970 print "</table>";
1971
1972 print '<br>';
1973
1974 print $form->buttonsSaveCancel("Create");
1975
1976 print '</form>';
1977
1978 print '<br>';
1979 } else {
1981 }
1982 }
1983} elseif ($object->id > 0) {
1984 /* *************************************************************************** */
1985 /* */
1986 /* Edit and view mode */
1987 /* */
1988 /* *************************************************************************** */
1989 $lines = $object->lines;
1990
1991 $num_prod = count($lines);
1992 $indiceAsked = 0;
1993
1994 if ($object->id <= 0) {
1995 print $langs->trans("NoRecordFound");
1996 llxFooter();
1997 exit;
1998 }
1999
2000 $typeobject = '';
2001 if (!empty($object->origin) && $object->origin_id > 0) {
2002 $typeobject = $object->origin;
2003 $origin = $object->origin;
2004 $origin_id = $object->origin_id;
2005 $object->fetch_origin(); // Load property $object->origin_object, $object->commande, $object->propal, ...
2006 }
2007
2008 $soc = new Societe($db);
2009 $soc->fetch($object->socid);
2010
2011 $res = $object->fetch_optionals();
2012
2013 $head = reception_prepare_head($object);
2014 print dol_get_fiche_head($head, 'reception', $langs->trans("Reception"), -1, 'dollyrevert');
2015
2016 $formconfirm = '';
2017
2018 // Confirm deletion
2019 if ($action == 'delete') {
2020 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('DeleteReception'), $langs->trans("ConfirmDeleteReception", $object->ref), 'confirm_delete', '', 0, 1);
2021 }
2022
2023 // Confirmation validation
2024 if ($action == 'valid') {
2025 $objectref = substr($object->ref, 1, 4);
2026 if ($objectref == 'PROV') {
2027 $numref = $object->getNextNumRef($soc);
2028 } else {
2029 $numref = (string) $object->ref;
2030 }
2031
2032 $text = $langs->trans("ConfirmValidateReception", $numref);
2033 if (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION')) {
2034 $text .= '<br>'.img_picto('', 'movement', 'class="pictofixedwidth"').$langs->trans("StockMovementWillBeRecorded").'.';
2035 } elseif (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
2036 $text .= '<br>'.img_picto('', 'movement', 'class="pictofixedwidth"').$langs->trans("StockMovementNotYetRecorded").'.';
2037 }
2038
2039 if (isModEnabled('notification')) {
2040 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2041 $notify = new Notify($db);
2042 $text .= '<br>';
2043 $text .= $notify->confirmMessage('RECEPTION_VALIDATE', $object->socid, $object);
2044 }
2045
2046 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('ValidateReception'), $text, 'confirm_valid', '', 0, 1, 250);
2047 }
2048
2049 // Confirm cancellation
2050 if ($action == 'annuler') {
2051 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('CancelReception'), $langs->trans("ConfirmCancelReception", $object->ref), 'confirm_cancel', '', 0, 1);
2052 }
2053
2054 if (!$formconfirm) {
2055 $parameters = array('formConfirm' => $formconfirm);
2056 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2057 if (empty($reshook)) {
2058 $formconfirm .= $hookmanager->resPrint;
2059 } elseif ($reshook > 0) {
2060 $formconfirm = $hookmanager->resPrint;
2061 }
2062 }
2063
2064 // Print form confirm
2065 print $formconfirm;
2066
2067
2068 // Calculate totalWeight and totalVolume for all products
2069 // by adding weight and volume of each product line.
2070 $tmparray = $object->getTotalWeightVolume();
2071 $totalWeight = $tmparray['weight'];
2072 $totalVolume = $tmparray['volume'];
2073
2074
2075 if ($typeobject == 'commande' && $object->origin_object->id && isModEnabled('order')) {
2076 $objectsrc = new Commande($db);
2077 $objectsrc->fetch($object->origin_object->id);
2078 }
2079 if ($typeobject == 'propal' && $object->origin_object->id && isModEnabled("propal")) {
2080 $objectsrc = new Propal($db);
2081 $objectsrc->fetch($object->origin_object->id);
2082 }
2083 if (($typeobject == 'supplier_order' || $typeobject == 'CommandeFournisseur') && $object->origin_object->id && isModEnabled("supplier_order")) {
2084 $objectsrc = new CommandeFournisseur($db);
2085 $objectsrc->fetch($object->origin_object->id);
2086 }
2087 // Reception card
2088 $linkback = '<a href="'.DOL_URL_ROOT.'/reception/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
2089 $morehtmlref = '<div class="refidno">';
2090 // Ref customer reception
2091
2092 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('reception', 'creer'), 'string', '', 0, 1);
2093 $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('reception', 'creer'), 'string', '', null, null, '', 1);
2094
2095 // Thirdparty
2096 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
2097 // Project
2098 if ($origin && $origin_id > 0) {
2099 if (isModEnabled('project')) {
2100 $langs->load("projects");
2101 $morehtmlref .= '<br>';
2102 if (0) { // @phpstan-ignore-line Do not change on shipment
2103 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2104 if ($action != 'classify') {
2105 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2106 }
2107 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $objectsrc->socid, (string) $objectsrc->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
2108 } else {
2109 if (!empty($objectsrc) && !empty($objectsrc->fk_project)) {
2110 $proj = new Project($db);
2111 $proj->fetch($objectsrc->fk_project);
2112 $morehtmlref .= $proj->getNomUrl(1);
2113 if ($proj->title) {
2114 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2115 }
2116 }
2117 }
2118 }
2119 } elseif (!$origin && getDolGlobalString('RECEPTION_STANDALONE')) {
2120 // Project
2121 if (isModEnabled('project')) {
2122 $langs->load("projects");
2123 $morehtmlref .= '<br>';
2124 if ($permissiontoadd) {
2125 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2126 if ($action != 'classify') {
2127 $morehtmlref .= '<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token=' . newToken() . '&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> ';
2128 }
2129 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
2130 } else {
2131 if (!empty($object->fk_project)) {
2132 $proj = new Project($db);
2133 $proj->fetch($object->fk_project);
2134 $morehtmlref .= $proj->getNomUrl(1);
2135 if ($proj->title) {
2136 $morehtmlref .= '<span class="opacitymedium"> - ' . dol_escape_htmltag($proj->title) . '</span>';
2137 }
2138 }
2139 }
2140 }
2141 }
2142 $morehtmlref .= '</div>';
2143
2144 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
2145
2146
2147 print '<div class="fichecenter">';
2148 print '<div class="fichehalfleft">';
2149 print '<div class="underbanner clearboth"></div>';
2150
2151 print '<table class="border centpercent tableforfield">';
2152
2153 // Linked documents
2154 if ($typeobject == 'commande' && $object->origin_object->id && isModEnabled('order')) {
2155 print '<tr><td>';
2156 print $langs->trans("RefOrder").'</td>';
2157 print '<td colspan="3">';
2158 print $objectsrc->getNomUrl(1, 'commande');
2159 print "</td>\n";
2160 print '</tr>';
2161 }
2162 if ($typeobject == 'propal' && $object->origin_object->id && isModEnabled("propal")) {
2163 print '<tr><td>';
2164 print $langs->trans("RefProposal").'</td>';
2165 print '<td colspan="3">';
2166 print $objectsrc->getNomUrl(1, 'reception');
2167 print "</td>\n";
2168 print '</tr>';
2169 }
2170 if (($typeobject == 'supplier_order' || $typeobject == 'CommandeFournisseur') && $object->origin_object->id && isModEnabled("propal")) {
2171 print '<tr><td>';
2172 print $langs->trans("SupplierOrder").'</td>';
2173 print '<td colspan="3">';
2174 print $objectsrc->getNomUrl(1, 'reception');
2175 print "</td>\n";
2176 print '</tr>';
2177 }
2178
2179 // Date creation
2180 print '<tr><td class="titlefield">'.$langs->trans("DateCreation").'</td>';
2181 print '<td colspan="3">'.dol_print_date($object->date_creation, "dayhour", "tzuserrel")."</td>\n";
2182 print '</tr>';
2183
2184 // Reception Date
2185 print '<tr><td height="10">';
2186 print '<table class="nobordernopadding centpercent"><tr><td>';
2187 print $langs->trans('DateReception');
2188 print '</td>';
2189 if ($action != 'editdate_reception') {
2190 print '<td class="right"><a class="editfielda" href="' . $_SERVER["PHP_SELF"] . '?action=editdate_reception&token=' . newToken() . '&id=' . $object->id . '">' . img_edit($langs->trans('SetReceptionDate'), 1) . '</a></td>';
2191 }
2192 print '</tr></table>';
2193 print '</td><td>';
2194 if ($action == 'editdate_reception') {
2195 print '<form name="setdate_reception" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
2196 print '<input type="hidden" name="token" value="' . newToken() . '">';
2197 print '<input type="hidden" name="action" value="setdate_reception">';
2198 print $form->selectDate($object->date_reception ? $object->date_reception : -1, 'recep_', 1, 1, 0, "setdate_reception", 1, 0);
2199 print '<input type="submit" class="button button-edit smallpaddingimp" value="' . $langs->trans('Modify') . '">';
2200 print '</form>';
2201 } else {
2202 print $object->date_reception ? dol_print_date($object->date_reception, 'dayhour') : '&nbsp;';
2203 }
2204 print '</td>';
2205 print '</tr>';
2206
2207 // Delivery date planned
2208 print '<tr><td height="10">';
2209 print '<table class="nobordernopadding" width="100%"><tr><td>';
2210 print $langs->trans('DateDeliveryPlanned');
2211 print '</td>';
2212
2213 if ($action != 'editdate_livraison' && $permissiontoadd) {
2214 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>';
2215 }
2216 print '</tr></table>';
2217 print '</td><td colspan="2">';
2218 if ($action == 'editdate_livraison') {
2219 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2220 print '<input type="hidden" name="token" value="'.newToken().'">';
2221 print '<input type="hidden" name="action" value="setdate_livraison">';
2222 print $form->selectDate($object->date_delivery ? $object->date_delivery : -1, 'liv_', 1, 1, 0, "setdate_livraison", 1, 0);
2223 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
2224 print '</form>';
2225 } else {
2226 print $object->date_delivery ? dol_print_date($object->date_delivery, 'dayhour') : '&nbsp;';
2227 }
2228 print '</td>';
2229 print '</tr>';
2230
2231 // Weight
2232 print '<tr><td>';
2233 print $form->editfieldkey("Weight", 'trueWeight', (string) $object->trueWeight, $object, $user->hasRight('reception', 'creer'));
2234 print '</td><td colspan="3">';
2235
2236 if ($action == 'edittrueWeight') {
2237 print '<form name="settrueweight" action="'.$_SERVER["PHP_SELF"].'" method="post">';
2238 print '<input name="action" value="settrueWeight" type="hidden">';
2239 print '<input name="id" value="'.$object->id.'" type="hidden">';
2240 print '<input type="hidden" name="token" value="'.newToken().'">';
2241 print '<input id="trueWeight" name="trueWeight" value="'.$object->trueWeight.'" type="text">';
2242 print $formproduct->selectMeasuringUnits("weight_units", "weight", (string) $object->weight_units, 0, 2);
2243 print ' <input class="button" name="modify" value="'.$langs->trans("Modify").'" type="submit">';
2244 print ' <input class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'" type="submit">';
2245 print '</form>';
2246 } else {
2247 print $object->trueWeight;
2248 print ($object->trueWeight && $object->weight_units != '') ? ' '.measuringUnitString(0, "weight", $object->weight_units) : '';
2249 }
2250
2251 // Calculated
2252 if ($totalWeight > 0) {
2253 if (!empty($object->trueWeight)) {
2254 print ' ('.$langs->trans("SumOfProductWeights").': ';
2255 }
2256 print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, getDolGlobalInt('MAIN_WEIGHT_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_WEIGHT_DEFAULT_UNIT', 'no'));
2257 if (!empty($object->trueWeight)) {
2258 print ')';
2259 }
2260 }
2261 print '</td></tr>';
2262
2263 // Width
2264 print '<tr><td>'.$form->editfieldkey("Width", 'trueWidth', (string) $object->trueWidth, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
2265 print $form->editfieldval("Width", 'trueWidth', $object->trueWidth, $object, $user->hasRight('reception', 'creer'));
2266 print ($object->trueWidth && $object->width_units != '') ? ' '.measuringUnitString(0, "size", $object->width_units) : '';
2267 print '</td></tr>';
2268
2269 // Height
2270 print '<tr><td>'.$form->editfieldkey("Height", 'trueHeight', (string) $object->trueHeight, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
2271 if ($action == 'edittrueHeight') {
2272 print '<form name="settrueHeight" action="'.$_SERVER["PHP_SELF"].'" method="post">';
2273 print '<input name="action" value="settrueHeight" type="hidden">';
2274 print '<input name="id" value="'.$object->id.'" type="hidden">';
2275 print '<input type="hidden" name="token" value="'.newToken().'">';
2276 print '<input id="trueHeight" name="trueHeight" value="'.$object->trueHeight.'" type="text">';
2277 print $formproduct->selectMeasuringUnits("size_units", "size", $object->size_units, 0, 2);
2278 print ' <input class="button" name="modify" value="'.$langs->trans("Modify").'" type="submit">';
2279 print ' <input class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'" type="submit">';
2280 print '</form>';
2281 } else {
2282 print $object->trueHeight;
2283 print ($object->trueHeight && $object->height_units != '') ? ' '.measuringUnitString(0, "size", $object->height_units) : '';
2284 }
2285
2286 print '</td></tr>';
2287
2288 // Depth
2289 print '<tr><td>'.$form->editfieldkey("Depth", 'trueDepth', (string) $object->trueDepth, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
2290 print $form->editfieldval("Depth", 'trueDepth', $object->trueDepth, $object, $user->hasRight('reception', 'creer'));
2291 print ($object->trueDepth && $object->depth_units != '') ? ' '.measuringUnitString(0, "size", $object->depth_units) : '';
2292 print '</td></tr>';
2293
2294 // Volume
2295 print '<tr><td>';
2296 print $langs->trans("Volume");
2297 print '</td>';
2298 print '<td colspan="3">';
2299 $calculatedVolume = 0;
2300 $volumeUnit = 0;
2301 if ($object->trueWidth && $object->trueHeight && $object->trueDepth) {
2302 $calculatedVolume = ($object->trueWidth * $object->trueHeight * $object->trueDepth);
2303 $volumeUnit = $object->size_units * 3;
2304 }
2305 // If reception volume not defined we use sum of products
2306 if ($calculatedVolume > 0) {
2307 if ($volumeUnit < 50) {
2308 print showDimensionInBestUnit($calculatedVolume, $volumeUnit, "volume", $langs, getDolGlobalInt('MAIN_VOLUME_DEFAULT_ROUND', -1), getDolGlobalString("MAIN_VOLUME_DEFAULT_UNIT", 'no'));
2309 } else {
2310 print $calculatedVolume.' '.measuringUnitString(0, "volume", $volumeUnit);
2311 }
2312 }
2313 if ($totalVolume > 0) {
2314 if ($calculatedVolume) {
2315 print ' ('.$langs->trans("SumOfProductVolumes").': ';
2316 }
2317 print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, getDolGlobalInt('MAIN_VOLUME_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_VOLUME_DEFAULT_UNIT', 'no'));
2318 //if (empty($calculatedVolume)) print ' ('.$langs->trans("Calculated").')';
2319 if ($calculatedVolume) {
2320 print ')';
2321 }
2322 }
2323 print "</td>\n";
2324 print '</tr>';
2325
2326 // Other attributes
2327 $cols = 2;
2328
2329 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2330
2331 print '</table>';
2332
2333 print '</div>';
2334 print '<div class="fichehalfright">';
2335 print '<div class="underbanner clearboth"></div>';
2336
2337 print '<table class="border centpercent tableforfield">';
2338
2339 // Reception method
2340 print '<tr><td height="10">';
2341 print '<table class="nobordernopadding centpercent"><tr><td>';
2342 print $langs->trans('ReceptionMethod');
2343 print '</td>';
2344
2345 if ($action != 'editshipping_method_id' && $permissiontoadd) {
2346 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>';
2347 }
2348 print '</tr></table>';
2349 print '</td><td colspan="2">';
2350 if ($action == 'editshipping_method_id') {
2351 print '<form name="setshipping_method_id" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2352 print '<input type="hidden" name="token" value="'.newToken().'">';
2353 print '<input type="hidden" name="action" value="setshipping_method_id">';
2354 $object->fetch_delivery_methods();
2355 print $form->selectarray("shipping_method_id", $object->meths, $object->shipping_method_id, 1, 0, 0, "", 1);
2356 if ($user->admin) {
2357 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
2358 }
2359 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
2360 print '</form>';
2361 } else {
2362 if ($object->shipping_method_id > 0) {
2363 // Get code using getLabelFromKey
2364 $code = $langs->getLabelFromKey($db, (string) $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code');
2365 print $langs->trans("SendingMethod".strtoupper($code));
2366 }
2367 }
2368 print '</td>';
2369 print '</tr>';
2370
2371 // Tracking Number
2372 print '<tr><td class="titlefield">'.$form->editfieldkey("TrackingNumber", 'tracking_number', $object->tracking_number, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
2373 print $form->editfieldval("TrackingNumber", 'tracking_number', $object->tracking_url, $object, $user->hasRight('reception', 'creer'), 'safehtmlstring', $object->tracking_number);
2374 print '</td></tr>';
2375
2376 // Incoterms
2377 if (isModEnabled('incoterm')) {
2378 print '<tr><td>';
2379 print '<table width="100%" class="nobordernopadding"><tr><td>';
2380 print $langs->trans('IncotermLabel');
2381 print '<td><td class="right">';
2382 if ($user->hasRight('reception', 'creer')) {
2383 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/reception/card.php?id='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
2384 } else {
2385 print '&nbsp;';
2386 }
2387 print '</td></tr></table>';
2388 print '</td>';
2389 print '<td colspan="3">';
2390 if ($action != 'editincoterm') {
2391 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
2392 } else {
2393 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
2394 }
2395 print '</td></tr>';
2396 }
2397
2398 print "</table>";
2399
2400 print '</div>';
2401 print '</div>';
2402
2403 print '<div class="clearboth"></div>';
2404
2405 /*
2406 * Lines of simple reception
2407 */
2408 if (!$origin_id && getDolGlobalString('RECEPTION_STANDALONE')) {
2409 if (!empty($object->table_element_line)) {
2410 // Show object lines
2411 $result = $object->getLinesArray();
2412
2413 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
2414 <input type="hidden" name="token" value="' . newToken().'">
2415 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
2416 <input type="hidden" name="mode" value="">
2417 <input type="hidden" name="page_y" value="">
2418 <input type="hidden" name="id" value="' . $object->id.'">
2419 ';
2420
2421 if (!empty($conf->use_javascript_ajax) && $object->status == $object::STATUS_DRAFT) {
2422 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
2423 }
2424
2425 print '<div class="div-table-responsive-no-min">';
2426 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
2427 print '<table id="tablelines" class="noborder noshadow" width="100%">';
2428 }
2429
2430 if (!empty($object->lines)) {
2431 $object->printObjectLines($action, $mysoc, null, GETPOSTINT('lineid'), 0, '/reception/tpl');
2432 }
2433
2434 // Form to add new line
2435 if ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines') {
2436 if ($action != 'editline') {
2437 // Add products/services form
2438
2439 $parameters = array();
2440 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2441 if ($reshook < 0) {
2442 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2443 }
2444 if (empty($reshook)) {
2445 $object->formAddObjectLine(0, $mysoc, $soc);
2446 }
2447 }
2448 }
2449
2450 if (!empty($object->lines) || ($object->status == Reception::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
2451 print '</table>';
2452 }
2453 print '</div>';
2454
2455 print "</form>\n";
2456 }
2457 } elseif (!empty($object->origin) && $object->origin_id > 0) {
2458 // Lines of products of origin
2459 if ($action == 'editline') {
2460 print '<form name="updateline" id="updateline" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;lineid='.$line_id.'" method="POST">
2461 <input type="hidden" name="token" value="' . newToken().'">
2462 <input type="hidden" name="action" value="updateline">
2463 <input type="hidden" name="mode" value="">
2464 <input type="hidden" name="id" value="' . $object->id.'">';
2465 }
2466 print '<br><br>';
2467
2468 print '<div class="div-table-responsive-no-min">';
2469 print '<table id="tablelines" class="noborder centpercent">';
2470 print '<thead>';
2471 print '<tr class="liste_titre">';
2472 // #
2473 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
2474 print '<td width="5" class="center">&nbsp;</td>';
2475 }
2476 // Product/Service
2477 print '<td>'.$langs->trans("Products").'</td>';
2478 // Comment
2479 print '<td>'.$langs->trans("Comment").'</td>';
2480 // Qty
2481 print '<td class="center">'.$langs->trans("QtyOrdered").'</td>';
2482 if ($origin && $origin_id > 0) {
2483 print '<td class="center">'.$langs->trans("QtyInOtherReceptions").'</td>';
2484 }
2485
2486 $editColspan = 3;
2487 if ($action == 'editline') {
2488 if (!isModEnabled('stock')) {
2489 $editColspan--;
2490 }
2491 if (empty($conf->productbatch->enabled)) {
2492 $editColspan--;
2493 }
2494 print '<td class="center" colspan="'.$editColspan.'">';
2495 if ($object->statut <= 1) {
2496 print $langs->trans("QtyToReceive").' - ';
2497 } else {
2498 print $langs->trans("QtyReceived").' - ';
2499 }
2500 if (isModEnabled('stock')) {
2501 print $langs->trans("WarehouseTarget").' - ';
2502 }
2503 if (isModEnabled('productbatch')) {
2504 print $langs->trans("Batch");
2505 }
2506 print '</td>';
2507
2508 $parameters = array();
2509 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2510 if ($reshook < 0) {
2511 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2512 } else {
2513 print $hookmanager->resPrint;
2514 }
2515 } else {
2516 $statusreceived = $object::STATUS_CLOSED;
2517 if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION")) {
2518 $statusreceived = $object::STATUS_VALIDATED;
2519 }
2520 if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION_CLOSE")) {
2521 $statusreceived = $object::STATUS_CLOSED;
2522 }
2523 if ($object->statut < $statusreceived) {
2524 print '<td class="center">'.$langs->trans("QtyToReceive").'</td>';
2525 } else {
2526 print '<td class="center">'.$langs->trans("QtyReceived").'</td>';
2527 }
2528 if (isModEnabled('stock')) {
2529 print '<td class="left">'.$langs->trans("WarehouseTarget").'</td>';
2530 }
2531
2532 if (isModEnabled('productbatch')) {
2533 print '<td class="left">'.$langs->trans("Batch").'</td>';
2534 }
2535
2536 $parameters = array();
2537 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2538 if ($reshook < 0) {
2539 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2540 } else {
2541 print $hookmanager->resPrint;
2542 }
2543 }
2544 print '<td class="center">'.$langs->trans("CalculatedWeight").'</td>';
2545 print '<td class="center">'.$langs->trans("CalculatedVolume").'</td>';
2546 //print '<td class="center">'.$langs->trans("Size").'</td>';
2547 if ($object->statut == 0) {
2548 print '<td class="linecoledit"></td>';
2549 print '<td class="linecoldelete" width="10"></td>';
2550 }
2551 print "</tr>\n";
2552 print '</thead>';
2553
2554 $var = false;
2555
2556 $outputlangs = $langs;
2557 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
2558 $object->fetch_thirdparty();
2559 $newlang = '';
2560 if (/* empty($newlang) && */ GETPOST('lang_id', 'aZ09')) {
2561 $newlang = GETPOST('lang_id', 'aZ09');
2562 }
2563 if (empty($newlang)) {
2564 $newlang = $object->thirdparty->default_lang;
2565 }
2566 if (!empty($newlang)) {
2567 $outputlangs = new Translate("", $conf);
2568 $outputlangs->setDefaultLang($newlang);
2569 }
2570 }
2571
2572 // Get list of products already sent for same source object into $alreadysent
2573 $alreadysent = array();
2574
2575 if (empty($origin) || $origin == 'order_supplier') {
2576 $origin = 'supplier_order';
2577 }
2578
2579 if ($origin_id > 0) {
2580 $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";
2581 $sql .= ", ed.rowid as receptionline_id, ed.qty, ed.fk_reception as reception_id, ed.fk_entrepot";
2582 $sql .= ", e.rowid as reception_id, e.ref as reception_ref, e.date_creation, e.date_valid, e.date_delivery, e.date_reception";
2583 $sql .= ', p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tobatch as product_tobatch';
2584 $sql .= ', p.description as product_desc';
2585 $sql .= " FROM ".MAIN_DB_PREFIX."receptiondet_batch as ed";
2586 $sql .= ", ".MAIN_DB_PREFIX."reception as e";
2587 $sql .= ", ".MAIN_DB_PREFIX.(($origin == 'supplier_order') ? 'commande_fournisseur' : $origin)."det as obj"; // @phan-suppress-current-line SqlInjection
2588 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON obj.fk_product = p.rowid";
2589 $sql .= " WHERE e.entity IN (".getEntity('reception').")";
2590 $sql .= " AND obj.fk_commande = ".((int) $origin_id);
2591 $sql .= " AND obj.rowid = ed.fk_elementdet";
2592 $sql .= " AND ed.fk_reception = e.rowid";
2593 $sql .= " AND ed.fk_reception !=".((int) $object->id);
2594 $sql .= " ORDER BY obj.fk_product";
2595
2596 dol_syslog("get list of reception lines", LOG_DEBUG);
2597 $resql = $db->query($sql);
2598 if ($resql) {
2599 $num = $db->num_rows($resql);
2600 $i = 0;
2601
2602 while ($i < $num) {
2603 $obj = $db->fetch_object($resql);
2604 if ($obj) {
2605 // $obj->rowid is rowid in $origin."det" table
2606 $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);
2607 }
2608 $i++;
2609 }
2610 }
2611 //var_dump($alreadysent);
2612 }
2613
2614 $arrayofpurchaselinealreadyoutput = array();
2615
2616 // Loop on each product to send/sent. Warning: $lines must be sorted by ->fk_commandefourndet (it is a regroupment key on output)
2617 print '<tbody>';
2618 for ($i = 0; $i < $num_prod; $i++) {
2619 print '<!-- origin line id = '.(!empty($lines[$i]->origin_line_id) ? $lines[$i]->origin_line_id : 0).' -->'; // id of order line
2620 print '<tr class="oddeven" id="row-'.$lines[$i]->id.'" data-id="'.$lines[$i]->id.'" data-element="'.$lines[$i]->element.'">';
2621
2622 // #
2623 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
2624 print '<td class="center">'.($i + 1).'</td>';
2625 }
2626
2627 // Predefined product or service
2628 if ($lines[$i]->fk_product > 0) {
2629 // Define output language
2630 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
2631 $prod = new Product($db);
2632 $prod->fetch($lines[$i]->fk_product);
2633 $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["label"])) ? $prod->multilangs[$outputlangs->defaultlang]["label"] : $lines[$i]->product->label;
2634 } else {
2635 $label = (!empty($lines[$i]->product->label) ? $lines[$i]->product->label : $lines[$i]->product->product_label);
2636 }
2637
2638 print '<td class="linecoldescription">';
2639 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
2640 $text = $lines[$i]->product->getNomUrl(1);
2641 $text .= ' - '.$label;
2642 $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($lines[$i]->description));
2643 print $form->textwithtooltip($text, $description, 3, 0, '', (string) $i);
2644 print_date_range(!empty($lines[$i]->date_start) ? $lines[$i]->date_start : 0, !empty($lines[$i]->date_end) ? $lines[$i]->date_end : 0);
2645 if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
2646 print (!empty($lines[$i]->description) && $lines[$i]->description != $label) ? '<br>'.dol_htmlentitiesbr($lines[$i]->description) : '';
2647 }
2648 }
2649 print "</td>\n";
2650 } else {
2651 print '<td class="linecoldescription">';
2652 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
2653 if ($lines[$i]->product_type == Product::TYPE_SERVICE) {
2654 $text = img_object($langs->trans('Service'), 'service');
2655 } else {
2656 $text = img_object($langs->trans('Product'), 'product');
2657 }
2658
2659 if (!empty($lines[$i]->label)) {
2660 $text .= ' <strong>'.$lines[$i]->label.'</strong>';
2661 print $form->textwithtooltip($text, $lines[$i]->description, 3, 0, '', (string) $i);
2662 } else {
2663 print $text.' '.nl2br($lines[$i]->description);
2664 }
2665
2666 print_date_range($lines[$i]->date_start, $lines[$i]->date_end);
2667 }
2668 print "</td>\n";
2669 }
2670
2671 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2672 print '<td><input name="comment'.$line_id.'" id="comment'.$line_id.'" value="'.dol_escape_htmltag($lines[$i]->comment).'"></td>';
2673 } else {
2674 print '<td style="white-space: pre-wrap; max-width: 200px;">'.dol_escape_htmltag($lines[$i]->comment).'</td>';
2675 }
2676
2677
2678 // Qty ordered
2679 print '<td class="center linecolqty">';
2680 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
2681 print $lines[$i]->qty_asked;
2682 }
2683 print '</td>';
2684
2685 // Qty in other receptions (with reception and warehouse used)
2686 if ($origin && $origin_id > 0) {
2687 print '<td class="center nowrap linecolqtyinotherreceptions">';
2688 $htmltooltip = '';
2689 $qtyalreadyreceived = 0;
2690 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
2691 foreach ($alreadysent as $key => $val) {
2692 if ($lines[$i]->fk_commandefourndet == $key) {
2693 $j = 0;
2694 foreach ($val as $receptionline_id => $receptionline_var) {
2695 if ($receptionline_var['reception_id'] == $lines[$i]->fk_reception) {
2696 continue; // We want to show only "other receptions"
2697 }
2698
2699 $j++;
2700 if ($j > 1) {
2701 $htmltooltip .= '<br>';
2702 }
2703 $reception_static->fetch($receptionline_var['reception_id']);
2704 $htmltooltip .= $reception_static->getNomUrl(1, 'nolink', 0, 0, 1);
2705 $htmltooltip .= ' - '.$receptionline_var['qty'];
2706
2707 $htmltext = $langs->trans("DateValidation").' : '.(empty($receptionline_var['date_valid']) ? $langs->trans("Draft") : dol_print_date($receptionline_var['date_valid'], 'dayhour'));
2708 if (isModEnabled('stock') && $receptionline_var['warehouse'] > 0) {
2709 $warehousestatic->fetch($receptionline_var['warehouse']);
2710 $htmltext .= '<br>'.$langs->trans("From").' : '.$warehousestatic->getNomUrl(1, '', 0, 1);
2711 }
2712 $htmltooltip .= ' '.$form->textwithpicto('', $htmltext, 1);
2713
2714 $qtyalreadyreceived += $receptionline_var['qty'];
2715 }
2716 if ($j) {
2717 $htmltooltip = $langs->trans("QtyInOtherReceptions").'...<br><br>'.$htmltooltip.'<br><input type="submit" name="dummyhiddenbuttontogetfocus" style="display:none" autofocus>';
2718 }
2719 }
2720 }
2721 }
2722 print $form->textwithpicto((string) $qtyalreadyreceived, $htmltooltip, 1, 'info', '', 0, 3, 'tooltip'.$lines[$i]->id);
2723 print '</td>';
2724 }
2725
2726 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2727 // edit mode
2728 print '<td colspan="'.$editColspan.'" class="center"><table class="nobordernopadding">';
2729 if (isModEnabled('stock')) {
2730 if ($lines[$i]->fk_product > 0) {
2731 print '<!-- case edit 1 -->';
2732 print '<tr>';
2733 // Qty to receive or received
2734 print '<td><input name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty.'"></td>';
2735 // Warehouse source
2736 print '<td>'.$formproduct->selectWarehouses($lines[$i]->fk_entrepot, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1).'</td>';
2737 // Batch number management
2738 if ($conf->productbatch->enabled && !empty($lines[$i]->product->status_batch)) {
2739 print '<td class="nowraponall left"><input name="batch'.$line_id.'" id="batch'.$line_id.'" type="text" value="'.$lines[$i]->batch.'"><br>';
2740 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
2741 print $langs->trans('SellByDate').' : ';
2742 print $form->selectDate($lines[$i]->sellby, 'dlc'.$line_id, 0, 0, 1, "").'</br>';
2743 }
2744 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
2745 print $langs->trans('EatByDate').' : ';
2746 print $form->selectDate($lines[$i]->eatby, 'dluo'.$line_id, 0, 0, 1, "");
2747 }
2748 print '</td>';
2749 }
2750 print '</tr>';
2751 } else {
2752 print '<!-- case edit 2 -->';
2753 print '<tr>';
2754 // Qty to receive or received
2755 print '<td><input name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty.'"></td>';
2756 // Warehouse source
2757 print '<td></td>';
2758 // Batch number management
2759 print '<td></td>';
2760 print '</tr>';
2761 }
2762 }
2763 print '</table></td>';
2764
2765 $parameters = array();
2766 $parameters['line'] = $lines[$i];
2767 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2768 if ($reshook < 0) {
2769 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2770 } else {
2771 print $hookmanager->resPrint;
2772 }
2773 } else {
2774 // Qty to receive or received
2775 print '<td class="center linecolqtytoreceive">'.$lines[$i]->qty.'</td>';
2776
2777 // Warehouse source
2778 if (isModEnabled('stock')) {
2779 if ($lines[$i]->fk_entrepot > 0) {
2780 $entrepot = new Entrepot($db);
2781 $entrepot->fetch($lines[$i]->fk_entrepot);
2782
2783 print '<td class="left tdoverflowmax150" title="'.dol_escape_htmltag($entrepot->label).'">';
2784 print $entrepot->getNomUrl(1);
2785 print '</td>';
2786 } else {
2787 print '<td></td>';
2788 }
2789 }
2790
2791 // Batch number management
2792 if (isModEnabled('productbatch')) {
2793 if (isset($lines[$i]->batch)) {
2794 print '<!-- Detail of lot -->';
2795 print '<td class="linecolbatch nowrap">';
2796 $detail = $langs->trans("NA");
2797 if ($lines[$i]->product->status_batch > 0 && $lines[$i]->fk_product > 0) {
2798 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
2799 $productlot = new Productlot($db);
2800 $reslot = $productlot->fetch(0, $lines[$i]->fk_product, $lines[$i]->batch);
2801 if ($reslot > 0) {
2802 $detail = $productlot->getNomUrl(1);
2803 } else {
2804 // lot is not created and info is only in reception lines
2805 $batchinfo = $langs->trans("Batch").': '.$lines[$i]->batch;
2806 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
2807 $batchinfo .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($lines[$i]->sellby, "day");
2808 }
2809 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
2810 $batchinfo .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($lines[$i]->eatby, "day");
2811 }
2812 $detail = $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"), $batchinfo);
2813 }
2814 }
2815 print $detail . '</td>';
2816 } else {
2817 print '<td></td>';
2818 }
2819 }
2820
2821 $parameters = array();
2822 $parameters['line'] = $lines[$i];
2823 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2824 if ($reshook < 0) {
2825 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2826 } else {
2827 print $hookmanager->resPrint;
2828 }
2829 }
2830
2831 // Weight
2832 print '<td class="center linecolweight">';
2833 if (!empty($lines[$i]->fk_product_type) && $lines[$i]->fk_product_type == Product::TYPE_PRODUCT) {
2834 print $lines[$i]->product->weight * $lines[$i]->qty.' '.measuringUnitString(0, "weight", $lines[$i]->product->weight_units);
2835 } else {
2836 print '&nbsp;';
2837 }
2838 print '</td>';
2839
2840 // Volume
2841 print '<td class="center linecolvolume">';
2842 if (!empty($lines[$i]->fk_product_type) && $lines[$i]->fk_product_type == Product::TYPE_PRODUCT) {
2843 print $lines[$i]->product->volume * $lines[$i]->qty.' '.measuringUnitString(0, "volume", $lines[$i]->product->volume_units);
2844 } else {
2845 print '&nbsp;';
2846 }
2847 print '</td>';
2848
2849
2850 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2851 print '<td class="center valignmiddle" colspan="2">';
2852 print '<input type="submit" class="button small button-save" id="savelinebutton marginbottomonly" name="save" value="'.$langs->trans("Save").'"><br>';
2853 print '<input type="submit" class="button small button-cancel" id="cancellinebutton" name="cancel" value="'.$langs->trans("Cancel").'"><br>';
2854 print '</td>';
2855 } elseif ($object->statut == Reception::STATUS_DRAFT) {
2856 // edit-delete buttons
2857 print '<td class="linecoledit center">';
2858 print '<a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&token='.newToken().'&lineid='.$lines[$i]->id.'">'.img_edit().'</a>';
2859 print '</td>';
2860 print '<td class="linecoldelete" width="10">';
2861 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deleteline&token='.newToken().'&lineid='.$lines[$i]->id.'">'.img_delete().'</a>';
2862 print '</td>';
2863
2864 // Display lines extrafields
2865 if (isset($rowExtrafieldsStart, $rowExtrafieldsView, $rowEnd)) { // @phan-suppress-current-line PhanPluginUndeclaredVariableIsset
2866 print $rowExtrafieldsStart;
2867 print $rowExtrafieldsView;
2868 print $rowEnd;
2869 }
2870 }
2871 print "</tr>";
2872
2873 $arrayofpurchaselinealreadyoutput[$lines[$i]->fk_commandefourndet] = $lines[$i]->fk_commandefourndet;
2874
2875 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2876 if ($reshook < 0) {
2877 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2878 } else {
2879 print $hookmanager->resPrint;
2880 }
2881
2882 // Display lines extrafields
2883 $extralabelslines = $extrafields->attributes[$lines[$i]->table_element];
2884 if (!empty($extralabelslines) && is_array($extralabelslines) && count($extralabelslines) > 0) {
2885 $colspan = 8;
2886 if (isModEnabled('stock')) {
2887 $colspan++;
2888 }
2889 if (isModEnabled('productbatch')) {
2890 $colspan++;
2891 }
2892
2893 $line = new CommandeFournisseurDispatch($db);
2894 $line->id = $lines[$i]->id;
2895 $line->fetch_optionals();
2896
2897 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2898 print $line->showOptionals($extrafields, 'edit', array('colspan' => $colspan), '');
2899 } else {
2900 print $line->showOptionals($extrafields, 'view', array('colspan' => $colspan), '');
2901 }
2902 }
2903 }
2904 print '</tbody>';
2905
2906 // TODO Show also lines ordered but not delivered
2907
2908 print "</table>\n";
2909 print '</div>';
2910
2911
2912 print dol_get_fiche_end();
2913
2914
2915 $object->fetchObjectLinked($object->id, $object->element);
2916 }
2917
2918 /*
2919 * Button actions
2920 */
2921
2922 if (($user->socid == 0) && ($action != 'presend')) {
2923 print '<div class="tabsAction">';
2924
2925 $parameters = array();
2926 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2927 if (empty($reshook)) {
2928 if ($object->statut == Reception::STATUS_DRAFT && $num_prod > 0) {
2929 if ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'creer'))
2930 || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'reception_advance', 'validate'))) {
2931 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken().'">'.$langs->trans("Validate").'</a>';
2932 } else {
2933 print '<a class="butActionRefused" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Validate").'</a>';
2934 }
2935 }
2936 // Back to draft
2937 if ($object->statut == Reception::STATUS_VALIDATED && $user->hasRight('reception', 'creer')) {
2938 print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=modif&token='.newToken().'">'.$langs->trans('SetToDraft').'</a></div>';
2939 }
2940
2941 // TODO add alternative status
2942 // 0=draft, 1=validated, 2=billed, we miss a status "delivered" (only available on order)
2943 if ($object->statut == Reception::STATUS_CLOSED && $user->hasRight('reception', 'creer')) {
2944 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("ReOpen").'</a>';
2945 }
2946
2947 // Send mail
2948 if (empty($user->socid)) {
2949 if ($object->statut > 0) {
2950 if (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('reception', 'reception_advance', 'send')) {
2951 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendByMail').'</a>';
2952 } else {
2953 print '<a class="butActionRefused" href="#">'.$langs->trans('SendByMail').'</a>';
2954 }
2955 }
2956 }
2957
2958 // Create bill
2959 if (isModEnabled("supplier_invoice") && ($object->statut == Reception::STATUS_VALIDATED || $object->statut == Reception::STATUS_CLOSED) && !getDolGlobalString('RECEPTION_STANDALONE')) {
2960 if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight('supplier_invoice', 'creer')) {
2961 if (getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0') {
2962 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>';
2963 }
2964 }
2965 }
2966
2967
2968 // Set Billed and Closed
2969 if ($object->statut == Reception::STATUS_VALIDATED) {
2970 if ($user->hasRight('reception', 'creer') && $object->statut > 0) {
2971 if (!$object->billed && getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0') {
2972 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled&token='.newToken().'">'.$langs->trans('ClassifyBilled').'</a>';
2973 }
2974 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifyclosed&token='.newToken().'">'.$langs->trans("Close").'</a>';
2975 }
2976 }
2977
2978 if ($user->hasRight('reception', 'supprimer')) {
2979 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'">'.$langs->trans("Delete").'</a>';
2980 }
2981 }
2982
2983 print '</div>';
2984 }
2985
2986
2987 /*
2988 * Documents generated
2989 */
2990
2991 if ($action != 'presend' && $action != 'editline') {
2992 print '<div class="fichecenter"><div class="fichehalfleft">';
2993
2994 $objectref = dol_sanitizeFileName((string) $object->ref);
2995 $filedir = $conf->reception->dir_output."/".$objectref;
2996
2997 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2998
2999 $genallowed = $user->hasRight('reception', 'lire');
3000 $delallowed = $user->hasRight('reception', 'creer');
3001
3002 print $formfile->showdocuments('reception', $objectref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang);
3003
3004 // Show links to link elements
3005 //$tmparray = $form->showLinkToObjectBlock($object, null, array('order'), 1);
3006 $somethingshown = $form->showLinkedObjectBlock($object, '');
3007
3008 print '</div><div class="fichehalfright">';
3009
3010 print '</div></div>';
3011 }
3012
3013 // Presend form
3014 $modelmail = 'reception_send';
3015 $defaulttopic = 'SendReceptionRef';
3016 $diroutput = $conf->reception->dir_output;
3017 $trackid = 'rec'.$object->id;
3018
3019 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
3020}
3021
3022
3023llxFooter();
3024
3025$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage table ReceptionLineBatch.
Class to manage predefined suppliers products.
Class to manage line orders.
Class to manage customers orders.
Class to manage a WYSIWYG editor.
Class to manage warehouses.
Class to manage standard extra fields.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class with static methods for building HTML components related to products Only components common to ...
Class to manage building of HTML components.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
Class to manage the table of subscription to notifications.
Class ProductCombination Used to represent the relation between a product and one of its variants.
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 table commandefournisseurdispatch.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
global $mysoc
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.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
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, $morecssdiv='')
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round=-1, $forceunitoutput='no', $use_short_label=0)
Output a dimension with best unit.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
dol_htmlcleanlastbr($stringtodecode)
This function remove all ending and br at end.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
print_date_range($date_start, $date_end, $format='', $outputlangs=null)
Format output for start and end date.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
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...
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
measuringUnitString($unitid, $measuring_style='', $unitscale=null, $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.