dolibarr 22.0.5
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
5 * Copyright (C) 2005-2015 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
7 * Copyright (C) 2010-2013 Juanjo Menent <jmenent@2byte.es>
8 * Copyright (C) 2011-2023 Philippe Grand <philippe.grand@atoo-net.com>
9 * Copyright (C) 2012-2023 Christophe Battarel <christophe.battarel@altairis.fr>
10 * Copyright (C) 2012-2016 Marcos García <marcosgdf@gmail.com>
11 * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
12 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
13 * Copyright (C) 2014 Ferran Marcet <fmarcet@2byte.es>
14 * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
15 * Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
16 * Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
17 * Copyright (C) 2023-2024 Benjamin Falière <benjamin.faliere@altairis.fr>
18 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
19 * Copyright (C) 2025 Lenin Rivas <lenin.rivas777@gmail.com>
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 3 of the License, or
24 * (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program. If not, see <https://www.gnu.org/licenses/>.
33 */
34
41// Load Dolibarr environment
42require '../main.inc.php';
43require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
44require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
45require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
46require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php';
48require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php';
49require_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
50require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
51require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php';
52
53require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
54require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
55
56if (isModEnabled("propal")) {
57 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
58}
59
60if (isModEnabled('project')) {
61 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
62 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
63}
64
65if (isModEnabled('variants')) {
66 require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
67}
68
69
79// Load translation files required by the page
80$langs->loadLangs(array('orders', 'sendings', 'companies', 'bills', 'propal', 'deliveries', 'products', 'other'));
81
82if (isModEnabled('incoterm')) {
83 $langs->load('incoterm');
84}
85if (isModEnabled('margin')) {
86 $langs->load('margins');
87}
88if (isModEnabled('productbatch')) {
89 $langs->load('productbatch');
90}
91
92
93$id = (GETPOSTINT('id') ? GETPOSTINT('id') : GETPOSTINT('orderid'));
94$ref = GETPOST('ref', 'alpha');
95$socid = GETPOSTINT('socid');
96$action = GETPOST('action', 'aZ09');
97$cancel = GETPOST('cancel', 'alpha');
98$confirm = GETPOST('confirm', 'alpha');
99$backtopage = GETPOST('backtopage', 'alpha');
100
101$lineid = GETPOSTINT('lineid');
102$contactid = GETPOSTINT('contactid');
103$projectid = GETPOSTINT('projectid');
104$origin = GETPOST('origin', 'alpha');
105$originid = (GETPOSTINT('originid') ? GETPOSTINT('originid') : GETPOSTINT('origin_id')); // For backward compatibility
106$rank = (GETPOSTINT('rank') > 0) ? GETPOSTINT('rank') : -1;
107
108// Type Contact default
109$type_contact_code = (getDolGlobalString('ORDER_TYPE_CONTACT_DEFAULT') ? getDolGlobalString('ORDER_TYPE_CONTACT_DEFAULT') : 'CUSTOMER');
110
111// PDF
112$hidedetails = (GETPOSTINT('hidedetails') ? GETPOSTINT('hidedetails') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0));
113$hidedesc = (GETPOSTINT('hidedesc') ? GETPOSTINT('hidedesc') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0));
114$hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0));
115
116// Security check
117if (!empty($user->socid)) {
118 $socid = $user->socid;
119}
120
121$array_options = 0;
122$object_id = 0;
123$price_base_type = null;
124$lineClassName = null;
125$remise_percent = null;
126$ref_client = null;
127$availability_id = null;
128$shipping_method_id = null;
129$warehouse_id = null;
130$demand_reason_id = null;
131$formproject = null;
132$objectsrc = null;
133$note_public = null;
134$note_private = null;
135
136// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
137$hookmanager->initHooks(array('ordercard', 'globalcard'));
138
139$result = restrictedArea($user, 'commande', $id);
140
141$object = new Commande($db);
142$extrafields = new ExtraFields($db);
143
144// fetch optionals attributes and labels
145$extrafields->fetch_name_optionals_label($object->table_element);
146
147// Load object
148include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'
149
150// Permissions / Rights
151$usercanread = $user->hasRight("commande", "lire");
152$usercancreate = $user->hasRight("commande", "creer");
153$usercandelete = $user->hasRight("commande", "supprimer");
154
155// Advanced permissions
156$usercanclose = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !empty($usercancreate)) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('commande', 'order_advance', 'close')));
157$usercanvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $usercancreate) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('commande', 'order_advance', 'validate')));
158$usercancancel = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $usercancreate) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('commande', 'order_advance', 'annuler')));
159$usercansend = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('commande', 'order_advance', 'send'));
160$usercangeneretedoc = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('commande', 'order_advance', 'generetedoc'));
161
162$usermustrespectpricemin = ((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('produit', 'ignore_price_min_advance')) || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS'));
163$usercancreatepurchaseorder = ($user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer'));
164
165$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
166$permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
167$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
168$permissiontoeditextra = $usercancreate;
169if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
170 // For action 'update_extras', is there a specific permission set for the attribute to update
171 $permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
172}
173
174$error = 0;
175
176$date_delivery = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
177
178$selectedLines = array();
179
180
181/*
182 * Actions
183 */
184
185$parameters = array('socid' => $socid);
186// Note that $action and $object may be modified by some hooks
187$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
188if ($reshook < 0) {
189 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
190}
191
192if (empty($reshook)) {
193 $backurlforlist = DOL_URL_ROOT.'/commande/list.php';
194
195 if (empty($backtopage) || ($cancel && empty($id))) {
196 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
197 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
198 $backtopage = $backurlforlist;
199 } else {
200 $backtopage = DOL_URL_ROOT.'/commande/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
201 }
202 }
203 }
204
205 $selectedLines = GETPOST('toselect', 'array');
206
207 if ($cancel) {
208 if (!empty($backtopageforcancel)) {
209 header("Location: ".$backtopageforcancel);
210 exit;
211 } elseif (!empty($backtopage)) {
212 header("Location: ".$backtopage);
213 exit;
214 }
215 $action = '';
216 }
217
218 include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be 'include', not 'include_once'
219
220 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be 'include', not 'include_once'
221
222 include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
223
224 // Action clone object
225 if ($action == 'confirm_clone' && $confirm == 'yes' && $usercancreate) {
226 if (!($socid > 0)) {
227 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('IdThirdParty')), null, 'errors');
228 } else {
229 if ($object->id > 0) {
230 // We clone object to avoid to denaturate loaded object when setting some properties for clone or if createFromClone modifies the object.
231 $objectutil = dol_clone($object, 1);
232
233 $result = $objectutil->createFromClone($user, $socid);
234 if ($result > 0) {
235 $warningMsgLineList = array();
236 // check all product lines are to sell otherwise add a warning message for each product line is not to sell
237 foreach ($object->lines as $line) {
238 if (!is_object($line->product)) {
239 $line->fetch_product();
240 }
241 if (is_object($line->product) && $line->product->id > 0) {
242 if (empty($line->product->status)) {
243 $warningMsgLineList[$line->id] = $langs->trans('WarningLineProductNotToSell', $line->product->ref);
244 }
245 }
246 }
247 if (!empty($warningMsgLineList)) {
248 setEventMessages('', $warningMsgLineList, 'warnings');
249 }
250
251 header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
252 exit;
253 } else {
254 setEventMessages($object->error, $object->errors, 'errors');
255 $action = '';
256 }
257 }
258 }
259 } elseif ($action == 'reopen' && $usercancreate) {
260 // Reopen a closed order
262 if (getDolGlobalInt('ORDER_REOPEN_TO_DRAFT')) {
263 $idwarehouse = GETPOSTINT('idwarehouse');
264 $result = $object->setDraft($user, $idwarehouse);
265 if ($result < 0) {
266 setEventMessages($object->error, $object->errors, 'errors');
267 }
268 } else {
269 $result = $object->set_reopen($user);
270 if ($result > 0) {
271 setEventMessages($langs->trans('OrderReopened', $object->ref), null);
272 } else {
273 setEventMessages($object->error, $object->errors, 'errors');
274 }
275 }
276 }
277 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $usercandelete) {
278 // Remove order
279 $result = $object->delete($user);
280 if ($result > 0) {
281 header('Location: list.php?restore_lastsearch_values=1');
282 exit;
283 } else {
284 setEventMessages($object->error, $object->errors, 'errors');
285 }
286 } elseif ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate) {
287 // Remove a product line
288 $result = $object->deleteLine($user, $lineid);
289 if ($result > 0) {
290 // reorder lines
291 $object->line_order(true);
292 // Define output language
293 $outputlangs = $langs;
294 $newlang = '';
295 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
296 $newlang = GETPOST('lang_id', 'aZ09');
297 }
298 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
299 $newlang = $object->thirdparty->default_lang;
300 }
301 if (!empty($newlang)) {
302 $outputlangs = new Translate("", $conf);
303 $outputlangs->setDefaultLang($newlang);
304 }
305 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
306 $ret = $object->fetch($object->id); // Reload to get new records
307 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
308 }
309
310 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
311 exit;
312 } else {
313 setEventMessages($object->error, $object->errors, 'errors');
314 }
315 } elseif ($action == 'confirm_delete_subtotalline' && $confirm == 'yes' && $usercancreate) {
316 $result = $object->deleteSubtotalLine($langs, GETPOSTINT('lineid'), (bool) GETPOST('deletecorrespondingsubtotalline'), $user);
317 if ($result > 0) {
318 // reorder lines
319 $object->line_order(true);
320 // Define output language
321 $outputlangs = $langs;
322 $newlang = '';
323 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
324 $newlang = GETPOST('lang_id', 'aZ09');
325 }
326 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
327 $newlang = $object->thirdparty->default_lang;
328 }
329 if (!empty($newlang)) {
330 $outputlangs = new Translate("", $conf);
331 $outputlangs->setDefaultLang($newlang);
332 }
333 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
334 $ret = $object->fetch($object->id); // Reload to get new records
335 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
336 }
337
338 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
339 exit;
340 } else {
341 setEventMessages($object->error, $object->errors, 'errors');
342 }
343 } elseif ($action == 'classin' && $usercancreate) {
344 // Link to a project
345 $object->setProject(GETPOSTINT('projectid'));
346 } elseif ($action == 'add' && $usercancreate) {
347 // Add order
348 $datecommande = dol_mktime(12, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
349 $date_delivery = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
350
351 if ($datecommande == '') {
352 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Date')), null, 'errors');
353 $action = 'create';
354 $error++;
355 }
356
357 if ($socid < 1) {
358 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), null, 'errors');
359 $action = 'create';
360 $error++;
361 }
362
363 if (!$error) {
364 $object->socid = $socid;
365 $object->fetch_thirdparty();
366
367 $db->begin();
368
369 $object->date_commande = $datecommande;
370 $object->note_private = GETPOST('note_private', 'restricthtml');
371 $object->note_public = GETPOST('note_public', 'restricthtml');
372 $object->source = GETPOSTINT('source_id');
373 $object->fk_project = GETPOSTINT('projectid');
374 $object->ref_client = GETPOST('ref_client', 'alpha');
375 $object->model_pdf = GETPOST('model');
376 $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
377 $object->deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
378 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
379 $object->fk_account = GETPOSTINT('fk_account');
380 $object->availability_id = GETPOSTINT('availability_id');
381 $object->demand_reason_id = GETPOSTINT('demand_reason_id');
382 $object->delivery_date = $date_delivery;
383 $object->shipping_method_id = GETPOSTINT('shipping_method_id');
384 $object->warehouse_id = GETPOSTINT('warehouse_id');
385 $object->fk_delivery_address = GETPOSTINT('fk_address');
386 $object->contact_id = GETPOSTINT('contactid');
387 $object->fk_incoterms = GETPOSTINT('incoterm_id');
388 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
389 $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
390 $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
391 // Fill array 'array_options' with data from add form
392 if (!$error) {
393 $ret = $extrafields->setOptionalsFromPost(null, $object);
394 if ($ret < 0) {
395 $error++;
396 }
397 }
398
399 // If creation from another object of another module (Example: origin=propal, originid=1)
400 if (!empty($origin) && !empty($originid)) {
401 // Parse element/subelement (ex: project_task)
402 $element = $subelement = $origin;
403 $regs = array();
404 if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
405 $element = $regs [1];
406 $subelement = $regs [2];
407 }
408
409 // For compatibility
410 if ($element == 'order') {
411 $element = $subelement = 'commande';
412 }
413 if ($element == 'propal') {
414 $element = 'comm/propal';
415 $subelement = 'propal';
416 }
417 if ($element == 'contract') {
418 $element = $subelement = 'contrat';
419 }
420
421 $object->origin = $origin; // deprecated
422 $object->origin_type = $origin;
423 $object->origin_id = $originid;
424
425 // Possibility to add external linked objects with hooks
426 $object->linked_objects [$object->origin_type] = $object->origin_id;
427 $other_linked_objects = GETPOST('other_linked_objects', 'array');
428 if (!empty($other_linked_objects)) {
429 $object->linked_objects = array_merge($object->linked_objects, $other_linked_objects);
430 }
431
432 if (!$error) {
433 $object_id = $object->create($user);
434
435 if ($object_id > 0) {
436 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
437
438 $classname = ucfirst($subelement);
439 $srcobject = new $classname($db);
440 '@phan-var-force Commande|Propal|Contrat $srcobject';
441
442 dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines");
443 $result = $srcobject->fetch($object->origin_id);
444 if ($result > 0) {
445 $lines = $srcobject->lines;
446 if (empty($lines) && method_exists($srcobject, 'fetch_lines')) {
447 $srcobject->fetch_lines();
448 $lines = $srcobject->lines;
449 }
450
451 $fk_parent_line = 0;
452 $num = count($lines);
453
454 for ($i = 0; $i < $num; $i++) {
455 if (!in_array($lines[$i]->id, $selectedLines)) {
456 continue; // Skip unselected lines
457 }
458
459 $label = (!empty($lines[$i]->label) ? $lines[$i]->label : '');
460 $desc = (!empty($lines[$i]->desc) ? $lines[$i]->desc : '');
461 $product_type = (!empty($lines[$i]->product_type) ? $lines[$i]->product_type : 0);
462
463 // Dates
464 // TODO mutualiser
465 $date_start = $lines[$i]->date_debut_prevue;
466 if ($lines[$i]->date_debut_reel) {
467 $date_start = $lines[$i]->date_debut_reel;
468 }
469 if ($lines[$i]->date_start) {
470 $date_start = $lines[$i]->date_start;
471 }
472 $date_end = $lines[$i]->date_fin_prevue;
473 if ($lines[$i]->date_fin_reel) {
474 $date_end = $lines[$i]->date_fin_reel;
475 }
476 if ($lines[$i]->date_end) {
477 $date_end = $lines[$i]->date_end;
478 }
479
480 // Reset fk_parent_line for no child products and special product
481 if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
482 $fk_parent_line = 0;
483 }
484
485 // Extrafields
486 if (method_exists($lines[$i], 'fetch_optionals')) { // For avoid conflicts if trigger used
487 $lines[$i]->fetch_optionals();
488 $array_options = $lines[$i]->array_options;
489 }
490
491 $tva_tx = $lines[$i]->tva_tx;
492 if (!empty($lines[$i]->vat_src_code) && !preg_match('/\‍(/', $tva_tx)) {
493 $tva_tx .= ' ('.$lines[$i]->vat_src_code.')';
494 }
495
496 $result = $object->addline(
497 $desc,
498 $lines[$i]->subprice,
499 $lines[$i]->qty,
500 $tva_tx,
501 $lines[$i]->localtax1_tx,
502 $lines[$i]->localtax2_tx,
503 $lines[$i]->fk_product,
504 $lines[$i]->remise_percent,
505 $lines[$i]->info_bits,
506 $lines[$i]->fk_remise_except,
507 'HT',
508 0,
509 $date_start,
510 $date_end,
511 $product_type,
512 $lines[$i]->rang,
513 $lines[$i]->special_code,
514 $fk_parent_line,
515 $lines[$i]->fk_fournprice,
516 $lines[$i]->pa_ht,
517 $label,
518 $array_options,
519 $lines[$i]->fk_unit,
520 $object->origin,
521 $lines[$i]->rowid,
522 0,
523 $lines[$i]->ref_ext,
524 0
525 );
526
527 if ($result < 0) {
528 $error++;
529 break;
530 }
531
532 foreach ($object->lines as $line) {
533 if ($line->id == $result) {
534 $line->extraparams = $lines[$i]->extraparams;
535 $line->setExtraParameters();
536 }
537 }
538
539 // Defined the new fk_parent_line
540 if ($result > 0 && $lines[$i]->product_type == 9) {
541 $fk_parent_line = $result;
542 }
543 }
544 } else {
545 setEventMessages($srcobject->error, $srcobject->errors, 'errors');
546 $error++;
547 }
548
549 // Now we create same links to contact than the ones found on origin object
550 /* Useless, already into the create
551 if (getDolGlobalString('MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN')) {
552 $originforcontact = $object->origin;
553 $originidforcontact = $object->origin_id;
554 if ($originforcontact == 'shipping') // shipment and order share the same contacts. If creating from shipment we take data of order
555 {
556 $originforcontact=$srcobject->origin;
557 $originidforcontact=$srcobject->origin_id;
558 }
559 $sqlcontact = "SELECT code, fk_socpeople FROM ".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as ctc";
560 $sqlcontact.= " WHERE element_id = ".((int) $originidforcontact)." AND ec.fk_c_type_contact = ctc.rowid AND ctc.element = '".$db->escape($originforcontact)."'";
561
562 $resqlcontact = $db->query($sqlcontact);
563 if ($resqlcontact)
564 {
565 while($objcontact = $db->fetch_object($resqlcontact))
566 {
567 //print $objcontact->code.'-'.$objcontact->fk_socpeople."\n";
568 $object->add_contact($objcontact->fk_socpeople, $objcontact->code);
569 }
570 }
571 else dol_print_error($resqlcontact);
572 }*/
573
574 // Hooks
575 $parameters = array('objFrom' => $srcobject);
576 // Note that $action and $object may be modified by hook
577 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action);
578 if ($reshook < 0) {
579 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
580 $error++;
581 }
582 } else {
583 setEventMessages($object->error, $object->errors, 'errors');
584 $error++;
585 }
586 } else {
587 // Required extrafield left blank, error message already defined by setOptionalsFromPost()
588 $action = 'create';
589 }
590 } else {
591 if (!$error) {
592 $object_id = $object->create($user);
593 }
594 }
595
596 // Insert default contacts if defined
597 if ($object_id > 0) {
598 if (GETPOSTINT('contactid')) {
599 // $result = $object->add_contact(GETPOSTINT('contactid'), 'CUSTOMER', 'external');
600 $result = $object->add_contact(GETPOSTINT('contactid'), $type_contact_code, 'external');
601 if ($result < 0) {
602 setEventMessages($langs->trans("ErrorFailedToAddContact"), null, 'errors');
603 $error++;
604 }
605 }
606
607 $id = $object_id;
608 $action = '';
609 }
610
611 if (isModEnabled('category')) {
612 $categories = GETPOST('categories', 'array');
613 if (method_exists($object, 'setCategories')) {
614 $object->setCategories($categories);
615 }
616 }
617
618 // End of object creation, we show it
619 if ($object_id > 0 && !$error) {
620 $db->commit();
621 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object_id);
622 exit();
623 } else {
624 $db->rollback();
625 $action = 'create';
626 setEventMessages($object->error, $object->errors, 'errors');
627 }
628 }
629 } elseif ($action == 'classifybilled' && $usercancreate) {
630 $ret = $object->classifyBilled($user);
631
632 if ($ret < 0) {
633 setEventMessages($object->error, $object->errors, 'errors');
634 }
635 } elseif ($action == 'classifyunbilled' && $usercancreate) {
636 $ret = $object->classifyUnBilled($user);
637 if ($ret < 0) {
638 setEventMessages($object->error, $object->errors, 'errors');
639 }
640 } elseif ($action == 'setref_client' && $usercancreate) {
641 // Positionne ref commande client
642 $result = $object->set_ref_client($user, GETPOST('ref_client'));
643 if ($result < 0) {
644 setEventMessages($object->error, $object->errors, 'errors');
645 }
646 } elseif ($action == 'setremise' && $usercancreate) {
647 $result = $object->setDiscount($user, price2num(GETPOST('remise'), 2));
648 if ($result < 0) {
649 setEventMessages($object->error, $object->errors, 'errors');
650 }
651 } elseif ($action == 'setabsolutediscount' && $usercancreate) {
652 if (GETPOST('remise_id')) {
653 if ($object->id > 0) {
654 $object->insert_discount(GETPOSTINT('remise_id'));
655 } else {
656 dol_print_error($db, $object->error);
657 }
658 }
659 } elseif ($action == 'setdate' && $usercancreate) {
660 $date = dol_mktime(0, 0, 0, GETPOSTINT('order_month'), GETPOSTINT('order_day'), GETPOSTINT('order_year'));
661
662 $result = $object->set_date($user, $date);
663 if ($result < 0) {
664 setEventMessages($object->error, $object->errors, 'errors');
665 }
666 } elseif ($action == 'setdate_livraison' && $usercancreate) {
667 $date_delivery = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
668
669 $object->fetch($id);
670 $result = $object->setDeliveryDate($user, $date_delivery);
671 if ($result < 0) {
672 setEventMessages($object->error, $object->errors, 'errors');
673 }
674 } elseif ($action == 'setmode' && $usercancreate) {
675 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
676 if ($result < 0) {
677 setEventMessages($object->error, $object->errors, 'errors');
678 }
679 } elseif ($action == 'setposinfo' && $usercancreate) {
680 $object->fetch($id);
681 $object->module_source = GETPOST('posmodule');
682 $object->pos_source = GETPOST('posterminal');
683 $result = $object->update($user);
684 if ($result < 0) {
685 dol_print_error($db, $object->error);
686 }
687 } elseif ($action == 'setmulticurrencycode' && $usercancreate) {
688 // Multicurrency Code
689 $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
690 } elseif ($action == 'setmulticurrencyrate' && $usercancreate) {
691 // Multicurrency rate
692 $result = $object->setMulticurrencyRate(GETPOSTFLOAT('multicurrency_tx'), GETPOSTINT('calculation_mode'));
693 } elseif ($action == 'setavailability' && $usercancreate) {
694 $result = $object->availability(GETPOSTINT('availability_id'));
695 if ($result < 0) {
696 setEventMessages($object->error, $object->errors, 'errors');
697 }
698 } elseif ($action == 'setdemandreason' && $usercancreate) {
699 $result = $object->demand_reason(GETPOSTINT('demand_reason_id'));
700 if ($result < 0) {
701 setEventMessages($object->error, $object->errors, 'errors');
702 }
703 } elseif ($action == 'setconditions' && $usercancreate) {
704 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'), GETPOSTFLOAT('cond_reglement_id_deposit_percent'));
705 if ($result < 0) {
706 dol_print_error($db, $object->error);
707 } else {
708 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
709 // Define output language
710 $outputlangs = $langs;
711 $newlang = GETPOST('lang_id', 'alpha');
712 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
713 $newlang = $object->thirdparty->default_lang;
714 }
715 if (!empty($newlang)) {
716 $outputlangs = new Translate("", $conf);
717 $outputlangs->setDefaultLang($newlang);
718 }
719
720 $ret = $object->fetch($object->id); // Reload to get new records
721 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
722 }
723 }
724 } elseif ($action == 'set_incoterms' && isModEnabled('incoterm') && $usercancreate) {
725 // Set incoterm
726 $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms'));
727 if ($result < 0) {
728 setEventMessages($object->error, $object->errors, 'errors');
729 }
730 } elseif ($action == 'setbankaccount' && $usercancreate) {
731 // bank account
732 $result = $object->setBankAccount(GETPOSTINT('fk_account'));
733 if ($result < 0) {
734 setEventMessages($object->error, $object->errors, 'errors');
735 }
736 } elseif ($action == 'setshippingmethod' && $usercancreate) {
737 // shipping method
738 $result = $object->setShippingMethod(GETPOSTINT('shipping_method_id'));
739 if ($result < 0) {
740 setEventMessages($object->error, $object->errors, 'errors');
741 }
742 } elseif ($action == 'setwarehouse' && $usercancreate) {
743 // warehouse
744 $result = $object->setWarehouse(GETPOSTINT('warehouse_id'));
745 if ($result < 0) {
746 setEventMessages($object->error, $object->errors, 'errors');
747 }
748 //} elseif ($action == 'setremisepercent' && $usercancreate) {
749 // $result = $object->setDiscount($user, price2num(GETPOST('remise_percent'), '', 2));
750 //} elseif ($action == 'setremiseabsolue' && $usercancreate) {
751 // $result = $object->set_remise_absolue($user, price2num(GETPOST('remise_absolue'), 'MU', 2));
752 } elseif ($action == 'settags' && isModEnabled('category') && $usercancreate) {
753 $result = $object->setCategories(GETPOST('categories', 'array'));
754 if ($result < 0) {
755 setEventMessages($object->error, $object->errors, 'errors');
756 }
757 } elseif ($action == 'addline' && GETPOST('updateallvatlinesblock', 'alpha') && GETPOST('vatforblocklines', 'alpha') !== '' && $usercancreate) {
758 $tx_tva = GETPOST('vatforblocklines') ? GETPOST('vatforblocklines') : 0;
759 $object->updateSubtotalLineBlockLines($langs, $object->getRangOfLine($lineid), 'tva', $tx_tva);
760 } elseif ($action == 'addline' && GETPOST('updatealldiscountlinesblock', 'alpha') && GETPOST('discountforblocklines', 'alpha') !== '' && $usercancreate) {
761 $discount = GETPOST('discountforblocklines') ? GETPOST('discountforblocklines') : 0;
762 $object->updateSubtotalLineBlockLines($langs, $object->getRangOfLine($lineid), 'discount', $discount);
763 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && (GETPOST('alldate_start', 'alpha') || GETPOST('alldate_end', 'alpha')) && $usercancreate) {
764 // Define date start and date end for all line
765 $alldate_start = dol_mktime(GETPOSTINT('alldate_starthour'), GETPOSTINT('alldate_startmin'), 0, GETPOSTINT('alldate_startmonth'), GETPOSTINT('alldate_startday'), GETPOSTINT('alldate_startyear'));
766 $alldate_end = dol_mktime(GETPOSTINT('alldate_endhour'), GETPOSTINT('alldate_endmin'), 0, GETPOSTINT('alldate_endmonth'), GETPOSTINT('alldate_endday'), GETPOSTINT('alldate_endyear'));
767 foreach ($object->lines as $line) {
768 if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
769 continue;
770 }
771 if ($line->product_type == 1) { // only service line
772 $result = $object->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $alldate_start, $alldate_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice);
773 }
774 }
775 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('vatforalllines', 'alpha') !== '' && $usercancreate) {
776 // Define vat_rate
777 $vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
778 $vat_rate = str_replace('*', '', $vat_rate);
779 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
780 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
781 foreach ($object->lines as $line) {
782 if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
783 continue;
784 }
785 $result = $object->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice);
786 }
787 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('remiseforalllines', 'alpha') !== '' && $usercancreate) {
788 // Define remise_percent
789 $remise_percent = (GETPOST('remiseforalllines') ? GETPOST('remiseforalllines') : 0);
790 $remise_percent = str_replace('*', '', $remise_percent);
791 foreach ($object->lines as $line) {
792 if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
793 continue;
794 }
795 $tvatx = $line->tva_tx;
796 if (!empty($line->vat_src_code)) {
797 $tvatx .= ' ('.$line->vat_src_code.')';
798 }
799 $result = $object->updateline($line->id, $line->desc, $line->subprice, $line->qty, (float) $remise_percent, $tvatx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice);
800 }
801 } elseif ($action == 'addline' && $usercancreate && (
802 (GETPOST('submitforallmargins', 'alpha') && GETPOST('marginforalllines', 'alpha') !== '') ||
803 (GETPOST('submitforallmark', 'alpha') && GETPOST('markforalllines', 'alpha') !== ''))) {
804 $outlangs = $langs;
805 // Define margin
806 $margin_rate = GETPOSTISSET('marginforalllines') ? GETPOST('marginforalllines', 'int') : '';
807 $mark_rate = GETPOSTISSET('markforalllines') ? GETPOST('markforalllines', 'int') : '';
808 foreach ($object->lines as &$line) if ($line->subprice > 0) {
809 if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
810 continue;
811 }
812 $subprice_multicurrency = $line->subprice;
813 if (is_numeric($margin_rate) && $margin_rate > 0) {
814 $line->subprice = floatval(price2num(floatval($line->pa_ht) * (1 + floatval($margin_rate) / 100), 'MU'));
815 } elseif (is_numeric($mark_rate) && $mark_rate > 0) {
816 $line->subprice = floatval($line->pa_ht / (1 - (floatval($mark_rate) / 100)));
817 } else {
818 $line->subprice = floatval($line->pa_ht);
819 }
820
821 $prod = new Product($db);
822 $res = $prod->fetch($line->fk_product);
823 if ($res > 0) {
824 if ($prod->price_min > $line->subprice) {
825 $price_subprice = price($line->subprice, 0, $outlangs, 1, -1, -1, 'auto');
826 $price_price_min = price($prod->price_min, 0, $outlangs, 1, -1, -1, 'auto');
827 setEventMessages($prod->ref . ' - ' . $prod->label . ' (' . $price_subprice . ' < ' . $price_price_min . ' ' . strtolower($langs->trans("MinPrice")) . ')' . "\n", null, 'warnings');
828 } else {
829 setEventMessages($prod->error, $prod->errors, 'errors');
830 }
831 } else {
832 setEventMessages($prod->error, $prod->errors, 'errors');
833 }
834 // Manage $line->subprice and $line->multicurrency_subprice
835 $multicurrency_subprice = (float) $line->subprice * $line->multicurrency_subprice / $subprice_multicurrency;
836 // Update DB
837 $result = $object->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->product_ref, $line->special_code, $line->array_options, $line->fk_unit, $multicurrency_subprice);
838 // Update $object with new margin info
839 if ($result > 0) {
840 if (is_numeric($margin_rate) && empty($mark_rate)) {
841 $line->marge_tx = $margin_rate;
842 } elseif (is_numeric($mark_rate) && empty($margin_rate)) {
843 $line->marque_tx = $mark_rate;
844 }
845 $line->total_ht = $line->qty * (float) $line->subprice;
846 $line->total_tva = $line->tva_tx * $line->qty * (float) $line->subprice;
847 $line->total_ttc = (1 + $line->tva_tx) * $line->qty * (float) $line->subprice;
848 // Manage $line->subprice and $line->multicurrency_subprice
849 $line->multicurrency_total_ht = $line->qty * (float) $subprice_multicurrency * $line->multicurrency_subprice / $line->subprice;
850 $line->multicurrency_total_tva = $line->tva_tx * $line->qty * (float) $subprice_multicurrency * $line->multicurrency_subprice / $line->subprice;
851 $line->multicurrency_total_ttc = (1 + $line->tva_tx) * $line->qty * (float) $subprice_multicurrency * $line->multicurrency_subprice / $line->subprice;
852 // Used previous $line->subprice and $line->multicurrency_subprice above, now they can be set to their new values
853 $line->multicurrency_subprice = $multicurrency_subprice;
854 } else {
855 setEventMessages($object->error, $object->errors, 'errors');
856 }
857 }
858 } elseif ($action == 'confirm_addtitleline' && $usercancreate) {
859 // Handling adding a new title line for subtotals module
860
861 $langs->load('subtotals');
862
863 $desc = GETPOST('subtotallinedesc', 'alphanohtml');
864 $depth = GETPOSTINT('subtotallinelevel') ?? 1;
865
866 $subtotal_options = array();
867
868 foreach (Commande::$TITLE_OPTIONS as $option) {
869 $value = GETPOST($option, 'alphanohtml');
870 if ($value) {
871 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
872 }
873 }
874
875 // Insert line
876 $result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
877
878 if ($result >= 0) {
879 if ($result == 0) {
880 setEventMessages($object->error, $object->errors, 'warnings');
881 }
882 $ret = $object->fetch($object->id); // Reload to get new records
883 $object->fetch_thirdparty();
884
885 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
886 // Define output language
887 $outputlangs = $langs;
888 $newlang = GETPOST('lang_id', 'alpha');
889 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
890 $newlang = $object->thirdparty->default_lang;
891 }
892 if (!empty($newlang)) {
893 $outputlangs = new Translate("", $conf);
894 $outputlangs->setDefaultLang($newlang);
895 }
896
897 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
898 }
899 } else {
900 setEventMessages($object->error, $object->errors, 'errors');
901 }
902 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
903 exit();
904 } elseif ($action == 'confirm_addsubtotalline' && $usercancreate) {
905 // Handling adding a new subtotal line for subtotals module
906
907 $langs->load('subtotals');
908
909 $choosen_line = GETPOST('subtotaltitleline', 'alphanohtml');
910 foreach ($object->lines as $line) {
911 if ($line->desc == $choosen_line && $line->special_code == SUBTOTALS_SPECIAL_CODE) {
912 $desc = $line->desc;
913 $depth = -$line->qty;
914 }
915 }
916
917 $subtotal_options = array();
918
919 foreach (Commande::$SUBTOTAL_OPTIONS as $option) {
920 $value = GETPOST($option, 'alphanohtml');
921 if ($value) {
922 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
923 }
924 }
925
926 // Insert line
927 if (isset($desc) && isset($depth)) {
928 $result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
929 } else {
930 $object->errors[] = $langs->trans("CorrespondingTitleNotFound");
931 }
932
933 if (isset($result) && $result >= 0) {
934 $ret = $object->fetch($object->id); // Reload to get new records
935 $object->fetch_thirdparty();
936
937 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
938 // Define output language
939 $outputlangs = $langs;
940 $newlang = GETPOST('lang_id', 'alpha');
941 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
942 $newlang = $object->thirdparty->default_lang;
943 }
944 if (!empty($newlang)) {
945 $outputlangs = new Translate("", $conf);
946 $outputlangs->setDefaultLang($newlang);
947 }
948
949 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
950 }
951 } else {
952 setEventMessages($object->error, $object->errors, 'errors');
953 }
954 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
955 exit();
956 } elseif ($action == 'addline' && !GETPOST('submitforalllines', 'alpha') && $usercancreate) { // Add a new line
957 $langs->load('errors');
958 $error = 0;
959
960 // Set if we used free entry or predefined product
961 $predef = '';
962 $line_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
963
964 $price_ht = '';
965 $price_ht_devise = '';
966 $price_ttc = '';
967 $price_ttc_devise = '';
968
969 if (GETPOST('price_ht') !== '') {
970 $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
971 }
972 if (GETPOST('multicurrency_price_ht') !== '') {
973 $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
974 }
975 if (GETPOST('price_ttc') !== '') {
976 $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
977 }
978 if (GETPOST('multicurrency_price_ttc') !== '') {
979 $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
980 }
981
982 $prod_entry_mode = GETPOST('prod_entry_mode', 'aZ09');
983 if ($prod_entry_mode == 'free') {
984 $idprod = 0;
985 } else {
986 $idprod = GETPOSTINT('idprod');
987
988 if (getDolGlobalString('MAIN_DISABLE_FREE_LINES') && $idprod <= 0) {
989 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
990 $error++;
991 }
992 }
993
994 $tva_tx = GETPOST('tva_tx', 'alpha');
995
996 $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2);
997
998 $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0);
999 if (empty($remise_percent)) {
1000 $remise_percent = 0;
1001 }
1002
1003 // Extrafields
1004 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1005 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
1006 // Unset extrafield
1007 if (is_array($extralabelsline)) {
1008 // Get extra fields
1009 foreach ($extralabelsline as $key => $value) {
1010 unset($_POST["options_".$key]);
1011 }
1012 }
1013
1014 if ((empty($idprod) || $idprod < 0) && ($price_ht < 0) && ($qty < 0)) {
1015 setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPriceHT'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1016 $error++;
1017 }
1018 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) {
1019 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
1020 $error++;
1021 }
1022 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && $price_ht === '' && $price_ht_devise === '' && $price_ttc === '' && $price_ttc_devise === '') { // Unit price can be 0 but not ''. Also price can be negative for order.
1023 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
1024 $error++;
1025 }
1026 if ($qty == '') {
1027 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1028 $error++;
1029 }
1030 if ($qty < 0) {
1031 setEventMessages($langs->trans('FieldCannotBeNegative', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1032 $error++;
1033 }
1034 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($line_desc)) {
1035 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
1036 $error++;
1037 }
1038
1039 if (!$error && isModEnabled('variants') && $prod_entry_mode != 'free') {
1040 if ($combinations = GETPOST('combinations', 'array')) {
1041 //Check if there is a product with the given combination
1042 $prodcomb = new ProductCombination($db);
1043
1044 if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
1045 $idprod = $res->fk_product_child;
1046 } else {
1047 setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
1048 $error++;
1049 }
1050 }
1051 }
1052
1053 if (!$error && ($qty >= 0) && (!empty($line_desc) || (!empty($idprod) && $idprod > 0))) {
1054 $pu_ht = 0;
1055 $pu_ttc = 0;
1056 $pu_ht_devise = 0;
1057 $pu_ttc_devise = 0;
1058 $price_min = 0;
1059 $price_min_ttc = 0;
1060 $tva_npr = 0;
1061 $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
1062
1063 // Clean parameters
1064 $date_start = dol_mktime(GETPOSTINT('date_start'.$predef.'hour'), GETPOSTINT('date_start'.$predef.'min'), GETPOSTINT('date_start'.$predef.'sec'), GETPOSTINT('date_start'.$predef.'month'), GETPOSTINT('date_start'.$predef.'day'), GETPOSTINT('date_start'.$predef.'year'));
1065 $date_end = dol_mktime(GETPOSTINT('date_end'.$predef.'hour'), GETPOSTINT('date_end'.$predef.'min'), GETPOSTINT('date_end'.$predef.'sec'), GETPOSTINT('date_end'.$predef.'month'), GETPOSTINT('date_end'.$predef.'day'), GETPOSTINT('date_end'.$predef.'year'));
1066
1067 $db->begin();
1068
1069 // Ecrase $pu par celui du produit
1070 // Ecrase $desc par celui du produit
1071 // Ecrase $base_price_type par celui du produit
1072 if (!empty($idprod) && $idprod > 0) {
1073 $prod = new Product($db);
1074 $prod->fetch($idprod);
1075
1076 $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
1077
1078 // Update if prices fields are defined
1079 /*$tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
1080 $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
1081 if (empty($tva_tx)) {
1082 $tva_npr = 0;
1083 }*/
1084
1085 // Price unique per product
1086 $pu_ht = $prod->price;
1087 $pu_ttc = $prod->price_ttc;
1088 $price_min = $prod->price_min;
1089 $price_min_ttc = $prod->price_min_ttc;
1090 $price_base_type = $prod->price_base_type;
1091
1092 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) {
1093 // If price per customer
1094 require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php';
1095
1096 $prodcustprice = new ProductCustomerPrice($db);
1097
1098 $filter = array('t.fk_product' => (string) $prod->id, 't.fk_soc' => (string) $object->thirdparty->id);
1099
1100 // If a price per customer exist
1101 $pricebycustomerexist = false;
1102 $result = $prodcustprice->fetchAll('', '', 0, 0, $filter);
1103 if ($result >= 0) {
1104 // If there is some prices specific to the customer
1105 if (count($prodcustprice->lines) > 0) {
1106 $date_now = (int) floor(dol_now() / 86400) * 86400; // date without hours
1107 foreach ($prodcustprice->lines as $k => $custprice_line) {
1108 if ($custprice_line->date_begin <= $date_now && (empty($custprice_line->date_end) || $date_now <= $custprice_line->date_end)) {
1109 $pricebycustomerexist = true;
1110 $pu_ht = price($custprice_line->price);
1111 $pu_ttc = price($custprice_line->price_ttc);
1112 $price_min = price($custprice_line->price_min);
1113 $price_min_ttc = price($custprice_line->price_min_ttc);
1114 $price_base_type = $custprice_line->price_base_type;
1115 /*$tva_tx = $custprice_line->tva_tx;
1116 if ($custprice_line->default_vat_code && !preg_match('/\‍(.*\‍)/', (string) $tva_tx)) {
1117 $tva_tx .= ' (' . $custprice_line->default_vat_code . ')';
1118 }
1119 $tva_npr = $custprice_line->recuperableonly;
1120 if (empty($tva_tx)) {
1121 $tva_npr = 0;
1122 }*/
1123 break;
1124 }
1125 }
1126 }
1127 } else {
1128 setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
1129 }
1130
1131 if (!$pricebycustomerexist && !empty($object->thirdparty->price_level)) { // If price per segment
1132 $pu_ht = $prod->multiprices[$object->thirdparty->price_level];
1133 $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
1134 $price_min = $prod->multiprices_min[$object->thirdparty->price_level];
1135 $price_min_ttc = $prod->multiprices_min_ttc[$object->thirdparty->price_level];
1136 $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
1137 if (getDolGlobalString('PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL')) { // using this option is a bug. kept for backward compatibility
1138 if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) {
1139 $tva_tx = $prod->multiprices_tva_tx[$object->thirdparty->price_level];
1140 }
1141 if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) {
1142 $tva_npr = $prod->multiprices_recuperableonly[$object->thirdparty->price_level];
1143 }
1144 }
1145 }
1146 } elseif (getDolGlobalString('PRODUIT_MULTIPRICES') && !empty($object->thirdparty->price_level)) { // If price per segment
1147 $pu_ht = $prod->multiprices[$object->thirdparty->price_level];
1148 $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
1149 $price_min = $prod->multiprices_min[$object->thirdparty->price_level];
1150 $price_min_ttc = $prod->multiprices_min_ttc[$object->thirdparty->price_level];
1151 $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
1152 if (getDolGlobalString('PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL')) { // using this option is a bug. kept for backward compatibility
1153 if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) {
1154 $tva_tx = $prod->multiprices_tva_tx[$object->thirdparty->price_level];
1155 }
1156 if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) {
1157 $tva_npr = $prod->multiprices_recuperableonly[$object->thirdparty->price_level];
1158 }
1159 }
1160 } elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
1161 // If price per customer
1162 require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php';
1163
1164 $prodcustprice = new ProductCustomerPrice($db);
1165
1166 $filter = array('t.fk_product' => (string) $prod->id, 't.fk_soc' => (string) $object->thirdparty->id);
1167
1168 $result = $prodcustprice->fetchAll('', '', 0, 0, $filter);
1169 if ($result >= 0) {
1170 // If there is some prices specific to the customer
1171 if (count($prodcustprice->lines) > 0) {
1172 $date_now = (int) floor(dol_now() / 86400) * 86400; // date without hours
1173 foreach ($prodcustprice->lines as $k => $custprice_line) {
1174 if ($custprice_line->date_begin <= $date_now && (empty($custprice_line->date_end) || $date_now <= $custprice_line->date_end)) {
1175 $pu_ht = price($custprice_line->price);
1176 $pu_ttc = price($custprice_line->price_ttc);
1177 $price_min = price($custprice_line->price_min);
1178 $price_min_ttc = price($custprice_line->price_min_ttc);
1179 $price_base_type = $custprice_line->price_base_type;
1180 /*$tva_tx = $custprice_line->tva_tx;
1181 if ($custprice_line->default_vat_code && !preg_match('/\‍(.*\‍)/', $tva_tx)) {
1182 $tva_tx .= ' (' . $custprice_line->default_vat_code . ')';
1183 }
1184 $tva_npr = $custprice_line->recuperableonly;
1185 if (empty($tva_tx)) {
1186 $tva_npr = 0;
1187 }*/
1188 break;
1189 }
1190 }
1191 }
1192 } else {
1193 setEventMessages($prodcustprice->error, $prodcustprice->errors, 'errors');
1194 }
1195 } elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY')) {
1196 // If price per quantity
1197 if ($prod->prices_by_qty[0]) { // yes, this product has some prices per quantity
1198 // Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
1199 $pqp = GETPOSTINT('pbq');
1200
1201 // Search price into product_price_by_qty from $prod->id
1202 foreach ($prod->prices_by_qty_list[0] as $priceforthequantityarray) {
1203 if ($priceforthequantityarray['rowid'] != $pqp) {
1204 continue;
1205 }
1206 // We found the price
1207 if ($priceforthequantityarray['price_base_type'] == 'HT') {
1208 $pu_ht = $priceforthequantityarray['unitprice'];
1209 } else {
1210 $pu_ttc = $priceforthequantityarray['unitprice'];
1211 }
1212 // Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
1213 break;
1214 }
1215 }
1216 } elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
1217 // If price per quantity and customer
1218 if ($prod->prices_by_qty[$object->thirdparty->price_level]) { // yes, this product has some prices per quantity
1219 // Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
1220 $pqp = GETPOSTINT('pbq');
1221 // Search price into product_price_by_qty from $prod->id
1222 foreach ($prod->prices_by_qty_list[$object->thirdparty->price_level] as $priceforthequantityarray) {
1223 if ($priceforthequantityarray['rowid'] != $pqp) {
1224 continue;
1225 }
1226 // We found the price
1227 if ($priceforthequantityarray['price_base_type'] == 'HT') {
1228 $pu_ht = $priceforthequantityarray['unitprice'];
1229 } else {
1230 $pu_ttc = $priceforthequantityarray['unitprice'];
1231 }
1232 // Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
1233 break;
1234 }
1235 }
1236 }
1237
1238 $tmpvat = (float) price2num(preg_replace('/\s*\‍(.*\‍)/', '', $tva_tx));
1239 $tmpprodvat = (float) price2num(preg_replace('/\s*\‍(.*\‍)/', '', (string) $prod->tva_tx));
1240
1241 // Set unit price to use
1242 if (!empty($price_ht) || (string) $price_ht === '0') {
1243 $pu_ht = (float) price2num($price_ht, 'MU');
1244 $pu_ttc = (float) price2num((float) $pu_ht * (1 + ((float) $tmpvat / 100)), 'MU');
1245 } elseif (!empty($price_ht_devise) || (string) $price_ht_devise === '0') {
1246 $pu_ht_devise = price2num($price_ht_devise, 'MU');
1247 $pu_ht = '';
1248 $pu_ttc = '';
1249 } elseif (!empty($price_ttc) || (string) $price_ttc === '0') {
1250 $pu_ttc = (float) price2num($price_ttc, 'MU');
1251 $pu_ht = (float) price2num((float) $pu_ttc / (1 + ((float) $tmpvat / 100)), 'MU');
1252 } elseif ($tmpvat != $tmpprodvat) {
1253 // Is this still used ?
1254 if ($price_base_type != 'HT') {
1255 $pu_ht = (float) price2num((float) $pu_ttc / (1 + ((float) $tmpvat / 100)), 'MU');
1256 } else {
1257 $pu_ttc = (float) price2num((float) $pu_ht * (1 + ((float) $tmpvat / 100)), 'MU');
1258 }
1259 }
1260
1261 $desc = '';
1262
1263 // Define output language
1264 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
1265 $outputlangs = $langs;
1266 $newlang = '';
1267 if (/* empty($newlang) && */ GETPOST('lang_id', 'aZ09')) {
1268 $newlang = GETPOST('lang_id', 'aZ09');
1269 }
1270 if (empty($newlang)) {
1271 $newlang = $object->thirdparty->default_lang;
1272 }
1273 if (!empty($newlang)) {
1274 $outputlangs = new Translate("", $conf);
1275 $outputlangs->setDefaultLang($newlang);
1276 }
1277
1278 $desc = (!empty($prod->multilangs[$outputlangs->defaultlang]["description"])) ? $prod->multilangs[$outputlangs->defaultlang]["description"] : $prod->description;
1279 } else {
1280 $desc = $prod->description;
1281 }
1282
1283 if (getDolGlobalInt('PRODUIT_AUTOFILL_DESC') == 0) {
1284 // 'DoNotAutofillButAutoConcat'
1285 $desc = dol_concatdesc($desc, $line_desc, false, getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION') ? true : false);
1286 } else {
1287 //'AutoFillFormFieldBeforeSubmit' or 'DoNotUseDescriptionOfProdut' => User has already done the modification they want
1288 $desc = $line_desc;
1289 }
1290
1291 // Add custom code and origin country into description
1292 if (!getDolGlobalString('MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE') && (!empty($prod->customcode) || !empty($prod->country_code))) {
1293 $tmptxt = '(';
1294 // Define output language
1295 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
1296 $outputlangs = $langs;
1297 $newlang = '';
1298 if (/* empty($newlang) && */ GETPOST('lang_id', 'alpha')) {
1299 $newlang = GETPOST('lang_id', 'alpha');
1300 }
1301 if (empty($newlang)) {
1302 $newlang = $object->thirdparty->default_lang;
1303 }
1304 if (!empty($newlang)) {
1305 $outputlangs = new Translate("", $conf);
1306 $outputlangs->setDefaultLang($newlang);
1307 $outputlangs->load('products');
1308 }
1309 if (!empty($prod->customcode)) {
1310 $tmptxt .= $outputlangs->transnoentitiesnoconv("CustomsCode").': '.$prod->customcode;
1311 }
1312 if (!empty($prod->customcode) && !empty($prod->country_code)) {
1313 $tmptxt .= ' - ';
1314 }
1315 if (!empty($prod->country_code)) {
1316 $tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, '', $db, $outputlangs, 0);
1317 }
1318 } else {
1319 if (!empty($prod->customcode)) {
1320 $tmptxt .= $langs->transnoentitiesnoconv("CustomsCode").': '.$prod->customcode;
1321 }
1322 if (!empty($prod->customcode) && !empty($prod->country_code)) {
1323 $tmptxt .= ' - ';
1324 }
1325 if (!empty($prod->country_code)) {
1326 $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin").': '.getCountry($prod->country_code, '', $db, $langs, 0);
1327 }
1328 }
1329 $tmptxt .= ')';
1330 $desc = dol_concatdesc($desc, $tmptxt);
1331 }
1332
1333 $type = $prod->type;
1334 $fk_unit = $prod->fk_unit;
1335 } else {
1336 $pu_ht = price2num($price_ht, 'MU');
1337 $pu_ttc = price2num($price_ttc, 'MU');
1338 $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
1339 $tva_tx = str_replace('*', '', $tva_tx);
1340 if (empty($tva_tx)) {
1341 $tva_npr = 0;
1342 }
1343 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1344 $desc = $line_desc;
1345 $type = GETPOST('type');
1346 $fk_unit = GETPOST('units', 'alpha');
1347 $pu_ht_devise = price2num($price_ht_devise, 'MU');
1348 $pu_ttc_devise = price2num($price_ttc_devise, 'MU');
1349
1350 if ($pu_ttc && !$pu_ht) {
1351 $price_base_type = 'TTC';
1352 }
1353 }
1354
1355 $info_bits = 0;
1356 if ($tva_npr) {
1357 $info_bits |= 0x01;
1358 }
1359
1360 // Local Taxes
1361 $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr);
1362 $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr);
1363
1364 // Margin
1365 $fournprice = (int) (GETPOST('fournprice'.$predef) ? GETPOST('fournprice'.$predef) : 0); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
1366 $buyingprice = price2num((GETPOST('buying_price'.$predef) != '' ? GETPOST('buying_price'.$predef) : ''), '', 2); // If buying_price is '0', we must keep this value
1367
1368 // Prepare a price equivalent for minimum price check
1369 $pu_equivalent = $pu_ht;
1370 $pu_equivalent_ttc = $pu_ttc;
1371
1372 $currency_tx = $object->multicurrency_tx;
1373
1374 // Check if we have a foreign currency
1375 // If so, we update the pu_equiv as the equivalent price in base currency.
1376 // multicurrency_tx is the number of foreign currency units for 1 unit of base
1377 // (see calcul_price_total() in price.lib.php which uses $pu = $pu_devise / $multicurrency_tx),
1378 // so the conversion back to base must divide, not multiply (see issue #33042).
1379 if ($pu_ht == '' && $pu_ht_devise != '' && $currency_tx != '') {
1380 $pu_equivalent = (float) $pu_ht_devise / (float) $currency_tx;
1381 }
1382 if ($pu_ttc == '' && $pu_ttc_devise != '' && $currency_tx != '') {
1383 $pu_equivalent_ttc = (float) $pu_ttc_devise / (float) $currency_tx;
1384 }
1385
1386 // TODO $pu_equivalent or $pu_equivalent_ttc must be calculated from the one not null taking into account all taxes
1387 /*
1388 if ($pu_equivalent) {
1389 $tmp = calcul_price_total(1, $pu_equivalent, 0, $tva_tx, -1, -1, 0, 'HT', $info_bits, $type);
1390 $pu_equivalent_ttc = ...
1391 } else {
1392 $tmp = calcul_price_total(1, $pu_equivalent_ttc, 0, $tva_tx, -1, -1, 0, 'TTC', $info_bits, $type);
1393 $pu_equivalent_ht = ...
1394 }
1395 */
1396
1397 //var_dump(price2num($price_min)); var_dump(price2num($pu_ht)); var_dump($remise_percent);
1398 //var_dump(price2num($price_min_ttc)); var_dump(price2num($pu_ttc)); var_dump($remise_percent);exit;
1399
1400 $desc = dol_htmlcleanlastbr($desc);
1401
1402 // Check price is not lower than minimum
1403 if ($usermustrespectpricemin) {
1404 if ($pu_equivalent && $price_min && (((float) price2num($pu_equivalent) * (1 - $remise_percent / 100)) < (float) price2num($price_min)) && $price_base_type == 'HT') {
1405 $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
1406 setEventMessages($mesg, null, 'errors');
1407 $error++;
1408 } elseif ($pu_equivalent_ttc && $price_min_ttc && (((float) price2num($pu_equivalent_ttc) * (1 - $remise_percent / 100)) < (float) price2num($price_min_ttc)) && $price_base_type == 'TTC') {
1409 $mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
1410 setEventMessages($mesg, null, 'errors');
1411 $error++;
1412 }
1413 }
1414
1415 if (!$error) {
1416 // Insert line
1417 $result = $object->addline($desc, $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, min($rank, count($object->lines) + 1), 0, GETPOSTINT('fk_parent_line'), (int) $fournprice, $buyingprice, $label, $array_options, $fk_unit, '', 0, (float) $pu_ht_devise);
1418
1419 if ($result > 0) {
1420 $db->commit();
1421
1422 $ret = $object->fetch($object->id); // Reload to get new records
1423 if ($ret > 0) {
1424 $object->fetch_thirdparty();
1425 }
1426
1427 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1428 // Define output language
1429 $outputlangs = $langs;
1430 $newlang = GETPOST('lang_id', 'alpha');
1431 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1432 $newlang = $object->thirdparty->default_lang;
1433 }
1434 if (!empty($newlang)) {
1435 $outputlangs = new Translate("", $conf);
1436 $outputlangs->setDefaultLang($newlang);
1437 }
1438
1439 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1440 }
1441
1442 unset($_POST['prod_entry_mode']);
1443
1444 unset($_POST['qty']);
1445 unset($_POST['type']);
1446 unset($_POST['remise_percent']);
1447 unset($_POST['price_ht']);
1448 unset($_POST['multicurrency_price_ht']);
1449 unset($_POST['price_ttc']);
1450 unset($_POST['tva_tx']);
1451 unset($_POST['product_ref']);
1452 unset($_POST['product_label']);
1453 unset($_POST['product_desc']);
1454 unset($_POST['fournprice']);
1455 unset($_POST['buying_price']);
1456 unset($_POST['np_marginRate']);
1457 unset($_POST['np_markRate']);
1458 unset($_POST['dp_desc']);
1459 unset($_POST['idprod']);
1460 unset($_POST['units']);
1461
1462 unset($_POST['date_starthour']);
1463 unset($_POST['date_startmin']);
1464 unset($_POST['date_startsec']);
1465 unset($_POST['date_startday']);
1466 unset($_POST['date_startmonth']);
1467 unset($_POST['date_startyear']);
1468 unset($_POST['date_endhour']);
1469 unset($_POST['date_endmin']);
1470 unset($_POST['date_endsec']);
1471 unset($_POST['date_endday']);
1472 unset($_POST['date_endmonth']);
1473 unset($_POST['date_endyear']);
1474 } else {
1475 $db->rollback();
1476
1477 setEventMessages($object->error, $object->errors, 'errors');
1478 }
1479 }
1480 }
1481 } elseif ($action == 'updatetitleline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1482 // Handling updating a title line for subtotals module
1483
1484 $langs->load('subtotals');
1485
1486 $desc = GETPOST('line_desc', 'alphanohtml') ?? $langs->trans("Title");
1487 $depth = GETPOSTINT('line_depth') ?? 1;
1488
1489 $subtotal_options = array();
1490
1491 foreach (Commande::$TITLE_OPTIONS as $option) {
1492 $value = GETPOST($option, 'alphanohtml');
1493 if ($value) {
1494 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
1495 }
1496 }
1497
1498 // Update line
1499 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
1500
1501 if ($result >= 0) {
1502 if ($result == 0) {
1503 setEventMessages($object->error, $object->errors, 'warnings');
1504 }
1505 $ret = $object->fetch($object->id); // Reload to get new records
1506 $object->fetch_thirdparty();
1507
1508 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1509 // Define output language
1510 $outputlangs = $langs;
1511 $newlang = GETPOST('lang_id', 'alpha');
1512 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1513 $newlang = $object->thirdparty->default_lang;
1514 }
1515 if (!empty($newlang)) {
1516 $outputlangs = new Translate("", $conf);
1517 $outputlangs->setDefaultLang($newlang);
1518 }
1519
1520 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1521 }
1522 } else {
1523 setEventMessages($object->error, $object->errors, 'errors');
1524 }
1525 } elseif ($action == 'updatesubtotalline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1526 // Handling updating a subtotal line for subtotals module
1527
1528 $langs->load('subtotals');
1529
1530 $desc = GETPOST('line_desc', 'alphanohtml');
1531 $depth = GETPOSTINT('line_depth');
1532
1533 $subtotal_options = array();
1534
1535 foreach (Commande::$SUBTOTAL_OPTIONS as $option) {
1536 $value = GETPOST($option, 'alphanohtml');
1537 if ($value) {
1538 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
1539 }
1540 }
1541
1542 // Update line
1543 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
1544
1545 if ($result > 0) {
1546 $ret = $object->fetch($object->id); // Reload to get new records
1547 $object->fetch_thirdparty();
1548
1549 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1550 // Define output language
1551 $outputlangs = $langs;
1552 $newlang = GETPOST('lang_id', 'alpha');
1553 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1554 $newlang = $object->thirdparty->default_lang;
1555 }
1556 if (!empty($newlang)) {
1557 $outputlangs = new Translate("", $conf);
1558 $outputlangs->setDefaultLang($newlang);
1559 }
1560
1561 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1562 }
1563 } else {
1564 setEventMessages($object->error, $object->errors, 'errors');
1565 }
1566 } elseif ($action == 'updateline' && $usercancreate && GETPOST('save')) {
1567 // Update a line
1568
1569 // Clean parameters
1570 $date_start = '';
1571 $date_end = '';
1572 $date_start = dol_mktime(GETPOSTINT('date_starthour'), GETPOSTINT('date_startmin'), GETPOSTINT('date_startsec'), GETPOSTINT('date_startmonth'), GETPOSTINT('date_startday'), GETPOSTINT('date_startyear'));
1573 $date_end = dol_mktime(GETPOSTINT('date_endhour'), GETPOSTINT('date_endmin'), GETPOSTINT('date_endsec'), GETPOSTINT('date_endmonth'), GETPOSTINT('date_endday'), GETPOSTINT('date_endyear'));
1574
1575 $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml'));
1576
1577 // Define info_bits
1578 $info_bits = 0;
1579 if (preg_match('/\*/', GETPOST('tva_tx'))) {
1580 $info_bits |= 0x01;
1581 }
1582
1583 // Define vat_rate
1584 $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx', 'alpha') : 0);
1585 $vat_rate = str_replace('*', '', $vat_rate);
1586 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
1587 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
1588 $pu_ht = price2num(GETPOST('price_ht'), '', 2);
1589 $pu_ttc = price2num(GETPOST('price_ttc'), '', 2);
1590
1591 $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), '', 2);
1592 $pu_ttc_devise = price2num(GETPOST('multicurrency_subprice_ttc'), '', 2);
1593
1594 $qty = price2num(GETPOST('qty', 'alpha'), 'MS');
1595
1596 // Prepare a price equivalent for minimum price check
1597 $pu_equivalent = $pu_ht;
1598 $pu_equivalent_ttc = $pu_ttc;
1599
1600 $currency_tx = $object->multicurrency_tx;
1601
1602 // Check if we have a foreign currency
1603 // If so, we update the pu_equiv as the equivalent price in base currency.
1604 // multicurrency_tx is the number of foreign currency units for 1 unit of base
1605 // (see calcul_price_total() in price.lib.php which uses $pu = $pu_devise / $multicurrency_tx),
1606 // so the conversion back to base must divide, not multiply (see issue #33042).
1607 if ($pu_ht == '' && $pu_ht_devise != '' && $currency_tx != '') {
1608 $pu_equivalent = (float) $pu_ht_devise / (float) $currency_tx;
1609 }
1610 if ($pu_ttc == '' && $pu_ttc_devise != '' && $currency_tx != '') {
1611 $pu_equivalent_ttc = (float) $pu_ttc_devise / (float) $currency_tx;
1612 }
1613
1614 // TODO $pu_equivalent or $pu_equivalent_ttc must be calculated from the one not null taking into account all taxes
1615 /*
1616 if ($pu_equivalent) {
1617 $tmp = calcul_price_total(1, $pu_equivalent, 0, $vat_rate, -1, -1, 0, 'HT', $info_bits, $type);
1618 $pu_equivalent_ttc = ...
1619 } else {
1620 $tmp = calcul_price_total(1, $pu_equivalent_ttc, 0, $vat_rate, -1, -1, 0, 'TTC', $info_bits, $type);
1621 $pu_equivalent_ht = ...
1622 }
1623 */
1624
1625 // Add buying price
1626 $fournprice = (int) (GETPOST('fournprice') ? GETPOST('fournprice') : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
1627 $buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we must keep this value
1628
1629 // Extrafields Lines
1630 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1631 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
1632 // Unset extrafield POST Data
1633 if (is_array($extralabelsline)) {
1634 foreach ($extralabelsline as $key => $value) {
1635 unset($_POST["options_".$key]);
1636 }
1637 }
1638
1639 // Define special_code for special lines
1640 $special_code = GETPOSTINT('special_code');
1641 if (!GETPOST('qty')) {
1642 $special_code = 3;
1643 }
1644
1645 $remise_percent = GETPOST('remise_percent') != '' ? price2num(GETPOST('remise_percent'), '', 2) : 0;
1646
1647 $pu = $pu_ht;
1648 $price_base_type = 'HT';
1649 if (empty($pu) && !empty($pu_ttc)) {
1650 $pu = $pu_ttc;
1651 $price_base_type = 'TTC';
1652 }
1653
1654 // Check minimum price
1655 $productid = GETPOSTINT('productid');
1656 if (!empty($productid)) {
1657 $product = new Product($db);
1658 $product->fetch($productid);
1659
1660 $type = $product->type;
1661
1662 $price_min = $product->price_min;
1663 if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) && !empty($object->thirdparty->price_level)) {
1664 $price_min = $product->multiprices_min[$object->thirdparty->price_level];
1665 }
1666 $price_min_ttc = $product->price_min_ttc;
1667 if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) && !empty($object->thirdparty->price_level)) {
1668 $price_min_ttc = $product->multiprices_min_ttc[$object->thirdparty->price_level];
1669 }
1670
1671 $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
1672
1673 // Check price is not lower than minimum
1674 if ($usermustrespectpricemin) {
1675 if ($pu_equivalent && $price_min && (((float) price2num($pu_equivalent) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min)) && $price_base_type == 'HT') {
1676 $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
1677 setEventMessages($mesg, null, 'errors');
1678 $error++;
1679 $action = 'editline';
1680 } elseif ($pu_equivalent_ttc && $price_min_ttc && (((float) price2num($pu_equivalent_ttc) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min_ttc)) && $price_base_type == 'TTC') {
1681 $mesg = $langs->trans("CantBeLessThanMinPriceInclTax", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
1682 setEventMessages($mesg, null, 'errors');
1683 $error++;
1684 $action = 'editline';
1685 }
1686 }
1687 } else {
1688 $type = GETPOST('type');
1689 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1690
1691 // Check parameters
1692 if (GETPOST('type') < 0) {
1693 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
1694 $error++;
1695 $action = 'editline';
1696 }
1697 }
1698
1699 if ($qty < 0) {
1700 setEventMessages($langs->trans('FieldCannotBeNegative', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
1701 $error++;
1702 $action = 'editline';
1703 }
1704
1705 $object->loadExpeditions();
1706 if (isset($object->expeditions[GETPOST('lineid', 'int')])) {
1707 if ($qty < $object->expeditions[GETPOST('lineid', 'int')]) {
1708 setEventMessages($langs->trans('ErrorQtyOrderedLessQtyShipped'), null, 'errors');
1709 $error++;
1710 $action = 'editline';
1711 }
1712 }
1713
1714 if (!$error) {
1715 $db->begin();
1716
1717 if (!$user->hasRight('margins', 'creer')) {
1718 foreach ($object->lines as &$line) {
1719 if ($line->id == GETPOSTINT('lineid')) {
1720 $fournprice = $line->fk_fournprice;
1721 $buyingprice = $line->pa_ht;
1722 break;
1723 }
1724 }
1725 }
1726
1727 $qty = price2num(GETPOST('qty', 'alpha'), 'MS');
1728
1729 $result = $object->updateline(GETPOSTINT('lineid'), $description, (float) $pu, (float) $qty, $remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $price_base_type, $info_bits, $date_start, $date_end, $type, GETPOSTINT('fk_parent_line'), 0, (int) $fournprice, $buyingprice, $label, $special_code, $array_options, GETPOSTINT('units'), (float) $pu_ht_devise);
1730
1731 if ($result >= 0) {
1732 $db->commit();
1733
1734 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1735 // Define output language
1736 $outputlangs = $langs;
1737 $newlang = '';
1738 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1739 $newlang = GETPOST('lang_id', 'aZ09');
1740 }
1741 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1742 $newlang = $object->thirdparty->default_lang;
1743 }
1744 if (!empty($newlang)) {
1745 $outputlangs = new Translate("", $conf);
1746 $outputlangs->setDefaultLang($newlang);
1747 }
1748
1749 $ret = $object->fetch($object->id); // Reload to get new records
1750 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1751 }
1752
1753 unset($_POST['qty']);
1754 unset($_POST['type']);
1755 unset($_POST['productid']);
1756 unset($_POST['remise_percent']);
1757 unset($_POST['price_ht']);
1758 unset($_POST['multicurrency_price_ht']);
1759 unset($_POST['price_ttc']);
1760 unset($_POST['tva_tx']);
1761 unset($_POST['product_ref']);
1762 unset($_POST['product_label']);
1763 unset($_POST['product_desc']);
1764 unset($_POST['fournprice']);
1765 unset($_POST['buying_price']);
1766
1767 unset($_POST['date_starthour']);
1768 unset($_POST['date_startmin']);
1769 unset($_POST['date_startsec']);
1770 unset($_POST['date_startday']);
1771 unset($_POST['date_startmonth']);
1772 unset($_POST['date_startyear']);
1773 unset($_POST['date_endhour']);
1774 unset($_POST['date_endmin']);
1775 unset($_POST['date_endsec']);
1776 unset($_POST['date_endday']);
1777 unset($_POST['date_endmonth']);
1778 unset($_POST['date_endyear']);
1779 } else {
1780 $db->rollback();
1781
1782 setEventMessages($object->error, $object->errors, 'errors');
1783 }
1784 }
1785 } elseif ($action == 'updateline' && $usercancreate && GETPOST('cancel', 'alpha')) {
1786 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To re-display card in edit mode
1787 exit();
1788 } elseif ($action == 'confirm_validate' && $confirm == 'yes' && $usercanvalidate) {
1789 $idwarehouse = GETPOSTINT('idwarehouse');
1790
1791 $qualified_for_stock_change = 0;
1792 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1793 $qualified_for_stock_change = $object->hasProductsOrServices(2);
1794 } else {
1795 $qualified_for_stock_change = $object->hasProductsOrServices(1);
1796 }
1797
1798 // Check parameters
1799 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
1800 if (!$idwarehouse || $idwarehouse == -1) {
1801 $error++;
1802 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1803 $action = '';
1804 }
1805 }
1806
1807 if (!$error) {
1808 $locationTarget = '';
1809
1810 $db->begin();
1811
1812 $result = $object->valid($user, $idwarehouse);
1813 if ($result >= 0) {
1814 $error = 0;
1815 $deposit = null;
1816
1817 $deposit_percent_from_payment_terms = (float) getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id);
1818
1819 if (
1820 GETPOST('generate_deposit', 'alpha') == 'on' && !empty($deposit_percent_from_payment_terms)
1821 && isModEnabled('invoice') && $user->hasRight('facture', 'creer')
1822 ) {
1823 require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
1824
1825 $date = dol_mktime(0, 0, 0, GETPOSTINT('datefmonth'), GETPOSTINT('datefday'), GETPOSTINT('datefyear'));
1826 $forceFields = array();
1827
1828 if (GETPOSTISSET('date_pointoftax')) {
1829 $forceFields['date_pointoftax'] = dol_mktime(0, 0, 0, GETPOSTINT('date_pointoftaxmonth'), GETPOSTINT('date_pointoftaxday'), GETPOSTINT('date_pointoftaxyear'));
1830 }
1831
1832 $deposit = Facture::createDepositFromOrigin($object, $date, GETPOSTINT('cond_reglement_id'), $user, 0, GETPOSTINT('validate_generated_deposit') == 'on', $forceFields);
1833
1834 if ($deposit) {
1835 setEventMessage('DepositGenerated');
1836 $locationTarget = DOL_URL_ROOT . '/compta/facture/card.php?id=' . $deposit->id;
1837 } else {
1838 $error++;
1839 setEventMessages($object->error, $object->errors, 'errors');
1840 }
1841 }
1842
1843 // Define output language
1844 if (! $error) {
1845 $db->commit();
1846
1847 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1848 $outputlangs = $langs;
1849 $newlang = '';
1850 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1851 $newlang = GETPOST('lang_id', 'aZ09');
1852 }
1853 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1854 $newlang = $object->thirdparty->default_lang;
1855 }
1856 if (!empty($newlang)) {
1857 $outputlangs = new Translate("", $conf);
1858 $outputlangs->setDefaultLang($newlang);
1859 }
1860 $model = $object->model_pdf;
1861 $ret = $object->fetch($id); // Reload to get new records
1862
1863 $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1864
1865 if ($deposit) {
1866 $deposit->fetch($deposit->id); // Reload to get new records
1867 $deposit->generateDocument($deposit->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1868 }
1869 }
1870
1871 if ($locationTarget) {
1872 header('Location: ' . $locationTarget);
1873 exit;
1874 }
1875 } else {
1876 $db->rollback();
1877 }
1878 } else {
1879 $db->rollback();
1880 setEventMessages($object->error, $object->errors, 'errors');
1881 }
1882 }
1883 } elseif ($action == 'confirm_modif' && $usercancreate) {
1884 // Go back to draft status
1885 $idwarehouse = GETPOST('idwarehouse');
1886
1887 $qualified_for_stock_change = 0;
1888 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1889 $qualified_for_stock_change = $object->hasProductsOrServices(2);
1890 } else {
1891 $qualified_for_stock_change = $object->hasProductsOrServices(1);
1892 }
1893
1894 // Check parameters
1895 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
1896 if (!$idwarehouse || $idwarehouse == -1) {
1897 $error++;
1898 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1899 $action = '';
1900 }
1901 }
1902
1903 if (!$error) {
1904 $result = $object->setDraft($user, $idwarehouse);
1905 if ($result >= 0) {
1906 // Define output language
1907 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1908 $outputlangs = $langs;
1909 $newlang = '';
1910 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1911 $newlang = GETPOST('lang_id', 'aZ09');
1912 }
1913 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1914 $newlang = $object->thirdparty->default_lang;
1915 }
1916 if (!empty($newlang)) {
1917 $outputlangs = new Translate("", $conf);
1918 $outputlangs->setDefaultLang($newlang);
1919 }
1920 $model = $object->model_pdf;
1921 $ret = $object->fetch($id); // Reload to get new records
1922
1923 $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1924 }
1925 } else {
1926 setEventMessages($object->error, $object->errors, 'errors');
1927 }
1928 }
1929 } elseif ($action == 'confirm_shipped' && $confirm == 'yes' && $usercanclose) {
1930 $result = $object->cloture($user);
1931 if ($result < 0) {
1932 setEventMessages($object->error, $object->errors, 'errors');
1933 }
1934 } elseif ($action == 'confirm_cancel' && $confirm == 'yes' && $usercanvalidate) {
1935 $idwarehouse = GETPOSTINT('idwarehouse');
1936
1937 $qualified_for_stock_change = 0;
1938 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1939 $qualified_for_stock_change = $object->hasProductsOrServices(2);
1940 } else {
1941 $qualified_for_stock_change = $object->hasProductsOrServices(1);
1942 }
1943
1944 // Check parameters
1945 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
1946 if (!$idwarehouse || $idwarehouse == -1) {
1947 $error++;
1948 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1949 $action = '';
1950 }
1951 }
1952
1953 if (!$error) {
1954 $result = $object->cancel($idwarehouse);
1955
1956 if ($result < 0) {
1957 setEventMessages($object->error, $object->errors, 'errors');
1958 }
1959 }
1960 }
1961
1962 if ($action == 'update_extras' && $permissiontoeditextra) {
1963 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
1964
1965 $attribute_name = GETPOST('attribute', 'aZ09');
1966
1967 // Fill array 'array_options' with data from update form
1968 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
1969 if ($ret < 0) {
1970 $error++;
1971 }
1972
1973 if (!$error) {
1974 // Actions on extra fields
1975 $result = $object->updateExtraField($attribute_name, 'ORDER_MODIFY');
1976 if ($result < 0) {
1977 setEventMessages($object->error, $object->errors, 'errors');
1978 $error++;
1979 }
1980 }
1981
1982 if ($error) {
1983 $action = 'edit_extras';
1984 }
1985 }
1986
1987 // Add lines from objectlinked
1988 if ($action == 'import_lines_from_object' && $usercancreate && $object->status == Commande::STATUS_DRAFT) {
1989 $fromElement = GETPOST('fromelement');
1990 $fromElementid = GETPOST('fromelementid');
1991 $importLines = GETPOST('line_checkbox');
1992
1993 if (!empty($importLines) && is_array($importLines) && !empty($fromElement) && ctype_alpha($fromElement) && !empty($fromElementid)) {
1994 if ($fromElement == 'commande') {
1995 dol_include_once('/'.$fromElement.'/class/'.$fromElement.'.class.php');
1996 $lineClassName = 'OrderLine';
1997 } elseif ($fromElement == 'propal') {
1998 dol_include_once('/comm/'.$fromElement.'/class/'.$fromElement.'.class.php');
1999 $lineClassName = 'PropaleLigne';
2000 } elseif ($fromElement == 'facture') {
2001 dol_include_once('/compta/'.$fromElement.'/class/'.$fromElement.'.class.php');
2002 $lineClassName = 'FactureLigne';
2003 }
2004 $nextRang = count($object->lines) + 1;
2005 $importCount = 0;
2006 $error = 0;
2007 foreach ($importLines as $lineId) {
2008 $lineId = intval($lineId);
2009 $originLine = new $lineClassName($db);
2010 if (intval($fromElementid) > 0 && $originLine->fetch($lineId) > 0) {
2011 $originLine->fetch_optionals();
2012 $desc = $originLine->desc;
2013 $pu_ht = $originLine->subprice;
2014 $qty = $originLine->qty;
2015 $txtva = $originLine->tva_tx;
2016 $txlocaltax1 = $originLine->localtax1_tx;
2017 $txlocaltax2 = $originLine->localtax2_tx;
2018 $fk_product = $originLine->fk_product;
2019 $remise_percent = $originLine->remise_percent;
2020 $date_start = $originLine->date_start;
2021 $date_end = $originLine->date_end;
2022 $fk_code_ventilation = 0;
2023 $info_bits = $originLine->info_bits;
2024 $fk_remise_except = $originLine->fk_remise_except;
2025 $price_base_type = 'HT';
2026 $pu_ttc = 0;
2027 $type = $originLine->product_type;
2028 $rang = $nextRang++;
2029 $special_code = $originLine->special_code;
2030 $origin = $originLine->element;
2031 $origin_id = $originLine->id;
2032 $fk_parent_line = 0;
2033 $fk_fournprice = $originLine->fk_fournprice;
2034 $pa_ht = $originLine->pa_ht;
2035 $label = $originLine->label;
2036 $array_options = $originLine->array_options;
2037 $situation_percent = 100;
2038 $fk_prev_id = '';
2039 $fk_unit = $originLine->fk_unit;
2040 $pu_ht_devise = $originLine->multicurrency_subprice;
2041
2042 $res = $object->addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $remise_percent, $info_bits, $fk_remise_except, $price_base_type, $pu_ttc, $date_start, $date_end, $type, $rang, $special_code, $fk_parent_line, $fk_fournprice, $pa_ht, $label, $array_options, $fk_unit, $origin, $origin_id, $pu_ht_devise);
2043
2044 if ($res > 0) {
2045 $importCount++;
2046 } else {
2047 $error++;
2048 }
2049 } else {
2050 $error++;
2051 }
2052 }
2053
2054 if ($error) {
2055 setEventMessages($langs->trans('ErrorsOnXLines', $error), null, 'errors');
2056 }
2057 }
2058 }
2059
2060 // Actions when printing a doc from card
2061 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
2062
2063 // Actions to build doc
2064 $upload_dir = !empty($conf->commande->multidir_output[$object->entity]) ? $conf->commande->multidir_output[$object->entity] : $conf->commande->dir_output;
2065 $permissiontoadd = $usercancreate;
2066 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
2067
2068 // Actions to send emails
2069 $triggersendname = 'ORDER_SENTBYMAIL';
2070 $paramname = 'id';
2071 $autocopy = 'MAIN_MAIL_AUTOCOPY_ORDER_TO'; // used to know the automatic BCC to add
2072 $trackid = 'ord'.$object->id;
2073 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
2074
2075
2076 if (!$error && getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB') && $usercancreate) {
2077 if ($action == 'addcontact' && $usercancreate) {
2078 if ($object->id > 0) {
2079 $contactid = (GETPOST('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid'));
2080 $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
2081 $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
2082 }
2083
2084 if ($result >= 0) {
2085 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
2086 exit();
2087 } else {
2088 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
2089 $langs->load("errors");
2090 setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
2091 } else {
2092 setEventMessages($object->error, $object->errors, 'errors');
2093 }
2094 }
2095 } elseif ($action == 'swapstatut' && $usercancreate) {
2096 // bascule du statut d'un contact
2097 if ($object->id > 0) {
2098 $result = $object->swapContactStatus(GETPOSTINT('ligne'));
2099 } else {
2100 dol_print_error($db);
2101 }
2102 } elseif ($action == 'deletecontact' && $usercancreate) {
2103 // Efface un contact
2104 $result = $object->delete_contact($lineid);
2105
2106 if ($result >= 0) {
2107 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
2108 exit();
2109 } else {
2110 dol_print_error($db);
2111 }
2112 }
2113 }
2114}
2115
2116
2117/*
2118 * View
2119 */
2120
2121$title = $object->ref." - ".$langs->trans('Card');
2122if ($action == 'create') {
2123 $title = $langs->trans("NewOrder");
2124}
2125$help_url = 'EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes|DE:Modul_Kundenaufträge';
2126
2127llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-order page-card');
2128
2129$form = new Form($db);
2130$formfile = new FormFile($db);
2131$formorder = new FormOrder($db);
2132$formmargin = new FormMargin($db);
2133if (isModEnabled('project')) {
2134 $formproject = new FormProjets($db);
2135}
2136
2137// Mode creation
2138if ($action == 'create' && $usercancreate) {
2139 print load_fiche_titre($langs->trans('CreateOrder'), '', 'order');
2140
2141 $soc = new Societe($db);
2142 if ($socid > 0) {
2143 $res = $soc->fetch($socid);
2144 }
2145
2146 //$remise_absolue = 0;
2147
2148 $currency_code = $conf->currency;
2149
2150 $cond_reglement_id = GETPOSTINT('cond_reglement_id');
2151 $deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
2152 $mode_reglement_id = GETPOSTINT('mode_reglement_id');
2153 $fk_account = GETPOSTINT('fk_account');
2154
2155 if (!empty($origin) && !empty($originid)) {
2156 // Parse element/subelement (ex: project_task)
2157 $element = $subelement = $origin;
2158 $regs = array();
2159 if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
2160 $element = $regs[1];
2161 $subelement = $regs[2];
2162 }
2163
2164 if ($element == 'project') {
2165 $projectid = $originid;
2166
2167 if (!$cond_reglement_id) {
2168 $cond_reglement_id = $soc->cond_reglement_id;
2169 }
2170 if (!$deposit_percent) {
2171 $deposit_percent = $soc->deposit_percent;
2172 }
2173 if (!$mode_reglement_id) {
2174 $mode_reglement_id = $soc->mode_reglement_id;
2175 }
2176 if (!$remise_percent) {
2177 $remise_percent = $soc->remise_percent;
2178 }
2179 /*if (!$dateorder) {
2180 // Do not set 0 here (0 for a date is 1970)
2181 $dateorder = (empty($dateinvoice) ? (empty($conf->global->MAIN_AUTOFILL_DATE_ORDER) ?-1 : '') : $dateorder);
2182 }*/
2183 } else {
2184 // For compatibility
2185 if ($element == 'order' || $element == 'commande') {
2186 $element = $subelement = 'commande';
2187 } elseif ($element == 'propal') {
2188 $element = 'comm/propal';
2189 $subelement = 'propal';
2190 } elseif ($element == 'contract') {
2191 $element = $subelement = 'contrat';
2192 }
2193
2194 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
2195
2196 $classname = ucfirst($subelement);
2197 $objectsrc = new $classname($db);
2198 '@phan-var-force Commande|Propal|Contrat $objectsrc'; // Can possibly be other class but CommonObject is too general
2199 $objectsrc->fetch($originid);
2200 if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
2201 $objectsrc->fetch_lines();
2202 }
2203 $objectsrc->fetch_thirdparty();
2204
2205 // Replicate extrafields
2206 $objectsrc->fetch_optionals();
2207 $object->array_options = $objectsrc->array_options;
2208
2209 $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
2210 $ref_client = (!empty($objectsrc->ref_client) ? $objectsrc->ref_client : '');
2211
2212 $soc = $objectsrc->thirdparty;
2213 $cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0));
2214 $deposit_percent = (!empty($objectsrc->deposit_percent) ? $objectsrc->deposit_percent : (!empty($soc->deposit_percent) ? $soc->deposit_percent : null));
2215 $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0));
2216 $fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0));
2217 $availability_id = (!empty($objectsrc->availability_id) ? $objectsrc->availability_id : 0);
2218 $shipping_method_id = (!empty($objectsrc->shipping_method_id) ? $objectsrc->shipping_method_id : (!empty($soc->shipping_method_id) ? $soc->shipping_method_id : 0));
2219 $warehouse_id = (!empty($objectsrc->warehouse_id) ? $objectsrc->warehouse_id : (!empty($soc->warehouse_id) ? $soc->warehouse_id : 0));
2220 $demand_reason_id = (!empty($objectsrc->demand_reason_id) ? $objectsrc->demand_reason_id : (!empty($soc->demand_reason_id) ? $soc->demand_reason_id : 0));
2221 //$remise_percent = (!empty($objectsrc->remise_percent) ? $objectsrc->remise_percent : (!empty($soc->remise_percent) ? $soc->remise_percent : 0));
2222 //$remise_absolue = (!empty($objectsrc->remise_absolue) ? $objectsrc->remise_absolue : (!empty($soc->remise_absolue) ? $soc->remise_absolue : 0));
2223 $dateorder = !getDolGlobalString('MAIN_AUTOFILL_DATE_ORDER') ? -1 : '';
2224
2225 $date_delivery = (!empty($objectsrc->delivery_date) ? $objectsrc->delivery_date : '');
2226
2227 if (isModEnabled("multicurrency")) {
2228 if (!empty($objectsrc->multicurrency_code)) {
2229 $currency_code = $objectsrc->multicurrency_code;
2230 }
2231 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
2232 $currency_tx = $objectsrc->multicurrency_tx;
2233 }
2234 }
2235
2236 $note_private = $object->getDefaultCreateValueFor('note_private', (!empty($objectsrc->note_private) ? $objectsrc->note_private : null));
2237 $note_public = $object->getDefaultCreateValueFor('note_public', (!empty($objectsrc->note_public) ? $objectsrc->note_public : null));
2238
2239 // Object source contacts list
2240 $srccontactslist = $objectsrc->liste_contact(-1, 'external', 1);
2241 }
2242 } else {
2243 $cond_reglement_id = empty($soc->cond_reglement_id) ? $cond_reglement_id : $soc->cond_reglement_id;
2244 $deposit_percent = empty($soc->deposit_percent) ? $deposit_percent : $soc->deposit_percent;
2245 $mode_reglement_id = empty($soc->mode_reglement_id) ? $mode_reglement_id : $soc->mode_reglement_id;
2246 $fk_account = empty($soc->mode_reglement_id) ? $fk_account : $soc->fk_account;
2247 $availability_id = 0;
2248 $shipping_method_id = $soc->shipping_method_id;
2249 $warehouse_id = $soc->fk_warehouse;
2250 $demand_reason_id = $soc->demand_reason_id;
2251 //$remise_percent = $soc->remise_percent;
2252 //$remise_absolue = 0;
2253 $dateorder = !getDolGlobalString('MAIN_AUTOFILL_DATE_ORDER') ? -1 : '';
2254
2255 if (isModEnabled("multicurrency") && !empty($soc->multicurrency_code)) {
2256 $currency_code = $soc->multicurrency_code;
2257 }
2258
2259 $note_private = $object->getDefaultCreateValueFor('note_private');
2260 $note_public = $object->getDefaultCreateValueFor('note_public');
2261 }
2262
2263 // If form was posted (but error returned), we must reuse the value posted in priority (standard Dolibarr behaviour)
2264 if (!GETPOST('changecompany')) {
2265 if (GETPOSTISSET('cond_reglement_id')) {
2266 $cond_reglement_id = GETPOSTINT('cond_reglement_id');
2267 }
2268 if (GETPOSTISSET('deposit_percent')) {
2269 $deposit_percent = GETPOSTFLOAT('deposit_percent');
2270 }
2271 if (GETPOSTISSET('mode_reglement_id')) {
2272 $mode_reglement_id = GETPOSTINT('mode_reglement_id');
2273 }
2274 if (GETPOSTISSET('cond_reglement_id')) {
2275 $fk_account = GETPOSTINT('fk_account');
2276 }
2277 }
2278
2279 // Warehouse default if null
2280 if ($soc->fk_warehouse > 0) {
2281 $warehouse_id = $soc->fk_warehouse;
2282 }
2283 if (isModEnabled('stock') && empty($warehouse_id) && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
2284 if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
2285 $warehouse_id = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE');
2286 }
2287 if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->fk_warehouse)) {
2288 $warehouse_id = $user->fk_warehouse;
2289 }
2290 }
2291
2292 print '<form name="crea_commande" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
2293 print '<input type="hidden" name="token" value="'.newToken().'">';
2294 print '<input type="hidden" name="action" value="add">';
2295 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
2296 print '<input type="hidden" name="remise_percent" value="'.$soc->remise_percent.'">';
2297 print '<input type="hidden" name="origin" value="'.$origin.'">';
2298 print '<input type="hidden" name="originid" value="'.$originid.'">';
2299 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2300 if (!empty($currency_tx)) {
2301 print '<input type="hidden" name="originmulticurrency_tx" value="'.$currency_tx.'">';
2302 }
2303
2304 print dol_get_fiche_head([]);
2305
2306 // Call Hook tabContentCreateOrder
2307 $parameters = array();
2308 // Note that $action and $object may be modified by hook
2309 $reshook = $hookmanager->executeHooks('tabContentCreateOrder', $parameters, $object, $action);
2310 if (empty($reshook)) {
2311 print '<table class="border centpercent">';
2312
2313 // Reference
2314 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Ref').'</td><td>'.$langs->trans("Draft").'</td></tr>';
2315
2316 // Reference client
2317 print '<tr><td>'.$langs->trans('RefCustomer').'</td><td>';
2318 if (getDolGlobalString('MAIN_USE_PROPAL_REFCLIENT_FOR_ORDER') && !empty($origin) && !empty($originid)) {
2319 print '<input type="text" name="ref_client" value="'.$ref_client.'"></td>';
2320 } else {
2321 print '<input type="text" name="ref_client" value="'.GETPOST('ref_client').'"></td>';
2322 }
2323 print '</tr>';
2324
2325 // Thirdparty
2326 print '<tr>';
2327 print '<td class="fieldrequired">'.$langs->trans('Customer').'</td>';
2328 if ($socid > 0) {
2329 print '<td>';
2330 print $soc->getNomUrl(1, 'customer');
2331 print '<input type="hidden" name="socid" value="'.$soc->id.'">';
2332 print '</td>';
2333 } else {
2334 print '<td class="valuefieldcreate">';
2335 $filter = '((s.client:IN:1,2,3) AND (s.status:=:1))';
2336 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
2337 // reload page to retrieve customer information
2338 if (!getDolGlobalString('RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED')) {
2339 print '<script>
2340 $(document).ready(function() {
2341 $("#socid").change(function() {
2342 console.log("We have changed the company - Reload page");
2343 var socid = $(this).val();
2344 // reload page
2345 $("input[name=action]").val("create");
2346 $("input[name=changecompany]").val("1");
2347 $("form[name=crea_commande]").submit();
2348 });
2349 });
2350 </script>';
2351 }
2352 print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&customer=3&fournisseur=0&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddThirdParty").'"></span></a>';
2353 print '</td>';
2354 }
2355 print '</tr>'."\n";
2356
2357 // Contact of order
2358 if ($socid > 0) {
2359 // Contacts (ask contact only if thirdparty already defined).
2360 // print "<tr><td>".$langs->trans("DefaultContact").'</td><td>';
2361 print "<tr><td>";
2362 print $form->textwithpicto($langs->trans("DefaultContact"), $langs->trans("TypeContact_commande_external_".$type_contact_code));
2363 print '</td><td>';
2364 print img_picto('', 'contact', 'class="pictofixedwidth"');
2365 //print $form->selectcontacts($soc->id, $contactid, 'contactid', 1, empty($srccontactslist) ? "" : $srccontactslist, '', 1, 'maxwidth300 widthcentpercentminusx');
2366 print $form->select_contact($soc->id, $contactid, 'contactid', 1, empty($srccontactslist) ? "" : $srccontactslist, '', 1, 'maxwidth300 widthcentpercentminusx', true);
2367 print '</td></tr>';
2368
2369 // Ligne info remises tiers
2370 print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
2371
2372 $absolute_discount = $soc->getAvailableDiscounts();
2373
2374 $thirdparty = $soc;
2375 $discount_type = 0;
2376 $backtopage = $_SERVER["PHP_SELF"].'?socid='.$thirdparty->id.'&action='.$action.'&origin='.urlencode((string) (GETPOST('origin'))).'&originid='.urlencode((string) (GETPOSTINT('originid')));
2377 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2378
2379 print '</td></tr>';
2380 }
2381
2382 // Date
2383 print '<tr><td class="fieldrequired">'.$langs->trans('Date').'</td><td>';
2384 print img_picto('', 'action', 'class="pictofixedwidth"');
2385 print $form->selectDate('', 're', 0, 0, 0, "crea_commande", 1, 1); // Always autofill date with current date
2386 print '</td></tr>';
2387
2388 // Date delivery planned
2389 print '<tr><td>'.$langs->trans("DateDeliveryPlanned").'</td>';
2390 print '<td colspan="3">';
2391 $date_delivery = ($date_delivery ? $date_delivery : $object->delivery_date);
2392 print img_picto('', 'action', 'class="pictofixedwidth"');
2393 print $form->selectDate($date_delivery ? $date_delivery : -1, 'liv_', 1, 1, 1);
2394 print "</td>\n";
2395 print '</tr>';
2396
2397 // Delivery delay
2398 print '<tr class="fielddeliverydelay"><td>'.$langs->trans('AvailabilityPeriod').'</td><td>';
2399 print img_picto('', 'clock', 'class="pictofixedwidth"');
2400 $form->selectAvailabilityDelay((GETPOSTISSET('availability_id') ? GETPOST('availability_id') : $availability_id), 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx');
2401 print '</td></tr>';
2402
2403 // Terms of payment
2404 print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
2405 print img_picto('', 'payment', 'class="pictofixedwidth"');
2406 print $form->getSelectConditionsPaiements((int) $cond_reglement_id, 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', (float) $deposit_percent);
2407 print '</td></tr>';
2408
2409 // Payment mode
2410 print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
2411 print img_picto('', 'bank', 'class="pictofixedwidth"');
2412 print $form->select_types_paiements((string) $mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
2413 print '</td></tr>';
2414
2415 // Bank Account
2416 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_ORDER') && isModEnabled("bank")) {
2417 print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
2418 print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes($fk_account, 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
2419 print '</td></tr>';
2420 }
2421
2422 // Shipping Method
2423 if (isModEnabled('shipping')) {
2424 print '<tr><td>'.$langs->trans('SendingMethod').'</td><td>';
2425 print img_picto('', 'object_dolly', 'class="pictofixedwidth"');
2426 $form->selectShippingMethod(((GETPOSTISSET('shipping_method_id') && GETPOSTINT('shipping_method_id') != 0) ? GETPOST('shipping_method_id') : $shipping_method_id), 'shipping_method_id', '', 1, '', 0, 'maxwidth200 widthcentpercentminusx');
2427 print '</td></tr>';
2428 }
2429
2430 // Warehouse
2431 if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
2432 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2433 $formproduct = new FormProduct($db);
2434 print '<tr><td>'.$langs->trans('Warehouse').'</td><td>';
2435 print img_picto('', 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses((GETPOSTISSET('warehouse_id') ? GETPOST('warehouse_id') : $warehouse_id), 'warehouse_id', '', 1, 0, 0, '', 0, 0, array(), 'maxwidth500 widthcentpercentminusxx');
2436 print '</td></tr>';
2437 }
2438
2439 // Source / Channel - What trigger creation
2440 print '<tr><td>'.$langs->trans('Source').'</td><td>';
2441 print img_picto('', 'question', 'class="pictofixedwidth"');
2442 $form->selectInputReason((GETPOSTISSET('demand_reason_id') ? GETPOST('demand_reason_id') : $demand_reason_id), 'demand_reason_id', '', 1, 'maxwidth200 widthcentpercentminusx');
2443 print '</td></tr>';
2444
2445 // TODO How record was recorded OrderMode (llx_c_input_method)
2446
2447 // Project
2448 if (isModEnabled('project')) {
2449 $langs->load("projects");
2450 print '<tr>';
2451 print '<td>'.$langs->trans("Project").'</td><td>';
2452 print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects((($soc->id > 0 && !getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_CUSTOMERS')) ? $soc->id : -1), (GETPOSTISSET('projectid') ? GETPOST('projectid') : $projectid), 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
2453 print ' <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>';
2454 print '</td>';
2455 print '</tr>';
2456 }
2457
2458 // Incoterms
2459 if (isModEnabled('incoterm')) {
2460 print '<tr>';
2461 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), !empty($objectsrc->fk_incoterms) ? (string) $objectsrc->fk_incoterms : (string) $soc->fk_incoterms, 1).'</label></td>';
2462 print '<td class="maxwidthonsmartphone">';
2463 $incoterm_id = GETPOST('incoterm_id');
2464 $location_incoterms = GETPOST('location_incoterms');
2465 if (empty($incoterm_id)) {
2466 $incoterm_id = (!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : $soc->fk_incoterms);
2467 $location_incoterms = (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : $soc->location_incoterms);
2468 }
2469 print img_picto('', 'incoterm', 'class="pictofixedwidth"');
2470 print $form->select_incoterms($incoterm_id, $location_incoterms);
2471 print '</td></tr>';
2472 }
2473
2474 // Other attributes
2475 $parameters = array();
2476 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
2477 $parameters['objectsrc'] = $objectsrc;
2478 }
2479 $parameters['socid'] = $socid;
2480
2481 // Note that $action and $object may be modified by hook
2482 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action);
2483 print $hookmanager->resPrint;
2484 if (empty($reshook)) {
2485 if (getDolGlobalString('THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_ORDER') && !empty($soc->id)) {
2486 // copy from thirdparty
2487 $tpExtrafields = new ExtraFields($db);
2488 $tpExtrafieldLabels = $tpExtrafields->fetch_name_optionals_label($soc->table_element);
2489 if ($soc->fetch_optionals() > 0) {
2490 $object->array_options = array_merge($object->array_options, $soc->array_options);
2491 }
2492 }
2493
2494 print $object->showOptionals($extrafields, 'create', $parameters);
2495 }
2496
2497 // Template to use by default
2498 print '<tr><td>'.$langs->trans('DefaultModel').'</td>';
2499 print '<td>';
2500 include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
2502 $preselected = getDolGlobalString('COMMANDE_ADDON_PDF');
2503 print img_picto('', 'pdf', 'class="pictofixedwidth"');
2504 print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1);
2505 print "</td></tr>";
2506
2507 // Multicurrency
2508 if (isModEnabled("multicurrency")) {
2509 print '<tr>';
2510 print '<td>'.$form->editfieldkey("Currency", 'multicurrency_code', '', $object, 0).'</td>';
2511 print '<td class="maxwidthonsmartphone">';
2512 print img_picto('', 'currency', 'class="pictofixedwidth"').$form->selectMultiCurrency(((GETPOSTISSET('multicurrency_code') && !GETPOST('changecompany')) ? GETPOST('multicurrency_code') : $currency_code), 'multicurrency_code', 0, '', false, 'maxwidth200 widthcentpercentminusx');
2513 print '</td></tr>';
2514 }
2515
2516 // Categories
2517 if (!empty($conf->categorie->enabled)) {
2518 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
2519 print $form->selectCategories(Categorie::TYPE_ORDER, 'categories', $object);
2520 print "</td></tr>";
2521 }
2522
2523 // Note public
2524 print '<tr>';
2525 print '<td class="tdtop">'.$langs->trans('NotePublic').'</td>';
2526 print '<td>';
2527
2528 $doleditor = new DolEditor('note_public', (string) $note_public, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
2529 print $doleditor->Create(1);
2530 // print '<textarea name="note_public" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_public.'</textarea>';
2531 print '</td></tr>';
2532
2533 // Note private
2534 if (empty($user->socid)) {
2535 print '<tr>';
2536 print '<td class="tdtop">'.$langs->trans('NotePrivate').'</td>';
2537 print '<td>';
2538
2539 $doleditor = new DolEditor('note_private', (string) $note_private, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
2540 print $doleditor->Create(1);
2541 // print '<textarea name="note" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'</textarea>';
2542 print '</td></tr>';
2543 }
2544
2545 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
2546 // TODO for compatibility
2547 if ($origin == 'contrat') {
2548 // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
2549 //$objectsrc->remise_absolue = $remise_absolue;
2550 //$objectsrc->remise_percent = $remise_percent;
2551 $objectsrc->update_price(1);
2552 }
2553
2554 print "\n<!-- ".$classname." info -->";
2555 print "\n";
2556 print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
2557 print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
2558 print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
2559 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
2560 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
2561
2562 switch ($classname) {
2563 case 'Propal':
2564 $newclassname = 'CommercialProposal';
2565 break;
2566 case 'Commande':
2567 $newclassname = 'Order';
2568 break;
2569 case 'Expedition':
2570 $newclassname = 'Sending';
2571 break;
2572 case 'Contrat':
2573 $newclassname = 'Contract';
2574 break;
2575 default:
2576 $newclassname = $classname;
2577 }
2578
2579 print '<tr><td>'.$langs->trans($newclassname).'</td><td>'.$objectsrc->getNomUrl(1).'</td></tr>';
2580
2581 // Amount
2582 print '<tr><td>'.$langs->trans('AmountHT').'</td><td>'.price($objectsrc->total_ht).'</td></tr>';
2583 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($objectsrc->total_tva)."</td></tr>";
2584 if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0) { // Localtax1 RE
2585 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax1)."</td></tr>";
2586 }
2587
2588 if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) { // Localtax2 IRPF
2589 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax2)."</td></tr>";
2590 }
2591
2592 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($objectsrc->total_ttc)."</td></tr>";
2593
2594 if (isModEnabled("multicurrency")) {
2595 print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td>'.price($objectsrc->multicurrency_total_ht).'</td></tr>';
2596 print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td>'.price($objectsrc->multicurrency_total_tva)."</td></tr>";
2597 print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td>'.price($objectsrc->multicurrency_total_ttc)."</td></tr>";
2598 }
2599 }
2600
2601 print "\n";
2602
2603 print '</table>';
2604 }
2605
2606 print dol_get_fiche_end();
2607
2608 print $form->buttonsSaveCancel("CreateDraft");
2609
2610 // Show origin lines
2611 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
2612 $title = $langs->trans('ProductsAndServices');
2613 print load_fiche_titre($title);
2614
2615 print '<div class="div-table-responsive-no-min">';
2616 print '<table class="noborder centpercent">';
2617
2618 $objectsrc->printOriginLinesList('', $selectedLines);
2619
2620 print '</table>';
2621 print '</div>';
2622 }
2623
2624 print '</form>';
2625} else {
2626 // Mode view
2627 $now = dol_now();
2628
2629 if ($object->id > 0) {
2630 $product_static = new Product($db);
2631
2632 $soc = new Societe($db);
2633 $soc->fetch($object->socid);
2634
2635 $author = new User($db);
2636 $author->fetch($object->user_author_id);
2637
2638 $object->fetch_thirdparty();
2639 $res = $object->fetch_optionals();
2640
2642 print dol_get_fiche_head($head, 'order', $langs->trans("CustomerOrder"), -1, 'order', 0, '', '', 0, '', 1);
2643
2644 $formconfirm = '';
2645
2646 // Confirmation to delete
2647 if ($action == 'delete') {
2648 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteOrder'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', '', 0, 1);
2649 }
2650
2651 // Confirmation of validation
2652 if ($action == 'validate') {
2653 // We check that object has a temporary ref
2654 $ref = substr($object->ref, 1, 4);
2655 if ($ref == 'PROV' || $ref == '') {
2656 $numref = $object->getNextNumRef($soc);
2657 if (empty($numref)) {
2658 $error++;
2659 setEventMessages($object->error, $object->errors, 'errors');
2660 }
2661 } else {
2662 $numref = $object->ref;
2663 }
2664
2665 $text = $langs->trans('ConfirmValidateOrder', $numref);
2666 if (isModEnabled('notification')) {
2667 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2668 $notify = new Notify($db);
2669 $text .= '<br>';
2670 $text .= $notify->confirmMessage('ORDER_VALIDATE', $object->socid, $object);
2671 }
2672
2673 $qualified_for_stock_change = 0;
2674 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2675 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2676 } else {
2677 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2678 }
2679
2680 $formquestion = array();
2681 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
2682 $langs->load("stocks");
2683 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2684 $formproduct = new FormProduct($db);
2685 $forcecombo = 0;
2686 if ($conf->browser->name == 'ie') {
2687 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
2688 }
2689 $formquestion = array(
2690 // 'text' => $langs->trans("ConfirmClone"),
2691 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
2692 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
2693 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOSTINT('idwarehouse') ? GETPOSTINT('idwarehouse') : 'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
2694 );
2695 }
2696
2697 // mandatoryPeriod
2698 $nbMandated = 0;
2699 foreach ($object->lines as $line) {
2700 $res = $line->fetch_product();
2701 if ($res > 0) {
2702 if ($line->product->isService() && $line->product->isMandatoryPeriod() && (empty($line->date_start) || empty($line->date_end))) {
2703 $nbMandated++;
2704 break;
2705 }
2706 }
2707 }
2708 if ($nbMandated > 0) {
2709 if (getDolGlobalString('SERVICE_STRICT_MANDATORY_PERIOD')) {
2710 setEventMessages($langs->trans("mandatoryPeriodNeedTobeSetMsgValidate"), null, 'errors');
2711 $error++;
2712 } else {
2713 $text .= '<div><span class="clearboth nowraponall warning">'.img_warning().$langs->trans("mandatoryPeriodNeedTobeSetMsgValidate").'</span></div>';
2714 }
2715 }
2716
2717 if (getDolGlobalInt('SALE_ORDER_SUGGEST_DOWN_PAYMENT_INVOICE_CREATION')) {
2718 // This is a hidden option:
2719 // Suggestion to create invoice during order validation is not enabled by default.
2720 // Such choice should be managed by the workflow module and trigger. This option generates conflicts with some setup.
2721 // It may also break step of creating an order when invoicing must be done from proposals and not from orders
2722 $deposit_percent_from_payment_terms = (float) getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id);
2723
2724 if (!empty($deposit_percent_from_payment_terms) && isModEnabled('invoice') && $user->hasRight('facture', 'creer')) {
2725 require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
2726
2727 $object->fetchObjectLinked();
2728
2729 $eligibleForDepositGeneration = true;
2730
2731 if (array_key_exists('facture', $object->linkedObjects)) {
2732 foreach ($object->linkedObjects['facture'] as $invoice) {
2733 '@phan-var-force Facture $invoice';
2734 if ($invoice->type == Facture::TYPE_DEPOSIT) {
2735 $eligibleForDepositGeneration = false;
2736 break;
2737 }
2738 }
2739 }
2740
2741 if ($eligibleForDepositGeneration && array_key_exists('propal', $object->linkedObjects)) {
2742 foreach ($object->linkedObjects['propal'] as $proposal) {
2743 $proposal->fetchObjectLinked();
2744
2745 if (array_key_exists('facture', $proposal->linkedObjects)) {
2746 foreach ($proposal->linkedObjects['facture'] as $invoice) {
2747 '@phan-var-force Facture $invoice';
2748 if ($invoice->type == Facture::TYPE_DEPOSIT) {
2749 $eligibleForDepositGeneration = false;
2750 break 2;
2751 }
2752 }
2753 }
2754 }
2755 }
2756
2757 if ($eligibleForDepositGeneration) {
2758 $formquestion[] = array(
2759 'type' => 'checkbox',
2760 'tdclass' => '',
2761 'name' => 'generate_deposit',
2762 'label' => $form->textwithpicto($langs->trans('GenerateDeposit', $object->deposit_percent), $langs->trans('DepositGenerationPermittedByThePaymentTermsSelected'))
2763 );
2764
2765 $formquestion[] = array(
2766 'type' => 'date',
2767 'tdclass' => 'fieldrequired showonlyifgeneratedeposit',
2768 'name' => 'datef',
2769 'label' => $langs->trans('DateInvoice'),
2770 'value' => dol_now(),
2771 'datenow' => true
2772 );
2773
2774 if (getDolGlobalString('INVOICE_POINTOFTAX_DATE')) {
2775 $formquestion[] = array(
2776 'type' => 'date',
2777 'tdclass' => 'fieldrequired showonlyifgeneratedeposit',
2778 'name' => 'date_pointoftax',
2779 'label' => $langs->trans('DatePointOfTax'),
2780 'value' => dol_now(),
2781 'datenow' => true
2782 );
2783 }
2784
2785
2786 $paymentTermsSelect = $form->getSelectConditionsPaiements(0, 'cond_reglement_id', -1, 0, 0, 'minwidth200');
2787
2788 $formquestion[] = array(
2789 'type' => 'other',
2790 'tdclass' => 'fieldrequired showonlyifgeneratedeposit',
2791 'name' => 'cond_reglement_id',
2792 'label' => $langs->trans('PaymentTerm'),
2793 'value' => $paymentTermsSelect
2794 );
2795
2796 $formquestion[] = array(
2797 'type' => 'checkbox',
2798 'tdclass' => 'showonlyifgeneratedeposit',
2799 'name' => 'validate_generated_deposit',
2800 'label' => $langs->trans('ValidateGeneratedDeposit')
2801 );
2802
2803 $formquestion[] = array(
2804 'type' => 'onecolumn',
2805 'value' => '
2806 <script>
2807 $(document).ready(function() {
2808 $("[name=generate_deposit]").change(function () {
2809 let $self = $(this);
2810 let $target = $(".showonlyifgeneratedeposit").parent(".tagtr");
2811
2812 if (! $self.parents(".tagtr").is(":hidden") && $self.is(":checked")) {
2813 $target.show();
2814 } else {
2815 $target.hide();
2816 }
2817
2818 return true;
2819 });
2820 });
2821 </script>
2822 '
2823 );
2824 }
2825 }
2826 }
2827
2828 if (!$error) {
2829 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_validate', $formquestion, 0, 1, 240);
2830 }
2831 }
2832
2833 // Confirm back to draft status
2834 if ($action == 'modif') {
2835 $qualified_for_stock_change = 0;
2836 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2837 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2838 } else {
2839 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2840 }
2841
2842 $text = $langs->trans('ConfirmUnvalidateOrder', $object->ref);
2843 $formquestion = array();
2844 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
2845 $langs->load("stocks");
2846 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2847 $formproduct = new FormProduct($db);
2848 $forcecombo = 0;
2849 if ($conf->browser->name == 'ie') {
2850 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
2851 }
2852 $formquestion = array(
2853 // 'text' => $langs->trans("ConfirmClone"),
2854 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
2855 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
2856 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockIncrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
2857 );
2858 }
2859
2860 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('UnvalidateOrder'), $text, 'confirm_modif', $formquestion, "yes", 1, 220);
2861 }
2862
2863 // Confirmation of closing
2864 if ($action == 'shipped') {
2865 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('CloseOrder'), $langs->trans('ConfirmCloseOrder'), 'confirm_shipped', '', 0, 1);
2866 }
2867
2868 // Confirmation of cancellation
2869 if ($action == 'cancel') {
2870 $qualified_for_stock_change = 0;
2871 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2872 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2873 } else {
2874 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2875 }
2876
2877 $text = $langs->trans('ConfirmCancelOrder', $object->ref);
2878 $formquestion = array();
2879 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
2880 $langs->load("stocks");
2881 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2882 $formproduct = new FormProduct($db);
2883 $forcecombo = 0;
2884 if ($conf->browser->name == 'ie') {
2885 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
2886 }
2887 $formquestion = array(
2888 // 'text' => $langs->trans("ConfirmClone"),
2889 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
2890 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
2891 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockIncrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
2892 );
2893 }
2894
2895 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans("Cancel"), $text, 'confirm_cancel', $formquestion, 0, 1);
2896 }
2897
2898 // Confirmation to delete line
2899 if ($action == 'ask_deleteline') {
2900 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
2901 }
2902
2903 // Confirmation de la suppression d'une ligne subtotal
2904 if ($action == 'ask_subtotal_deleteline') {
2905 $langs->load("subtotals");
2906 $title = "DeleteSubtotalLine";
2907 $question = "ConfirmDeleteSubtotalLine";
2908 if (GETPOST('type') == 'title') {
2909 $formconfirm = array(array('type' => 'checkbox', 'name' => 'deletecorrespondingsubtotalline', 'label' => $langs->trans("DeleteCorrespondingSubtotalLine"), 'value' => 0));
2910 $title = "DeleteTitleLine";
2911 $question = "ConfirmDeleteTitleLine";
2912 }
2913 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans($title), $langs->trans($question), 'confirm_delete_subtotalline', $formconfirm, 'no', 1);
2914 }
2915
2916 // Clone confirmation
2917 if ($action == 'clone') {
2918 $filter = '(s.client:IN:1,2,3)';
2919 // Create an array for form
2920 $formquestion = array(
2921 array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter, '', 0, 0, array(), 0, 'maxwidth300'))
2922 );
2923 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
2924 }
2925
2926 // Subtotal line form
2927 if ($action == 'add_title_line') {
2928 $langs->load('subtotals');
2929 $type = 'title';
2930 $depth_array = $object->getPossibleLevels($langs);
2931 require dol_buildpath('/core/tpl/subtotal_create.tpl.php');
2932 } elseif ($action == 'add_subtotal_line') {
2933 $langs->load('subtotals');
2934 $type = 'subtotal';
2935 $titles = $object->getPossibleTitles();
2936 require dol_buildpath('/core/tpl/subtotal_create.tpl.php');
2937 }
2938
2939 // Call Hook formConfirm
2940 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
2941 // Note that $action and $object may be modified by hook
2942 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
2943 if (empty($reshook)) {
2944 $formconfirm .= $hookmanager->resPrint;
2945 } elseif ($reshook > 0) {
2946 $formconfirm = $hookmanager->resPrint;
2947 }
2948
2949 // Print form confirm
2950 print $formconfirm;
2951
2952
2953 // Order card
2954
2955 $linkback = '<a href="'.DOL_URL_ROOT.'/commande/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
2956
2957 $morehtmlref = '<div class="refidno">';
2958 // Ref customer
2959 $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, (int) $usercancreate, 'string', '', 0, 1);
2960 $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, (int) $usercancreate, 'string'.(isset($conf->global->THIRDPARTY_REF_INPUT_SIZE) ? ':' . getDolGlobalString('THIRDPARTY_REF_INPUT_SIZE') : ''), '', null, null, '', 1);
2961 // Thirdparty
2962 $morehtmlref .= '<br>'.$soc->getNomUrl(1, 'customer');
2963 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
2964 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
2965 }
2966 // Project
2967 if (isModEnabled('project')) {
2968 $langs->load("projects");
2969 $morehtmlref .= '<br>';
2970 if ($usercancreate) {
2971 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2972 if ($action != 'classify') {
2973 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2974 }
2975 $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');
2976 } else {
2977 if (!empty($object->fk_project)) {
2978 $proj = new Project($db);
2979 $proj->fetch($object->fk_project);
2980 $morehtmlref .= $proj->getNomUrl(1);
2981 if ($proj->title) {
2982 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2983 }
2984 }
2985 }
2986 }
2987 $morehtmlref .= '</div>';
2988
2989
2990 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
2991
2992 // Call Hook tabContentViewOrder
2993 $parameters = array();
2994 // Note that $action and $object may be modified by hook
2995 $reshook = $hookmanager->executeHooks('tabContentViewOrder', $parameters, $object, $action);
2996 if (empty($reshook)) {
2997 print '<div class="fichecenter">';
2998 print '<div class="fichehalfleft">';
2999 print '<div class="underbanner clearboth"></div>';
3000
3001 print '<table class="border tableforfield centpercent">';
3002
3003 // POS
3004 if (isModEnabled('takepos') || $object->module_source || getDolGlobalString('ORDER_ALLOW_POS_SOURCE_EDIT')) {
3005 $langs->load("cashdesk");
3006 print '<tr><td class="fieldname_type">';
3007 print '<table class="nobordernopadding centpercent"><tr><td>';
3008 print $form->textwithpicto($langs->trans('PointOfSale'), $langs->trans('POSInfo'));
3009 print '</td>';
3010 if ($action != 'editposinfo' && $usercancreate) {
3011 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editposinfo&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetPOSInfo'), 1).'</a></td>';
3012 }
3013 print '</tr></table>';
3014 print '</td><td class="valuefield fieldname_type">';
3015 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" name="formposinfo">';
3016 print '<input type="hidden" name="action" value="setposinfo">';
3017 print '<input type="hidden" name="token" value="' . newToken() . '">';
3018 if ($action == 'editposinfo') {
3019 print '<input type="text" class="maxwidth150" name="posmodule" placeholder="'.$langs->trans("POSModule").'" value="'.$object->module_source.'"> ';
3020 print '<input type="text" class="maxwidth100" name="posterminal" placeholder="'.$langs->trans("Terminal").'" value="'.$object->pos_source.'">';
3021 print '<input type="submit" class="button" name="submitposinfo" value="'.$langs->trans("Submit").'">';
3022 } else {
3023 if ($object->module_source) {
3024 print '<span class="opacitymediumbycolor paddingleft">'.dolPrintHTML(ucfirst($object->module_source).' - '.$langs->transnoentitiesnoconv("Terminal").' '.$object->pos_source).'</span>';
3025 }
3026 }
3027 print '</form>';
3028 print '</td></tr>';
3029 }
3030
3031 if ($soc->outstanding_limit) {
3032 // Outstanding Bill
3033 print '<tr><td class="titlefield">';
3034 print $langs->trans('OutstandingBill');
3035 print '</td><td class="valuefield">';
3036 $arrayoutstandingbills = $soc->getOutstandingBills();
3037 print price($arrayoutstandingbills['opened']).' / ';
3038 print price($soc->outstanding_limit, 0, '', 1, - 1, - 1, $conf->currency);
3039 print '</td>';
3040 print '</tr>';
3041 }
3042
3043 // Relative and absolute discounts
3044 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
3045 $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
3046 $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
3047 } else {
3048 $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
3049 $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
3050 }
3051
3052 $addrelativediscount = '<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditRelativeDiscounts").'</a>';
3053 $addabsolutediscount = '<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditGlobalDiscounts").'</a>';
3054 $addcreditnote = '<a href="'.DOL_URL_ROOT.'/compta/facture/card.php?action=create&socid='.$soc->id.'&type=2&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("AddCreditNote").'</a>';
3055
3056 print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td class="valuefield">';
3057
3058 $absolute_discount = $soc->getAvailableDiscounts(null, $filterabsolutediscount);
3059 $absolute_creditnote = $soc->getAvailableDiscounts(null, $filtercreditnote);
3060 $absolute_discount = price2num($absolute_discount, 'MT');
3061 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
3062
3063 $thirdparty = $soc;
3064 $discount_type = 0;
3065 $backtopage = $_SERVER["PHP_SELF"].'?id='.$object->id;
3066 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
3067
3068 print '</td></tr>';
3069
3070 // Date
3071 print '<tr><td>';
3072 $editenable = $usercancreate && $object->status == Commande::STATUS_DRAFT;
3073 print $form->editfieldkey("Date", 'date', '', $object, (int) $editenable);
3074 print '</td><td class="valuefield">';
3075 if ($action == 'editdate') {
3076 print '<form name="setdate" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
3077 print '<input type="hidden" name="token" value="'.newToken().'">';
3078 print '<input type="hidden" name="action" value="setdate">';
3079 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
3080 print $form->selectDate($object->date, 'order_', 0, 0, 0, "setdate");
3081 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
3082 print '</form>';
3083 } else {
3084 print $object->date ? dol_print_date($object->date, 'day') : '&nbsp;';
3085 if ($object->hasDelay() && empty($object->delivery_date)) { // If there is a delivery date planned, warning should be on this date
3086 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
3087 }
3088 }
3089 print '</td>';
3090 print '</tr>';
3091
3092 // Delivery date planned
3093 print '<tr><td>';
3094 $editenable = $usercancreate;
3095 print $form->editfieldkey("DateDeliveryPlanned", 'date_livraison', '', $object, (int) $editenable);
3096 print '</td><td class="valuefield">';
3097 if ($action == 'editdate_livraison') {
3098 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
3099 print '<input type="hidden" name="token" value="'.newToken().'">';
3100 print '<input type="hidden" name="action" value="setdate_livraison">';
3101 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
3102 print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', 1, 1, 0, "setdate_livraison", 1, 0);
3103 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
3104 print '</form>';
3105 } else {
3106 print $object->delivery_date ? dol_print_date($object->delivery_date, 'dayhour') : '&nbsp;';
3107 if ($object->hasDelay() && !empty($object->delivery_date)) {
3108 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
3109 }
3110 }
3111 print '</td>';
3112 print '</tr>';
3113
3114 // Delivery delay
3115 print '<tr class="fielddeliverydelay"><td>';
3116 $editenable = $usercancreate;
3117 print $form->editfieldkey("AvailabilityPeriod", 'availability', '', $object, (int) $editenable);
3118 print '</td><td class="valuefield">';
3119 if ($action == 'editavailability') {
3120 $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->availability_id, 'availability_id', 1);
3121 } else {
3122 $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->availability_id, 'none', 1);
3123 }
3124 print '</td></tr>';
3125
3126 // Shipping Method
3127 if (isModEnabled('shipping')) {
3128 print '<tr><td>';
3129 $editenable = $usercancreate;
3130 print $form->editfieldkey("SendingMethod", 'shippingmethod', '', $object, (int) $editenable);
3131 print '</td><td class="valuefield">';
3132 if ($action == 'editshippingmethod') {
3133 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->shipping_method_id, 'shipping_method_id', 1);
3134 } else {
3135 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->shipping_method_id, 'none');
3136 }
3137 print '</td>';
3138 print '</tr>';
3139 }
3140
3141 // Warehouse
3142 if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
3143 $langs->load('stocks');
3144 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
3145 $formproduct = new FormProduct($db);
3146 print '<tr><td>';
3147 $editenable = $usercancreate;
3148 print $form->editfieldkey("Warehouse", 'warehouse', '', $object, (int) $editenable);
3149 print '</td><td class="valuefield">';
3150 if ($action == 'editwarehouse') {
3151 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->warehouse_id, 'warehouse_id', 1);
3152 } else {
3153 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->warehouse_id, 'none');
3154 }
3155 print '</td>';
3156 print '</tr>';
3157 }
3158
3159 // Source reason (why we have an order)
3160 print '<tr><td>';
3161 $editenable = $usercancreate;
3162 print $form->editfieldkey("Source", 'demandreason', '', $object, (int) $editenable);
3163 print '</td><td class="valuefield">';
3164 if ($action == 'editdemandreason') {
3165 $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->demand_reason_id, 'demand_reason_id', 1);
3166 } else {
3167 $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->demand_reason_id, 'none');
3168 }
3169 print '</td></tr>';
3170
3171 // Terms of payment
3172 print '<tr><td>';
3173 $editenable = $usercancreate;
3174 print $form->editfieldkey("PaymentConditionsShort", 'conditions', '', $object, (int) $editenable);
3175 print '</td><td class="valuefield">';
3176 if ($action == 'editconditions') {
3177 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent);
3178 } else {
3179 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'none', 1, '', 1, $object->deposit_percent);
3180 }
3181 print '</td>';
3182
3183 print '</tr>';
3184
3185 // Mode of payment
3186 print '<tr><td>';
3187 $editenable = $usercancreate;
3188 print $form->editfieldkey("PaymentMode", 'mode', '', $object, (int) $editenable);
3189 print '</td><td class="valuefield">';
3190 if ($action == 'editmode') {
3191 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1);
3192 } else {
3193 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'none');
3194 }
3195 print '</td></tr>';
3196
3197 // TODO Order mode (how we receive order). Not yet implemented
3198 /*
3199 print '<tr><td>';
3200 $editenable = $usercancreate;
3201 print $form->editfieldkey("SourceMode", 'inputmode', '', $object, $editenable);
3202 print '</td><td>';
3203 if ($action == 'editinputmode') {
3204 $form->formInputMode($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->source, 'input_mode_id', 1);
3205 } else {
3206 $form->formInputMode($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->source, 'none');
3207 }
3208 print '</td></tr>';
3209 */
3210
3211 $tmparray = $object->getTotalWeightVolume();
3212 $totalWeight = $tmparray['weight'];
3213 $totalVolume = $tmparray['volume'];
3214 if ($totalWeight) {
3215 print '<tr><td>'.$langs->trans("CalculatedWeight").'</td>';
3216 print '<td class="valuefield">';
3217 print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, getDolGlobalInt('MAIN_WEIGHT_DEFAULT_ROUND', -1), isset($conf->global->MAIN_WEIGHT_DEFAULT_UNIT) ? $conf->global->MAIN_WEIGHT_DEFAULT_UNIT : 'no');
3218 print '</td></tr>';
3219 }
3220 if ($totalVolume) {
3221 print '<tr><td>'.$langs->trans("CalculatedVolume").'</td>';
3222 print '<td class="valuefield">';
3223 print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, getDolGlobalInt('MAIN_VOLUME_DEFAULT_ROUND', -1), isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT) ? $conf->global->MAIN_VOLUME_DEFAULT_UNIT : 'no');
3224 print '</td></tr>';
3225 }
3226
3227 // TODO How record was recorded OrderMode (llx_c_input_method)
3228
3229 // Incoterms
3230 if (isModEnabled('incoterm')) {
3231 print '<tr><td>';
3232 $editenable = $usercancreate;
3233 print $form->editfieldkey("IncotermLabel", 'incoterm', '', $object, (int) $editenable);
3234 print '</td>';
3235 print '<td class="valuefield">';
3236 if ($action != 'editincoterm') {
3237 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
3238 } else {
3239 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
3240 }
3241 print '</td></tr>';
3242 }
3243
3244 // Bank Account
3245 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_ORDER') && isModEnabled("bank")) {
3246 print '<tr><td>';
3247 $editenable = $usercancreate;
3248 print $form->editfieldkey("BankAccount", 'bankaccount', '', $object, (int) $editenable);
3249 print '</td><td class="valuefield">';
3250 if ($action == 'editbankaccount') {
3251 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'fk_account', 1);
3252 } else {
3253 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'none');
3254 }
3255 print '</td>';
3256 print '</tr>';
3257 }
3258
3259 // Tags-Categories
3260 if (isModEnabled('category')) {
3261 print '<tr><td>';
3262 print '<table class="nobordernopadding centpercent"><tr><td>';
3263 print $langs->trans("Categories");
3264 print '<td><td class="right">';
3265 if ($usercancreate) {
3266 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/commande/card.php?id='.$object->id.'&action=edittags&token='.newToken().'">'.img_edit().'</a>';
3267 } else {
3268 print '&nbsp;';
3269 }
3270 print '</td></tr></table>';
3271 print '</td>';
3272 print '<td>';
3273 if ($action == 'edittags') {
3274 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
3275 print '<input type="hidden" name="action" value="settags">';
3276 print '<input type="hidden" name="token" value="'.newToken().'">';
3277 print $form->selectCategories(Categorie::TYPE_ORDER, 'categories', $object);
3278 print '<input type="submit" class="button valignmiddle smallpaddingimp" value="'.$langs->trans("Modify").'">';
3279 print '</form>';
3280 } else {
3281 print $form->showCategories($object->id, Categorie::TYPE_ORDER, 1);
3282 }
3283 print "</td></tr>";
3284 }
3285
3286 // Other attributes
3287 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
3288
3289 print '</table>';
3290
3291 print '</div>';
3292 print '<div class="fichehalfright">';
3293 print '<div class="underbanner clearboth"></div>';
3294
3295 print '<table class="border tableforfield centpercent">';
3296
3297 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
3298
3299 $alert = '';
3300 if (getDolGlobalString('ORDER_MANAGE_MIN_AMOUNT') && $object->total_ht < $object->thirdparty->order_min_amount) {
3301 $alert = ' ' . img_warning($langs->trans('OrderMinAmount') . ': ' . price($object->thirdparty->order_min_amount));
3302 }
3303
3304 print '<tr>';
3305 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
3306 print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
3307 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3308 // Multicurrency Amount HT
3309 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3310 }
3311 print '</tr>';
3312
3313 print '<tr>';
3314 print '<td class="titlefieldmiddle">' . $langs->trans('AmountVAT') . '</td>';
3315 print '<td class="nowrap amountcard right">' . price($object->total_tva, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
3316 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3317 // Multicurrency Amount VAT
3318 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3319 }
3320 print '</tr>';
3321
3322 // Amount Local Taxes
3323 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) {
3324 print '<tr>';
3325 print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
3326 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
3327 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3328 $object->multicurrency_total_localtax1 = price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
3329
3330 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3331 }
3332 print '</tr>';
3333 }
3334
3335 // Amount Local Taxes
3336 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
3337 print '<tr>';
3338 print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
3339 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
3340 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3341 $object->multicurrency_total_localtax2 = price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
3342
3343 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
3344 }
3345 print '</tr>';
3346 }
3347
3348 print '<tr>';
3349 print '<td>' . $langs->trans('AmountTTC') . '</td>';
3350 print '<td class="valuefield nowrap right amountcard">' . price($object->total_ttc, 1, '', 1, -1, -1, $conf->currency) . '</td>';
3351 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
3352 // Multicurrency Amount TTC
3353 print '<td class="valuefield nowrap right amountcard">' . price($object->multicurrency_total_ttc, 1, '', 1, -1, -1, $object->multicurrency_code) . '</td>';
3354 }
3355 print '</tr>'."\n";
3356
3357 print '</table>';
3358
3359 // Statut
3360 //print '<tr><td>' . $langs->trans('Status') . '</td><td>' . $object->getLibStatut(4) . '</td></tr>';
3361
3362 // Margin Infos
3363 if (isModEnabled('margin')) {
3364 $formmargin->displayMarginInfos($object);
3365 }
3366
3367
3368 print '</div>';
3369 print '</div>'; // Close fichecenter
3370
3371 print '<div class="clearboth"></div><br>';
3372
3373 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
3374 $blocname = 'contacts';
3375 $title = $langs->trans('ContactsAddresses');
3376 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
3377 }
3378
3379 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
3380 $blocname = 'notes';
3381 $title = $langs->trans('Notes');
3382 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
3383 }
3384
3385 /*
3386 * Lines
3387 */
3388
3389 // Get object lines
3390 $result = $object->getLinesArray();
3391
3392 // Add products/services form
3393 //$forceall = 1;
3394 global $inputalsopricewithtax;
3395 $inputalsopricewithtax = 1;
3396
3397 print '<form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">
3398 <input type="hidden" name="token" value="' . newToken().'">
3399 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
3400 <input type="hidden" name="mode" value="">
3401 <input type="hidden" name="page_y" value="">
3402 <input type="hidden" name="id" value="' . $object->id.'">
3403 <input type="hidden" name="backtopage" value="'.$backtopage.'">
3404 ';
3405
3406 if (!empty($conf->use_javascript_ajax) && $object->status == Commande::STATUS_DRAFT) {
3407 if (isModEnabled('subtotals')) {
3408 include DOL_DOCUMENT_ROOT.'/core/tpl/subtotal_ajaxrow.tpl.php';
3409 } else {
3410 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
3411 }
3412 }
3413
3414 print '<div class="div-table-responsive-no-min">';
3415 print '<table id="tablelines" class="noborder noshadow" width="100%">';
3416
3417 // Show object lines
3418 if (!empty($object->lines)) {
3419 $object->printObjectLines($action, $mysoc, $soc, $lineid, 1);
3420 }
3421
3422 /*
3423 * Form to add new line
3424 */
3425 if ($object->status == Commande::STATUS_DRAFT && $usercancreate && $action != 'selectlines') {
3426 if ($action != 'editline') {
3427 // Add free products/services
3428
3429 $parameters = array();
3430 // Note that $action and $object may be modified by hook
3431 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action);
3432 if ($reshook < 0) {
3433 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
3434 }
3435 if (empty($reshook)) {
3436 $object->formAddObjectLine(1, $mysoc, $soc);
3437 }
3438 } else {
3439 $parameters = array();
3440 $reshook = $hookmanager->executeHooks('formEditObjectLine', $parameters, $object, $action);
3441 }
3442 }
3443 print '</table>';
3444 print '</div>';
3445
3446 print "</form>\n";
3447 }
3448
3449 print dol_get_fiche_end();
3450
3451 /*
3452 * Buttons for actions
3453 */
3454 if ($action != 'presend' && $action != 'editline') {
3455 print '<div class="tabsAction">';
3456
3457 $parameters = array();
3458 // Note that $action and $object may be modified by hook
3459 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action);
3460 if (empty($reshook)) {
3461 $numlines = count($object->lines);
3462
3463 // Reopen a closed order
3464 if (($object->status == Commande::STATUS_CLOSED || $object->status == Commande::STATUS_CANCELED) && $usercancreate && (!$object->billed || !getDolGlobalInt('ORDER_DONT_REOPEN_BILLED'))) {
3465 print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&amp;token='.newToken().'&amp;id='.$object->id, '');
3466 }
3467
3468 // Send
3469 if (empty($user->socid)) {
3470 if ($object->status > Commande::STATUS_DRAFT || getDolGlobalString('COMMANDE_SENDBYEMAIL_FOR_ALL_STATUS')) {
3471 if ($usercansend) {
3472 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER["PHP_SELF"].'?action=presend&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', '');
3473 } else {
3474 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER['PHP_SELF']. '#', '', false);
3475 }
3476 }
3477 }
3478
3479 // Subtotal
3480 if ($object->status == Commande::STATUS_DRAFT && isModEnabled('subtotals')
3481 && (getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element)) || getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element)))) {
3482 $langs->load('subtotals');
3483
3484 $url_button = array();
3485
3486 $url_button[] = array(
3487 'lang' => 'subtotals',
3488 'enabled' => (isModEnabled('order') && $object->status == Commande::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_TITLE_'.strtoupper($object->element))),
3489 'perm' => (bool) $usercancreate,
3490 'label' => $langs->trans('AddTitleLine'),
3491 'url' => '/commande/card.php?id='.$object->id.'&action=add_title_line&token='.newToken()
3492 );
3493
3494 $url_button[] = array(
3495 'lang' => 'subtotals',
3496 'enabled' => (isModEnabled('order') && $object->status == Commande::STATUS_DRAFT && getDolGlobalInt('SUBTOTAL_'.strtoupper($object->element))),
3497 'perm' => (bool) $usercancreate,
3498 'label' => $langs->trans('AddSubtotalLine'),
3499 'url' => '/commande/card.php?id='.$object->id.'&action=add_subtotal_line&token='.newToken()
3500 );
3501 print dolGetButtonAction('', $langs->trans('Subtotal'), 'default', $url_button, '', true);
3502 }
3503
3504 // Valid
3505 if ($object->status == Commande::STATUS_DRAFT && ($object->total_ttc >= 0 || getDolGlobalString('ORDER_ENABLE_NEGATIVE')) && $usercanvalidate) {
3506 if ($numlines > 0) {
3507 print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=validate&amp;token='.newToken().'&amp;id='.$object->id, (string) $object->id, 1);
3508 } else {
3509 $langs->load("errors");
3510 print dolGetButtonAction($langs->trans("ErrorObjectMustHaveLinesToBeValidated", $object->ref), $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=validate&amp;token='.newToken().'&amp;id='.$object->id, (string) $object->id, -1);
3511 }
3512 }
3513 // Edit
3514 if (($object->status == Commande::STATUS_VALIDATED || ($object->status == Commande::STATUS_SHIPMENTONPROCESS && getDolGlobalString('EDIT_ORDER_SHIPMENT_ON_PROCESS'))) && $usercancreate) {
3515 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?action=modif&amp;token='.newToken().'&amp;id='.$object->id, '');
3516 }
3517
3518 $arrayforbutaction = array();
3519 // Create a purchase order
3520
3521 if (!getDolGlobalInt('COMMANDE_DISABLE_ADD_PURCHASE_ORDER')) {
3522 $arrayforbutaction[] = array(
3523 'lang' => 'orders',
3524 'enabled' => (isModEnabled("supplier_order") && $object->status > Commande::STATUS_DRAFT),
3525 'perm' => $usercancreatepurchaseorder,
3526 'label' => 'AddPurchaseOrder',
3527 'url' => '/fourn/commande/card.php?action=create&amp;origin=' . urlencode($object->element) . '&amp;originid=' . ((int) $object->id)
3528 );
3529 }
3530
3531 /*if (isModEnabled("supplier_order") && $object->status > Commande::STATUS_DRAFT && $object->getNbOfServicesLines() > 0) {
3532 if ($usercancreatepurchaseorder) { isModEnabled("supplier_order") && $object->status > Commande::STATUS_DRAFT && $object->getNbOfServicesLines() > 0
3533 print dolGetButtonAction('', $langs->trans('AddPurchaseOrder'), 'default', DOL_URL_ROOT.'/fourn/commande/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id, '');
3534 }
3535 }*/
3536
3537 // Create intervention
3538 if (!getDolGlobalInt('COMMANDE_DISABLE_ADD_INTERVENTION')) {
3539 $arrayforbutaction[] = array(
3540 'lang' => 'interventions',
3541 'enabled' => (isModEnabled("intervention") && $object->status > Commande::STATUS_DRAFT && $object->status < Commande::STATUS_CLOSED && $object->getNbOfServicesLines() > 0),
3542 'perm' => ($user->hasRight('ficheinter', 'creer') == 1),
3543 'label' => 'AddIntervention',
3544 'url' => '/fichinter/card.php?action=create&origin=' . urlencode($object->element) . '&originid=' . ((int) $object->id) . '&socid=' . ((int) $object->socid),
3545 );
3546 }
3547
3548 // Create contract
3549 $arrayforbutaction[] = array(
3550 'lang' => 'contracts',
3551 'enabled' => (isModEnabled("contract") && ($object->status == Commande::STATUS_VALIDATED || $object->status == Commande::STATUS_SHIPMENTONPROCESS || $object->status == Commande::STATUS_CLOSED)),
3552 'perm' => ($user->hasRight('contrat', 'creer') == 1),
3553 'label' => 'AddContract',
3554 'url' => '/contrat/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid,
3555 );
3556 /*if (isModEnabled('contrat') && ($object->status == Commande::STATUS_VALIDATED || $object->status == Commande::STATUS_SHIPMENTONPROCESS || $object->status == Commande::STATUS_CLOSED)) {
3557 $langs->load("contracts");
3558
3559 if ($user->hasRight('contrat', 'creer')) {
3560 print dolGetButtonAction('', $langs->trans('AddContract'), 'default', DOL_URL_ROOT.'/contrat/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->socid, '');
3561 }
3562 }*/
3563
3564 $numshipping = 0;
3565
3566 // Create shipment
3567 if (isModEnabled('shipping')) {
3568 $numshipping = $object->countNbOfShipments();
3569
3570 if ($object->status > Commande::STATUS_DRAFT && $object->status < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || getDolGlobalString('STOCK_SUPPORTS_SERVICES'))) {
3571 if ((getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION') && $user->hasRight('expedition', 'creer')) || (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') && $user->hasRight('expedition', 'delivery', 'creer'))) {
3572 // Add button to create shipment into the combo
3573 $arrayforbutaction[] = array(
3574 'lang' => 'sendings',
3575 'enabled' => (isModEnabled("shipping") && ($object->status > Commande::STATUS_DRAFT && $object->status < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || getDolGlobalString('STOCK_SUPPORTS_SERVICES')))),
3576 'perm' => $user->hasRight('expedition', 'creer'),
3577 'label' => 'CreateShipment',
3578 'url' => '/expedition/shipment.php?id=' . $object->id
3579 );
3580 } else {
3581 //c$langs->load("errors");
3582 //print dolGetButtonAction($langs->trans('ErrorModuleSetupNotComplete'), $langs->trans('CreateShipment'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
3583 $arrayforbutaction[] = array(
3584 'lang' => 'sendings',
3585 'enabled' => (isModEnabled("shipping") && ($object->status > Commande::STATUS_DRAFT && $object->status < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || getDolGlobalString('STOCK_SUPPORTS_SERVICES')))),
3586 'perm' => 0,
3587 'label' => 'CreateShipment',
3588 'url' => '/expedition/shipment.php?id=' . $object->id
3589 );
3590 }
3591 }
3592 }
3593
3594 // Create bill
3595 $arrayforbutaction[] = array(
3596 'lang' => 'bills',
3597 'enabled' => (isModEnabled('invoice') && $object->status > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0),
3598 'perm' => ($user->hasRight('facture', 'creer') && !getDolGlobalInt('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')),
3599 'label' => 'CreateBill',
3600 'url' => '/compta/facture/card.php?action=create&amp;token=' . newToken() . '&amp;origin=' . urlencode($object->element) . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid
3601 );
3602 /*
3603 if (isModEnabled('facture') && $object->status > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) {
3604 if (isModEnabled('facture') && $user->hasRight('facture', 'creer') && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) {
3605 print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&amp;token='.newToken().'&amp;origin='.urlencode($object->element).'&amp;originid='.$object->id.'&amp;socid='.$object->socid, '');
3606 }
3607 }*/
3608
3609 $actionButtonsParameters = [
3610 "areDropdownButtons" => !getDolGlobalInt("MAIN_REMOVE_DROPDOWN_CREATE_BUTTONS_ON_ORDER")
3611 ];
3612
3613 if ($numlines > 0) {
3614 print dolGetButtonAction('', $langs->trans("Create"), 'default', $arrayforbutaction, (string) $object->id, 1, $actionButtonsParameters);
3615 } else {
3616 print dolGetButtonAction($langs->trans("ErrorObjectMustHaveLinesToBeValidated", $object->ref), $langs->trans("Create"), 'default', $arrayforbutaction, (string) $object->id, 0, $actionButtonsParameters);
3617 }
3618
3619 // Set to shipped
3620 if (($object->status == Commande::STATUS_VALIDATED || $object->status == Commande::STATUS_SHIPMENTONPROCESS) && $usercanclose) {
3621 print dolGetButtonAction('', $langs->trans('ClassifyShipped'), 'default', $_SERVER["PHP_SELF"].'?action=shipped&amp;token='.newToken().'&amp;id='.$object->id, '');
3622 }
3623
3624 // Set billed or unbilled
3625 // Note: Even if module invoice is not enabled, we should be able to use button "Classified billed"
3626 if ($object->status > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) {
3627 if ($usercancreate && $object->status >= Commande::STATUS_VALIDATED && !getDolGlobalString('ORDER_DISABLE_CLASSIFY_BILLED_FROM_ORDER') && !getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')) {
3628 print dolGetButtonAction('', $langs->trans('ClassifyBilled'), 'default', $_SERVER["PHP_SELF"].'?action=classifybilled&amp;token='.newToken().'&amp;id='.$object->id, '');
3629 }
3630 }
3631 if ($object->status > Commande::STATUS_DRAFT && $object->billed) {
3632 if ($usercancreate && $object->status >= Commande::STATUS_VALIDATED && !getDolGlobalString('ORDER_DISABLE_CLASSIFY_BILLED_FROM_ORDER') && !getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')) {
3633 print dolGetButtonAction('', $langs->trans('ClassifyUnBilled'), 'delete', $_SERVER["PHP_SELF"].'?action=classifyunbilled&amp;token='.newToken().'&amp;id='.$object->id, '');
3634 }
3635 }
3636
3637 // Clone
3638 if ($usercancreate) {
3639 print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER["PHP_SELF"].'?action=clone&token='.newToken().'&id='.$object->id.'&socid='.$object->socid, '');
3640 }
3641
3642 // Cancel order
3643 if ($object->status == Commande::STATUS_VALIDATED && !empty($usercancancel)) {
3644 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel&token='.newToken().'">'.$langs->trans("CancelOrder").'</a>';
3645 }
3646
3647 // Delete order
3648 if ($usercandelete) {
3649 if ($numshipping == 0) {
3650 print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, '');
3651 } else {
3652 print dolGetButtonAction($langs->trans('ShippingExist'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
3653 }
3654 }
3655 }
3656 print '</div>';
3657 }
3658
3659 // Select mail models is same action as presend
3660 if (GETPOST('modelselected')) {
3661 $action = 'presend';
3662 }
3663
3664 if ($action != 'presend') {
3665 print '<div class="fichecenter"><div class="fichehalfleft">';
3666 print '<a name="builddoc"></a>'; // ancre
3667 // Documents
3668 $objref = dol_sanitizeFileName($object->ref);
3669 $relativepath = $objref.'/'.$objref.'.pdf';
3670 $filedir = $conf->commande->multidir_output[$object->entity].'/'.$objref;
3671 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
3672 $genallowed = $usercanread;
3673 $delallowed = $usercancreate;
3674 print $formfile->showdocuments('commande', $objref, $filedir, $urlsource, $genallowed, (int) $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang, '', $object);
3675
3676
3677 // Show links to link elements
3678 $tmparray = $form->showLinkToObjectBlock($object, array(), array('order'), 1);
3679 $linktoelem = $tmparray['linktoelem'];
3680 $htmltoenteralink = $tmparray['htmltoenteralink'];
3681 print $htmltoenteralink;
3682
3683 $compatibleImportElementsList = false;
3684 if ($usercancreate
3685 && $object->status == Commande::STATUS_DRAFT) {
3686 $compatibleImportElementsList = array('commande', 'propal', 'facture', 'subscription'); // import from linked elements
3687 }
3688 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, $compatibleImportElementsList);
3689
3690 // Show online payment link
3691 // The list can be complete by the hook 'doValidatePayment' executed inside getValidOnlinePaymentMethods()
3692 include_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
3693 $validpaymentmethod = getValidOnlinePaymentMethods('');
3694 $useonlinepayment = count($validpaymentmethod);
3695
3696 if (getDolGlobalString('ORDER_HIDE_ONLINE_PAYMENT_ON_ORDER')) {
3697 $useonlinepayment = 0;
3698 }
3699 if ($object->status != Commande::STATUS_DRAFT && $useonlinepayment) {
3700 print '<br><!-- Link to pay -->';
3701 require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
3702 print showOnlinePaymentUrl('order', $object->ref).'<br>';
3703 }
3704
3705 print '</div><div class="fichehalfright">';
3706
3707 $MAXEVENT = 10;
3708
3709 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/commande/agenda.php?id='.$object->id);
3710
3711 // List of actions on element
3712 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
3713 $formactions = new FormActions($db);
3714 $somethingshown = $formactions->showactions($object, 'order', $socid, 1, '', $MAXEVENT, '', $morehtmlcenter); // Show all action for thirdparty
3715
3716 print '</div></div>';
3717 }
3718
3719 // Presend form
3720 $modelmail = 'order_send';
3721 $defaulttopic = 'SendOrderRef';
3722 $diroutput = getMultidirOutput($object);
3723 $trackid = 'ord'.$object->id;
3724
3725 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
3726 }
3727}
3728
3729// End of page
3730llxFooter();
3731$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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 customers orders.
const STATUS_SHIPMENTONPROCESS
Shipment on process.
const STATUS_CLOSED
Closed (Sent, billed or not)
const STATUS_CANCELED
Canceled status.
const STATUS_DRAFT
Draft status.
const STATUS_VALIDATED
Validated status.
Class to manage a WYSIWYG editor.
Class to manage standard extra fields.
static createDepositFromOrigin(CommonObject $origin, $date, $payment_terms_id, User $user, $notrigger=0, $autoValidateDeposit=false, $overrideFields=array())
Creates a deposit from a proposal or an order by grouping lines by VAT rates.
const TYPE_DEPOSIT
Deposit invoice.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class permettant la generation de composants html autre Only common components are here.
Class to manage HTML output components for orders Before adding component here, check they are not in...
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.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
Class to manage projects.
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.
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_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
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_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning 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 '.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
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.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0, $attop=0)
Set event message in dol_events session object.
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.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
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'.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
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...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='')
Return the value of a $_GET or $_POST supervariable, converted into float.
if(!function_exists( 'utf8_encode')) if(!function_exists('utf8_decode')) if(!function_exists( 'str_starts_with')) if(!function_exists('str_ends_with')) if(!function_exists( 'str_contains')) getMultidirOutput($object, $module='', $forobject=0, $mode='output')
Return the full path of the directory where a module (or an object of a module) stores its files.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($object, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
getDictionaryValue($tablename, $field, $id, $checkentity=false, $rowidfield='rowid')
Return the value of a filed into a dictionary for the record $id.
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
commande_prepare_head(Commande $object)
Prepare array with list of tabs.
Definition order.lib.php:35
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.