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