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'), GETPOST('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('/\‍(.*\‍)/', (string) $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 $object->loadExpeditions();
1335 if (isset($object->expeditions[GETPOST('lineid', 'int')])) {
1336 if ($qty < $object->expeditions[GETPOST('lineid', 'int')]) {
1337 setEventMessages($langs->trans('ErrorQtyOrderedLessQtyShipped'), null, 'errors');
1338 $error++;
1339 $action = 'editline';
1340 }
1341 }
1342
1343 if (!$error) {
1344 if (!$user->hasRight('margins', 'creer')) {
1345 foreach ($object->lines as &$line) {
1346 if ($line->id == GETPOSTINT('lineid')) {
1347 $fournprice = $line->fk_fournprice;
1348 $buyingprice = $line->pa_ht;
1349 break;
1350 }
1351 }
1352 }
1353
1354 $price_base_type = 'HT';
1355 $pu = $pu_ht;
1356 if (empty($pu) && !empty($pu_ttc)) {
1357 $pu = $pu_ttc;
1358 $price_base_type = 'TTC';
1359 }
1360
1361 $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);
1362
1363 if ($result >= 0) {
1364 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1365 // Define output language
1366 $outputlangs = $langs;
1367 $newlang = '';
1368 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1369 $newlang = GETPOST('lang_id', 'aZ09');
1370 }
1371 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1372 $newlang = $object->thirdparty->default_lang;
1373 }
1374 if (!empty($newlang)) {
1375 $outputlangs = new Translate("", $conf);
1376 $outputlangs->setDefaultLang($newlang);
1377 }
1378
1379 $ret = $object->fetch($object->id); // Reload to get new records
1380 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1381 }
1382
1383 unset($_POST['qty']);
1384 unset($_POST['type']);
1385 unset($_POST['productid']);
1386 unset($_POST['remise_percent']);
1387 unset($_POST['price_ht']);
1388 unset($_POST['multicurrency_price_ht']);
1389 unset($_POST['price_ttc']);
1390 unset($_POST['tva_tx']);
1391 unset($_POST['product_ref']);
1392 unset($_POST['product_label']);
1393 unset($_POST['product_desc']);
1394 unset($_POST['fournprice']);
1395 unset($_POST['buying_price']);
1396
1397 unset($_POST['date_starthour']);
1398 unset($_POST['date_startmin']);
1399 unset($_POST['date_startsec']);
1400 unset($_POST['date_startday']);
1401 unset($_POST['date_startmonth']);
1402 unset($_POST['date_startyear']);
1403 unset($_POST['date_endhour']);
1404 unset($_POST['date_endmin']);
1405 unset($_POST['date_endsec']);
1406 unset($_POST['date_endday']);
1407 unset($_POST['date_endmonth']);
1408 unset($_POST['date_endyear']);
1409 } else {
1410 setEventMessages($object->error, $object->errors, 'errors');
1411 }
1412 }
1413 } elseif ($action == 'updateline' && $usercancreate && GETPOST('cancel', 'alpha')) {
1414 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To re-display card in edit mode
1415 exit();
1416 } elseif ($action == 'confirm_validate' && $confirm == 'yes' && $usercanvalidate) {
1417 $idwarehouse = GETPOSTINT('idwarehouse');
1418
1419 $qualified_for_stock_change = 0;
1420 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1421 $qualified_for_stock_change = $object->hasProductsOrServices(2);
1422 } else {
1423 $qualified_for_stock_change = $object->hasProductsOrServices(1);
1424 }
1425
1426 // Check parameters
1427 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
1428 if (!$idwarehouse || $idwarehouse == -1) {
1429 $error++;
1430 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1431 $action = '';
1432 }
1433 }
1434
1435 if (!$error) {
1436 $locationTarget = '';
1437
1438 $db->begin();
1439
1440 $result = $object->valid($user, $idwarehouse);
1441 if ($result >= 0) {
1442 $error = 0;
1443 $deposit = null;
1444
1445 $deposit_percent_from_payment_terms = (float) getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id);
1446
1447 if (
1448 GETPOST('generate_deposit', 'alpha') == 'on' && !empty($deposit_percent_from_payment_terms)
1449 && isModEnabled('invoice') && $user->hasRight('facture', 'creer')
1450 ) {
1451 require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
1452
1453 $date = dol_mktime(0, 0, 0, GETPOSTINT('datefmonth'), GETPOSTINT('datefday'), GETPOSTINT('datefyear'));
1454 $forceFields = array();
1455
1456 if (GETPOSTISSET('date_pointoftax')) {
1457 $forceFields['date_pointoftax'] = dol_mktime(0, 0, 0, GETPOSTINT('date_pointoftaxmonth'), GETPOSTINT('date_pointoftaxday'), GETPOSTINT('date_pointoftaxyear'));
1458 }
1459
1460 $deposit = Facture::createDepositFromOrigin($object, $date, GETPOSTINT('cond_reglement_id'), $user, 0, GETPOSTINT('validate_generated_deposit') == 'on', $forceFields);
1461
1462 if ($deposit) {
1463 setEventMessage('DepositGenerated');
1464 $locationTarget = DOL_URL_ROOT . '/compta/facture/card.php?id=' . $deposit->id;
1465 } else {
1466 $error++;
1467 setEventMessages($object->error, $object->errors, 'errors');
1468 }
1469 }
1470
1471 // Define output language
1472 if (! $error) {
1473 $db->commit();
1474
1475 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1476 $outputlangs = $langs;
1477 $newlang = '';
1478 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1479 $newlang = GETPOST('lang_id', 'aZ09');
1480 }
1481 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1482 $newlang = $object->thirdparty->default_lang;
1483 }
1484 if (!empty($newlang)) {
1485 $outputlangs = new Translate("", $conf);
1486 $outputlangs->setDefaultLang($newlang);
1487 }
1488 $model = $object->model_pdf;
1489 $ret = $object->fetch($id); // Reload to get new records
1490
1491 $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1492
1493 if ($deposit) {
1494 $deposit->fetch($deposit->id); // Reload to get new records
1495 $deposit->generateDocument($deposit->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1496 }
1497 }
1498
1499 if ($locationTarget) {
1500 header('Location: ' . $locationTarget);
1501 exit;
1502 }
1503 } else {
1504 $db->rollback();
1505 }
1506 } else {
1507 $db->rollback();
1508 setEventMessages($object->error, $object->errors, 'errors');
1509 }
1510 }
1511 } elseif ($action == 'confirm_modif' && $usercancreate) {
1512 // Go back to draft status
1513 $idwarehouse = GETPOST('idwarehouse');
1514
1515 $qualified_for_stock_change = 0;
1516 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1517 $qualified_for_stock_change = $object->hasProductsOrServices(2);
1518 } else {
1519 $qualified_for_stock_change = $object->hasProductsOrServices(1);
1520 }
1521
1522 // Check parameters
1523 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
1524 if (!$idwarehouse || $idwarehouse == -1) {
1525 $error++;
1526 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1527 $action = '';
1528 }
1529 }
1530
1531 if (!$error) {
1532 $result = $object->setDraft($user, $idwarehouse);
1533 if ($result >= 0) {
1534 // Define output language
1535 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1536 $outputlangs = $langs;
1537 $newlang = '';
1538 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1539 $newlang = GETPOST('lang_id', 'aZ09');
1540 }
1541 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1542 $newlang = $object->thirdparty->default_lang;
1543 }
1544 if (!empty($newlang)) {
1545 $outputlangs = new Translate("", $conf);
1546 $outputlangs->setDefaultLang($newlang);
1547 }
1548 $model = $object->model_pdf;
1549 $ret = $object->fetch($id); // Reload to get new records
1550
1551 $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1552 }
1553 } else {
1554 setEventMessages($object->error, $object->errors, 'errors');
1555 }
1556 }
1557 } elseif ($action == 'confirm_shipped' && $confirm == 'yes' && $usercanclose) {
1558 $result = $object->cloture($user);
1559 if ($result < 0) {
1560 setEventMessages($object->error, $object->errors, 'errors');
1561 }
1562 } elseif ($action == 'confirm_cancel' && $confirm == 'yes' && $usercanvalidate) {
1563 $idwarehouse = GETPOSTINT('idwarehouse');
1564
1565 $qualified_for_stock_change = 0;
1566 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1567 $qualified_for_stock_change = $object->hasProductsOrServices(2);
1568 } else {
1569 $qualified_for_stock_change = $object->hasProductsOrServices(1);
1570 }
1571
1572 // Check parameters
1573 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
1574 if (!$idwarehouse || $idwarehouse == -1) {
1575 $error++;
1576 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1577 $action = '';
1578 }
1579 }
1580
1581 if (!$error) {
1582 $result = $object->cancel($idwarehouse);
1583
1584 if ($result < 0) {
1585 setEventMessages($object->error, $object->errors, 'errors');
1586 }
1587 }
1588 }
1589
1590 if ($action == 'update_extras' && $usercancreate) {
1591 $object->oldcopy = dol_clone($object, 2);
1592 $attribute_name = GETPOST('attribute', 'restricthtml');
1593
1594 // Fill array 'array_options' with data from update form
1595 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
1596 if ($ret < 0) {
1597 $error++;
1598 }
1599
1600 if (!$error) {
1601 // Actions on extra fields
1602 $result = $object->updateExtraField($attribute_name, 'ORDER_MODIFY');
1603 if ($result < 0) {
1604 setEventMessages($object->error, $object->errors, 'errors');
1605 $error++;
1606 }
1607 }
1608
1609 if ($error) {
1610 $action = 'edit_extras';
1611 }
1612 }
1613
1614 // add lines from objectlinked
1615 if ($action == 'import_lines_from_object'
1616 && $usercancreate
1617 && $object->statut == Commande::STATUS_DRAFT
1618 ) {
1619 $fromElement = GETPOST('fromelement');
1620 $fromElementid = GETPOST('fromelementid');
1621 $importLines = GETPOST('line_checkbox');
1622
1623 if (!empty($importLines) && is_array($importLines) && !empty($fromElement) && ctype_alpha($fromElement) && !empty($fromElementid)) {
1624 if ($fromElement == 'commande') {
1625 dol_include_once('/'.$fromElement.'/class/'.$fromElement.'.class.php');
1626 $lineClassName = 'OrderLine';
1627 } elseif ($fromElement == 'propal') {
1628 dol_include_once('/comm/'.$fromElement.'/class/'.$fromElement.'.class.php');
1629 $lineClassName = 'PropaleLigne';
1630 } elseif ($fromElement == 'facture') {
1631 dol_include_once('/compta/'.$fromElement.'/class/'.$fromElement.'.class.php');
1632 $lineClassName = 'FactureLigne';
1633 }
1634 $nextRang = count($object->lines) + 1;
1635 $importCount = 0;
1636 $error = 0;
1637 foreach ($importLines as $lineId) {
1638 $lineId = intval($lineId);
1639 $originLine = new $lineClassName($db);
1640 if (intval($fromElementid) > 0 && $originLine->fetch($lineId) > 0) {
1641 $originLine->fetch_optionals();
1642 $desc = $originLine->desc;
1643 $pu_ht = $originLine->subprice;
1644 $qty = $originLine->qty;
1645 $txtva = $originLine->tva_tx;
1646 $txlocaltax1 = $originLine->localtax1_tx;
1647 $txlocaltax2 = $originLine->localtax2_tx;
1648 $fk_product = $originLine->fk_product;
1649 $remise_percent = $originLine->remise_percent;
1650 $date_start = $originLine->date_start;
1651 $date_end = $originLine->date_end;
1652 $fk_code_ventilation = 0;
1653 $info_bits = $originLine->info_bits;
1654 $fk_remise_except = $originLine->fk_remise_except;
1655 $price_base_type = 'HT';
1656 $pu_ttc = 0;
1657 $type = $originLine->product_type;
1658 $rang = $nextRang++;
1659 $special_code = $originLine->special_code;
1660 $origin = $originLine->element;
1661 $origin_id = $originLine->id;
1662 $fk_parent_line = 0;
1663 $fk_fournprice = $originLine->fk_fournprice;
1664 $pa_ht = $originLine->pa_ht;
1665 $label = $originLine->label;
1666 $array_options = $originLine->array_options;
1667 $situation_percent = 100;
1668 $fk_prev_id = '';
1669 $fk_unit = $originLine->fk_unit;
1670 $pu_ht_devise = $originLine->multicurrency_subprice;
1671
1672 $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);
1673
1674 if ($res > 0) {
1675 $importCount++;
1676 } else {
1677 $error++;
1678 }
1679 } else {
1680 $error++;
1681 }
1682 }
1683
1684 if ($error) {
1685 setEventMessages($langs->trans('ErrorsOnXLines', $error), null, 'errors');
1686 }
1687 }
1688 }
1689
1690 // Actions when printing a doc from card
1691 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
1692
1693 // Actions to build doc
1694 $upload_dir = !empty($conf->commande->multidir_output[$object->entity]) ? $conf->commande->multidir_output[$object->entity] : $conf->commande->dir_output;
1695 $permissiontoadd = $usercancreate;
1696 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1697
1698 // Actions to send emails
1699 $triggersendname = 'ORDER_SENTBYMAIL';
1700 $paramname = 'id';
1701 $autocopy = 'MAIN_MAIL_AUTOCOPY_ORDER_TO'; // used to know the automatic BCC to add
1702 $trackid = 'ord'.$object->id;
1703 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1704
1705
1706 if (!$error && getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB') && $usercancreate) {
1707 if ($action == 'addcontact' && $usercancreate) {
1708 if ($object->id > 0) {
1709 $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
1710 $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
1711 $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
1712 }
1713
1714 if ($result >= 0) {
1715 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1716 exit();
1717 } else {
1718 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1719 $langs->load("errors");
1720 setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
1721 } else {
1722 setEventMessages($object->error, $object->errors, 'errors');
1723 }
1724 }
1725 } elseif ($action == 'swapstatut' && $usercancreate) {
1726 // bascule du statut d'un contact
1727 if ($object->id > 0) {
1728 $result = $object->swapContactStatus(GETPOSTINT('ligne'));
1729 } else {
1730 dol_print_error($db);
1731 }
1732 } elseif ($action == 'deletecontact' && $usercancreate) {
1733 // Efface un contact
1734 $result = $object->delete_contact($lineid);
1735
1736 if ($result >= 0) {
1737 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1738 exit();
1739 } else {
1740 dol_print_error($db);
1741 }
1742 }
1743 }
1744}
1745
1746
1747/*
1748 * View
1749 */
1750
1751$title = $object->ref." - ".$langs->trans('Card');
1752if ($action == 'create') {
1753 $title = $langs->trans("NewOrder");
1754}
1755$help_url = 'EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes|DE:Modul_Kundenaufträge';
1756
1757llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-order page-card');
1758
1759$form = new Form($db);
1760$formfile = new FormFile($db);
1761$formorder = new FormOrder($db);
1762$formmargin = new FormMargin($db);
1763if (isModEnabled('project')) {
1764 $formproject = new FormProjets($db);
1765}
1766
1767// Mode creation
1768if ($action == 'create' && $usercancreate) {
1769 print load_fiche_titre($langs->trans('CreateOrder'), '', 'order');
1770
1771 $soc = new Societe($db);
1772 if ($socid > 0) {
1773 $res = $soc->fetch($socid);
1774 }
1775
1776 //$remise_absolue = 0;
1777
1778 $currency_code = $conf->currency;
1779
1780 $cond_reglement_id = GETPOSTINT('cond_reglement_id');
1781 $deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
1782 $mode_reglement_id = GETPOSTINT('mode_reglement_id');
1783 $fk_account = GETPOSTINT('fk_account');
1784
1785 if (!empty($origin) && !empty($originid)) {
1786 // Parse element/subelement (ex: project_task)
1787 $element = $subelement = $origin;
1788 $regs = array();
1789 if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
1790 $element = $regs[1];
1791 $subelement = $regs[2];
1792 }
1793
1794 if ($element == 'project') {
1795 $projectid = $originid;
1796
1797 if (!$cond_reglement_id) {
1798 $cond_reglement_id = $soc->cond_reglement_id;
1799 }
1800 if (!$deposit_percent) {
1801 $deposit_percent = $soc->deposit_percent;
1802 }
1803 if (!$mode_reglement_id) {
1804 $mode_reglement_id = $soc->mode_reglement_id;
1805 }
1806 if (!$remise_percent) {
1807 $remise_percent = $soc->remise_percent;
1808 }
1809 /*if (!$dateorder) {
1810 // Do not set 0 here (0 for a date is 1970)
1811 $dateorder = (empty($dateinvoice) ? (empty($conf->global->MAIN_AUTOFILL_DATE_ORDER) ?-1 : '') : $dateorder);
1812 }*/
1813 } else {
1814 // For compatibility
1815 if ($element == 'order' || $element == 'commande') {
1816 $element = $subelement = 'commande';
1817 } elseif ($element == 'propal') {
1818 $element = 'comm/propal';
1819 $subelement = 'propal';
1820 } elseif ($element == 'contract') {
1821 $element = $subelement = 'contrat';
1822 }
1823
1824 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1825
1826 $classname = ucfirst($subelement);
1827 $objectsrc = new $classname($db);
1828 '@phan-var-force Commande|Propal|Contrat $objectsrc'; // Can possibly be other class but CommonObject is too general
1829 $objectsrc->fetch($originid);
1830 if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
1831 $objectsrc->fetch_lines();
1832 }
1833 $objectsrc->fetch_thirdparty();
1834
1835 // Replicate extrafields
1836 $objectsrc->fetch_optionals();
1837 $object->array_options = $objectsrc->array_options;
1838
1839 $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
1840 $ref_client = (!empty($objectsrc->ref_client) ? $objectsrc->ref_client : '');
1841
1842 $soc = $objectsrc->thirdparty;
1843 $cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0));
1844 $deposit_percent = (!empty($objectsrc->deposit_percent) ? $objectsrc->deposit_percent : (!empty($soc->deposit_percent) ? $soc->deposit_percent : null));
1845 $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0));
1846 $fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0));
1847 $availability_id = (!empty($objectsrc->availability_id) ? $objectsrc->availability_id : 0);
1848 $shipping_method_id = (!empty($objectsrc->shipping_method_id) ? $objectsrc->shipping_method_id : (!empty($soc->shipping_method_id) ? $soc->shipping_method_id : 0));
1849 $warehouse_id = (!empty($objectsrc->warehouse_id) ? $objectsrc->warehouse_id : (!empty($soc->warehouse_id) ? $soc->warehouse_id : 0));
1850 $demand_reason_id = (!empty($objectsrc->demand_reason_id) ? $objectsrc->demand_reason_id : (!empty($soc->demand_reason_id) ? $soc->demand_reason_id : 0));
1851 //$remise_percent = (!empty($objectsrc->remise_percent) ? $objectsrc->remise_percent : (!empty($soc->remise_percent) ? $soc->remise_percent : 0));
1852 //$remise_absolue = (!empty($objectsrc->remise_absolue) ? $objectsrc->remise_absolue : (!empty($soc->remise_absolue) ? $soc->remise_absolue : 0));
1853 $dateorder = !getDolGlobalString('MAIN_AUTOFILL_DATE_ORDER') ? -1 : '';
1854
1855 $date_delivery = (!empty($objectsrc->delivery_date) ? $objectsrc->delivery_date : '');
1856
1857 if (isModEnabled("multicurrency")) {
1858 if (!empty($objectsrc->multicurrency_code)) {
1859 $currency_code = $objectsrc->multicurrency_code;
1860 }
1861 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
1862 $currency_tx = $objectsrc->multicurrency_tx;
1863 }
1864 }
1865
1866 $note_private = $object->getDefaultCreateValueFor('note_private', (!empty($objectsrc->note_private) ? $objectsrc->note_private : null));
1867 $note_public = $object->getDefaultCreateValueFor('note_public', (!empty($objectsrc->note_public) ? $objectsrc->note_public : null));
1868
1869 // Object source contacts list
1870 $srccontactslist = $objectsrc->liste_contact(-1, 'external', 1);
1871 }
1872 } else {
1873 $cond_reglement_id = empty($soc->cond_reglement_id) ? $cond_reglement_id : $soc->cond_reglement_id;
1874 $deposit_percent = empty($soc->deposit_percent) ? $deposit_percent : $soc->deposit_percent;
1875 $mode_reglement_id = empty($soc->mode_reglement_id) ? $mode_reglement_id : $soc->mode_reglement_id;
1876 $fk_account = empty($soc->mode_reglement_id) ? $fk_account : $soc->fk_account;
1877 $availability_id = 0;
1878 $shipping_method_id = $soc->shipping_method_id;
1879 $warehouse_id = $soc->fk_warehouse;
1880 $demand_reason_id = $soc->demand_reason_id;
1881 //$remise_percent = $soc->remise_percent;
1882 //$remise_absolue = 0;
1883 $dateorder = !getDolGlobalString('MAIN_AUTOFILL_DATE_ORDER') ? -1 : '';
1884
1885 if (isModEnabled("multicurrency") && !empty($soc->multicurrency_code)) {
1886 $currency_code = $soc->multicurrency_code;
1887 }
1888
1889 $note_private = $object->getDefaultCreateValueFor('note_private');
1890 $note_public = $object->getDefaultCreateValueFor('note_public');
1891 }
1892
1893 // If form was posted (but error returned), we must reuse the value posted in priority (standard Dolibarr behaviour)
1894 if (!GETPOST('changecompany')) {
1895 if (GETPOSTISSET('cond_reglement_id')) {
1896 $cond_reglement_id = GETPOSTINT('cond_reglement_id');
1897 }
1898 if (GETPOSTISSET('deposit_percent')) {
1899 $deposit_percent = GETPOSTFLOAT('deposit_percent');
1900 }
1901 if (GETPOSTISSET('mode_reglement_id')) {
1902 $mode_reglement_id = GETPOSTINT('mode_reglement_id');
1903 }
1904 if (GETPOSTISSET('cond_reglement_id')) {
1905 $fk_account = GETPOSTINT('fk_account');
1906 }
1907 }
1908
1909 // Warehouse default if null
1910 if ($soc->fk_warehouse > 0) {
1911 $warehouse_id = $soc->fk_warehouse;
1912 }
1913 if (isModEnabled('stock') && empty($warehouse_id) && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
1914 if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE')) {
1915 $warehouse_id = getDolGlobalString('MAIN_DEFAULT_WAREHOUSE');
1916 }
1917 if (empty($object->warehouse_id) && getDolGlobalString('MAIN_DEFAULT_WAREHOUSE_USER') && !empty($user->warehouse_id)) {
1918 $warehouse_id = $user->fk_warehouse;
1919 }
1920 }
1921
1922 print '<form name="crea_commande" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1923 print '<input type="hidden" name="token" value="'.newToken().'">';
1924 print '<input type="hidden" name="action" value="add">';
1925 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
1926 print '<input type="hidden" name="remise_percent" value="'.$soc->remise_percent.'">';
1927 print '<input type="hidden" name="origin" value="'.$origin.'">';
1928 print '<input type="hidden" name="originid" value="'.$originid.'">';
1929 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1930 if (!empty($currency_tx)) {
1931 print '<input type="hidden" name="originmulticurrency_tx" value="'.$currency_tx.'">';
1932 }
1933
1934 print dol_get_fiche_head([]);
1935
1936 // Call Hook tabContentCreateOrder
1937 $parameters = array();
1938 // Note that $action and $object may be modified by hook
1939 $reshook = $hookmanager->executeHooks('tabContentCreateOrder', $parameters, $object, $action);
1940 if (empty($reshook)) {
1941 print '<table class="border centpercent">';
1942
1943 // Reference
1944 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Ref').'</td><td>'.$langs->trans("Draft").'</td></tr>';
1945
1946 // Reference client
1947 print '<tr><td>'.$langs->trans('RefCustomer').'</td><td>';
1948 if (getDolGlobalString('MAIN_USE_PROPAL_REFCLIENT_FOR_ORDER') && !empty($origin) && !empty($originid)) {
1949 print '<input type="text" name="ref_client" value="'.$ref_client.'"></td>';
1950 } else {
1951 print '<input type="text" name="ref_client" value="'.GETPOST('ref_client').'"></td>';
1952 }
1953 print '</tr>';
1954
1955 // Thirdparty
1956 print '<tr>';
1957 print '<td class="fieldrequired">'.$langs->trans('Customer').'</td>';
1958 if ($socid > 0) {
1959 print '<td>';
1960 print $soc->getNomUrl(1, 'customer');
1961 print '<input type="hidden" name="socid" value="'.$soc->id.'">';
1962 print '</td>';
1963 } else {
1964 print '<td class="valuefieldcreate">';
1965 $filter = '((s.client:IN:1,2,3) AND (s.status:=:1))';
1966 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
1967 // reload page to retrieve customer information
1968 if (!getDolGlobalString('RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED')) {
1969 print '<script>
1970 $(document).ready(function() {
1971 $("#socid").change(function() {
1972 console.log("We have changed the company - Reload page");
1973 var socid = $(this).val();
1974 // reload page
1975 $("input[name=action]").val("create");
1976 $("input[name=changecompany]").val("1");
1977 $("form[name=crea_commande]").submit();
1978 });
1979 });
1980 </script>';
1981 }
1982 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>';
1983 print '</td>';
1984 }
1985 print '</tr>'."\n";
1986
1987 // Contact of order
1988 if ($socid > 0) {
1989 // Contacts (ask contact only if thirdparty already defined).
1990 print "<tr><td>".$langs->trans("DefaultContact").'</td><td>';
1991 print img_picto('', 'contact', 'class="pictofixedwidth"');
1992 //print $form->selectcontacts($soc->id, $contactid, 'contactid', 1, empty($srccontactslist) ? "" : $srccontactslist, '', 1, 'maxwidth300 widthcentpercentminusx');
1993 print $form->select_contact($soc->id, $contactid, 'contactid', 1, empty($srccontactslist) ? "" : $srccontactslist, '', 1, 'maxwidth300 widthcentpercentminusx', true);
1994 print '</td></tr>';
1995
1996 // Ligne info remises tiers
1997 print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
1998
1999 $absolute_discount = $soc->getAvailableDiscounts();
2000
2001 $thirdparty = $soc;
2002 $discount_type = 0;
2003 $backtopage = $_SERVER["PHP_SELF"].'?socid='.$thirdparty->id.'&action='.$action.'&origin='.urlencode((string) (GETPOST('origin'))).'&originid='.urlencode((string) (GETPOSTINT('originid')));
2004 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2005
2006 print '</td></tr>';
2007 }
2008
2009 // Date
2010 print '<tr><td class="fieldrequired">'.$langs->trans('Date').'</td><td>';
2011 print img_picto('', 'action', 'class="pictofixedwidth"');
2012 print $form->selectDate('', 're', 0, 0, 0, "crea_commande", 1, 1); // Always autofill date with current date
2013 print '</td></tr>';
2014
2015 // Date delivery planned
2016 print '<tr><td>'.$langs->trans("DateDeliveryPlanned").'</td>';
2017 print '<td colspan="3">';
2018 $date_delivery = ($date_delivery ? $date_delivery : $object->delivery_date);
2019 print img_picto('', 'action', 'class="pictofixedwidth"');
2020 print $form->selectDate($date_delivery ? $date_delivery : -1, 'liv_', 1, 1, 1);
2021 print "</td>\n";
2022 print '</tr>';
2023
2024 // Delivery delay
2025 print '<tr class="fielddeliverydelay"><td>'.$langs->trans('AvailabilityPeriod').'</td><td>';
2026 print img_picto('', 'clock', 'class="pictofixedwidth"');
2027 $form->selectAvailabilityDelay((GETPOSTISSET('availability_id') ? GETPOST('availability_id') : $availability_id), 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx');
2028 print '</td></tr>';
2029
2030 // Terms of payment
2031 print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
2032 print img_picto('', 'payment', 'class="pictofixedwidth"');
2033 print $form->getSelectConditionsPaiements($cond_reglement_id, 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', $deposit_percent);
2034 print '</td></tr>';
2035
2036 // Payment mode
2037 print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
2038 print img_picto('', 'bank', 'class="pictofixedwidth"');
2039 print $form->select_types_paiements($mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
2040 print '</td></tr>';
2041
2042 // Bank Account
2043 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_ORDER') && isModEnabled("bank")) {
2044 print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
2045 print img_picto('', 'bank_account', 'class="pictofixedwidth"').$form->select_comptes($fk_account, 'fk_account', 0, '', 1, '', 0, 'maxwidth200 widthcentpercentminusx', 1);
2046 print '</td></tr>';
2047 }
2048
2049 // Shipping Method
2050 if (isModEnabled('shipping')) {
2051 print '<tr><td>'.$langs->trans('SendingMethod').'</td><td>';
2052 print img_picto('', 'object_dolly', 'class="pictofixedwidth"');
2053 $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');
2054 print '</td></tr>';
2055 }
2056
2057 // Warehouse
2058 if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
2059 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2060 $formproduct = new FormProduct($db);
2061 print '<tr><td>'.$langs->trans('Warehouse').'</td><td>';
2062 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');
2063 print '</td></tr>';
2064 }
2065
2066 // Source / Channel - What trigger creation
2067 print '<tr><td>'.$langs->trans('Source').'</td><td>';
2068 print img_picto('', 'question', 'class="pictofixedwidth"');
2069 $form->selectInputReason((GETPOSTISSET('demand_reason_id') ? GETPOST('demand_reason_id') : $demand_reason_id), 'demand_reason_id', '', 1, 'maxwidth200 widthcentpercentminusx');
2070 print '</td></tr>';
2071
2072 // TODO How record was recorded OrderMode (llx_c_input_method)
2073
2074 // Project
2075 if (isModEnabled('project')) {
2076 $langs->load("projects");
2077 print '<tr>';
2078 print '<td>'.$langs->trans("Project").'</td><td>';
2079 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');
2080 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>';
2081 print '</td>';
2082 print '</tr>';
2083 }
2084
2085 // Incoterms
2086 if (isModEnabled('incoterm')) {
2087 print '<tr>';
2088 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), !empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : $soc->fk_incoterms, 1).'</label></td>';
2089 print '<td class="maxwidthonsmartphone">';
2090 $incoterm_id = GETPOST('incoterm_id');
2091 $location_incoterms = GETPOST('location_incoterms');
2092 if (empty($incoterm_id)) {
2093 $incoterm_id = (!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : $soc->fk_incoterms);
2094 $location_incoterms = (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : $soc->location_incoterms);
2095 }
2096 print img_picto('', 'incoterm', 'class="pictofixedwidth"');
2097 print $form->select_incoterms($incoterm_id, $location_incoterms);
2098 print '</td></tr>';
2099 }
2100
2101 // Other attributes
2102 $parameters = array();
2103 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
2104 $parameters['objectsrc'] = $objectsrc;
2105 }
2106 $parameters['socid'] = $socid;
2107
2108 // Note that $action and $object may be modified by hook
2109 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action);
2110 print $hookmanager->resPrint;
2111 if (empty($reshook)) {
2112 if (getDolGlobalString('THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_ORDER') && !empty($soc->id)) {
2113 // copy from thirdparty
2114 $tpExtrafields = new ExtraFields($db);
2115 $tpExtrafieldLabels = $tpExtrafields->fetch_name_optionals_label($soc->table_element);
2116 if ($soc->fetch_optionals() > 0) {
2117 $object->array_options = array_merge($object->array_options, $soc->array_options);
2118 }
2119 }
2120
2121 print $object->showOptionals($extrafields, 'create', $parameters);
2122 }
2123
2124 // Template to use by default
2125 print '<tr><td>'.$langs->trans('DefaultModel').'</td>';
2126 print '<td>';
2127 include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php';
2129 $preselected = getDolGlobalString('COMMANDE_ADDON_PDF');
2130 print img_picto('', 'pdf', 'class="pictofixedwidth"');
2131 print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1);
2132 print "</td></tr>";
2133
2134 // Multicurrency
2135 if (isModEnabled("multicurrency")) {
2136 print '<tr>';
2137 print '<td>'.$form->editfieldkey("Currency", 'multicurrency_code', '', $object, 0).'</td>';
2138 print '<td class="maxwidthonsmartphone">';
2139 print img_picto('', 'currency', 'class="pictofixedwidth"').$form->selectMultiCurrency(((GETPOSTISSET('multicurrency_code') && !GETPOST('changecompany')) ? GETPOST('multicurrency_code') : $currency_code), 'multicurrency_code', 0, '', 0, 'maxwidth200 widthcentpercentminusx');
2140 print '</td></tr>';
2141 }
2142
2143 // Note public
2144 print '<tr>';
2145 print '<td class="tdtop">'.$langs->trans('NotePublic').'</td>';
2146 print '<td>';
2147
2148 $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
2149 print $doleditor->Create(1);
2150 // print '<textarea name="note_public" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_public.'</textarea>';
2151 print '</td></tr>';
2152
2153 // Note private
2154 if (empty($user->socid)) {
2155 print '<tr>';
2156 print '<td class="tdtop">'.$langs->trans('NotePrivate').'</td>';
2157 print '<td>';
2158
2159 $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
2160 print $doleditor->Create(1);
2161 // print '<textarea name="note" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'</textarea>';
2162 print '</td></tr>';
2163 }
2164
2165 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
2166 // TODO for compatibility
2167 if ($origin == 'contrat') {
2168 // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
2169 //$objectsrc->remise_absolue = $remise_absolue;
2170 //$objectsrc->remise_percent = $remise_percent;
2171 $objectsrc->update_price(1);
2172 }
2173
2174 print "\n<!-- ".$classname." info -->";
2175 print "\n";
2176 print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
2177 print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
2178 print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
2179 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
2180 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
2181
2182 switch ($classname) {
2183 case 'Propal':
2184 $newclassname = 'CommercialProposal';
2185 break;
2186 case 'Commande':
2187 $newclassname = 'Order';
2188 break;
2189 case 'Expedition':
2190 $newclassname = 'Sending';
2191 break;
2192 case 'Contrat':
2193 $newclassname = 'Contract';
2194 break;
2195 default:
2196 $newclassname = $classname;
2197 }
2198
2199 print '<tr><td>'.$langs->trans($newclassname).'</td><td>'.$objectsrc->getNomUrl(1).'</td></tr>';
2200
2201 // Amount
2202 print '<tr><td>'.$langs->trans('AmountHT').'</td><td>'.price($objectsrc->total_ht).'</td></tr>';
2203 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($objectsrc->total_tva)."</td></tr>";
2204 if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0) { // Localtax1 RE
2205 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax1)."</td></tr>";
2206 }
2207
2208 if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) { // Localtax2 IRPF
2209 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax2)."</td></tr>";
2210 }
2211
2212 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($objectsrc->total_ttc)."</td></tr>";
2213
2214 if (isModEnabled("multicurrency")) {
2215 print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td>'.price($objectsrc->multicurrency_total_ht).'</td></tr>';
2216 print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td>'.price($objectsrc->multicurrency_total_tva)."</td></tr>";
2217 print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td>'.price($objectsrc->multicurrency_total_ttc)."</td></tr>";
2218 }
2219 }
2220
2221 print "\n";
2222
2223 print '</table>';
2224 }
2225
2226 print dol_get_fiche_end();
2227
2228 print $form->buttonsSaveCancel("CreateDraft");
2229
2230 // Show origin lines
2231 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
2232 $title = $langs->trans('ProductsAndServices');
2233 print load_fiche_titre($title);
2234
2235 print '<div class="div-table-responsive-no-min">';
2236 print '<table class="noborder centpercent">';
2237
2238 $objectsrc->printOriginLinesList('', $selectedLines);
2239
2240 print '</table>';
2241 print '</div>';
2242 }
2243
2244 print '</form>';
2245} else {
2246 // Mode view
2247 $now = dol_now();
2248
2249 if ($object->id > 0) {
2250 $product_static = new Product($db);
2251
2252 $soc = new Societe($db);
2253 $soc->fetch($object->socid);
2254
2255 $author = new User($db);
2256 $author->fetch($object->user_author_id);
2257
2258 $object->fetch_thirdparty();
2259 $res = $object->fetch_optionals();
2260
2262 print dol_get_fiche_head($head, 'order', $langs->trans("CustomerOrder"), -1, 'order');
2263
2264 $formconfirm = '';
2265
2266 // Confirmation to delete
2267 if ($action == 'delete') {
2268 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteOrder'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', '', 0, 1);
2269 }
2270
2271 // Confirmation of validation
2272 if ($action == 'validate') {
2273 // We check that object has a temporary ref
2274 $ref = substr($object->ref, 1, 4);
2275 if ($ref == 'PROV' || $ref == '') {
2276 $numref = $object->getNextNumRef($soc);
2277 if (empty($numref)) {
2278 $error++;
2279 setEventMessages($object->error, $object->errors, 'errors');
2280 }
2281 } else {
2282 $numref = $object->ref;
2283 }
2284
2285 $text = $langs->trans('ConfirmValidateOrder', $numref);
2286 if (isModEnabled('notification')) {
2287 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2288 $notify = new Notify($db);
2289 $text .= '<br>';
2290 $text .= $notify->confirmMessage('ORDER_VALIDATE', $object->socid, $object);
2291 }
2292
2293 $qualified_for_stock_change = 0;
2294 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2295 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2296 } else {
2297 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2298 }
2299
2300 $formquestion = array();
2301 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
2302 $langs->load("stocks");
2303 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2304 $formproduct = new FormProduct($db);
2305 $forcecombo = 0;
2306 if ($conf->browser->name == 'ie') {
2307 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
2308 }
2309 $formquestion = array(
2310 // 'text' => $langs->trans("ConfirmClone"),
2311 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
2312 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
2313 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOSTINT('idwarehouse') ? GETPOSTINT('idwarehouse') : 'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
2314 );
2315 }
2316
2317 // mandatoryPeriod
2318 $nbMandated = 0;
2319 foreach ($object->lines as $line) {
2320 $res = $line->fetch_product();
2321 if ($res > 0) {
2322 if ($line->product->isService() && $line->product->isMandatoryPeriod() && (empty($line->date_start) || empty($line->date_end))) {
2323 $nbMandated++;
2324 break;
2325 }
2326 }
2327 }
2328 if ($nbMandated > 0) {
2329 if (getDolGlobalString('SERVICE_STRICT_MANDATORY_PERIOD')) {
2330 setEventMessages($langs->trans("mandatoryPeriodNeedTobeSetMsgValidate"), null, 'errors');
2331 $error++;
2332 } else {
2333 $text .= '<div><span class="clearboth nowraponall warning">'.img_warning().$langs->trans("mandatoryPeriodNeedTobeSetMsgValidate").'</span></div>';
2334 }
2335 }
2336
2337 if (getDolGlobalInt('SALE_ORDER_SUGGEST_DOWN_PAYMENT_INVOICE_CREATION')) {
2338 // This is a hidden option:
2339 // Suggestion to create invoice during order validation is not enabled by default.
2340 // Such choice should be managed by the workflow module and trigger. This option generates conflicts with some setup.
2341 // It may also break step of creating an order when invoicing must be done from proposals and not from orders
2342 $deposit_percent_from_payment_terms = (float) getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id);
2343
2344 if (!empty($deposit_percent_from_payment_terms) && isModEnabled('invoice') && $user->hasRight('facture', 'creer')) {
2345 require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php';
2346
2347 $object->fetchObjectLinked();
2348
2349 $eligibleForDepositGeneration = true;
2350
2351 if (array_key_exists('facture', $object->linkedObjects)) {
2352 foreach ($object->linkedObjects['facture'] as $invoice) {
2353 '@phan-var-force Facture $invoice';
2354 if ($invoice->type == Facture::TYPE_DEPOSIT) {
2355 $eligibleForDepositGeneration = false;
2356 break;
2357 }
2358 }
2359 }
2360
2361 if ($eligibleForDepositGeneration && array_key_exists('propal', $object->linkedObjects)) {
2362 foreach ($object->linkedObjects['propal'] as $proposal) {
2363 $proposal->fetchObjectLinked();
2364
2365 if (array_key_exists('facture', $proposal->linkedObjects)) {
2366 foreach ($proposal->linkedObjects['facture'] as $invoice) {
2367 '@phan-var-force Facture $invoice';
2368 if ($invoice->type == Facture::TYPE_DEPOSIT) {
2369 $eligibleForDepositGeneration = false;
2370 break 2;
2371 }
2372 }
2373 }
2374 }
2375 }
2376
2377 if ($eligibleForDepositGeneration) {
2378 $formquestion[] = array(
2379 'type' => 'checkbox',
2380 'tdclass' => '',
2381 'name' => 'generate_deposit',
2382 'label' => $form->textwithpicto($langs->trans('GenerateDeposit', $object->deposit_percent), $langs->trans('DepositGenerationPermittedByThePaymentTermsSelected'))
2383 );
2384
2385 $formquestion[] = array(
2386 'type' => 'date',
2387 'tdclass' => 'fieldrequired showonlyifgeneratedeposit',
2388 'name' => 'datef',
2389 'label' => $langs->trans('DateInvoice'),
2390 'value' => dol_now(),
2391 'datenow' => true
2392 );
2393
2394 if (getDolGlobalString('INVOICE_POINTOFTAX_DATE')) {
2395 $formquestion[] = array(
2396 'type' => 'date',
2397 'tdclass' => 'fieldrequired showonlyifgeneratedeposit',
2398 'name' => 'date_pointoftax',
2399 'label' => $langs->trans('DatePointOfTax'),
2400 'value' => dol_now(),
2401 'datenow' => true
2402 );
2403 }
2404
2405
2406 $paymentTermsSelect = $form->getSelectConditionsPaiements(0, 'cond_reglement_id', -1, 0, 0, 'minwidth200');
2407
2408 $formquestion[] = array(
2409 'type' => 'other',
2410 'tdclass' => 'fieldrequired showonlyifgeneratedeposit',
2411 'name' => 'cond_reglement_id',
2412 'label' => $langs->trans('PaymentTerm'),
2413 'value' => $paymentTermsSelect
2414 );
2415
2416 $formquestion[] = array(
2417 'type' => 'checkbox',
2418 'tdclass' => 'showonlyifgeneratedeposit',
2419 'name' => 'validate_generated_deposit',
2420 'label' => $langs->trans('ValidateGeneratedDeposit')
2421 );
2422
2423 $formquestion[] = array(
2424 'type' => 'onecolumn',
2425 'value' => '
2426 <script>
2427 $(document).ready(function() {
2428 $("[name=generate_deposit]").change(function () {
2429 let $self = $(this);
2430 let $target = $(".showonlyifgeneratedeposit").parent(".tagtr");
2431
2432 if (! $self.parents(".tagtr").is(":hidden") && $self.is(":checked")) {
2433 $target.show();
2434 } else {
2435 $target.hide();
2436 }
2437
2438 return true;
2439 });
2440 });
2441 </script>
2442 '
2443 );
2444 }
2445 }
2446 }
2447
2448 if (!$error) {
2449 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_validate', $formquestion, 0, 1, 240);
2450 }
2451 }
2452
2453 // Confirm back to draft status
2454 if ($action == 'modif') {
2455 $qualified_for_stock_change = 0;
2456 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2457 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2458 } else {
2459 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2460 }
2461
2462 $text = $langs->trans('ConfirmUnvalidateOrder', $object->ref);
2463 $formquestion = array();
2464 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
2465 $langs->load("stocks");
2466 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2467 $formproduct = new FormProduct($db);
2468 $forcecombo = 0;
2469 if ($conf->browser->name == 'ie') {
2470 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
2471 }
2472 $formquestion = array(
2473 // 'text' => $langs->trans("ConfirmClone"),
2474 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
2475 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
2476 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockIncrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
2477 );
2478 }
2479
2480 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('UnvalidateOrder'), $text, 'confirm_modif', $formquestion, "yes", 1, 220);
2481 }
2482
2483 /*
2484 * Confirmation de la cloture
2485 */
2486 if ($action == 'shipped') {
2487 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('CloseOrder'), $langs->trans('ConfirmCloseOrder'), 'confirm_shipped', '', 0, 1);
2488 }
2489
2490 /*
2491 * Confirmation de l'annulation
2492 */
2493 if ($action == 'cancel') {
2494 $qualified_for_stock_change = 0;
2495 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2496 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2497 } else {
2498 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2499 }
2500
2501 $text = $langs->trans('ConfirmCancelOrder', $object->ref);
2502 $formquestion = array();
2503 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_VALIDATE_ORDER') && $qualified_for_stock_change) {
2504 $langs->load("stocks");
2505 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2506 $formproduct = new FormProduct($db);
2507 $forcecombo = 0;
2508 if ($conf->browser->name == 'ie') {
2509 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
2510 }
2511 $formquestion = array(
2512 // 'text' => $langs->trans("ConfirmClone"),
2513 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
2514 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
2515 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockIncrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse') ? GETPOST('idwarehouse') : 'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
2516 );
2517 }
2518
2519 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans("Cancel"), $text, 'confirm_cancel', $formquestion, 0, 1);
2520 }
2521
2522 // Confirmation to delete line
2523 if ($action == 'ask_deleteline') {
2524 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
2525 }
2526
2527 // Clone confirmation
2528 if ($action == 'clone') {
2529 $filter = '(s.client:IN:1,2,3)';
2530 // Create an array for form
2531 $formquestion = array(
2532 array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter, '', 0, 0, array(), 0, 'maxwidth300'))
2533 );
2534 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
2535 }
2536
2537 // Call Hook formConfirm
2538 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
2539 // Note that $action and $object may be modified by hook
2540 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
2541 if (empty($reshook)) {
2542 $formconfirm .= $hookmanager->resPrint;
2543 } elseif ($reshook > 0) {
2544 $formconfirm = $hookmanager->resPrint;
2545 }
2546
2547 // Print form confirm
2548 print $formconfirm;
2549
2550
2551 // Order card
2552
2553 $linkback = '<a href="'.DOL_URL_ROOT.'/commande/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
2554
2555 $morehtmlref = '<div class="refidno">';
2556 // Ref customer
2557 $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string', '', 0, 1);
2558 $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);
2559 // Thirdparty
2560 $morehtmlref .= '<br>'.$soc->getNomUrl(1, 'customer');
2561 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
2562 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
2563 }
2564 // Project
2565 if (isModEnabled('project')) {
2566 $langs->load("projects");
2567 $morehtmlref .= '<br>';
2568 if ($usercancreate) {
2569 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2570 if ($action != 'classify') {
2571 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2572 }
2573 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
2574 } else {
2575 if (!empty($object->fk_project)) {
2576 $proj = new Project($db);
2577 $proj->fetch($object->fk_project);
2578 $morehtmlref .= $proj->getNomUrl(1);
2579 if ($proj->title) {
2580 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2581 }
2582 }
2583 }
2584 }
2585 $morehtmlref .= '</div>';
2586
2587
2588 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
2589
2590 // Call Hook tabContentViewOrder
2591 $parameters = array();
2592 // Note that $action and $object may be modified by hook
2593 $reshook = $hookmanager->executeHooks('tabContentViewOrder', $parameters, $object, $action);
2594 if (empty($reshook)) {
2595 print '<div class="fichecenter">';
2596 print '<div class="fichehalfleft">';
2597 print '<div class="underbanner clearboth"></div>';
2598
2599 print '<table class="border tableforfield centpercent">';
2600
2601 if ($soc->outstanding_limit) {
2602 // Outstanding Bill
2603 print '<tr><td class="titlefield">';
2604 print $langs->trans('OutstandingBill');
2605 print '</td><td class="valuefield">';
2606 $arrayoutstandingbills = $soc->getOutstandingBills();
2607 print price($arrayoutstandingbills['opened']).' / ';
2608 print price($soc->outstanding_limit, 0, '', 1, - 1, - 1, $conf->currency);
2609 print '</td>';
2610 print '</tr>';
2611 }
2612
2613 // Relative and absolute discounts
2614 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
2615 $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2616 $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2617 } else {
2618 $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
2619 $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
2620 }
2621
2622 $addrelativediscount = '<a href="'.DOL_URL_ROOT.'/comm/remise.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditRelativeDiscounts").'</a>';
2623 $addabsolutediscount = '<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$soc->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?facid='.$object->id.'">'.$langs->trans("EditGlobalDiscounts").'</a>';
2624 $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>';
2625
2626 print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td class="valuefield">';
2627
2628 $absolute_discount = $soc->getAvailableDiscounts(null, $filterabsolutediscount);
2629 $absolute_creditnote = $soc->getAvailableDiscounts(null, $filtercreditnote);
2630 $absolute_discount = price2num($absolute_discount, 'MT');
2631 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
2632
2633 $thirdparty = $soc;
2634 $discount_type = 0;
2635 $backtopage = $_SERVER["PHP_SELF"].'?id='.$object->id;
2636 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2637
2638 print '</td></tr>';
2639
2640 // Date
2641 print '<tr><td>';
2642 $editenable = $usercancreate && $object->statut == Commande::STATUS_DRAFT;
2643 print $form->editfieldkey("Date", 'date', '', $object, $editenable);
2644 print '</td><td class="valuefield">';
2645 if ($action == 'editdate') {
2646 print '<form name="setdate" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2647 print '<input type="hidden" name="token" value="'.newToken().'">';
2648 print '<input type="hidden" name="action" value="setdate">';
2649 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2650 print $form->selectDate($object->date, 'order_', 0, 0, 0, "setdate");
2651 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
2652 print '</form>';
2653 } else {
2654 print $object->date ? dol_print_date($object->date, 'day') : '&nbsp;';
2655 if ($object->hasDelay() && empty($object->delivery_date)) { // If there is a delivery date planned, warning should be on this date
2656 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
2657 }
2658 }
2659 print '</td>';
2660 print '</tr>';
2661
2662 // Delivery date planned
2663 print '<tr><td>';
2664 $editenable = $usercancreate;
2665 print $form->editfieldkey("DateDeliveryPlanned", 'date_livraison', '', $object, $editenable);
2666 print '</td><td class="valuefield">';
2667 if ($action == 'editdate_livraison') {
2668 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2669 print '<input type="hidden" name="token" value="'.newToken().'">';
2670 print '<input type="hidden" name="action" value="setdate_livraison">';
2671 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2672 print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', 1, 1, 0, "setdate_livraison", 1, 0);
2673 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
2674 print '</form>';
2675 } else {
2676 print $object->delivery_date ? dol_print_date($object->delivery_date, 'dayhour') : '&nbsp;';
2677 if ($object->hasDelay() && !empty($object->delivery_date)) {
2678 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
2679 }
2680 }
2681 print '</td>';
2682 print '</tr>';
2683
2684 // Delivery delay
2685 print '<tr class="fielddeliverydelay"><td>';
2686 $editenable = $usercancreate;
2687 print $form->editfieldkey("AvailabilityPeriod", 'availability', '', $object, $editenable);
2688 print '</td><td class="valuefield">';
2689 if ($action == 'editavailability') {
2690 $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'availability_id', 1);
2691 } else {
2692 $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'none', 1);
2693 }
2694 print '</td></tr>';
2695
2696 // Shipping Method
2697 if (isModEnabled('shipping')) {
2698 print '<tr><td>';
2699 $editenable = $usercancreate;
2700 print $form->editfieldkey("SendingMethod", 'shippingmethod', '', $object, $editenable);
2701 print '</td><td class="valuefield">';
2702 if ($action == 'editshippingmethod') {
2703 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1);
2704 } else {
2705 $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none');
2706 }
2707 print '</td>';
2708 print '</tr>';
2709 }
2710
2711 // Warehouse
2712 if (isModEnabled('stock') && getDolGlobalString('WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER')) {
2713 $langs->load('stocks');
2714 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2715 $formproduct = new FormProduct($db);
2716 print '<tr><td>';
2717 $editenable = $usercancreate;
2718 print $form->editfieldkey("Warehouse", 'warehouse', '', $object, $editenable);
2719 print '</td><td class="valuefield">';
2720 if ($action == 'editwarehouse') {
2721 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->warehouse_id, 'warehouse_id', 1);
2722 } else {
2723 $formproduct->formSelectWarehouses($_SERVER['PHP_SELF'].'?id='.$object->id, $object->warehouse_id, 'none');
2724 }
2725 print '</td>';
2726 print '</tr>';
2727 }
2728
2729 // Source reason (why we have an order)
2730 print '<tr><td>';
2731 $editenable = $usercancreate;
2732 print $form->editfieldkey("Source", 'demandreason', '', $object, $editenable);
2733 print '</td><td class="valuefield">';
2734 if ($action == 'editdemandreason') {
2735 $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'demand_reason_id', 1);
2736 } else {
2737 $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'none');
2738 }
2739 print '</td></tr>';
2740
2741 // Terms of payment
2742 print '<tr><td>';
2743 $editenable = $usercancreate;
2744 print $form->editfieldkey("PaymentConditionsShort", 'conditions', '', $object, $editenable);
2745 print '</td><td class="valuefield">';
2746 if ($action == 'editconditions') {
2747 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent);
2748 } else {
2749 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none', 1, '', 1, $object->deposit_percent);
2750 }
2751 print '</td>';
2752
2753 print '</tr>';
2754
2755 // Mode of payment
2756 print '<tr><td>';
2757 $editenable = $usercancreate;
2758 print $form->editfieldkey("PaymentMode", 'mode', '', $object, $editenable);
2759 print '</td><td class="valuefield">';
2760 if ($action == 'editmode') {
2761 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1);
2762 } else {
2763 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'none');
2764 }
2765 print '</td></tr>';
2766
2767 // TODO Order mode (how we receive order). Not yet implemented
2768 /*
2769 print '<tr><td>';
2770 $editenable = $usercancreate;
2771 print $form->editfieldkey("SourceMode", 'inputmode', '', $object, $editenable);
2772 print '</td><td>';
2773 if ($action == 'editinputmode') {
2774 $form->formInputMode($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->source, 'input_mode_id', 1);
2775 } else {
2776 $form->formInputMode($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->source, 'none');
2777 }
2778 print '</td></tr>';
2779 */
2780
2781 $tmparray = $object->getTotalWeightVolume();
2782 $totalWeight = $tmparray['weight'];
2783 $totalVolume = $tmparray['volume'];
2784 if ($totalWeight) {
2785 print '<tr><td>'.$langs->trans("CalculatedWeight").'</td>';
2786 print '<td class="valuefield">';
2787 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');
2788 print '</td></tr>';
2789 }
2790 if ($totalVolume) {
2791 print '<tr><td>'.$langs->trans("CalculatedVolume").'</td>';
2792 print '<td class="valuefield">';
2793 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');
2794 print '</td></tr>';
2795 }
2796
2797 // TODO How record was recorded OrderMode (llx_c_input_method)
2798
2799 // Incoterms
2800 if (isModEnabled('incoterm')) {
2801 print '<tr><td>';
2802 $editenable = $usercancreate;
2803 print $form->editfieldkey("IncotermLabel", 'incoterm', '', $object, $editenable);
2804 print '</td>';
2805 print '<td class="valuefield">';
2806 if ($action != 'editincoterm') {
2807 print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1);
2808 } else {
2809 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
2810 }
2811 print '</td></tr>';
2812 }
2813
2814 // Bank Account
2815 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_ORDER') && isModEnabled("bank")) {
2816 print '<tr><td>';
2817 $editenable = $usercancreate;
2818 print $form->editfieldkey("BankAccount", 'bankaccount', '', $object, $editenable);
2819 print '</td><td class="valuefield">';
2820 if ($action == 'editbankaccount') {
2821 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
2822 } else {
2823 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
2824 }
2825 print '</td>';
2826 print '</tr>';
2827 }
2828
2829 // Other attributes
2830 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2831
2832 print '</table>';
2833
2834 print '</div>';
2835 print '<div class="fichehalfright">';
2836 print '<div class="underbanner clearboth"></div>';
2837
2838 print '<table class="border tableforfield centpercent">';
2839
2840 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
2841
2842 $alert = '';
2843 if (getDolGlobalString('ORDER_MANAGE_MIN_AMOUNT') && $object->total_ht < $object->thirdparty->order_min_amount) {
2844 $alert = ' ' . img_warning($langs->trans('OrderMinAmount') . ': ' . price($object->thirdparty->order_min_amount));
2845 }
2846
2847 print '<tr>';
2848 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
2849 print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2850 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2851 // Multicurrency Amount HT
2852 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2853 }
2854 print '</tr>';
2855
2856 print '<tr>';
2857 print '<td class="titlefieldmiddle">' . $langs->trans('AmountVAT') . '</td>';
2858 print '<td class="nowrap amountcard right">' . price($object->total_tva, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2859 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2860 // Multicurrency Amount VAT
2861 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2862 }
2863 print '</tr>';
2864
2865 // Amount Local Taxes
2866 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) {
2867 print '<tr>';
2868 print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
2869 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2870 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2871 $object->multicurrency_total_localtax1 = price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
2872
2873 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2874 }
2875 print '</tr>';
2876 }
2877
2878 // Amount Local Taxes
2879 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
2880 print '<tr>';
2881 print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
2882 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2883 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2884 $object->multicurrency_total_localtax2 = price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
2885
2886 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2887 }
2888 print '</tr>';
2889 }
2890
2891 print '<tr>';
2892 print '<td>' . $langs->trans('AmountTTC') . '</td>';
2893 print '<td class="valuefield nowrap right amountcard">' . price($object->total_ttc, 1, '', 1, -1, -1, $conf->currency) . '</td>';
2894 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2895 // Multicurrency Amount TTC
2896 print '<td class="valuefield nowrap right amountcard">' . price($object->multicurrency_total_ttc, 1, '', 1, -1, -1, $object->multicurrency_code) . '</td>';
2897 }
2898 print '</tr>'."\n";
2899
2900 print '</table>';
2901
2902 // Statut
2903 //print '<tr><td>' . $langs->trans('Status') . '</td><td>' . $object->getLibStatut(4) . '</td></tr>';
2904
2905 // Margin Infos
2906 if (isModEnabled('margin')) {
2907 $formmargin->displayMarginInfos($object);
2908 }
2909
2910
2911 print '</div>';
2912 print '</div>'; // Close fichecenter
2913
2914 print '<div class="clearboth"></div><br>';
2915
2916 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
2917 $blocname = 'contacts';
2918 $title = $langs->trans('ContactsAddresses');
2919 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2920 }
2921
2922 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
2923 $blocname = 'notes';
2924 $title = $langs->trans('Notes');
2925 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2926 }
2927
2928 /*
2929 * Lines
2930 */
2931
2932 // Get object lines
2933 $result = $object->getLinesArray();
2934
2935 // Add products/services form
2936 //$forceall = 1;
2937 global $inputalsopricewithtax;
2938 $inputalsopricewithtax = 1;
2939
2940 print '<form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST">
2941 <input type="hidden" name="token" value="' . newToken().'">
2942 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
2943 <input type="hidden" name="mode" value="">
2944 <input type="hidden" name="page_y" value="">
2945 <input type="hidden" name="id" value="' . $object->id.'">
2946 <input type="hidden" name="backtopage" value="'.$backtopage.'">
2947 ';
2948
2949 if (!empty($conf->use_javascript_ajax) && $object->statut == Commande::STATUS_DRAFT) {
2950 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
2951 }
2952
2953 print '<div class="div-table-responsive-no-min">';
2954 print '<table id="tablelines" class="noborder noshadow" width="100%">';
2955
2956 // Show object lines
2957 if (!empty($object->lines)) {
2958 $object->printObjectLines($action, $mysoc, $soc, $lineid, 1);
2959 }
2960
2961 /*
2962 * Form to add new line
2963 */
2964 if ($object->statut == Commande::STATUS_DRAFT && $usercancreate && $action != 'selectlines') {
2965 if ($action != 'editline') {
2966 // Add free products/services
2967
2968 $parameters = array();
2969 // Note that $action and $object may be modified by hook
2970 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action);
2971 if ($reshook < 0) {
2972 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2973 }
2974 if (empty($reshook)) {
2975 $object->formAddObjectLine(1, $mysoc, $soc);
2976 }
2977 } else {
2978 $parameters = array();
2979 $reshook = $hookmanager->executeHooks('formEditObjectLine', $parameters, $object, $action);
2980 }
2981 }
2982 print '</table>';
2983 print '</div>';
2984
2985 print "</form>\n";
2986 }
2987
2988 print dol_get_fiche_end();
2989
2990 /*
2991 * Buttons for actions
2992 */
2993 if ($action != 'presend' && $action != 'editline') {
2994 print '<div class="tabsAction">';
2995
2996 $parameters = array();
2997 // Note that $action and $object may be modified by hook
2998 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action);
2999 if (empty($reshook)) {
3000 $numlines = count($object->lines);
3001
3002 // Reopen a closed order
3003 if (($object->statut == Commande::STATUS_CLOSED || $object->statut == Commande::STATUS_CANCELED) && $usercancreate && (!$object->billed || !getDolGlobalInt('ORDER_DONT_REOPEN_BILLED'))) {
3004 print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&amp;token='.newToken().'&amp;id='.$object->id, '');
3005 }
3006
3007 // Send
3008 if (empty($user->socid)) {
3009 if ($object->statut > Commande::STATUS_DRAFT || getDolGlobalString('COMMANDE_SENDBYEMAIL_FOR_ALL_STATUS')) {
3010 if ($usercansend) {
3011 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER["PHP_SELF"].'?action=presend&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', '');
3012 } else {
3013 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER['PHP_SELF']. '#', '', false);
3014 }
3015 }
3016 }
3017
3018 // Valid
3019 if ($object->statut == Commande::STATUS_DRAFT && ($object->total_ttc >= 0 || getDolGlobalString('ORDER_ENABLE_NEGATIVE')) && $usercanvalidate) {
3020 if ($numlines > 0) {
3021 print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=validate&amp;token='.newToken().'&amp;id='.$object->id, $object->id, 1);
3022 } else {
3023 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);
3024 }
3025 }
3026 // Edit
3027 if (($object->statut == Commande::STATUS_VALIDATED || ($object->statut == Commande::STATUS_SHIPMENTONPROCESS && getDolGlobalString('EDIT_ORDER_SHIPMENT_ON_PROCESS'))) && $usercancreate) {
3028 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?action=modif&amp;token='.newToken().'&amp;id='.$object->id, '');
3029 }
3030
3031 $arrayforbutaction = array();
3032 // Create a purchase order
3033
3034 if (!getDolGlobalInt('COMMANDE_DISABLE_ADD_PURCHASE_ORDER')) {
3035 $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));
3036 }
3037
3038 /*if (isModEnabled("supplier_order") && $object->statut > Commande::STATUS_DRAFT && $object->getNbOfServicesLines() > 0) {
3039 if ($usercancreatepurchaseorder) { isModEnabled("supplier_order") && $object->statut > Commande::STATUS_DRAFT && $object->getNbOfServicesLines() > 0
3040 print dolGetButtonAction('', $langs->trans('AddPurchaseOrder'), 'default', DOL_URL_ROOT.'/fourn/commande/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id, '');
3041 }
3042 }*/
3043
3044 // Create intervention
3045 $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);
3046 /*if (isModEnabled('ficheinter')) {
3047 $langs->load("interventions");
3048
3049 if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && $object->getNbOfServicesLines() > 0) {
3050 if ($user->hasRight('ficheinter', 'creer')) {
3051 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, '');
3052 } else {
3053 print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('AddIntervention'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
3054 }
3055 }
3056 }*/
3057
3058 // Create contract
3059 $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);
3060 /*if (isModEnabled('contrat') && ($object->statut == Commande::STATUS_VALIDATED || $object->statut == Commande::STATUS_SHIPMENTONPROCESS || $object->statut == Commande::STATUS_CLOSED)) {
3061 $langs->load("contracts");
3062
3063 if ($user->hasRight('contrat', 'creer')) {
3064 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, '');
3065 }
3066 }*/
3067
3068 $numshipping = 0;
3069 if (isModEnabled('shipping')) {
3070 $numshipping = $object->countNbOfShipments();
3071 }
3072
3073 // Create shipment
3074 if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || getDolGlobalString('STOCK_SUPPORTS_SERVICES'))) {
3075 if ((getDolGlobalInt('MAIN_SUBMODULE_EXPEDITION') && $user->hasRight('expedition', 'creer')) || (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') && $user->hasRight('expedition', 'delivery', 'creer'))) {
3076 $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);
3077 /*
3078 if ($user->hasRight('expedition', 'creer')) {
3079 print dolGetButtonAction('', $langs->trans('CreateShipment'), 'default', DOL_URL_ROOT.'/expedition/shipment.php?id='.$object->id, '');
3080 } else {
3081 print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('CreateShipment'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
3082 }*/
3083 } else {
3084 $langs->load("errors");
3085 print dolGetButtonAction($langs->trans('ErrorModuleSetupNotComplete'), $langs->trans('CreateShipment'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
3086 }
3087 }
3088
3089 // Create bill
3090 $arrayforbutaction[] = array(
3091 'lang' => 'bills',
3092 'enabled' => (isModEnabled('invoice') && $object->statut > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0),
3093 'perm' => ($user->hasRight('facture', 'creer') && !getDolGlobalInt('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')),
3094 'label' => 'CreateBill',
3095 'url' => '/compta/facture/card.php?action=create&amp;token='.newToken().'&amp;origin='.urlencode($object->element).'&amp;originid='.$object->id.'&amp;socid='.$object->socid
3096 );
3097 /*
3098 if (isModEnabled('facture') && $object->statut > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) {
3099 if (isModEnabled('facture') && $user->hasRight('facture', 'creer') && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) {
3100 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, '');
3101 }
3102 }*/
3103
3104 $actionButtonsParameters = [
3105 "areDropdownButtons" => !getDolGlobalInt("MAIN_REMOVE_DROPDOWN_CREATE_BUTTONS_ON_ORDER")
3106 ];
3107
3108 if ($numlines > 0) {
3109 print dolGetButtonAction('', $langs->trans("Create"), 'default', $arrayforbutaction, $object->id, 1, $actionButtonsParameters);
3110 } else {
3111 print dolGetButtonAction($langs->trans("ErrorObjectMustHaveLinesToBeValidated", $object->ref), $langs->trans("Create"), 'default', $arrayforbutaction, $object->id, 0, $actionButtonsParameters);
3112 }
3113
3114 // Set to shipped
3115 if (($object->statut == Commande::STATUS_VALIDATED || $object->statut == Commande::STATUS_SHIPMENTONPROCESS) && $usercanclose) {
3116 print dolGetButtonAction('', $langs->trans('ClassifyShipped'), 'default', $_SERVER["PHP_SELF"].'?action=shipped&amp;token='.newToken().'&amp;id='.$object->id, '');
3117 }
3118
3119 // Set billed or unbilled
3120 // Note: Even if module invoice is not enabled, we should be able to use button "Classified billed"
3121 if ($object->statut > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) {
3122 if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && !getDolGlobalString('ORDER_DISABLE_CLASSIFY_BILLED_FROM_ORDER') && !getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')) {
3123 print dolGetButtonAction('', $langs->trans('ClassifyBilled'), 'default', $_SERVER["PHP_SELF"].'?action=classifybilled&amp;token='.newToken().'&amp;id='.$object->id, '');
3124 }
3125 }
3126 if ($object->statut > Commande::STATUS_DRAFT && $object->billed) {
3127 if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && !getDolGlobalString('ORDER_DISABLE_CLASSIFY_BILLED_FROM_ORDER') && !getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')) {
3128 print dolGetButtonAction('', $langs->trans('ClassifyUnBilled'), 'delete', $_SERVER["PHP_SELF"].'?action=classifyunbilled&amp;token='.newToken().'&amp;id='.$object->id, '');
3129 }
3130 }
3131
3132 // Clone
3133 if ($usercancreate) {
3134 print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER["PHP_SELF"].'?action=clone&token='.newToken().'&id='.$object->id.'&socid='.$object->socid, '');
3135 }
3136
3137 // Cancel order
3138 if ($object->statut == Commande::STATUS_VALIDATED && !empty($usercancancel)) {
3139 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel&token='.newToken().'">'.$langs->trans("CancelOrder").'</a>';
3140 }
3141
3142 // Delete order
3143 if ($usercandelete) {
3144 if ($numshipping == 0) {
3145 print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, '');
3146 } else {
3147 print dolGetButtonAction($langs->trans('ShippingExist'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
3148 }
3149 }
3150 }
3151 print '</div>';
3152 }
3153
3154 // Select mail models is same action as presend
3155 if (GETPOST('modelselected')) {
3156 $action = 'presend';
3157 }
3158
3159 if ($action != 'presend') {
3160 print '<div class="fichecenter"><div class="fichehalfleft">';
3161 print '<a name="builddoc"></a>'; // ancre
3162 // Documents
3163 $objref = dol_sanitizeFileName($object->ref);
3164 $relativepath = $objref.'/'.$objref.'.pdf';
3165 $filedir = $conf->commande->multidir_output[$object->entity].'/'.$objref;
3166 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
3167 $genallowed = $usercanread;
3168 $delallowed = $usercancreate;
3169 print $formfile->showdocuments('commande', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang, '', $object);
3170
3171
3172 // Show links to link elements
3173 $tmparray = $form->showLinkToObjectBlock($object, array(), array('order'), 1);
3174 $linktoelem = $tmparray['linktoelem'];
3175 $htmltoenteralink = $tmparray['htmltoenteralink'];
3176 print $htmltoenteralink;
3177
3178 $compatibleImportElementsList = false;
3179 if ($usercancreate
3180 && $object->statut == Commande::STATUS_DRAFT) {
3181 $compatibleImportElementsList = array('commande', 'propal', 'facture'); // import from linked elements
3182 }
3183 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, $compatibleImportElementsList);
3184
3185 // Show online payment link
3186 // The list can be complete by the hook 'doValidatePayment' executed inside getValidOnlinePaymentMethods()
3187 include_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
3188 $validpaymentmethod = getValidOnlinePaymentMethods('');
3189 $useonlinepayment = count($validpaymentmethod);
3190
3191 if (getDolGlobalString('ORDER_HIDE_ONLINE_PAYMENT_ON_ORDER')) {
3192 $useonlinepayment = 0;
3193 }
3194 if ($object->statut != Commande::STATUS_DRAFT && $useonlinepayment) {
3195 print '<br><!-- Link to pay -->';
3196 require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
3197 print showOnlinePaymentUrl('order', $object->ref).'<br>';
3198 }
3199
3200 print '</div><div class="fichehalfright">';
3201
3202 $MAXEVENT = 10;
3203
3204 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/commande/agenda.php?id='.$object->id);
3205
3206 // List of actions on element
3207 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
3208 $formactions = new FormActions($db);
3209 $somethingshown = $formactions->showactions($object, 'order', $socid, 1, '', $MAXEVENT, '', $morehtmlcenter); // Show all action for thirdparty
3210
3211 print '</div></div>';
3212 }
3213
3214 // Presend form
3215 $modelmail = 'order_send';
3216 $defaulttopic = 'SendOrderRef';
3217 $diroutput = getMultidirOutput($object);
3218 $trackid = 'ord'.$object->id;
3219
3220 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
3221 }
3222}
3223
3224// End of page
3225llxFooter();
3226$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.