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