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