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