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