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