dolibarr 24.0.0-beta
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003-2008 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2005-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Simon TOSSER <simon@kornog-computing.com>
5 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
6 * Copyright (C) 2011-2017 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2013 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
10 * Copyright (C) 2014-2017 Francis Appels <francis.appels@yahoo.com>
11 * Copyright (C) 2015 Claudio Aschieri <c.aschieri@19.coop>
12 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
13 * Copyright (C) 2016 Yasser Carreón <yacasia@gmail.com>
14 * Copyright (C) 2018 Quentin Vial-Gouteyron <quentin.vial-gouteyron@atm-consulting.fr>
15 * Copyright (C) 2024-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 = $reception->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, 0, 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 // copy from order
1309 if ($objectsrc->fetch_optionals() > 0) {
1310 $recept->array_options = array_merge($recept->array_options, $objectsrc->array_options);
1311 }
1312 print $recept->showOptionals($extrafields, 'create', $parameters);
1313 }
1314
1315 // Incoterms
1316 if (isModEnabled('incoterm')) {
1317 print '<tr>';
1318 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $object->label_incoterms, 1).'</label></td>';
1319 print '<td colspan="3" class="maxwidthonsmartphone">';
1320 print img_picto('', 'incoterm', 'class="pictofixedwidth"');
1321 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''));
1322 print '</td></tr>';
1323 }
1324
1325 // Template to use by default
1327 if (is_countable($list) && count($list) > 0) {
1328 print '<tr><td>'.$langs->trans('Model').'</td>';
1329 print '<td colspan="2">';
1330 print img_picto('', 'pdf', 'class="pictofixedwidth"');
1331 include_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
1332 print $form->selectarray('model', $list, getDolGlobalString('RECEPTION_ADDON_PDF'), 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1);
1333 print "</td></tr>";
1334 }
1335
1336 // Note Public
1337 $htmltext ='';
1338 print '<tr>';
1339 print '<td class="tdtop">';
1340 print $form->textwithpicto($langs->trans('NotePublic'), $htmltext);
1341 print '</td>';
1342 print '<td valign="top" colspan="2">';
1343 $doleditor = new DolEditor('note_public', (string) $note_public, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
1344 print $doleditor->Create(1);
1345
1346 // Note Private
1347 if (!$user->socid) {
1348 print '<tr>';
1349 print '<td class="tdtop">';
1350 print $form->textwithpicto($langs->trans('NotePrivate'), $htmltext);
1351 print '</td>';
1352 print '<td valign="top" colspan="2">';
1353 $doleditor = new DolEditor('note_private', (string) $note_private, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
1354 print $doleditor->Create(1);
1355 print "</td></tr>";
1356 }
1357
1358 print "</table>\n";
1359
1360 print dol_get_fiche_end();
1361
1362 print $form->buttonsSaveCancel("CreateDraft");
1363
1364 print "</form>\n";
1365 } elseif ($origin) {
1366 if ($origin == 'supplierorder') {
1367 $classname = 'CommandeFournisseur';
1368 } else {
1369 $classname = ucfirst($origin);
1370 }
1371
1372 $objectsrc = new $classname($db);
1373 if ($objectsrc->fetch($origin_id)) { // This include the fetch_lines
1374 $soc = new Societe($db);
1375 $soc->fetch($objectsrc->socid);
1376
1377 $author = new User($db);
1378 $author->fetch($objectsrc->user_author_id);
1379
1380 if (isModEnabled('stock')) {
1381 $entrepot = new Entrepot($db);
1382 }
1383
1384 print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
1385 print '<input type="hidden" name="token" value="'.newToken().'">';
1386 print '<input type="hidden" name="action" value="add">';
1387 print '<input type="hidden" name="origin" value="'.$origin.'">';
1388 print '<input type="hidden" name="origin_id" value="'.$objectsrc->id.'">';
1389 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
1390 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1391 if (GETPOSTINT('entrepot_id')) {
1392 print '<input type="hidden" name="entrepot_id" value="'.GETPOSTINT('entrepot_id').'">';
1393 }
1394
1395 print dol_get_fiche_head();
1396
1397 print '<table class="border centpercent">';
1398
1399 // Ref
1400 print '<tr><td class="titlefieldcreate fieldrequired">';
1401 if ($origin == 'supplierorder' && isModEnabled("supplier_order")) {
1402 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;
1403 }
1404 if ($origin == 'propal' && isModEnabled("propal")) {
1405 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;
1406 }
1407 print '</a></td>';
1408 print "</tr>\n";
1409
1410 // Ref client
1411 print '<tr><td>';
1412 if ($origin == 'supplier_order') {
1413 print $langs->trans('SupplierOrder');
1414 } else {
1415 print $langs->trans('RefSupplier');
1416 }
1417 print '</td><td colspan="3">';
1418 print '<input type="text" name="ref_supplier" value="'.$objectsrc->ref_supplier.'" />';
1419 print '</td>';
1420 print '</tr>';
1421
1422 // Thirdparty provider
1423 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Company').'</td>';
1424 print '<td colspan="3">'.$soc->getNomUrl(1).'</td>';
1425 print '</tr>';
1426
1427 // Project
1428 if (isModEnabled('project') && $formproject !== null) {
1429 $projectid = GETPOSTINT('projectid') ? GETPOSTINT('projectid') : 0;
1430 if (empty($projectid) && !empty($objectsrc->fk_project)) {
1431 $projectid = $objectsrc->fk_project;
1432 }
1433 if ($origin == 'project') {
1434 $projectid = ($origin_id ? $origin_id : 0);
1435 }
1436
1437 $langs->load("projects");
1438 print '<tr>';
1439 print '<td>'.$langs->trans("Project").'</td><td colspan="2">';
1440 print img_picto('', 'project', 'class="paddingright"');
1441 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');
1442 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>';
1443 print '</td>';
1444 print '</tr>';
1445 }
1446
1447 // Reception Date
1448 print '<tr><td>'.$langs->trans("DateReception").'</td>';
1449 print '<td colspan="3">';
1450 print img_picto('', 'action', 'class="pictofixedwidth"');
1451 $date_reception = ($date_reception ? $date_reception : $object->date_reception); // $date_reception comes from GETPOST
1452 print $form->selectDate($date_reception ? $date_reception : -1, 'date_reception', 1, 1, 1);
1453 print "</td>\n";
1454 print '</tr>';
1455
1456 // Date delivery planned
1457 print '<tr><td>'.$langs->trans("DateDeliveryPlanned").'</td>';
1458 print '<td colspan="3">';
1459 print img_picto('', 'action', 'class="pictofixedwidth"');
1460 $date_delivery = ($date_delivery ? $date_delivery : $objectsrc->delivery_date); // $date_delivery comes from GETPOST
1461 print $form->selectDate($date_delivery ? $date_delivery : -1, 'date_delivery', 1, 1, 1);
1462 print "</td>\n";
1463 print '</tr>';
1464
1465 // Note Public
1466 print '<tr><td>'.$langs->trans("NotePublic").'</td>';
1467 print '<td colspan="3">';
1468 $doleditor = new DolEditor('note_public', $objectsrc->note_public, '', 60, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
1469 print $doleditor->Create(1);
1470 print "</td></tr>";
1471
1472 // Note Private
1473 if ($objectsrc->note_private && !$user->socid) {
1474 print '<tr><td>'.$langs->trans("NotePrivate").'</td>';
1475 print '<td colspan="3">';
1476 $doleditor = new DolEditor('note_private', $objectsrc->note_private, '', 60, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
1477 print $doleditor->Create(1);
1478 print "</td></tr>";
1479 }
1480
1481 // Weight
1482 print '<tr><td>';
1483 print $langs->trans("Weight");
1484 print '</td><td colspan="3"><input name="weight" size="4" value="'.GETPOST('weight').'"> ';
1485 $text = $formproduct->selectMeasuringUnits("weight_units", "weight", (string) GETPOSTINT('weight_units'), 0, 2);
1486 $htmltext = $langs->trans("KeepEmptyForAutoCalculation");
1487 print $form->textwithpicto($text, $htmltext);
1488 print '</td></tr>';
1489 // Dim
1490 print '<tr><td>';
1491 print $langs->trans("Width").' x '.$langs->trans("Height").' x '.$langs->trans("Depth");
1492 print ' </td><td colspan="3"><input name="trueWidth" size="4" value="'.GETPOST('trueWidth').'">';
1493 print ' x <input name="trueHeight" size="4" value="'.GETPOST('trueHeight').'">';
1494 print ' x <input name="trueDepth" size="4" value="'.GETPOST('trueDepth').'">';
1495 print ' ';
1496 $text = $formproduct->selectMeasuringUnits("size_units", "size", (string) GETPOSTINT('size_units'), 0, 2);
1497 $htmltext = $langs->trans("KeepEmptyForAutoCalculation");
1498 print $form->textwithpicto($text, $htmltext);
1499 print '</td></tr>';
1500
1501 // Delivery method
1502 print "<tr><td>".$langs->trans("ReceptionMethod")."</td>";
1503 print '<td colspan="3">';
1504 $recept->fetch_delivery_methods();
1505 print $form->selectarray("shipping_method_id", $recept->meths, GETPOSTINT('shipping_method_id'), 1, 0, 0, "", 1);
1506 if ($user->admin) {
1507 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1508 }
1509 print "</td></tr>\n";
1510
1511 // Tracking number
1512 print "<tr><td>".$langs->trans("TrackingNumber")."</td>";
1513 print '<td colspan="3">';
1514 print '<input name="tracking_number" size="20" value="'.GETPOST('tracking_number', 'alpha').'">';
1515 print "</td></tr>\n";
1516
1517 // Other attributes
1518 $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"', 'cols' => '3', 'socid' => $socid);
1519 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $recept, $action); // Note that $action and $objectsrc may have been modified by hook
1520 print $hookmanager->resPrint;
1521
1522 // Here $object can be of an object Reception
1523 $extrafields->fetch_name_optionals_label($object->table_element);
1524 if (empty($reshook) && !empty($extrafields->attributes[$object->table_element]['label'])) {
1525 // copy from order
1526 if ($objectsrc->fetch_optionals() > 0) {
1527 $recept->array_options = array_merge($recept->array_options, $objectsrc->array_options);
1528 }
1529 print $recept->showOptionals($extrafields, 'create', $parameters);
1530 }
1531
1532 // Incoterms
1533 if (isModEnabled('incoterm')) {
1534 print '<tr>';
1535 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $objectsrc->label_incoterms, 1).'</label></td>';
1536 print '<td colspan="3" class="maxwidthonsmartphone">';
1537 print $form->select_incoterms((!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : ''), (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : ''));
1538 print '</td></tr>';
1539 }
1540
1541 // Document model
1542 include_once DOL_DOCUMENT_ROOT.'/core/modules/reception/modules_reception.php';
1544
1545 if (is_array($list) && count($list) > 1) {
1546 print "<tr><td>".$langs->trans("DefaultModel")."</td>";
1547 print '<td colspan="3">';
1548 print $form->selectarray('model', $list, getDolGlobalString('RECEPTION_ADDON_PDF'));
1549 print "</td></tr>\n";
1550 }
1551
1552 print "</table>";
1553
1554 print dol_get_fiche_end();
1555
1556 // Number of lines show on the reception card
1557 $numAsked = 0;
1558
1563 $suffix2numAsked = array();
1564 $dispatchLines = array();
1565
1566 foreach ($_POST as $key => $value) {
1567 // If create form is coming from the button "Create Reception" of previous page
1568
1569 // without batch module enabled or product with no lot/serial
1570 $reg = array();
1571 if (preg_match('/^product_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
1572 $numAsked++;
1573 $paramSuffix = $reg[1] . '_' . $reg[2];
1574 $suffix2numAsked[$paramSuffix] = $numAsked;
1575
1576 // $numline=$reg[2] + 1; // line of product
1577 $numline = $numAsked;
1578
1579 $prod = "product_" . $paramSuffix;
1580 $qty = "qty_" . $paramSuffix;
1581 $ent = "entrepot_" . $paramSuffix;
1582 $pu = "pu_" . $paramSuffix; // This is unit price including discount
1583 $fk_commandefourndet = "fk_commandefourndet_" . $paramSuffix;
1584 $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));
1585 }
1586
1587 // with batch module enabled and product with lot/serial
1588 if (preg_match('/^product_batch_([0-9]+)_([0-9]+)$/i', $key, $reg)) {
1589 $numAsked++;
1590 $paramSuffix = $reg[1] . '_' . $reg[2];
1591 $suffix2numAsked[$paramSuffix] = $numAsked;
1592
1593 // eat-by date dispatch
1594 // $numline=$reg[2] + 1; // line of product
1595 $numline = $numAsked;
1596
1597 $prod = 'product_batch_' . $paramSuffix;
1598 $qty = 'qty_' . $paramSuffix;
1599 $ent = 'entrepot_' . $paramSuffix;
1600 $pu = 'pu_' . $paramSuffix;
1601 $lot = 'lot_number_' . $paramSuffix;
1602 $dDLUO = dol_mktime(12, 0, 0, GETPOSTINT('dluo_'.$paramSuffix.'month'), GETPOSTINT('dluo_'.$paramSuffix.'day'), GETPOSTINT('dluo_'.$paramSuffix.'year'));
1603 $dDLC = dol_mktime(12, 0, 0, GETPOSTINT('dlc_'.$paramSuffix.'month'), GETPOSTINT('dlc_'.$paramSuffix.'day'), GETPOSTINT('dlc_'.$paramSuffix.'year'));
1604 $fk_commandefourndet = 'fk_commandefourndet_'.$paramSuffix;
1605 $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));
1606 }
1607
1608 // If create form is coming from same page, it means that post was sent but an error occurred
1609 if (preg_match('/^productl([0-9]+)$/i', $key, $reg)) {
1610 $numAsked++;
1611 $paramSuffix = $reg[1];
1612 $suffix2numAsked[$paramSuffix] = $numAsked;
1613
1614 // eat-by date dispatch
1615 // $numline=$reg[2] + 1; // line of product
1616 $numline = $numAsked;
1617
1618 $prod = 'productid'.$paramSuffix;
1619 $comment = 'comment'.$paramSuffix;
1620 $qty = 'qtyl'.$paramSuffix;
1621 $ent = 'entl'.$paramSuffix;
1622 $pu = 'pul'.$paramSuffix;
1623 $lot = 'batch'.$paramSuffix;
1624 $dDLUO = dol_mktime(12, 0, 0, GETPOSTINT('dluo'.$paramSuffix.'month'), GETPOSTINT('dluo'.$paramSuffix.'day'), GETPOSTINT('dluo'.$paramSuffix.'year'));
1625 $dDLC = dol_mktime(12, 0, 0, GETPOSTINT('dlc'.$paramSuffix.'month'), GETPOSTINT('dlc'.$paramSuffix.'day'), GETPOSTINT('dlc'.$paramSuffix.'year'));
1626 $fk_commandefourndet = 'fk_commandefournisseurdet'.$paramSuffix;
1627 $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));
1628 }
1629 }
1630
1631 // If extrafield values are passed in the HTTP query, assign them to the correct dispatch line
1632 // Note that if an extrafield with the same name exists in the origin supplier order line, the value
1633 // from the HTTP query will be ignored
1634 foreach ($suffix2numAsked as $suffix => $n) {
1635 $dispatchLines[$n]['array_options'] = $extrafields->getOptionalsFromPost('receptiondet_batch', '_' . $suffix, '');
1636 }
1637
1638 $reshook = $hookmanager->executeHooks('dataProcessing', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1639 if ($reshook < 0) {
1640 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1641 } elseif (empty($reshook)) {
1642 // Only merge if resArray is a valid, non-empty array
1643 if (is_array($hookmanager->resArray) && !empty($hookmanager->resArray)) {
1644 // Check if the merge would overwrite valid data with NULL
1645 $tempMerged = array_merge($dispatchLines, $hookmanager->resArray);
1646
1647 // Sanity check: ensure our existing keys are still valid arrays
1648 $corrupted = false;
1649 foreach ($dispatchLines as $idx => $val) {
1650 if (!is_array($tempMerged[$idx]) || !isset($tempMerged[$idx]['fk_commandefourndet'])) {
1651 $corrupted = true;
1652 break;
1653 }
1654 }
1655
1656 if (!$corrupted) {
1657 $dispatchLines = $tempMerged;
1658 } else {
1659 // If merge corrupted data, ignore the hook result and keep original
1660 error_log("WARNING: Hook dataProcessing returned invalid data, ignoring merge.");
1661 }
1662 }
1663 } elseif ($reshook > 0) {
1664 // $resArray starts from [0], we need $dispatchLines to start from [1], so we shift it
1665 $dispatchLines = $hookmanager->resArray;
1666 array_unshift($dispatchLines, null);
1667 unset($dispatchLines[0]);
1668 $numAsked = count($dispatchLines);
1669 }
1670
1671 print '<script type="text/javascript">
1672 jQuery(document).ready(function() {
1673 jQuery("#autofill").click(function(event) {
1674 event.preventDefault();';
1675 $i = 1;
1676 while ($i <= $numAsked) {
1677 print 'jQuery("#qtyl'.$i.'").val(jQuery("#qtyasked'.$i.'").val() - jQuery("#qtydelivered'.$i.'").val());'."\n";
1678 $i++;
1679 }
1680 print '});
1681 jQuery("#autoreset").click(function(event) {
1682 event.preventDefault();';
1683 $i = 1;
1684 while ($i <= $numAsked) {
1685 print 'jQuery("#qtyl'.$i.'").val(0);'."\n";
1686 $i++;
1687 }
1688 print '});
1689 });
1690 </script>';
1691
1692 print '<br>';
1693
1694 print '<table class="noborder centpercent">';
1695
1696 // Load receptions already done for same order
1697 $objectsrc->loadReceptions();
1698
1699 if ($numAsked) {
1700 print '<tr class="liste_titre">';
1701 print '<td>'.$langs->trans("Description").'</td>';
1702 print '<td>'.$langs->trans("Comment").'</td>';
1703 print '<td class="center">'.$langs->trans("QtyOrdered").'</td>';
1704 print '<td class="center">'.$langs->trans("QtyReceived").'</td>';
1705 print '<td class="center">'.$langs->trans("QtyToReceive");
1706 if (getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
1707 print '<td>'.$langs->trans("BuyingPrice").'</td>';
1708 }
1709 if (!isModEnabled('productbatch')) {
1710 print ' <br><center><a href="#" id="autofill"><span class="fas fa-fill pictofixedwidth" style=""></span> '.$langs->trans("Fill").'</a>';
1711 print ' &nbsp; &nbsp; <a href="#" id="autoreset"><span class="fas fa-eraser pictofixedwidth" style=""></span>'.$langs->trans("Reset").'</a></center><br>';
1712 }
1713 print '</td>';
1714 if (isModEnabled('stock')) {
1715 print '<td class="left">'.$langs->trans("Warehouse").' ('.$langs->trans("Stock").')</td>';
1716 }
1717 if (isModEnabled('productbatch')) {
1718 print '<td class="left">'.$langs->trans("batch_number").'</td>';
1719 if (!getDolGlobalInt('PRODUCT_DISABLE_SELLBY')) {
1720 print '<td class="left">'.$langs->trans("SellByDate").'</td>';
1721 }
1722 if (!getDolGlobalInt('PRODUCT_DISABLE_EATBY')) {
1723 print '<td class="left">'.$langs->trans("EatByDate").'</td>';
1724 }
1725 }
1726
1727 $parameters = array();
1728 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1729 if ($reshook < 0) {
1730 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1731 } else {
1732 print $hookmanager->resPrint;
1733 }
1734 print "</tr>\n";
1735 }
1736
1737 // $objectsrc->lines contains the line of the purchase order
1738 // $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.
1739
1740 $arrayofpurchaselinealreadyoutput = array();
1741
1742 // $_POST contains fk_commandefourndet_X_Y where Y is num of product line and X is number of split lines
1743 $indiceAsked = 1;
1744 while ($indiceAsked <= $numAsked) { // Loop on $dispatchLines. Warning: $dispatchLines must be sorted by fk_commandefourndet (it is a regroupment key on output)
1745 $product = new Product($db);
1746 $line = new CommandeFournisseurLigne($db); // By default
1747
1748 // We search the purchase order line that is linked to the dispatchLines
1749 foreach ($objectsrc->lines as $supplierLine) {
1750 if ($dispatchLines[$indiceAsked]['fk_commandefourndet'] == $supplierLine->id) {
1751 $line = $supplierLine;
1752 break;
1753 }
1754 }
1755
1756 // Now $line can be CommandeFournisseurLigne but could be other type of line.
1757
1758 // Show product and description
1759 $type = $line->product_type ? $line->product_type : $line->fk_product_type;
1760 // Try to enhance type detection using date_start and date_end for free lines where type was not saved.
1761 if (!empty($line->date_start)) {
1762 $type = 1;
1763 }
1764 if (!empty($line->date_end)) {
1765 $type = 1;
1766 }
1767
1768 print '<!-- line fk_commandefourndet='.$line->id.' for product='.$line->fk_product.' -->'."\n";
1769 print '<tr class="oddeven">'."\n";
1770
1771 // Product label
1772 if ($line->fk_product > 0) { // If predefined product
1773 $product->fetch($line->fk_product);
1774 $product->load_stock('warehouseopen'); // Load all $product->stock_warehouse[idwarehouse]->detail_batch
1775 //var_dump($product->stock_warehouse[1]);
1776 //var_dump($dispatchLines[$indiceAsked]);
1777
1778 print '<td>';
1779 print '<a name="'.$line->id.'"></a>'; // Anchor to return to the line
1780
1781 print '<input type="hidden" name="productl'.$indiceAsked.'" value="'.$line->fk_product.'">';
1782
1783 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1784 print '<input type="hidden" name="productid'.$indiceAsked.'" value="'.$line->fk_product.'">';
1785
1786 // Show product and description
1787 $product_static = $product;
1788
1789 $text = $product_static->getNomUrl(1);
1790 $text .= ' - '.(!empty($line->label) ? $line->label : $line->product_label);
1791 $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($line->desc));
1792 print $form->textwithtooltip($text, $description, 3, 0, '', (string) $i);
1793
1794 // Show range
1795 print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end));
1796
1797 // Add description in form
1798 if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
1799 print ($line->desc && $line->desc != $line->product_label) ? '<br>'.dol_htmlentitiesbr($line->desc) : '';
1800 }
1801 }
1802 print '</td>';
1803 } else {
1804 print "<td>";
1805 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1806 if ($type == 1) {
1807 $text = img_object($langs->trans('Service'), 'service');
1808 } else {
1809 $text = img_object($langs->trans('Product'), 'product');
1810 }
1811
1812 if (!empty($line->label)) {
1813 $text .= ' <strong>'.$line->label.'</strong>';
1814 print $form->textwithtooltip($text, $line->desc, 3, 0, '', (string) $i);
1815 } else {
1816 print $text.' '.nl2br($line->desc);
1817 }
1818
1819 // Show range
1820 print_date_range($db->jdate($line->date_start), $db->jdate($line->date_end));
1821 }
1822 print "</td>\n";
1823 }
1824
1825 // Comment
1826 //$defaultcomment = 'Line create from order line id '.$line->id;
1827 $defaultcomment = $dispatchLines[$indiceAsked]['comment'];
1828 print '<td>';
1829 print '<input type="text" class="maxwidth100" name="comment'.$indiceAsked.'" value="'.$defaultcomment.'">';
1830 print '</td>';
1831
1832 // Qty in source purchase order line
1833 print '<td class="center">';
1834 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1835 print $line->qty;
1836 }
1837 print '<input type="hidden" name="fk_commandefournisseurdet'.$indiceAsked.'" value="'.$line->id.'">';
1838 print '<input type="hidden" name="pul'.$indiceAsked.'" value="'.$line->subprice.'">';
1839 print '<input name="qtyasked'.$indiceAsked.'" id="qtyasked'.$indiceAsked.'" type="hidden" value="'.$line->qty.'">';
1840 print '</td>';
1841 $qtyProdCom = $line->qty;
1842
1843 // Qty already received
1844 print '<td class="center">';
1845 $quantityDelivered = isset($objectsrc->receptions[$line->id]) ? $objectsrc->receptions[$line->id] : 0;
1846 if (! array_key_exists($line->id, $arrayofpurchaselinealreadyoutput)) { // Add test to avoid to show qty twice
1847 print $quantityDelivered;
1848 }
1849 print '<input name="qtydelivered'.$indiceAsked.'" id="qtydelivered'.$indiceAsked.'" type="hidden" value="'.$quantityDelivered.'">';
1850 print '</td>';
1851
1852
1853 if ($line->product_type == 1 && !getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1854 $quantityToBeDelivered = 0;
1855 } else {
1856 $quantityToBeDelivered = $dispatchLines[$indiceAsked]['qty'];
1857 }
1858 $warehouse_id = $dispatchLines[$indiceAsked]['ent'];
1859
1860
1861 $warehouseObject = null;
1862 if (isModEnabled('stock')) {
1863 // If warehouse was already selected or if product is not a predefined, we go into this part with no multiwarehouse selection
1864 print '<!-- Case warehouse already known or product not a predefined product -->';
1865 if (array_key_exists($dispatchLines[$indiceAsked]['ent'], $product->stock_warehouse)) {
1866 $stock = +$product->stock_warehouse[$dispatchLines[$indiceAsked]['ent']]->real; // Convert to number
1867 }
1868 $deliverableQty = $dispatchLines[$indiceAsked]['qty'];
1869 $cost_price = $dispatchLines[$indiceAsked]['pu'];
1870
1871 // Quantity to send
1872 print '<td class="center">';
1873 if ($line->product_type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1874 if (GETPOSTINT('qtyl'.$indiceAsked)) {
1875 $defaultqty = GETPOSTINT('qtyl'.$indiceAsked);
1876 }
1877 print '<input name="idl'.$indiceAsked.'" type="hidden" value="'.$line->id.'">';
1878 print '<input class="right" name="qtyl'.$indiceAsked.'" id="qtyl'.$indiceAsked.'" type="text" size="4" value="'.$deliverableQty.'">';
1879 } else {
1880 print $langs->trans("NA");
1881 }
1882 print '</td>';
1883
1884 if (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
1885 print '<td>';
1886 print '<input class="width75 right" name="cost_price'.$indiceAsked.'" id="cost_price'.$indiceAsked.'" value="'.price($cost_price).'">';
1887 print '</td>';
1888 }
1889
1890 // Stock
1891 if (isModEnabled('stock')) {
1892 print '<td class="left">';
1893 if ($line->product_type == Product::TYPE_PRODUCT || getDolGlobalString('STOCK_SUPPORTS_SERVICES')) { // Type of product need stock change ?
1894 // Show warehouse combo list
1895 $ent = "entl".$indiceAsked;
1896 $idl = "idl".$indiceAsked;
1897 $tmpentrepot_id = is_numeric(GETPOST($ent)) ? GETPOSTINT($ent) : $warehouse_id;
1898 if ($line->fk_product > 0) {
1899 print '<!-- Show warehouse selection -->';
1900 print $formproduct->selectWarehouses($tmpentrepot_id, 'entl'.$indiceAsked, '', 0, 0, $line->fk_product, '', 1);
1901 }
1902 } else {
1903 print $langs->trans("Service");
1904 }
1905 print '</td>';
1906 }
1907
1908 if (isModEnabled('productbatch')) {
1909 if (!empty($product->status_batch)) {
1910 print '<td><input name="batch'.$indiceAsked.'" value="'.$dispatchLines[$indiceAsked]['lot'].'"></td>';
1911 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1912 print '<td class="nowraponall">';
1913 print $form->selectDate($dispatchLines[$indiceAsked]['DLC'], 'dlc'.$indiceAsked, 0, 0, 1, "");
1914 print '</td>';
1915 }
1916 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1917 print '<td class="nowraponall">';
1918 print $form->selectDate($dispatchLines[$indiceAsked]['DLUO'], 'dluo'.$indiceAsked, 0, 0, 1, "");
1919 print '</td>';
1920 }
1921 } else {
1922 print '<td colspan="3"></td>';
1923 }
1924 }
1925
1926 $parameters = array();
1927 $parameters['dispatchLine'] = $dispatchLines[$indiceAsked];
1928 $parameters['indiceAsked'] = $indiceAsked;
1929 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1930 if ($reshook < 0) {
1931 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1932 } else {
1933 print $hookmanager->resPrint;
1934 }
1935 }
1936
1937 $arrayofpurchaselinealreadyoutput[$line->id] = $line->id;
1938
1939 print "</tr>\n";
1940
1941 // Display lines for extrafields of the Reception line
1942 // $line is a 'CommandeFournisseurLigne', $dispatchLines contains values of Reception lines so properties of CommandeFournisseurDispatch
1943 if (!empty($extrafields)) {
1944 $colspan = 5;
1945 if (isModEnabled('productbatch')) {
1946 $colspan += 2;
1947 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
1948 $colspan += 1;
1949 }
1950 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
1951 $colspan += 1;
1952 }
1953 }
1954 $recLine = new CommandeFournisseurDispatch($db);
1955
1956 $srcLine = new CommandeFournisseurLigne($db);
1957 $srcLine->id = $line->id;
1958 $srcLine->fetch_optionals(); // fetch extrafields also available in orderline
1959
1960 if (empty($recLine->array_options) && !empty($dispatchLines[$indiceAsked]['array_options'])) {
1961 $recLine->array_options = $dispatchLines[$indiceAsked]['array_options'];
1962 }
1963 $recLine->array_options = array_merge($recLine->array_options, $srcLine->array_options);
1964
1965 print $recLine->showOptionals($extrafields, 'edit', array('style' => 'class="oddeven"', 'colspan' => $colspan), (string) $indiceAsked, '', '1');
1966 }
1967
1968 $indiceAsked++;
1969 }
1970
1971 print "</table>";
1972
1973 print '<br>';
1974
1975 print $form->buttonsSaveCancel("Create");
1976
1977 print '</form>';
1978
1979 print '<br>';
1980 } else {
1982 }
1983 }
1984} elseif ($object->id > 0) {
1985 /* *************************************************************************** */
1986 /* */
1987 /* Edit and view mode */
1988 /* */
1989 /* *************************************************************************** */
1990 $lines = $object->lines;
1991
1992 $num_prod = count($lines);
1993 $indiceAsked = 0;
1994
1995 if ($object->id <= 0) {
1996 print $langs->trans("NoRecordFound");
1997 llxFooter();
1998 exit;
1999 }
2000
2001 $typeobject = '';
2002 if (!empty($object->origin) && $object->origin_id > 0) {
2003 $typeobject = $object->origin;
2004 $origin = $object->origin;
2005 $origin_id = $object->origin_id;
2006 $object->fetch_origin(); // Load property $object->origin_object, $object->commande, $object->propal, ...
2007 }
2008
2009 $soc = new Societe($db);
2010 $soc->fetch($object->socid);
2011
2012 $res = $object->fetch_optionals();
2013
2014 $head = reception_prepare_head($object);
2015 print dol_get_fiche_head($head, 'reception', $langs->trans("Reception"), -1, 'dollyrevert');
2016
2017 $formconfirm = '';
2018
2019 // Confirm deletion
2020 if ($action == 'delete') {
2021 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('DeleteReception'), $langs->trans("ConfirmDeleteReception", $object->ref), 'confirm_delete', '', 0, 1);
2022 }
2023
2024 // Confirmation validation
2025 if ($action == 'valid') {
2026 $objectref = substr($object->ref, 1, 4);
2027 if ($objectref == 'PROV') {
2028 $numref = $object->getNextNumRef($soc);
2029 } else {
2030 $numref = (string) $object->ref;
2031 }
2032
2033 $text = $langs->trans("ConfirmValidateReception", $numref);
2034 if (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION')) {
2035 $text .= '<br>'.img_picto('', 'movement', 'class="pictofixedwidth"').$langs->trans("StockMovementWillBeRecorded").'.';
2036 } elseif (getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE')) {
2037 $text .= '<br>'.img_picto('', 'movement', 'class="pictofixedwidth"').$langs->trans("StockMovementNotYetRecorded").'.';
2038 }
2039
2040 if (isModEnabled('notification')) {
2041 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2042 $notify = new Notify($db);
2043 $text .= '<br>';
2044 $text .= $notify->confirmMessage('RECEPTION_VALIDATE', $object->socid, $object);
2045 }
2046
2047 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('ValidateReception'), $text, 'confirm_valid', '', 0, 1, 250);
2048 }
2049
2050 // Confirm cancellation
2051 if ($action == 'annuler') {
2052 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('CancelReception'), $langs->trans("ConfirmCancelReception", $object->ref), 'confirm_cancel', '', 0, 1);
2053 }
2054
2055 if (!$formconfirm) {
2056 $parameters = array('formConfirm' => $formconfirm);
2057 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2058 if (empty($reshook)) {
2059 $formconfirm .= $hookmanager->resPrint;
2060 } elseif ($reshook > 0) {
2061 $formconfirm = $hookmanager->resPrint;
2062 }
2063 }
2064
2065 // Print form confirm
2066 print $formconfirm;
2067
2068
2069 // Calculate totalWeight and totalVolume for all products
2070 // by adding weight and volume of each product line.
2071 $tmparray = $object->getTotalWeightVolume();
2072 $totalWeight = $tmparray['weight'];
2073 $totalVolume = $tmparray['volume'];
2074
2075
2076 if ($typeobject == 'commande' && $object->origin_object->id && isModEnabled('order')) {
2077 $objectsrc = new Commande($db);
2078 $objectsrc->fetch($object->origin_object->id);
2079 }
2080 if ($typeobject == 'propal' && $object->origin_object->id && isModEnabled("propal")) {
2081 $objectsrc = new Propal($db);
2082 $objectsrc->fetch($object->origin_object->id);
2083 }
2084 if (($typeobject == 'supplier_order' || $typeobject == 'CommandeFournisseur') && $object->origin_object->id && isModEnabled("supplier_order")) {
2085 $objectsrc = new CommandeFournisseur($db);
2086 $objectsrc->fetch($object->origin_object->id);
2087 }
2088 // Reception card
2089 $linkback = '<a href="'.DOL_URL_ROOT.'/reception/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
2090 $morehtmlref = '<div class="refidno">';
2091 // Ref customer reception
2092
2093 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('reception', 'creer'), 'string', '', 0, 1);
2094 $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('reception', 'creer'), 'string', '', null, null, '', 1);
2095
2096 // Thirdparty
2097 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
2098 // Project
2099 if ($origin && $origin_id > 0) {
2100 if (isModEnabled('project')) {
2101 $langs->load("projects");
2102 $morehtmlref .= '<br>';
2103 if (0) { // @phpstan-ignore-line Do not change on shipment
2104 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2105 if ($action != 'classify') {
2106 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2107 }
2108 $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');
2109 } else {
2110 if (!empty($objectsrc) && !empty($objectsrc->fk_project)) {
2111 $proj = new Project($db);
2112 $proj->fetch($objectsrc->fk_project);
2113 $morehtmlref .= $proj->getNomUrl(1);
2114 if ($proj->title) {
2115 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2116 }
2117 }
2118 }
2119 }
2120 } elseif (!$origin && getDolGlobalString('RECEPTION_STANDALONE')) {
2121 // Project
2122 if (isModEnabled('project')) {
2123 $langs->load("projects");
2124 $morehtmlref .= '<br>';
2125 if ($permissiontoadd) {
2126 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2127 if ($action != 'classify') {
2128 $morehtmlref .= '<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token=' . newToken() . '&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> ';
2129 }
2130 $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');
2131 } else {
2132 if (!empty($object->fk_project)) {
2133 $proj = new Project($db);
2134 $proj->fetch($object->fk_project);
2135 $morehtmlref .= $proj->getNomUrl(1);
2136 if ($proj->title) {
2137 $morehtmlref .= '<span class="opacitymedium"> - ' . dol_escape_htmltag($proj->title) . '</span>';
2138 }
2139 }
2140 }
2141 }
2142 }
2143 $morehtmlref .= '</div>';
2144
2145 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
2146
2147
2148 print '<div class="fichecenter">';
2149 print '<div class="fichehalfleft">';
2150 print '<div class="underbanner clearboth"></div>';
2151
2152 print '<table class="border centpercent tableforfield">';
2153
2154 // Linked documents
2155 if ($typeobject == 'commande' && $object->origin_object->id && isModEnabled('order')) {
2156 print '<tr><td>';
2157 print $langs->trans("RefOrder").'</td>';
2158 print '<td colspan="3">';
2159 print $objectsrc->getNomUrl(1, 'commande');
2160 print "</td>\n";
2161 print '</tr>';
2162 }
2163 if ($typeobject == 'propal' && $object->origin_object->id && isModEnabled("propal")) {
2164 print '<tr><td>';
2165 print $langs->trans("RefProposal").'</td>';
2166 print '<td colspan="3">';
2167 print $objectsrc->getNomUrl(1, 'reception');
2168 print "</td>\n";
2169 print '</tr>';
2170 }
2171 if (($typeobject == 'supplier_order' || $typeobject == 'CommandeFournisseur') && $object->origin_object->id && isModEnabled("propal")) {
2172 print '<tr><td>';
2173 print $langs->trans("SupplierOrder").'</td>';
2174 print '<td colspan="3">';
2175 print $objectsrc->getNomUrl(1, 'reception');
2176 print "</td>\n";
2177 print '</tr>';
2178 }
2179
2180 // Date creation
2181 print '<tr><td class="titlefield">'.$langs->trans("DateCreation").'</td>';
2182 print '<td colspan="3">'.dol_print_date($object->date_creation, "dayhour", "tzuserrel")."</td>\n";
2183 print '</tr>';
2184
2185 // Reception Date
2186 print '<tr><td height="10">';
2187 print '<table class="nobordernopadding centpercent"><tr><td>';
2188 print $langs->trans('DateReception');
2189 print '</td>';
2190 if ($action != 'editdate_reception') {
2191 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>';
2192 }
2193 print '</tr></table>';
2194 print '</td><td>';
2195 if ($action == 'editdate_reception') {
2196 print '<form name="setdate_reception" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
2197 print '<input type="hidden" name="token" value="' . newToken() . '">';
2198 print '<input type="hidden" name="action" value="setdate_reception">';
2199 print $form->selectDate($object->date_reception ? $object->date_reception : -1, 'recep_', 1, 1, 0, "setdate_reception", 1, 0);
2200 print '<input type="submit" class="button button-edit smallpaddingimp" value="' . $langs->trans('Modify') . '">';
2201 print '</form>';
2202 } else {
2203 print $object->date_reception ? dol_print_date($object->date_reception, 'dayhour') : '&nbsp;';
2204 }
2205 print '</td>';
2206 print '</tr>';
2207
2208 // Delivery date planned
2209 print '<tr><td height="10">';
2210 print '<table class="nobordernopadding" width="100%"><tr><td>';
2211 print $langs->trans('DateDeliveryPlanned');
2212 print '</td>';
2213
2214 if ($action != 'editdate_livraison' && $permissiontoadd) {
2215 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>';
2216 }
2217 print '</tr></table>';
2218 print '</td><td colspan="2">';
2219 if ($action == 'editdate_livraison') {
2220 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2221 print '<input type="hidden" name="token" value="'.newToken().'">';
2222 print '<input type="hidden" name="action" value="setdate_livraison">';
2223 print $form->selectDate($object->date_delivery ? $object->date_delivery : -1, 'liv_', 1, 1, 0, "setdate_livraison", 1, 0);
2224 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
2225 print '</form>';
2226 } else {
2227 print $object->date_delivery ? dol_print_date($object->date_delivery, 'dayhour') : '&nbsp;';
2228 }
2229 print '</td>';
2230 print '</tr>';
2231
2232 // Weight
2233 print '<tr><td>';
2234 print $form->editfieldkey("Weight", 'trueWeight', (string) $object->trueWeight, $object, $user->hasRight('reception', 'creer'));
2235 print '</td><td colspan="3">';
2236
2237 if ($action == 'edittrueWeight') {
2238 print '<form name="settrueweight" action="'.$_SERVER["PHP_SELF"].'" method="post">';
2239 print '<input name="action" value="settrueWeight" type="hidden">';
2240 print '<input name="id" value="'.$object->id.'" type="hidden">';
2241 print '<input type="hidden" name="token" value="'.newToken().'">';
2242 print '<input id="trueWeight" name="trueWeight" value="'.$object->trueWeight.'" type="text">';
2243 print $formproduct->selectMeasuringUnits("weight_units", "weight", (string) $object->weight_units, 0, 2);
2244 print ' <input class="button" name="modify" value="'.$langs->trans("Modify").'" type="submit">';
2245 print ' <input class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'" type="submit">';
2246 print '</form>';
2247 } else {
2248 print $object->trueWeight;
2249 print ($object->trueWeight && $object->weight_units != '') ? ' '.measuringUnitString(0, "weight", $object->weight_units) : '';
2250 }
2251
2252 // Calculated
2253 if ($totalWeight > 0) {
2254 if (!empty($object->trueWeight)) {
2255 print ' ('.$langs->trans("SumOfProductWeights").': ';
2256 }
2257 print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, getDolGlobalInt('MAIN_WEIGHT_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_WEIGHT_DEFAULT_UNIT', 'no'));
2258 if (!empty($object->trueWeight)) {
2259 print ')';
2260 }
2261 }
2262 print '</td></tr>';
2263
2264 // Width
2265 print '<tr><td>'.$form->editfieldkey("Width", 'trueWidth', (string) $object->trueWidth, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
2266 print $form->editfieldval("Width", 'trueWidth', $object->trueWidth, $object, $user->hasRight('reception', 'creer'));
2267 print ($object->trueWidth && $object->width_units != '') ? ' '.measuringUnitString(0, "size", $object->width_units) : '';
2268 print '</td></tr>';
2269
2270 // Height
2271 print '<tr><td>'.$form->editfieldkey("Height", 'trueHeight', (string) $object->trueHeight, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
2272 if ($action == 'edittrueHeight') {
2273 print '<form name="settrueHeight" action="'.$_SERVER["PHP_SELF"].'" method="post">';
2274 print '<input name="action" value="settrueHeight" type="hidden">';
2275 print '<input name="id" value="'.$object->id.'" type="hidden">';
2276 print '<input type="hidden" name="token" value="'.newToken().'">';
2277 print '<input id="trueHeight" name="trueHeight" value="'.$object->trueHeight.'" type="text">';
2278 print $formproduct->selectMeasuringUnits("size_units", "size", $object->size_units, 0, 2);
2279 print ' <input class="button" name="modify" value="'.$langs->trans("Modify").'" type="submit">';
2280 print ' <input class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'" type="submit">';
2281 print '</form>';
2282 } else {
2283 print $object->trueHeight;
2284 print ($object->trueHeight && $object->height_units != '') ? ' '.measuringUnitString(0, "size", $object->height_units) : '';
2285 }
2286
2287 print '</td></tr>';
2288
2289 // Depth
2290 print '<tr><td>'.$form->editfieldkey("Depth", 'trueDepth', (string) $object->trueDepth, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
2291 print $form->editfieldval("Depth", 'trueDepth', $object->trueDepth, $object, $user->hasRight('reception', 'creer'));
2292 print ($object->trueDepth && $object->depth_units != '') ? ' '.measuringUnitString(0, "size", $object->depth_units) : '';
2293 print '</td></tr>';
2294
2295 // Volume
2296 print '<tr><td>';
2297 print $langs->trans("Volume");
2298 print '</td>';
2299 print '<td colspan="3">';
2300 $calculatedVolume = 0;
2301 $volumeUnit = 0;
2302 if ($object->trueWidth && $object->trueHeight && $object->trueDepth) {
2303 $calculatedVolume = ($object->trueWidth * $object->trueHeight * $object->trueDepth);
2304 $volumeUnit = $object->size_units * 3;
2305 }
2306 // If reception volume not defined we use sum of products
2307 if ($calculatedVolume > 0) {
2308 if ($volumeUnit < 50) {
2309 print showDimensionInBestUnit($calculatedVolume, $volumeUnit, "volume", $langs, getDolGlobalInt('MAIN_VOLUME_DEFAULT_ROUND', -1), getDolGlobalString("MAIN_VOLUME_DEFAULT_UNIT", 'no'));
2310 } else {
2311 print $calculatedVolume.' '.measuringUnitString(0, "volume", $volumeUnit);
2312 }
2313 }
2314 if ($totalVolume > 0) {
2315 if ($calculatedVolume) {
2316 print ' ('.$langs->trans("SumOfProductVolumes").': ';
2317 }
2318 print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, getDolGlobalInt('MAIN_VOLUME_DEFAULT_ROUND', -1), getDolGlobalString('MAIN_VOLUME_DEFAULT_UNIT', 'no'));
2319 //if (empty($calculatedVolume)) print ' ('.$langs->trans("Calculated").')';
2320 if ($calculatedVolume) {
2321 print ')';
2322 }
2323 }
2324 print "</td>\n";
2325 print '</tr>';
2326
2327 // Other attributes
2328 $cols = 2;
2329
2330 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2331
2332 print '</table>';
2333
2334 print '</div>';
2335 print '<div class="fichehalfright">';
2336 print '<div class="underbanner clearboth"></div>';
2337
2338 print '<table class="border centpercent tableforfield">';
2339
2340 // Reception method
2341 print '<tr><td height="10">';
2342 print '<table class="nobordernopadding centpercent"><tr><td>';
2343 print $langs->trans('ReceptionMethod');
2344 print '</td>';
2345
2346 if ($action != 'editshipping_method_id' && $permissiontoadd) {
2347 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>';
2348 }
2349 print '</tr></table>';
2350 print '</td><td colspan="2">';
2351 if ($action == 'editshipping_method_id') {
2352 print '<form name="setshipping_method_id" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2353 print '<input type="hidden" name="token" value="'.newToken().'">';
2354 print '<input type="hidden" name="action" value="setshipping_method_id">';
2355 $object->fetch_delivery_methods();
2356 print $form->selectarray("shipping_method_id", $object->meths, $object->shipping_method_id, 1, 0, 0, "", 1);
2357 if ($user->admin) {
2358 print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
2359 }
2360 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
2361 print '</form>';
2362 } else {
2363 if ($object->shipping_method_id > 0) {
2364 // Get code using getLabelFromKey
2365 $code = $langs->getLabelFromKey($db, (string) $object->shipping_method_id, 'c_shipment_mode', 'rowid', 'code');
2366 print $langs->trans("SendingMethod".strtoupper($code));
2367 }
2368 }
2369 print '</td>';
2370 print '</tr>';
2371
2372 // Tracking Number
2373 print '<tr><td class="titlefield">'.$form->editfieldkey("TrackingNumber", 'tracking_number', $object->tracking_number, $object, $user->hasRight('reception', 'creer')).'</td><td colspan="3">';
2374 print $form->editfieldval("TrackingNumber", 'tracking_number', $object->tracking_url, $object, $user->hasRight('reception', 'creer'), 'safehtmlstring', $object->tracking_number);
2375 print '</td></tr>';
2376
2377 // Incoterms
2378 if (isModEnabled('incoterm')) {
2379 print '<tr><td>';
2380 print '<table width="100%" class="nobordernopadding"><tr><td>';
2381 print $langs->trans('IncotermLabel');
2382 print '<td><td class="right">';
2383 if ($user->hasRight('reception', 'creer')) {
2384 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/reception/card.php?id='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
2385 } else {
2386 print '&nbsp;';
2387 }
2388 print '</td></tr></table>';
2389 print '</td>';
2390 print '<td colspan="3">';
2391 if ($action != 'editincoterm') {
2392 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
2393 } else {
2394 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
2395 }
2396 print '</td></tr>';
2397 }
2398
2399 print "</table>";
2400
2401 print '</div>';
2402 print '</div>';
2403
2404 print '<div class="clearboth"></div>';
2405
2406 /*
2407 * Lines of simple reception
2408 */
2409 if (!$origin_id && getDolGlobalString('RECEPTION_STANDALONE')) {
2410 if (!empty($object->table_element_line)) {
2411 // Show object lines
2412 $result = $object->getLinesArray();
2413
2414 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
2415 <input type="hidden" name="token" value="' . newToken().'">
2416 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
2417 <input type="hidden" name="mode" value="">
2418 <input type="hidden" name="page_y" value="">
2419 <input type="hidden" name="id" value="' . $object->id.'">
2420 ';
2421
2422 if (!empty($conf->use_javascript_ajax) && $object->status == $object::STATUS_DRAFT) {
2423 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
2424 }
2425
2426 print '<div class="div-table-responsive-no-min">';
2427 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
2428 print '<table id="tablelines" class="noborder noshadow" width="100%">';
2429 }
2430
2431 if (!empty($object->lines)) {
2432 $object->printObjectLines($action, $mysoc, null, GETPOSTINT('lineid'), 0, '/reception/tpl');
2433 }
2434
2435 // Form to add new line
2436 if ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines') {
2437 if ($action != 'editline') {
2438 // Add products/services form
2439
2440 $parameters = array();
2441 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2442 if ($reshook < 0) {
2443 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2444 }
2445 if (empty($reshook)) {
2446 $object->formAddObjectLine(0, $mysoc, $soc);
2447 }
2448 }
2449 }
2450
2451 if (!empty($object->lines) || ($object->status == Reception::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
2452 print '</table>';
2453 }
2454 print '</div>';
2455
2456 print "</form>\n";
2457 }
2458 } elseif (!empty($object->origin) && $object->origin_id > 0) {
2459 // Lines of products of origin
2460 if ($action == 'editline') {
2461 print '<form name="updateline" id="updateline" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;lineid='.$line_id.'" method="POST">
2462 <input type="hidden" name="token" value="' . newToken().'">
2463 <input type="hidden" name="action" value="updateline">
2464 <input type="hidden" name="mode" value="">
2465 <input type="hidden" name="id" value="' . $object->id.'">';
2466 }
2467 print '<br><br>';
2468
2469 print '<div class="div-table-responsive-no-min">';
2470 print '<table id="tablelines" class="noborder centpercent">';
2471 print '<thead>';
2472 print '<tr class="liste_titre">';
2473 // #
2474 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
2475 print '<td width="5" class="center">&nbsp;</td>';
2476 }
2477 // Product/Service
2478 print '<td>'.$langs->trans("Products").'</td>';
2479 // Comment
2480 print '<td>'.$langs->trans("Comment").'</td>';
2481 // Qty
2482 print '<td class="center">'.$langs->trans("QtyOrdered").'</td>';
2483 if ($origin && $origin_id > 0) {
2484 print '<td class="center">'.$langs->trans("QtyInOtherReceptions").'</td>';
2485 }
2486
2487 $editColspan = 3;
2488 if ($action == 'editline') {
2489 if (!isModEnabled('stock')) {
2490 $editColspan--;
2491 }
2492 if (empty($conf->productbatch->enabled)) {
2493 $editColspan--;
2494 }
2495 print '<td class="center" colspan="'.$editColspan.'">';
2496 if ($object->statut <= 1) {
2497 print $langs->trans("QtyToReceive").' - ';
2498 } else {
2499 print $langs->trans("QtyReceived").' - ';
2500 }
2501 if (isModEnabled('stock')) {
2502 print $langs->trans("WarehouseTarget").' - ';
2503 }
2504 if (isModEnabled('productbatch')) {
2505 print $langs->trans("Batch");
2506 }
2507 print '</td>';
2508
2509 $parameters = array();
2510 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2511 if ($reshook < 0) {
2512 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2513 } else {
2514 print $hookmanager->resPrint;
2515 }
2516 } else {
2517 $statusreceived = $object::STATUS_CLOSED;
2518 if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION")) {
2519 $statusreceived = $object::STATUS_VALIDATED;
2520 }
2521 if (getDolGlobalInt("STOCK_CALCULATE_ON_RECEPTION_CLOSE")) {
2522 $statusreceived = $object::STATUS_CLOSED;
2523 }
2524 if ($object->statut < $statusreceived) {
2525 print '<td class="center">'.$langs->trans("QtyToReceive").'</td>';
2526 } else {
2527 print '<td class="center">'.$langs->trans("QtyReceived").'</td>';
2528 }
2529 if (isModEnabled('stock')) {
2530 print '<td class="left">'.$langs->trans("WarehouseTarget").'</td>';
2531 }
2532
2533 if (isModEnabled('productbatch')) {
2534 print '<td class="left">'.$langs->trans("Batch").'</td>';
2535 }
2536
2537 $parameters = array();
2538 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2539 if ($reshook < 0) {
2540 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2541 } else {
2542 print $hookmanager->resPrint;
2543 }
2544 }
2545 print '<td class="center">'.$langs->trans("CalculatedWeight").'</td>';
2546 print '<td class="center">'.$langs->trans("CalculatedVolume").'</td>';
2547 //print '<td class="center">'.$langs->trans("Size").'</td>';
2548 if ($object->statut == 0) {
2549 print '<td class="linecoledit"></td>';
2550 print '<td class="linecoldelete" width="10"></td>';
2551 }
2552 print "</tr>\n";
2553 print '</thead>';
2554
2555 $var = false;
2556
2557 $outputlangs = $langs;
2558 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
2559 $object->fetch_thirdparty();
2560 $newlang = '';
2561 if (/* empty($newlang) && */ GETPOST('lang_id', 'aZ09')) {
2562 $newlang = GETPOST('lang_id', 'aZ09');
2563 }
2564 if (empty($newlang)) {
2565 $newlang = $object->thirdparty->default_lang;
2566 }
2567 if (!empty($newlang)) {
2568 $outputlangs = new Translate("", $conf);
2569 $outputlangs->setDefaultLang($newlang);
2570 }
2571 }
2572
2573 // Get list of products already sent for same source object into $alreadysent
2574 $alreadysent = array();
2575
2576 if (empty($origin) || $origin == 'order_supplier') {
2577 $origin = 'supplier_order';
2578 }
2579
2580 if ($origin_id > 0) {
2581 $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";
2582 $sql .= ", ed.rowid as receptionline_id, ed.qty, ed.fk_reception as reception_id, ed.fk_entrepot";
2583 $sql .= ", e.rowid as reception_id, e.ref as reception_ref, e.date_creation, e.date_valid, e.date_delivery, e.date_reception";
2584 $sql .= ', p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.tobatch as product_tobatch';
2585 $sql .= ', p.description as product_desc';
2586 $sql .= " FROM ".MAIN_DB_PREFIX."receptiondet_batch as ed";
2587 $sql .= ", ".MAIN_DB_PREFIX."reception as e";
2588 $sql .= ", ".MAIN_DB_PREFIX.(($origin == 'supplier_order') ? 'commande_fournisseur' : $origin)."det as obj";
2589 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON obj.fk_product = p.rowid";
2590 $sql .= " WHERE e.entity IN (".getEntity('reception').")";
2591 $sql .= " AND obj.fk_commande = ".((int) $origin_id);
2592 $sql .= " AND obj.rowid = ed.fk_elementdet";
2593 $sql .= " AND ed.fk_reception = e.rowid";
2594 $sql .= " AND ed.fk_reception !=".((int) $object->id);
2595 $sql .= " ORDER BY obj.fk_product";
2596
2597 dol_syslog("get list of reception lines", LOG_DEBUG);
2598 $resql = $db->query($sql);
2599 if ($resql) {
2600 $num = $db->num_rows($resql);
2601 $i = 0;
2602
2603 while ($i < $num) {
2604 $obj = $db->fetch_object($resql);
2605 if ($obj) {
2606 // $obj->rowid is rowid in $origin."det" table
2607 $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);
2608 }
2609 $i++;
2610 }
2611 }
2612 //var_dump($alreadysent);
2613 }
2614
2615 $arrayofpurchaselinealreadyoutput = array();
2616
2617 // Loop on each product to send/sent. Warning: $lines must be sorted by ->fk_commandefourndet (it is a regroupment key on output)
2618 print '<tbody>';
2619 for ($i = 0; $i < $num_prod; $i++) {
2620 print '<!-- origin line id = '.(!empty($lines[$i]->origin_line_id) ? $lines[$i]->origin_line_id : 0).' -->'; // id of order line
2621 print '<tr class="oddeven" id="row-'.$lines[$i]->id.'" data-id="'.$lines[$i]->id.'" data-element="'.$lines[$i]->element.'">';
2622
2623 // #
2624 if (getDolGlobalString('MAIN_VIEW_LINE_NUMBER')) {
2625 print '<td class="center">'.($i + 1).'</td>';
2626 }
2627
2628 // Predefined product or service
2629 if ($lines[$i]->fk_product > 0) {
2630 // Define output language
2631 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
2632 $prod = new Product($db);
2633 $prod->fetch($lines[$i]->fk_product);
2634 $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["label"])) ? $prod->multilangs[$outputlangs->defaultlang]["label"] : $lines[$i]->product->label;
2635 } else {
2636 $label = (!empty($lines[$i]->product->label) ? $lines[$i]->product->label : $lines[$i]->product->product_label);
2637 }
2638
2639 print '<td class="linecoldescription">';
2640 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
2641 $text = $lines[$i]->product->getNomUrl(1);
2642 $text .= ' - '.$label;
2643 $description = (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE') ? '' : dol_htmlentitiesbr($lines[$i]->description));
2644 print $form->textwithtooltip($text, $description, 3, 0, '', (string) $i);
2645 print_date_range(!empty($lines[$i]->date_start) ? $lines[$i]->date_start : 0, !empty($lines[$i]->date_end) ? $lines[$i]->date_end : 0);
2646 if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
2647 print (!empty($lines[$i]->description) && $lines[$i]->description != $label) ? '<br>'.dol_htmlentitiesbr($lines[$i]->description) : '';
2648 }
2649 }
2650 print "</td>\n";
2651 } else {
2652 print '<td class="linecoldescription">';
2653 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
2654 if ($lines[$i]->product_type == Product::TYPE_SERVICE) {
2655 $text = img_object($langs->trans('Service'), 'service');
2656 } else {
2657 $text = img_object($langs->trans('Product'), 'product');
2658 }
2659
2660 if (!empty($lines[$i]->label)) {
2661 $text .= ' <strong>'.$lines[$i]->label.'</strong>';
2662 print $form->textwithtooltip($text, $lines[$i]->description, 3, 0, '', (string) $i);
2663 } else {
2664 print $text.' '.nl2br($lines[$i]->description);
2665 }
2666
2667 print_date_range($lines[$i]->date_start, $lines[$i]->date_end);
2668 }
2669 print "</td>\n";
2670 }
2671
2672 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2673 print '<td><input name="comment'.$line_id.'" id="comment'.$line_id.'" value="'.dol_escape_htmltag($lines[$i]->comment).'"></td>';
2674 } else {
2675 print '<td style="white-space: pre-wrap; max-width: 200px;">'.dol_escape_htmltag($lines[$i]->comment).'</td>';
2676 }
2677
2678
2679 // Qty ordered
2680 print '<td class="center linecolqty">';
2681 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
2682 print $lines[$i]->qty_asked;
2683 }
2684 print '</td>';
2685
2686 // Qty in other receptions (with reception and warehouse used)
2687 if ($origin && $origin_id > 0) {
2688 print '<td class="center nowrap linecolqtyinotherreceptions">';
2689 $htmltooltip = '';
2690 $qtyalreadyreceived = 0;
2691 if (!array_key_exists($lines[$i]->fk_commandefourndet, $arrayofpurchaselinealreadyoutput)) {
2692 foreach ($alreadysent as $key => $val) {
2693 if ($lines[$i]->fk_commandefourndet == $key) {
2694 $j = 0;
2695 foreach ($val as $receptionline_id => $receptionline_var) {
2696 if ($receptionline_var['reception_id'] == $lines[$i]->fk_reception) {
2697 continue; // We want to show only "other receptions"
2698 }
2699
2700 $j++;
2701 if ($j > 1) {
2702 $htmltooltip .= '<br>';
2703 }
2704 $reception_static->fetch($receptionline_var['reception_id']);
2705 $htmltooltip .= $reception_static->getNomUrl(1, 'nolink', 0, 0, 1);
2706 $htmltooltip .= ' - '.$receptionline_var['qty'];
2707
2708 $htmltext = $langs->trans("DateValidation").' : '.(empty($receptionline_var['date_valid']) ? $langs->trans("Draft") : dol_print_date($receptionline_var['date_valid'], 'dayhour'));
2709 if (isModEnabled('stock') && $receptionline_var['warehouse'] > 0) {
2710 $warehousestatic->fetch($receptionline_var['warehouse']);
2711 $htmltext .= '<br>'.$langs->trans("From").' : '.$warehousestatic->getNomUrl(1, '', 0, 1);
2712 }
2713 $htmltooltip .= ' '.$form->textwithpicto('', $htmltext, 1);
2714
2715 $qtyalreadyreceived += $receptionline_var['qty'];
2716 }
2717 if ($j) {
2718 $htmltooltip = $langs->trans("QtyInOtherReceptions").'...<br><br>'.$htmltooltip.'<br><input type="submit" name="dummyhiddenbuttontogetfocus" style="display:none" autofocus>';
2719 }
2720 }
2721 }
2722 }
2723 print $form->textwithpicto((string) $qtyalreadyreceived, $htmltooltip, 1, 'info', '', 0, 3, 'tooltip'.$lines[$i]->id);
2724 print '</td>';
2725 }
2726
2727 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2728 // edit mode
2729 print '<td colspan="'.$editColspan.'" class="center"><table class="nobordernopadding">';
2730 if (isModEnabled('stock')) {
2731 if ($lines[$i]->fk_product > 0) {
2732 print '<!-- case edit 1 -->';
2733 print '<tr>';
2734 // Qty to receive or received
2735 print '<td><input name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty.'"></td>';
2736 // Warehouse source
2737 print '<td>'.$formproduct->selectWarehouses($lines[$i]->fk_entrepot, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1).'</td>';
2738 // Batch number management
2739 if ($conf->productbatch->enabled && !empty($lines[$i]->product->status_batch)) {
2740 print '<td class="nowraponall left"><input name="batch'.$line_id.'" id="batch'.$line_id.'" type="text" value="'.$lines[$i]->batch.'"><br>';
2741 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
2742 print $langs->trans('SellByDate').' : ';
2743 print $form->selectDate($lines[$i]->sellby, 'dlc'.$line_id, 0, 0, 1, "").'</br>';
2744 }
2745 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
2746 print $langs->trans('EatByDate').' : ';
2747 print $form->selectDate($lines[$i]->eatby, 'dluo'.$line_id, 0, 0, 1, "");
2748 }
2749 print '</td>';
2750 }
2751 print '</tr>';
2752 } else {
2753 print '<!-- case edit 2 -->';
2754 print '<tr>';
2755 // Qty to receive or received
2756 print '<td><input name="qtyl'.$line_id.'" id="qtyl'.$line_id.'" type="text" size="4" value="'.$lines[$i]->qty.'"></td>';
2757 // Warehouse source
2758 print '<td></td>';
2759 // Batch number management
2760 print '<td></td>';
2761 print '</tr>';
2762 }
2763 }
2764 print '</table></td>';
2765
2766 $parameters = array();
2767 $parameters['line'] = $lines[$i];
2768 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2769 if ($reshook < 0) {
2770 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2771 } else {
2772 print $hookmanager->resPrint;
2773 }
2774 } else {
2775 // Qty to receive or received
2776 print '<td class="center linecolqtytoreceive">'.$lines[$i]->qty.'</td>';
2777
2778 // Warehouse source
2779 if (isModEnabled('stock')) {
2780 if ($lines[$i]->fk_entrepot > 0) {
2781 $entrepot = new Entrepot($db);
2782 $entrepot->fetch($lines[$i]->fk_entrepot);
2783
2784 print '<td class="left tdoverflowmax150" title="'.dol_escape_htmltag($entrepot->label).'">';
2785 print $entrepot->getNomUrl(1);
2786 print '</td>';
2787 } else {
2788 print '<td></td>';
2789 }
2790 }
2791
2792 // Batch number management
2793 if (isModEnabled('productbatch')) {
2794 if (isset($lines[$i]->batch)) {
2795 print '<!-- Detail of lot -->';
2796 print '<td class="linecolbatch nowrap">';
2797 $detail = $langs->trans("NA");
2798 if ($lines[$i]->product->status_batch > 0 && $lines[$i]->fk_product > 0) {
2799 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/productlot.class.php';
2800 $productlot = new Productlot($db);
2801 $reslot = $productlot->fetch(0, $lines[$i]->fk_product, $lines[$i]->batch);
2802 if ($reslot > 0) {
2803 $detail = $productlot->getNomUrl(1);
2804 } else {
2805 // lot is not created and info is only in reception lines
2806 $batchinfo = $langs->trans("Batch").': '.$lines[$i]->batch;
2807 if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
2808 $batchinfo .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($lines[$i]->sellby, "day");
2809 }
2810 if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
2811 $batchinfo .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($lines[$i]->eatby, "day");
2812 }
2813 $detail = $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"), $batchinfo);
2814 }
2815 }
2816 print $detail . '</td>';
2817 } else {
2818 print '<td></td>';
2819 }
2820 }
2821
2822 $parameters = array();
2823 $parameters['line'] = $lines[$i];
2824 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2825 if ($reshook < 0) {
2826 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2827 } else {
2828 print $hookmanager->resPrint;
2829 }
2830 }
2831
2832 // Weight
2833 print '<td class="center linecolweight">';
2834 if (!empty($lines[$i]->fk_product_type) && $lines[$i]->fk_product_type == Product::TYPE_PRODUCT) {
2835 print $lines[$i]->product->weight * $lines[$i]->qty.' '.measuringUnitString(0, "weight", $lines[$i]->product->weight_units);
2836 } else {
2837 print '&nbsp;';
2838 }
2839 print '</td>';
2840
2841 // Volume
2842 print '<td class="center linecolvolume">';
2843 if (!empty($lines[$i]->fk_product_type) && $lines[$i]->fk_product_type == Product::TYPE_PRODUCT) {
2844 print $lines[$i]->product->volume * $lines[$i]->qty.' '.measuringUnitString(0, "volume", $lines[$i]->product->volume_units);
2845 } else {
2846 print '&nbsp;';
2847 }
2848 print '</td>';
2849
2850
2851 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2852 print '<td class="center valignmiddle" colspan="2">';
2853 print '<input type="submit" class="button small button-save" id="savelinebutton marginbottomonly" name="save" value="'.$langs->trans("Save").'"><br>';
2854 print '<input type="submit" class="button small button-cancel" id="cancellinebutton" name="cancel" value="'.$langs->trans("Cancel").'"><br>';
2855 print '</td>';
2856 } elseif ($object->statut == Reception::STATUS_DRAFT) {
2857 // edit-delete buttons
2858 print '<td class="linecoledit center">';
2859 print '<a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&token='.newToken().'&lineid='.$lines[$i]->id.'">'.img_edit().'</a>';
2860 print '</td>';
2861 print '<td class="linecoldelete" width="10">';
2862 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deleteline&token='.newToken().'&lineid='.$lines[$i]->id.'">'.img_delete().'</a>';
2863 print '</td>';
2864
2865 // Display lines extrafields
2866 if (isset($rowExtrafieldsStart, $rowExtrafieldsView, $rowEnd)) { // @phan-suppress-current-line PhanPluginUndeclaredVariableIsset
2867 print $rowExtrafieldsStart;
2868 print $rowExtrafieldsView;
2869 print $rowEnd;
2870 }
2871 }
2872 print "</tr>";
2873
2874 $arrayofpurchaselinealreadyoutput[$lines[$i]->fk_commandefourndet] = $lines[$i]->fk_commandefourndet;
2875
2876 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
2877 if ($reshook < 0) {
2878 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2879 } else {
2880 print $hookmanager->resPrint;
2881 }
2882
2883 // Display lines extrafields
2884 $extralabelslines = $extrafields->attributes[$lines[$i]->table_element];
2885 if (!empty($extralabelslines) && is_array($extralabelslines) && count($extralabelslines) > 0) {
2886 $colspan = 8;
2887 if (isModEnabled('stock')) {
2888 $colspan++;
2889 }
2890 if (isModEnabled('productbatch')) {
2891 $colspan++;
2892 }
2893
2894 $line = new CommandeFournisseurDispatch($db);
2895 $line->id = $lines[$i]->id;
2896 $line->fetch_optionals();
2897
2898 if ($action == 'editline' && $lines[$i]->id == $line_id) {
2899 print $line->showOptionals($extrafields, 'edit', array('colspan' => $colspan), '');
2900 } else {
2901 print $line->showOptionals($extrafields, 'view', array('colspan' => $colspan), '');
2902 }
2903 }
2904 }
2905 print '</tbody>';
2906
2907 // TODO Show also lines ordered but not delivered
2908
2909 print "</table>\n";
2910 print '</div>';
2911
2912
2913 print dol_get_fiche_end();
2914
2915
2916 $object->fetchObjectLinked($object->id, $object->element);
2917 }
2918
2919 /*
2920 * Button actions
2921 */
2922
2923 if (($user->socid == 0) && ($action != 'presend')) {
2924 print '<div class="tabsAction">';
2925
2926 $parameters = array();
2927 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2928 if (empty($reshook)) {
2929 if ($object->statut == Reception::STATUS_DRAFT && $num_prod > 0) {
2930 if ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'creer'))
2931 || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('reception', 'reception_advance', 'validate'))) {
2932 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken().'">'.$langs->trans("Validate").'</a>';
2933 } else {
2934 print '<a class="butActionRefused" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Validate").'</a>';
2935 }
2936 }
2937 // Back to draft
2938 if ($object->statut == Reception::STATUS_VALIDATED && $user->hasRight('reception', 'creer')) {
2939 print '<div class="inline-block divButAction"><a class="butAction" href="card.php?id='.$object->id.'&action=modif&token='.newToken().'">'.$langs->trans('SetToDraft').'</a></div>';
2940 }
2941
2942 // TODO add alternative status
2943 // 0=draft, 1=validated, 2=billed, we miss a status "delivered" (only available on order)
2944 if ($object->statut == Reception::STATUS_CLOSED && $user->hasRight('reception', 'creer')) {
2945 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("ReOpen").'</a>';
2946 }
2947
2948 // Send mail
2949 if (empty($user->socid)) {
2950 if ($object->statut > 0) {
2951 if (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('reception', 'reception_advance', 'send')) {
2952 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendByMail').'</a>';
2953 } else {
2954 print '<a class="butActionRefused" href="#">'.$langs->trans('SendByMail').'</a>';
2955 }
2956 }
2957 }
2958
2959 // Create bill
2960 if (isModEnabled("supplier_invoice") && ($object->statut == Reception::STATUS_VALIDATED || $object->statut == Reception::STATUS_CLOSED) && !getDolGlobalString('RECEPTION_STANDALONE')) {
2961 if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight('supplier_invoice', 'creer')) {
2962 if (getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0') {
2963 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>';
2964 }
2965 }
2966 }
2967
2968
2969 // Set Billed and Closed
2970 if ($object->statut == Reception::STATUS_VALIDATED) {
2971 if ($user->hasRight('reception', 'creer') && $object->statut > 0) {
2972 if (!$object->billed && getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0') {
2973 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled&token='.newToken().'">'.$langs->trans('ClassifyBilled').'</a>';
2974 }
2975 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifyclosed&token='.newToken().'">'.$langs->trans("Close").'</a>';
2976 }
2977 }
2978
2979 if ($user->hasRight('reception', 'supprimer')) {
2980 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'">'.$langs->trans("Delete").'</a>';
2981 }
2982 }
2983
2984 print '</div>';
2985 }
2986
2987
2988 /*
2989 * Documents generated
2990 */
2991
2992 if ($action != 'presend' && $action != 'editline') {
2993 print '<div class="fichecenter"><div class="fichehalfleft">';
2994
2995 $objectref = dol_sanitizeFileName((string) $object->ref);
2996 $filedir = $conf->reception->dir_output."/".$objectref;
2997
2998 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2999
3000 $genallowed = $user->hasRight('reception', 'lire');
3001 $delallowed = $user->hasRight('reception', 'creer');
3002
3003 print $formfile->showdocuments('reception', $objectref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang);
3004
3005 // Show links to link elements
3006 //$tmparray = $form->showLinkToObjectBlock($object, null, array('order'), 1);
3007 $somethingshown = $form->showLinkedObjectBlock($object, '');
3008
3009 print '</div><div class="fichehalfright">';
3010
3011 print '</div></div>';
3012 }
3013
3014 // Presend form
3015 $modelmail = 'reception_send';
3016 $defaulttopic = 'SendReceptionRef';
3017 $diroutput = $conf->reception->dir_output;
3018 $trackid = 'rec'.$object->id;
3019
3020 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
3021}
3022
3023
3024llxFooter();
3025
3026$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)
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='')
Show information in HTML for admin users or standard users.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $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.
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.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
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.
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.
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.