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