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