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