dolibarr 25.0.0-alpha
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Eric Seigne <eric.seigne@ryxeo.com>
5 * Copyright (C) 2005-2016 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2010-2015 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2011-2022 Philippe Grand <philippe.grand@atoo-net.com>
8 * Copyright (C) 2012-2016 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
10 * Copyright (C) 2014 Ion Agorria <ion@agorria.com>
11 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
13 * Copyright (C) 2022-2026 Charlene Benke <charlene@patas-monkey.com>
14 * Copyright (C) 2023 Joachim Kueter <git-jk@bloxera.com>
15 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
16 * Copyright (C) 2024 Nick Fragoulis
17 * Copyright (C) 2025-2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
18 * Copyright (C) 2026 William Mead <william@m34d.com>
19 * Copyright (C) 2026 Jose Martinez <jose.martinez@pichinov.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';
43
54require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
55require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
56require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
57require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php';
58require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
59require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
60require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
61require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_order/modules_commandefournisseur.php';
62require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
63require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php';
64require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
65require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
66
67if (isModEnabled('supplier_proposal')) {
68 require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
69}
70if (isModEnabled("product")) {
71 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
72}
73if (isModEnabled('project')) {
74 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
75 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
76}
77require_once NUSOAP_PATH.'/nusoap.php'; // Include SOAP
78
79if (isModEnabled('variants')) {
80 require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
81}
82
83if (isModEnabled('stock')) {
84 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php';
85 require_once DOL_DOCUMENT_ROOT.'/product/stock/class/mouvementstock.class.php';
86}
87
88// Load translation files required by the page
89$langs->loadLangs(array('admin', 'orders', 'sendings', 'companies', 'bills', 'propal', 'receptions', 'supplier_proposal', 'products', 'stocks', 'productbatch'));
90if (isModEnabled('incoterm')) {
91 $langs->load('incoterm');
92}
93
94
95// Get Parameters
96$action = GETPOST('action', 'alpha');
97$confirm = GETPOST('confirm', 'alpha');
98$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'purchaseordercard'; // To manage different context of search
99$cancel = GETPOST('cancel', 'alpha');
100$backtopage = GETPOST('backtopage', 'alpha');
101$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
102
103$id = GETPOSTINT('id');
104$ref = GETPOST('ref', 'alpha');
105$socid = GETPOSTINT('socid');
106$projectid = GETPOSTINT('projectid');
107$lineid = GETPOSTINT('lineid');
108$origin = GETPOST('origin', 'alpha');
109$originid = (GETPOSTINT('originid') ? GETPOSTINT('originid') : GETPOSTINT('origin_id')); // For backward compatibility
110$rank = (GETPOSTINT('rank') > 0) ? GETPOSTINT('rank') : -1;
111$stockDelete = GETPOST('stockDelete', 'int');
112
113// PDF
114$hidedetails = (GETPOSTINT('hidedetails') ? GETPOSTINT('hidedetails') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0));
115$hidedesc = (GETPOSTINT('hidedesc') ? GETPOSTINT('hidedesc') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0));
116$hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0));
117
118$datelivraison = dol_mktime(GETPOSTINT('liv_hour'), GETPOSTINT('liv_min'), GETPOSTINT('liv_sec'), GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
119
120
121// Security check
122if ($user->isExternalUser()) {
123 $socid = $user->isExternalUser();
124}
125
126// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
127$hookmanager->initHooks(array('ordersuppliercard', 'globalcard'));
128
130
131// fetch optionals attributes and labels
132$extrafields->fetch_name_optionals_label($object->table_element);
133
134// Load object
135if ($id > 0 || !empty($ref)) {
136 $ret = $object->fetch($id, $ref);
137 if ($ret < 0) {
138 dol_print_error($db, $object->error);
139 }
140 $ret = $object->fetch_thirdparty();
141 if ($ret < 0) {
142 dol_print_error($db, $object->error);
143 }
144} elseif (!empty($socid) && $socid > 0) {
145 $object->socid = $socid;
146 $ret = $object->fetch_thirdparty();
147 if ($ret < 0) {
148 dol_print_error($db, $object->error);
149 }
150}
151
152// Security check
153$isdraft = (isset($object->status) && ($object->status == $object::STATUS_DRAFT) ? 1 : 0);
154$result = restrictedArea($user, 'fournisseur', $object, 'commande_fournisseur', 'commande', 'fk_soc', 'rowid', $isdraft);
155
156// Common permissions
157$usercanread = ($user->hasRight("fournisseur", "commande", "lire") || $user->hasRight("supplier_order", "lire"));
158$usercancreate = ($user->hasRight("fournisseur", "commande", "creer") || $user->hasRight("supplier_order", "creer"));
159$usercandelete = (($user->hasRight("fournisseur", "commande", "supprimer") || $user->hasRight("supplier_order", "supprimer")) || ($usercancreate && isset($object->status) && $object->status == $object::STATUS_DRAFT));
160
161// Advanced permissions
162$usercanvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !empty($usercancreate)) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight("fournisseur", "supplier_order_advance", "validate")));
163
164// Additional area permissions
165$usercanapprove = $user->hasRight("fournisseur", "commande", "approuver");
166$usercanapprovesecond = $user->hasRight("fournisseur", "commande", "approve2");
167$usercanorder = $user->hasRight("fournisseur", "commande", "commander");
168if (!isModEnabled('reception')) {
169 $usercanreceive = $user->hasRight("fournisseur", "commande", "receptionner");
170} else {
171 $usercanreceive = $user->hasRight("reception", "creer");
172}
173
174// Permissions for includes
175$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
176$permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
177$permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php
178$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php
179$permissiontoeditextra = $permissiontoadd;
180if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
181 // For action 'update_extras', is there a specific permission set for the attribute to update
182 $permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
183}
184
185// Project permission
186$caneditproject = false;
187if (isModEnabled('project')) {
188 $caneditproject = !getDolGlobalString('SUPPLIER_ORDER_FORBID_EDIT_PROJECT') || ($object->status == CommandeFournisseur::STATUS_DRAFT && preg_match('/^[\‍(]?PROV/i', $object->ref));
189}
190
191$error = 0;
192$classname = null;
193
194
195/*
196 * Actions
197 */
198
199$parameters = array('socid' => $socid);
200$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
201if ($reshook < 0) {
202 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
203}
204
205if (empty($reshook)) {
206 $backurlforlist = DOL_URL_ROOT.'/fourn/commande/list.php'.($socid > 0 ? '?socid='.((int) $socid) : '');
207
208 if (empty($backtopage) || ($cancel && empty($id))) {
209 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
210 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
211 $backtopage = $backurlforlist;
212 } else {
213 $backtopage = DOL_URL_ROOT.'/fourn/commande/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
214 }
215 }
216 }
217
218 if ($cancel) {
219 if (!empty($backtopageforcancel)) {
220 header("Location: ".$backtopageforcancel);
221 exit;
222 } elseif (!empty($backtopage)) {
223 header("Location: ".$backtopage);
224 exit;
225 }
226 $action = '';
227 }
228
229 include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be 'include', not 'include_once'
230
231 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be 'include', not 'include_once'
232
233 include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
234
235 if ($action == 'setref_supplier' && $usercancreate) {
236 $result = $object->setValueFrom('ref_supplier', GETPOST('ref_supplier', 'alpha'), '', null, 'text', '', $user, 'ORDER_SUPPLIER_MODIFY');
237 if ($result < 0) {
238 setEventMessages($object->error, $object->errors, 'errors');
239 }
240 }
241
242 // Set incoterm
243 if ($action == 'set_incoterms' && $usercancreate) {
244 $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms'));
245 if ($result < 0) {
246 setEventMessages($object->error, $object->errors, 'errors');
247 }
248 }
249
250 // payment conditions
251 if ($action == 'setconditions' && $usercancreate) {
252 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'), GETPOSTFLOAT('cond_reglement_id_deposit_percent'));
253 if ($result < 0) {
254 setEventMessages($object->error, $object->errors, 'errors');
255 }
256 }
257
258 // payment mode
259 if ($action == 'setmode' && $usercancreate) {
260 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
261 if ($result < 0) {
262 setEventMessages($object->error, $object->errors, 'errors');
263 }
264 } elseif ($action == 'setmulticurrencycode' && $usercancreate) {
265 // Multicurrency Code
266 $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
267 } elseif ($action == 'setmulticurrencyrate' && $usercancreate) {
268 // Multicurrency rate
269 $result = $object->setMulticurrencyRate(GETPOSTFLOAT('multicurrency_tx'), GETPOSTINT('calculation_mode'));
270 }
271
272 // bank account
273 if ($action == 'setbankaccount' && $usercancreate) {
274 $result = $object->setBankAccount(GETPOSTINT('fk_account'));
275 if ($result < 0) {
276 setEventMessages($object->error, $object->errors, 'errors');
277 }
278 }
279
280 // date of delivery
281 if ($action == 'setwarehouse' && $usercancreate) {
282 $result = $object->setValueFrom('fk_warehouse', GETPOSTINT('fk_warehouse'), '', null, 'int', '', $user, 'ORDER_SUPPLIER_MODIFY');
283 if ($result < 0) {
284 setEventMessages($object->error, $object->errors, 'errors');
285 }
286 $action = '';
287 }
288
289 if ($action == 'setdate_livraison' && $usercancreate) {
290 $result = $object->setDeliveryDate($user, $datelivraison);
291 if ($result < 0) {
292 setEventMessages($object->error, $object->errors, 'errors');
293 }
294 }
295
296 // Set project
297 if ($action == 'classin' && $usercancreate && $caneditproject) {
298 $result = $object->setProject($projectid);
299 if ($result < 0) {
300 setEventMessages($object->error, $object->errors, 'errors');
301 }
302 }
303
304 // Subtotal
305 if ($action == 'confirm_delete_subtotalline' && $confirm == 'yes' && $usercancreate) {
306 // Delete line
307 $object->fetch($id);
308 $object->fetch_thirdparty();
309
310 $result = $object->deleteSubtotalLine($langs, GETPOSTINT('lineid'), (bool) GETPOST('deletecorrespondingsubtotalline'));
311 if ($result > 0) {
312 // reorder lines
313 $object->line_order(true);
314 // Define output language
315 $outputlangs = $langs;
316 $newlang = '';
317 if (getDolGlobalInt('MAIN_MULTILANGS') && GETPOST('lang_id')) {
318 $newlang = GETPOST('lang_id');
319 }
320 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
321 $newlang = $object->thirdparty->default_lang;
322 }
323 if (!empty($newlang)) {
324 $outputlangs = new Translate("", $conf);
325 $outputlangs->setDefaultLang($newlang);
326 $outputlangs->load('products');
327 }
328 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
329 $ret = $object->fetch($id); // Reload to get new records
330 $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
331 }
332 if ($result >= 0) {
333 header('Location: '.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $id]));
334 exit();
335 }
336 } else {
337 setEventMessages($object->error, $object->errors, 'errors');
338 $action = '';
339 }
340 }
341 if ($action == 'addline' && GETPOST('updateallvatlinesblock', 'alpha') && GETPOST('vatforblocklines', 'alpha') !== '' && $usercancreate) {
342 $tx_tva = GETPOST('vatforblocklines') ? GETPOST('vatforblocklines') : 0;
343 $result = $object->updateSubtotalLineBlockLines($langs, $object->getRangOfLine($lineid), 'tva', $tx_tva);
344 if ($result < 0) {
345 setEventMessages($object->error, $object->errors, 'errors');
346 }
347 } elseif ($action == 'addline' && GETPOST('updatealldiscountlinesblock', 'alpha') && GETPOST('discountforblocklines', 'alpha') !== '' && $usercancreate) {
348 $discount = GETPOST('discountforblocklines') ? GETPOST('discountforblocklines') : 0;
349 $result = $object->updateSubtotalLineBlockLines($langs, $object->getRangOfLine($lineid), 'discount', $discount);
350 if ($result < 0) {
351 setEventMessages($object->error, $object->errors, 'errors');
352 }
353 }
354 // Set tags
355 if ($action == 'settags' && isModEnabled('category') && $usercancreate) {
356 $result = $object->setCategories(GETPOST('categories', 'array'));
357 if ($result < 0) {
358 setEventMessages($object->error, $object->errors, 'errors');
359 }
360 }
361
362 // Edit Thirdparty
363 if (getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') && $action == 'set_thirdparty' && $usercancreate && $object->status == CommandeFournisseur::STATUS_DRAFT) {
364 $new_socid = GETPOSTINT('new_socid');
365 if (!empty($new_socid) && $new_socid != $object->thirdparty->id) {
366 $db->begin();
367
368 // Update supplier
369 $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande_fournisseur';
370 $sql .= ' SET fk_soc = '.((int) $new_socid);
371 $sql .= ' WHERE fk_soc = '.((int) $object->thirdparty->id);
372 $sql .= ' AND rowid = '.((int) $object->id);
373
374 $res = $db->query($sql);
375
376 if (!$res) {
377 $db->rollback();
378 } else {
379 $db->commit();
380
381 // Replace prices for each lines by new supplier prices
382 foreach ($object->lines as $l) {
383 $sql = 'SELECT price, unitprice, tva_tx, ref_fourn';
384 $sql .= ' FROM '.MAIN_DB_PREFIX.'product_fournisseur_price';
385 $sql .= ' WHERE fk_product = '.((int) $l->fk_product);
386 $sql .= ' AND fk_soc = '.((int) $new_socid);
387 $sql .= ' ORDER BY unitprice ASC';
388
389 $resql = $db->query($sql);
390 if ($resql) {
391 $num_row = $db->num_rows($resql);
392 if (empty($num_row)) {
393 // No product price for this supplier !
394 $l->subprice = 0;
395 $l->total_ht = 0;
396 $l->total_tva = 0;
397 $l->total_ttc = 0;
398 $l->ref_supplier = '';
399 if ($l->update() < 0) {
400 setEventMessages($l->error, $l->errors, 'errors');
401 }
402 } else {
403 // No need for loop to keep best supplier price
404 $obj = $db->fetch_object($resql);
405 $l->subprice = $obj->unitprice;
406 $l->total_ht = $obj->price;
407 $l->tva_tx = $obj->tva_tx;
408 $l->total_tva = $l->total_ht * ($obj->tva_tx / 100);
409 $l->total_ttc = $l->total_ht + $l->total_tva;
410 $l->ref_supplier = $obj->ref_fourn;
411 if ($l->update() < 0) {
412 setEventMessages($l->error, $l->errors, 'errors');
413 }
414 }
415 } else {
416 dol_print_error($db);
417 }
418 $db->free($resql);
419 }
420 $object->update_price();
421 }
422 }
423 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id);
424 exit;
425 }
426
427 if ($action == 'setremisepercent' && $usercancreate) {
428 $result = $object->set_remise($user, price2num(GETPOST('remise_percent')));
429 if ($result < 0) {
430 setEventMessages($object->error, $object->errors, 'errors');
431 }
432 }
433
434 if ($action == 'reopen' && $permissiontoadd) { // no test on permission here, permission to use will depends on status
435 $resSetReopen = $object->setReopen($user);
436 if ($resSetReopen) {
437 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
438 exit;
439 } else {
440 setEventMessages($object->error, $object->errors, 'errors');
441 }
442 }
443
444 /*
445 * Classify supplier order as billed
446 */
447 if ($action == 'classifybilled' && $usercancreate) {
448 $ret = $object->classifyBilled($user);
449 if ($ret < 0) {
450 setEventMessages($object->error, $object->errors, 'errors');
451 }
452 } elseif ($action == 'classifyunbilled' && $usercancreate) {
453 $ret = $object->classifyUnBilled($user);
454 if ($ret < 0) {
455 setEventMessages($object->error, $object->errors, 'errors');
456 }
457 }
458
459 // Add a product line
460 if ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && (GETPOST('alldate_start', 'alpha') || GETPOST('alldate_end', 'alpha')) && $usercancreate) {
461 // Define date start and date end for all line
462 $alldate_start = dol_mktime(GETPOSTINT('alldate_starthour'), GETPOSTINT('alldate_startmin'), 0, GETPOSTINT('alldate_startmonth'), GETPOSTINT('alldate_startday'), GETPOSTINT('alldate_startyear'));
463 $alldate_end = dol_mktime(GETPOSTINT('alldate_endhour'), GETPOSTINT('alldate_endmin'), 0, GETPOSTINT('alldate_endmonth'), GETPOSTINT('alldate_endday'), GETPOSTINT('alldate_endyear'));
464 foreach ($object->lines as $line) {
465 if ($line->product_type == 1) { // only service line
466 // Preserve the original entry mode of the line so the total is not drifted by rounding.
467 $line_price_base_type = $line->getPriceBaseType();
468 $line_pu = ($line_price_base_type === 'TTC') ? (float) $line->subprice_ttc : (float) $line->subprice;
469 $result = $object->updateline($line->id, $line->desc, $line_pu, $line->qty, (float) $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line_price_base_type, $line->info_bits, $line->product_type, 0, $alldate_start, $alldate_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice, $line->ref_supplier);
470 }
471 }
472 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('remiseforalllines', 'alpha') !== '' && $usercancreate) {
473 // Define vat_rate
474 $remise_percent = (GETPOST('remiseforalllines') ? GETPOST('remiseforalllines') : 0);
475 $remise_percent = str_replace('*', '', $remise_percent);
476 foreach ($object->lines as $line) {
477 // Preserve the original entry mode of the line so the total is not drifted by rounding.
478 $line_price_base_type = $line->getPriceBaseType();
479 $line_pu = ($line_price_base_type === 'TTC') ? (float) $line->subprice_ttc : (float) $line->subprice;
480 $result = $object->updateline($line->id, $line->desc, $line_pu, $line->qty, (float) $remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line_price_base_type, $line->info_bits, $line->product_type, 0, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice, $line->ref_supplier);
481 }
482 } elseif ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && GETPOST('vatforalllines', 'alpha') !== '' && $usercancreate) {
483 // Define new vat_rate for all lines
484 $vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
485 $vat_rate = str_replace('*', '', $vat_rate);
486 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
487 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
488 foreach ($object->lines as $line) {
489 if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
490 continue;
491 }
492 // Preserve the original entry mode of the line so the total is not drifted by rounding.
493 $line_price_base_type = $line->getPriceBaseType();
494 $line_pu = ($line_price_base_type === 'TTC') ? (float) $line->subprice_ttc : (float) $line->subprice;
495 $result = $object->updateline($line->id, $line->desc, $line_pu, $line->qty, (float) $line->remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $line_price_base_type, $line->info_bits, $line->product_type, 0, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice, $line->ref_supplier);
496 }
497 } elseif ($action == 'confirm_addtextline' && $usercancreate) {
498 // Handling adding a new text line for subtotals module
499
500 $langs->load('subtotals');
501
502 $desc = GETPOST('subtotaltextcontent', 'restricthtml');
503
504 // Insert line
505 $result = $object->addSubtotalLine($langs, $desc, 0, array());
506
507 if ($result >= 0) {
508 if ($result == 0) {
509 setEventMessages($object->error, $object->errors, 'warnings');
510 }
511 $ret = $object->fetch($object->id); // Reload to get new records
512 $object->fetch_thirdparty();
513
514 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
515 // Define output language
516 $outputlangs = $langs;
517 $newlang = GETPOST('lang_id', 'alpha');
518 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
519 $newlang = $object->thirdparty->default_lang;
520 }
521 if (!empty($newlang)) {
522 $outputlangs = new Translate("", $conf);
523 $outputlangs->setDefaultLang($newlang);
524 }
525
526 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
527 }
528 } else {
529 setEventMessages($object->error, $object->errors, 'errors');
530 }
531 header('Location: '.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $id]));
532 exit();
533 } elseif ($action == 'confirm_addtitleline' && $usercancreate) {
534 // Handling adding a new title line for subtotals module
535
536 $langs->load('subtotals');
537
538 $desc = GETPOST('subtotallinedesc', 'alphanohtml');
539 $depth = GETPOSTINT('subtotallinelevel') ?? 1;
540
541 $subtotal_options = array();
542
543 foreach (CommandeFournisseur::$TITLE_OPTIONS as $option) {
544 $value = GETPOST($option, 'alphanohtml');
545 if ($value) {
546 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
547 }
548 }
549
550 // Insert line
551 $result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
552
553 if ($result >= 0) {
554 if ($result == 0) {
555 setEventMessages($object->error, $object->errors, 'warnings');
556 }
557 $ret = $object->fetch($object->id); // Reload to get new records
558 $object->fetch_thirdparty();
559
560 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
561 // Define output language
562 $outputlangs = $langs;
563 $newlang = GETPOST('lang_id', 'alpha');
564 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
565 $newlang = $object->thirdparty->default_lang;
566 }
567 if (!empty($newlang)) {
568 $outputlangs = new Translate("", $conf);
569 $outputlangs->setDefaultLang($newlang);
570 }
571
572 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
573 }
574 } else {
575 setEventMessages($object->error, $object->errors, 'errors');
576 }
577 header('Location: '.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $id]));
578 exit();
579 } elseif ($action == 'confirm_addsubtotalline' && $usercancreate) {
580 // Handling adding a new subtotal line for subtotals module
581
582 $langs->load('subtotals');
583
584 $choosen_line = GETPOST('subtotaltitleline', 'alphanohtml');
585 foreach ($object->lines as $line) {
586 if ($line->desc == $choosen_line && $line->special_code == SUBTOTALS_SPECIAL_CODE) {
587 $desc = $line->desc;
588 $depth = -$line->qty;
589 }
590 }
591
592 $subtotal_options = array();
593
594 foreach (CommandeFournisseur::$SUBTOTAL_OPTIONS as $option) {
595 $value = GETPOST($option, 'alphanohtml');
596 if ($value) {
597 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
598 }
599 }
600
601 // Insert line
602 if (isset($desc) && isset($depth)) {
603 $result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
604 } else {
605 $result = -1;
606 $object->errors[] = $langs->trans("CorrespondingTitleNotFound");
607 }
608
609 if ($result >= 0) {
610 $ret = $object->fetch($object->id); // Reload to get new records
611 $object->fetch_thirdparty();
612
613 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
614 // Define output language
615 $outputlangs = $langs;
616 $newlang = GETPOST('lang_id', 'alpha');
617 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
618 $newlang = $object->thirdparty->default_lang;
619 }
620 if (!empty($newlang)) {
621 $outputlangs = new Translate("", $conf);
622 $outputlangs->setDefaultLang($newlang);
623 }
624
625 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
626 }
627 } else {
628 setEventMessages($object->error, $object->errors, 'errors');
629 }
630 header('Location: '.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $id]));
631 exit();
632 } elseif ($action == 'addline' && $usercancreate) {
633 $db->begin();
634
635 $langs->load('errors');
636 $error = 0;
637
638 // Set if we used free entry or predefined product
639 $predef = '';
640 $line_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
641 $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'));
642 $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'));
643
644 $prod_entry_mode = GETPOST('prod_entry_mode');
645 if ($prod_entry_mode == 'free') {
646 $idprod = 0;
647 } else {
648 $idprod = GETPOSTINT('idprod');
649 }
650
651 $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)'
652
653 $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
654 $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
655 $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
656 $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
657 $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
658
659 $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0);
660 if (empty($remise_percent)) {
661 $remise_percent = 0;
662 }
663
664 // Extrafields
665 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
666 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
667 // Unset extrafield
668 if (is_array($extralabelsline)) {
669 // Get extra fields
670 foreach ($extralabelsline as $key => $value) {
671 unset($_POST["options_".$key]);
672 }
673 }
674
675 if ($prod_entry_mode == 'free' && GETPOST('price_ht') < 0 && $qty < 0) {
676 setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPrice'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
677 $error++;
678 }
679 if ($prod_entry_mode == 'free' && !GETPOST('idprodfournprice') && GETPOST('type') < 0) {
680 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors');
681 $error++;
682 }
683 if ($prod_entry_mode == 'free' && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not ''
684 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('UnitPrice')), null, 'errors');
685 $error++;
686 }
687 if ($prod_entry_mode == 'free' && !GETPOST('dp_desc')) {
688 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors');
689 $error++;
690 }
691 if (GETPOST('qty', 'alpha') == '') { // 0 is allowed for order
692 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Qty')), null, 'errors');
693 $error++;
694 }
695
696 if (!$error && isModEnabled('variants') && $prod_entry_mode != 'free') {
697 if ($combinations = GETPOST('combinations', 'array:alphanohtml')) {
698 //Check if there is a product with the given combination
699 $prodcomb = new ProductCombination($db);
700
701 if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
702 $idprod = $res->fk_product_child;
703 } else {
704 setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
705 $error++;
706 }
707 }
708 }
709
710 if ($prod_entry_mode != 'free' && empty($error)) { // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or ''
711 $productsupplier = new ProductFournisseur($db);
712
713 $idprod = 0;
714 if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') {
715 $idprod = -99; // Same behaviour than with combolist. When not select idprodfournprice is now -99 (to avoid conflict with next action that may return -1, -2, ...)
716 }
717
718 $reg = array();
719 if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) {
720 $idprod = (int) $reg[1];
721 $res = $productsupplier->fetch($idprod); // Load product from its id
722 // Call to init some price properties of $productsupplier
723 // So if a supplier price already exists for another thirdparty (first one found), we use it as reference price
724 if (getDolGlobalString('SUPPLIER_TAKE_FIRST_PRICE_IF_NO_PRICE_FOR_CURRENT_SUPPLIER')) {
725 $fksoctosearch = 0;
726 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
727 if ($productsupplier->fourn_socid != $socid) { // The price we found is for another supplier, so we clear supplier price
728 $productsupplier->ref_supplier = '';
729 }
730 } else {
731 $fksoctosearch = $object->thirdparty->id;
732 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
733 }
734 } elseif (GETPOSTINT('idprodfournprice') > 0) { // field is not idprod_..., should be int
735 $qtytosearch = (float) $qty; // Just to see if a price exists for the quantity. Not used to find vat.
736 //$qtytosearch = -1; // We force qty to -1 to be sure to find if a supplier price exist
737 $idprod = $productsupplier->get_buyprice(GETPOSTINT('idprodfournprice'), $qtytosearch);
738 $res = $productsupplier->fetch($idprod);
739 }
740
741 if ($idprod > 0) {
742 $label = $productsupplier->label;
743
744 // Define output language
745 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
746 $outputlangs = $langs;
747 $newlang = '';
748 if (/* empty($newlang) && */ GETPOST('lang_id', 'aZ09')) {
749 $newlang = GETPOST('lang_id', 'aZ09');
750 }
751 if (empty($newlang)) {
752 $newlang = $object->thirdparty->default_lang;
753 }
754 if (!empty($newlang)) {
755 $outputlangs = new Translate("", $conf);
756 $outputlangs->setDefaultLang($newlang);
757 }
758 $desc = (!empty($productsupplier->multilangs[$outputlangs->defaultlang]["description"])) ? $productsupplier->multilangs[$outputlangs->defaultlang]["description"] : $productsupplier->description;
759 } else {
760 $desc = $productsupplier->description;
761 }
762 // if we use supplier description of the products
763 if (!empty($productsupplier->desc_supplier) && getDolGlobalString('PRODUIT_FOURN_TEXTS')) {
764 $desc = $productsupplier->desc_supplier;
765 }
766
767 if (getDolGlobalInt('PRODUIT_AUTOFILL_DESC') == 0) {
768 // 'DoNotAutofillButAutoConcat'
769 $desc = dol_concatdesc($desc, $line_desc, false, getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION') ? true : false);
770 } else {
771 //'AutoFillFormFieldBeforeSubmit' or 'DoNotUseDescriptionOfProdut' => User has already done the modification they want
772 $desc = $line_desc;
773 }
774
775 $ref_supplier = $productsupplier->ref_supplier;
776 if (empty($ref_supplier) && !empty(GETPOST('fourn_ref', 'alpha'))) {
777 $ref_supplier = GETPOST('fourn_ref', 'alpha');
778 }
779
780 // Get vat rate
781 $tva_npr = 0;
782 if (!GETPOSTISSET('tva_tx')) { // If vat rate not provided from the form (the form has the priority)
783 $tmpidprodfournprice = GETPOST('idprodfournprice', 'alpha'); // can be an id of price, or -1, -2, -99 or 'idprod_...'
784 if (is_numeric($tmpidprodfournprice) && (int) $tmpidprodfournprice > 0) {
785 $tmpidprodfournprice = (int) $tmpidprodfournprice;
786 } else {
787 $tmpidprodfournprice = 0;
788 }
789 $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
790 $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
791 if (empty($tva_tx)) {
792 $tva_npr = 0;
793 }
794 }
795
796 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
797 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
798
799 $type = $productsupplier->type;
800 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
801 $price_base_type = 'HT';
802 $pu = price2num($price_ht, 'MU');
803 $pu_devise = price2num($price_ht_devise, 'CU');
804 } elseif (GETPOST('price_ttc') != '' || GETPOST('multicurrency_price_ttc') != '') {
805 $price_base_type = 'TTC';
806 $pu = price2num($price_ttc, 'MU');
807 $pu_devise = price2num($price_ttc_devise, 'CU');
808 } else {
809 $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT');
810 if (empty($object->multicurrency_code) || ($productsupplier->fourn_multicurrency_code != $object->multicurrency_code)) { // If object is in a different currency and price not in this currency
811 $pu = $productsupplier->fourn_pu;
812 $pu_devise = 0;
813 } else {
814 $pu = $productsupplier->fourn_pu;
815 $pu_devise = $productsupplier->fourn_multicurrency_unitprice;
816 }
817 }
818
819 if (empty($pu)) {
820 $pu = 0; // If pu is '' or null, we force to have a numeric value
821 }
822
823 $result = $object->addline(
824 $desc,
825 ($price_base_type == 'HT' ? $pu : 0),
826 (float) $qty,
827 $tva_tx,
828 $localtax1_tx,
829 $localtax2_tx,
830 $idprod,
831 $productsupplier->product_fourn_price_id,
832 $ref_supplier,
833 $remise_percent,
834 $price_base_type,
835 ($price_base_type == 'TTC' ? $pu : 0),
836 $type,
837 $tva_npr,
838 0,
840 $date_end,
841 $array_options,
842 $productsupplier->fk_unit,
843 $pu_devise,
844 '',
845 0,
846 min($rank, count($object->lines) + 1)
847 );
848 }
849 if ($idprod == -99 || $idprod == 0) {
850 // Product not selected
851 $error++;
852 $langs->load("errors");
853 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
854 }
855 if ($idprod == -1) {
856 // Quantity too low
857 $error++;
858 $langs->load("errors");
859 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors');
860 }
861 } elseif (empty($error)) { // $price_ht is already set
862 $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
863 $tva_tx = str_replace('*', '', $tva_tx);
864 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
865 $desc = $line_desc;
866 $type = GETPOSTINT('type');
867 $ref_supplier = GETPOST('fourn_ref', 'alpha');
868
869 $fk_unit = ((string) GETPOST('units')) == '' ? null : GETPOSTINT('units');
870
871 if (!preg_match('/\‍((.*)\‍)/', $tva_tx)) {
872 $tva_tx = price2num($tva_tx); // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1'
873 }
874
875 // Local Taxes
876 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
877 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
878
879 // Keep the entry mode chosen by the user so the total is computed from the typed value (no rounding drift).
880 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
881 $price_base_type = 'HT';
882 $pu_ht = price2num($price_ht, 'MU'); // $pu_ht must be rounded according to settings
883 $pu_ttc = 0;
884 $pu_ht_devise = price2num($price_ht_devise, 'CU');
885 } else {
886 $price_base_type = 'TTC';
887 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
888 $pu_ht = 0;
889 $pu_ht_devise = price2num($price_ttc_devise, 'CU');
890 }
891
892 $result = $object->addline($desc, (float) $pu_ht, (float) $qty, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, $ref_supplier, $remise_percent, $price_base_type, (float) $pu_ttc, $type, 0, 0, $date_start, $date_end, $array_options, $fk_unit, (float) $pu_ht_devise);
893 }
894
895 //print "xx".$tva_tx; exit;
896 if (!$error && $result > 0) {
897 $db->commit();
898
899 $ret = $object->fetch($object->id); // Reload to get new records
900 $object->fetch_thirdparty(); // fetch() reset thirdparty to null, reload it before reading default_lang
901
902 // Define output language
903 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
904 $outputlangs = $langs;
905 $newlang = '';
906 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */) {
907 $newlang = $object->thirdparty->default_lang;
908 if (GETPOST('lang_id', 'aZ09')) {
909 $newlang = GETPOST('lang_id', 'aZ09');
910 }
911 }
912 if (!empty($newlang)) {
913 $outputlangs = new Translate("", $conf);
914 $outputlangs->setDefaultLang($newlang);
915 }
916 $model = $object->model_pdf;
917 $ret = $object->fetch($id); // Reload to get new records
918
919 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
920 if ($result < 0) {
921 setEventMessages($object->error, $object->errors, 'errors');
922 }
923 }
924
925 unset($_POST ['prod_entry_mode']);
926
927 unset($_POST['qty']);
928 unset($_POST['type']);
929 unset($_POST['remise_percent']);
930 unset($_POST['pu']);
931 unset($_POST['price_ht']);
932 unset($_POST['multicurrency_price_ht']);
933 unset($_POST['price_ttc']);
934 unset($_POST['fourn_ref']);
935 unset($_POST['tva_tx']);
936 unset($_POST['label']);
937 unset($localtax1_tx);
938 unset($localtax2_tx);
939 unset($_POST['np_marginRate']);
940 unset($_POST['np_markRate']);
941 unset($_POST['dp_desc']);
942 unset($_POST['idprodfournprice']);
943 unset($_POST['units']);
944
945 unset($_POST['date_starthour']);
946 unset($_POST['date_startmin']);
947 unset($_POST['date_startsec']);
948 unset($_POST['date_startday']);
949 unset($_POST['date_startmonth']);
950 unset($_POST['date_startyear']);
951 unset($_POST['date_endhour']);
952 unset($_POST['date_endmin']);
953 unset($_POST['date_endsec']);
954 unset($_POST['date_endday']);
955 unset($_POST['date_endmonth']);
956 unset($_POST['date_endyear']);
957
958 header('Location: '.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $id]));
959 exit();
960 } else {
961 $db->rollback();
962 setEventMessages($object->error, $object->errors, 'errors');
963 }
964
965 $action = '';
966 } elseif ($action == 'updatetitleline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
967 // Handling updating a title line for subtotals module
968
969 $langs->load('subtotals');
970
971 $desc = GETPOST('line_desc', 'alphanohtml') ?? $langs->trans("Title");
972 $depth = GETPOSTINT('line_depth') ?? 1;
973
974 $subtotal_options = array();
975
976 foreach (CommandeFournisseur::$TITLE_OPTIONS as $option) {
977 $value = GETPOST($option, 'alphanohtml');
978 if ($value) {
979 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
980 }
981 }
982
983 // Update line
984 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
985
986 if ($result >= 0) {
987 if ($result == 0) {
988 setEventMessages($object->error, $object->errors, 'warnings');
989 }
990 $ret = $object->fetch($object->id); // Reload to get new records
991 $object->fetch_thirdparty();
992
993 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
994 // Define output language
995 $outputlangs = $langs;
996 $newlang = GETPOST('lang_id', 'alpha');
997 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
998 $newlang = $object->thirdparty->default_lang;
999 }
1000 if (!empty($newlang)) {
1001 $outputlangs = new Translate("", $conf);
1002 $outputlangs->setDefaultLang($newlang);
1003 }
1004
1005 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1006 }
1007 } else {
1008 setEventMessages($object->error, $object->errors, 'errors');
1009 }
1010 } elseif ($action == 'updatetextline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1011 // Handling updating a text line for subtotals module
1012
1013 $langs->load('subtotals');
1014
1015 $desc = GETPOST('line_desc', 'restricthtml');
1016
1017 // Update line
1018 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, 0, array());
1019
1020 if ($result >= 0) {
1021 if ($result == 0) {
1022 setEventMessages($object->error, $object->errors, 'warnings');
1023 }
1024 $ret = $object->fetch($object->id); // Reload to get new records
1025 $object->fetch_thirdparty();
1026
1027 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1028 // Define output language
1029 $outputlangs = $langs;
1030 $newlang = GETPOST('lang_id', 'alpha');
1031 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1032 $newlang = $object->thirdparty->default_lang;
1033 }
1034 if (!empty($newlang)) {
1035 $outputlangs = new Translate("", $conf);
1036 $outputlangs->setDefaultLang($newlang);
1037 }
1038
1039 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1040 }
1041 } else {
1042 setEventMessages($object->error, $object->errors, 'errors');
1043 }
1044 } elseif ($action == 'updatesubtotalline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1045 // Handling updating a subtotal line for subtotals module
1046
1047 $langs->load('subtotals');
1048
1049 $desc = GETPOST('line_desc', 'alphanohtml');
1050 $depth = GETPOSTINT('line_depth');
1051
1052 $subtotal_options = array();
1053
1054 foreach (CommandeFournisseur::$SUBTOTAL_OPTIONS as $option) {
1055 $value = GETPOST($option, 'alphanohtml');
1056 if ($value) {
1057 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
1058 }
1059 }
1060
1061 // Update line
1062 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
1063
1064 if ($result > 0) {
1065 $ret = $object->fetch($object->id); // Reload to get new records
1066 $object->fetch_thirdparty();
1067
1068 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1069 // Define output language
1070 $outputlangs = $langs;
1071 $newlang = GETPOST('lang_id', 'alpha');
1072 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1073 $newlang = $object->thirdparty->default_lang;
1074 }
1075 if (!empty($newlang)) {
1076 $outputlangs = new Translate("", $conf);
1077 $outputlangs->setDefaultLang($newlang);
1078 }
1079
1080 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1081 }
1082 } else {
1083 setEventMessages($object->error, $object->errors, 'errors');
1084 }
1085 } elseif ($action == 'updateline' && $usercancreate && !GETPOST('cancel', 'alpha')) {
1086 // Updating a line in the order
1087 $db->begin();
1088
1089 $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
1090
1091 $line = null;
1092 if ($lineid) {
1093 $line = new CommandeFournisseurLigne($db);
1094 $res = $line->fetch($lineid);
1095 if (!$res) {
1096 dol_print_error($db);
1097 }
1098 }
1099
1100 $productsupplier = new ProductFournisseur($db);
1101 if (getDolGlobalInt('SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY') == 1) { // Not the common case
1102 if ($line->fk_product > 0 && $productsupplier->get_buyprice(0, (float) price2num(GETPOSTFLOAT('qty')), $line->fk_product, 'none', GETPOSTINT('socid')) < 0) {
1103 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings');
1104 }
1105 }
1106
1107 $date_start = dol_mktime(GETPOSTINT('date_starthour'), GETPOSTINT('date_startmin'), GETPOSTINT('date_startsec'), GETPOSTINT('date_startmonth'), GETPOSTINT('date_startday'), GETPOSTINT('date_startyear'));
1108 $date_end = dol_mktime(GETPOSTINT('date_endhour'), GETPOSTINT('date_endmin'), GETPOSTINT('date_endsec'), GETPOSTINT('date_endmonth'), GETPOSTINT('date_endday'), GETPOSTINT('date_endyear'));
1109
1110 // Define info_bits
1111 $info_bits = 0;
1112 if (preg_match('/\*/', $vat_rate)) {
1113 $info_bits |= 0x01;
1114 }
1115
1116 // Define vat_rate
1117 $vat_rate = str_replace('*', '', $vat_rate);
1118 $localtax1_rate = get_localtax($vat_rate, 1, $mysoc, $object->thirdparty);
1119 $localtax2_rate = get_localtax($vat_rate, 2, $mysoc, $object->thirdparty);
1120
1121 $pu_ht = price2num(GETPOST('price_ht'), '', 2);
1122 $pu_ttc = price2num(GETPOST('price_ttc'), '', 2);
1123
1124 // The form JS clears the other field when the user edits one of them: only the modified field is filled.
1125 // When both fields are submitted, the user did not change the price - we must preserve the original
1126 // storage mode of the line, otherwise a no-op save would shift the total by rounding.
1127 $ht = $pu_ht;
1128 $price_base_type = 'HT';
1129 if (empty($pu_ht) && !empty($pu_ttc)) {
1130 $ht = $pu_ttc;
1131 $price_base_type = 'TTC';
1132 } elseif (!empty($pu_ht) && !empty($pu_ttc)) {
1133 foreach ($object->lines as $line_obj) {
1134 if ($line_obj->id == GETPOSTINT('lineid')) {
1135 // Line was originally entered in TTC mode (subprice_ttc filled by addline)
1136 if ($line_obj->wasEnteredIncludingTax()) {
1137 $ht = $pu_ttc;
1138 $price_base_type = 'TTC';
1139 }
1140 break;
1141 }
1142 }
1143 }
1144
1145 $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), 'CU', 2);
1146
1147 // Extrafields Lines
1148 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1149 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
1150 // Unset extrafield POST Data
1151 if (is_array($extralabelsline)) {
1152 foreach ($extralabelsline as $key => $value) {
1153 unset($_POST["options_".$key]);
1154 }
1155 }
1156
1157 $result = $object->updateline(
1158 $lineid,
1159 GETPOST('product_desc', 'restricthtml'),
1160 (float) $ht,
1161 (float) price2num(GETPOST('qty'), 'MS'),
1162 (float) price2num(GETPOST('remise_percent'), '', 2),
1163 $vat_rate,
1164 $localtax1_rate,
1165 $localtax2_rate,
1166 $price_base_type,
1167 0,
1168 GETPOSTISSET("type") ? GETPOST("type") : $line->product_type,
1169 0,
1171 $date_end,
1172 $array_options,
1173 ((string) GETPOST('units') === '') ? null : GETPOSTINT('units'),
1174 (float) $pu_ht_devise,
1175 GETPOST('fourn_ref', 'alpha')
1176 );
1177 unset($_POST['qty']);
1178 unset($_POST['type']);
1179 unset($_POST['idprodfournprice']);
1180 unset($_POST['remmise_percent']);
1181 unset($_POST['dp_desc']);
1182 unset($_POST['np_desc']);
1183 unset($_POST['pu']);
1184 unset($_POST['fourn_ref']);
1185 unset($_POST['tva_tx']);
1186 unset($_POST['date_start']);
1187 unset($_POST['date_end']);
1188 unset($_POST['units']);
1189 unset($localtax1_tx);
1190 unset($localtax2_tx);
1191
1192 unset($_POST['date_starthour']);
1193 unset($_POST['date_startmin']);
1194 unset($_POST['date_startsec']);
1195 unset($_POST['date_startday']);
1196 unset($_POST['date_startmonth']);
1197 unset($_POST['date_startyear']);
1198 unset($_POST['date_endhour']);
1199 unset($_POST['date_endmin']);
1200 unset($_POST['date_endsec']);
1201 unset($_POST['date_endday']);
1202 unset($_POST['date_endmonth']);
1203 unset($_POST['date_endyear']);
1204
1205 if ($result >= 0) {
1206 // Define output language
1207 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1208 $outputlangs = $langs;
1209 $newlang = '';
1210 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1211 $newlang = GETPOST('lang_id', 'aZ09');
1212 }
1213 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1214 $newlang = $object->thirdparty->default_lang;
1215 }
1216 if (!empty($newlang)) {
1217 $outputlangs = new Translate("", $conf);
1218 $outputlangs->setDefaultLang($newlang);
1219 }
1220 $model = $object->model_pdf;
1221 $ret = $object->fetch($id); // Reload to get new records
1222
1223 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1224 if ($result < 0) {
1225 dol_print_error($db, $object->error, $object->errors);
1226 }
1227 }
1228
1229 $db->commit();
1230 } else {
1231 $db->rollback();
1232
1233 setEventMessages($object->error, $object->errors, 'errors');
1234 }
1235 }
1236
1237 // Remove a product line
1238 if ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate) {
1239 $db->begin();
1240
1241 $result = $object->deleteLine($lineid);
1242 if ($result > 0) {
1243 // reorder lines
1244 $object->line_order(true);
1245 // Define output language
1246 $outputlangs = $langs;
1247 $newlang = '';
1248 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1249 $newlang = GETPOST('lang_id', 'aZ09');
1250 }
1251 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1252 $newlang = $object->thirdparty->default_lang;
1253 }
1254 if (!empty($newlang)) {
1255 $outputlangs = new Translate("", $conf);
1256 $outputlangs->setDefaultLang($newlang);
1257 }
1258 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1259 $ret = $object->fetch($object->id); // Reload to get new records
1260 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1261 }
1262 } else {
1263 $error++;
1264 setEventMessages($object->error, $object->errors, 'errors');
1265 // Reset action to avoid asking again confirmation on failure
1266 $action = '';
1267 }
1268
1269 if (!$error) {
1270 // reopen order if necessary
1272 if ($object->setStatus($user, CommandeFournisseur::STATUS_RECEIVED_PARTIALLY) < 0) {
1273 setEventMessages($object->error, $object->errors, 'errors');
1274 $error++;
1275 $action = '';
1276 }
1277 }
1278 }
1279
1280 if (!$error) {
1281 $db->commit();
1282 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
1283 exit;
1284 } else {
1285 $db->rollback();
1286 }
1287 }
1288
1289 // Validate
1290 if ($action == 'confirm_valid' && $confirm == 'yes' && $usercanvalidate) {
1291 $db->begin();
1292
1293 $object->date_commande = dol_now();
1294 $result = $object->valid($user);
1295 if ($result >= 0) {
1296 // Define output language
1297 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1298 $outputlangs = $langs;
1299 $newlang = '';
1300 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1301 $newlang = GETPOST('lang_id', 'aZ09');
1302 }
1303 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1304 $newlang = $object->thirdparty->default_lang;
1305 }
1306 if (!empty($newlang)) {
1307 $outputlangs = new Translate("", $conf);
1308 $outputlangs->setDefaultLang($newlang);
1309 }
1310 $model = $object->model_pdf;
1311 $ret = $object->fetch($id); // Reload to get new records
1312
1313 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1314 if ($result < 0) {
1315 $error++;
1316 dol_print_error($db, $object->error, $object->errors);
1317 }
1318 }
1319 } else {
1320 $error++;
1321 setEventMessages($object->error, $object->errors, 'errors');
1322 }
1323
1324 // If we have permission, and if we don't need to provide the idwarehouse, we go directly on approved step
1325 if (!$error && !getDolGlobalString('SUPPLIER_ORDER_NO_DIRECT_APPROVE') && $usercanapprove && !(getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') && $object->hasProductsOrServices(1))) {
1326 $action = 'confirm_approve'; // can make standard or first level approval also if permission is set
1327 }
1328
1329 if (!$error) {
1330 $db->commit();
1331 } else {
1332 $db->rollback();
1333 }
1334 }
1335
1336 if (($action == 'confirm_approve' || $action == 'confirm_approve2') && $confirm == 'yes' && $usercanapprove) {
1337 $db->begin();
1338
1339 $idwarehouse = GETPOSTINT('idwarehouse');
1340
1341 $qualified_for_stock_change = 0;
1342 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
1343 $qualified_for_stock_change = $object->hasProductsOrServices(2);
1344 } else {
1345 $qualified_for_stock_change = $object->hasProductsOrServices(1);
1346 }
1347
1348 // Check parameters
1349 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') && $qualified_for_stock_change) { // warning name of option should be STOCK_CALCULATE_ON_SUPPLIER_APPROVE_ORDER
1350 if (!$idwarehouse || $idwarehouse == -1) {
1351 $error++;
1352 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1353 $action = '';
1354 }
1355 }
1356
1357 if (!$error) {
1358 $result = $object->approve($user, $idwarehouse, ($action == 'confirm_approve2' ? 1 : 0));
1359 if ($result > 0) {
1360 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1361 $outputlangs = $langs;
1362 $newlang = '';
1363 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1364 $newlang = GETPOST('lang_id', 'aZ09');
1365 }
1366 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1367 $newlang = $object->thirdparty->default_lang;
1368 }
1369 if (!empty($newlang)) {
1370 $outputlangs = new Translate("", $conf);
1371 $outputlangs->setDefaultLang($newlang);
1372 }
1373 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1374 }
1375 } else {
1376 $error++;
1377 setEventMessages($object->error, $object->errors, 'errors');
1378 }
1379 }
1380
1381 if (!$error) {
1382 $db->commit();
1383
1384 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
1385 exit;
1386 } else {
1387 $db->rollback();
1388 }
1389 }
1390
1391 if ($action == 'confirm_refuse' && $confirm == 'yes' && $usercanapprove) {
1392 if (GETPOST('refuse_note')) {
1393 $object->refuse_note = GETPOST('refuse_note');
1394 }
1395 $result = $object->refuse($user);
1396 if ($result > 0) {
1397 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
1398 exit;
1399 } else {
1400 setEventMessages($object->error, $object->errors, 'errors');
1401 }
1402 }
1403
1404 // Force mandatory order method
1405 if ($action == 'commande') { // Test on permission not required here
1406 $methodecommande = GETPOSTINT('methodecommande');
1407
1408 if ($cancel) {
1409 $action = '';
1410 } elseif ($methodecommande <= 0 && !getDolGlobalInt('SUPPLIER_ORDER_MODE_OPTIONAL')) {
1411 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("OrderMode")), null, 'errors');
1412 $action = 'createorder';
1413 }
1414 }
1415
1416 if ($action == 'confirm_commande' && $confirm == 'yes' && $usercanorder) {
1417 $db->begin();
1418 $object->context["sendmanualtriggers"] = GETPOST("manual_trigger_send");
1419 $result = $object->commande($user, GETPOSTINT("datecommande"), GETPOSTINT("methode"), GETPOST('comment'));
1420 if ($result > 0) {
1421 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1422 $outputlangs = $langs;
1423 $newlang = '';
1424 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1425 $newlang = GETPOST('lang_id', 'aZ09');
1426 }
1427 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1428 $newlang = $object->thirdparty->default_lang;
1429 }
1430 if (!empty($newlang)) {
1431 $outputlangs = new Translate("", $conf);
1432 $outputlangs->setDefaultLang($newlang);
1433 }
1434 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1435 }
1436 $action = '';
1437 } else {
1438 $error++;
1439 setEventMessages($object->error, $object->errors, 'errors');
1440 }
1441
1442 if (!$error) {
1443 $db->commit();
1444
1445 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
1446 exit;
1447 } else {
1448 $db->rollback();
1449 }
1450 }
1451
1452
1453 if ($action == 'confirm_delete' && $confirm == 'yes' && $usercandelete) {
1454 // Delete existing dispatched lines
1455 $errOnDelete = 0;
1456 $errorsOnDelete = array();
1457
1458 $db->begin();
1459
1460 if ($stockDelete) {
1461 // TODO We must find line already recorded in stock, not lines dispatched (stock recording may not have been done
1462 // even if dispatched in llx_receptiondet_batch)
1463 // For example to know if stock movement were already record, we may look at stock movements in llx_stock_movement linked to a reception
1464 // that is linked to the purchase order.
1465
1466 /*
1467 $dispatchedLines = $object->getDispachedLines();
1468
1469 if (!empty($dispatchedLines)) {
1470 foreach ($dispatchedLines as $dispatchedLine) {
1471 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
1472 $result = $supplierorderdispatch->fetch($dispatchedLine['id']);
1473 if ($result > 0) {
1474 $result = $supplierorderdispatch->delete($user);
1475 }
1476 if ($result < 0) {
1477 $errorsOnDelete = $object->errors;
1478 $errOnDelete++;
1479 }
1480 }
1481 }
1482
1483 if ($entrepot > 0 && $product > 0 && isModEnabled('enabled')) {
1484 $stockMovementLines = $object->getstockMovementLines()
1485
1486 if (!empty($stockMovementLines)) {
1487 foreach($stockMovementLines as $stockmovementline) {
1488 $qty = $stockmovementline->qty;
1489 $entrepot = $stockmovementline->fk_entrepot;
1490 $product = $stockmovementline->fk_product;
1491 $price = $stockmovementline->price;
1492 $comment = $langs->trans('SupplierOrderDeletion', $object->ref);
1493 $eatby = $stockmovementline->eatby;
1494 $sellby = $stockmovementline->sellby;
1495 $batch = $stockmovementline->batch;
1496
1497 $mouv = new MouvementStock($db);
1498 $mouv->setOrigin($object->element, $object->id);
1499 $result = $mouv->livraison($user, $product, $entrepot, $qty, $price, $comment, '', $eatby, $sellby, $batch);
1500 if ($result < 0) {
1501 $errorsOnDelete = $mouv->errors;
1502 $errOnDelete++;
1503 }
1504 }
1505 }
1506 }
1507 */
1508 }
1509
1510 // @phpstan-ignore-next-line
1511 if (empty($errOnDelete)) {
1512 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
1513 $result = $object->delete($user);
1514 if ($result > 0) {
1515 $db->commit();
1516 header("Location: " . DOL_URL_ROOT . '/fourn/commande/list.php?restore_lastsearch_values=1');
1517 exit;
1518 } else {
1519 $db->rollback();
1520 setEventMessages($object->error, $object->errors, 'errors');
1521 }
1522 } else {
1523 $db->rollback();
1524 setEventMessages('', $errorsOnDelete, 'errors');
1525 }
1526 }
1527
1528 // Action clone object
1529 if ($action == 'confirm_clone' && $confirm == 'yes' && $usercancreate) {
1530 // @phan-suppress-next-line PhanPluginBothLiteralsBinaryOp
1531 if (1 == 0 && !GETPOST('clone_content') && !GETPOST('clone_receivers')) {
1532 setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
1533 } else {
1534 if ($object->id > 0) {
1535 $orig = clone $object;
1536
1537 $result = $object->createFromClone($user, $socid);
1538 if ($result > 0) {
1539 header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
1540 exit;
1541 } else {
1542 setEventMessages($object->error, $object->errors, 'errors');
1543 $object = $orig;
1544 $action = '';
1545 }
1546 }
1547 }
1548 }
1549
1550 // Set status of reception (complete, partial, ...)
1551 if ($action == 'livraison' && $usercanreceive) {
1552 if ($cancel) {
1553 $action = '';
1554 } else {
1555 $db->begin();
1556
1557 if (GETPOST("type") != '') {
1558 $date_liv = dol_mktime(GETPOSTINT('rehour'), GETPOSTINT('remin'), GETPOSTINT('resec'), GETPOSTINT("remonth"), GETPOSTINT("reday"), GETPOSTINT("reyear"));
1559
1560 $result = $object->Livraison($user, $date_liv, GETPOST("type"), GETPOST("comment")); // GETPOST("type") is 'tot', 'par', 'nev', 'can'
1561 if ($result > 0) {
1562 $langs->load("sendings");
1563 setEventMessages($langs->trans("DeliveryStateSaved"), null);
1564 $action = '';
1565 } else {
1566 //if ($result == -3) {}
1567 $error++;
1568 setEventMessages($object->error, $object->errors, 'errors');
1569 }
1570 } else {
1571 $error++;
1572 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Delivery")), null, 'errors');
1573 }
1574
1575 if (!$error) {
1576 $db->commit();
1577 } else {
1578 $db->rollback();
1579 }
1580 }
1581 }
1582
1583 if ($action == 'confirm_cancel' && $confirm == 'yes' && $usercanorder) {
1584 if (GETPOST('cancel_note')) {
1585 $object->cancel_note = GETPOST('cancel_note');
1586 }
1587 $result = $object->cancel($user);
1588 if ($result > 0) {
1589 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
1590 exit;
1591 } else {
1592 setEventMessages($object->error, $object->errors, 'errors');
1593 }
1594 }
1595
1596 // Actions when printing a doc from card
1597 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
1598
1599 // Actions to send emails
1600 $triggersendname = 'ORDER_SUPPLIER_SENTBYMAIL';
1601 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO';
1602 $trackid = 'sord'.$object->id;
1603 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1604
1605 // Actions to build doc
1606 $upload_dir = getMultidirOutput($object);
1607 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1608
1609
1610 if ($action == 'update_extras' && $permissiontoeditextra) {
1611 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
1612
1613 $attribute_name = GETPOST('attribute', 'aZ09');
1614
1615 // Fill array 'array_options' with data from update form
1616 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
1617 if ($ret < 0) {
1618 $error++;
1619 }
1620
1621 if (!$error) {
1622 $result = $object->updateExtraField($attribute_name, 'ORDER_SUPPLIER_MODIFY');
1623 if ($result < 0) {
1624 setEventMessages($object->error, $object->errors, 'errors');
1625 $error++;
1626 }
1627 }
1628
1629 if ($error) {
1630 $action = 'edit_extras';
1631 }
1632 }
1633
1634 /*
1635 * Create an order
1636 */
1637 if ($action == 'add' && $permissiontoadd) {
1638 $error = 0;
1639 $selectedLines = GETPOST('toselect', 'array:int');
1640 if ($socid < 1) {
1641 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors');
1642 $action = 'create';
1643 $error++;
1644 }
1645
1646 if (!$error) {
1647 $db->begin();
1648
1649 // Creation commande
1650 $object->ref_supplier = GETPOST('refsupplier');
1651 $object->socid = $socid;
1652 $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
1653 $object->deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
1654 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
1655 $object->fk_account = GETPOSTINT('fk_account');
1656 $object->note_private = GETPOST('note_private', 'restricthtml');
1657 $object->note_public = GETPOST('note_public', 'restricthtml');
1658 $object->delivery_date = $datelivraison;
1659 $object->fk_warehouse = GETPOSTINT('fk_warehouse');
1660 $object->fk_incoterms = GETPOSTINT('incoterm_id');
1661 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
1662 $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
1663 $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
1664 $object->fk_project = GETPOSTINT('projectid');
1665
1666 // Fill array 'array_options' with data from add form
1667 if (!$error) {
1668 $ret = $extrafields->setOptionalsFromPost(null, $object);
1669 if ($ret < 0) {
1670 $error++;
1671 }
1672 }
1673
1674 if (!$error) {
1675 // If creation from another object of another module (Example: origin=propal, originid=1)
1676 if (!empty($origin) && !empty($originid)) {
1677 $element = $subelement = $origin;
1678 $classname = ucfirst($subelement);
1679 if ($origin == 'propal' || $origin == 'proposal') {
1680 $element = 'comm/propal';
1681 $subelement = 'propal';
1682 $classname = 'Propal';
1683 }
1684 if ($origin == 'order' || $origin == 'commande') {
1685 $element = $subelement = 'commande';
1686 $classname = 'Commande';
1687 }
1688 if ($origin == 'supplier_proposal') {
1689 $classname = 'SupplierProposal';
1690 $element = 'supplier_proposal';
1691 $subelement = 'supplier_proposal';
1692 }
1693
1694 $object->origin = $origin;
1695 $object->origin_type = $origin;
1696 $object->origin_id = $originid;
1697
1698 // Possibility to add external linked objects with hooks
1699 $object->linked_objects[$object->origin_type] = $object->origin_id;
1700 $other_linked_objects = GETPOST('other_linked_objects', 'array');
1701 if (!empty($other_linked_objects)) {
1702 $object->linked_objects = array_merge($object->linked_objects, $other_linked_objects);
1703 }
1704
1705 $id = $object->create($user);
1706 if ($id > 0) {
1707 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1708
1709 $srcobject = new $classname($db);
1710
1711 dol_syslog("Try to find source object origin=".$object->origin_type." originid=".$object->origin_id." to add lines");
1712 $result = $srcobject->fetch($object->origin_id);
1713 if ($result > 0) {
1714 if (empty($object->delivery_date)) {
1715 $tmpdate = $srcobject->delivery_date;
1716 $object->setDeliveryDate($user, $tmpdate);
1717 }
1718
1719 $object->set_id_projet($user, $srcobject->fk_project);
1720
1721 $lines = $srcobject->lines;
1722 if (empty($lines) && method_exists($srcobject, 'fetch_lines')) {
1723 $srcobject->fetch_lines();
1724 $lines = $srcobject->lines;
1725 }
1726
1727 $fk_parent_line = 0;
1728 $num = count($lines);
1729
1730 for ($i = 0; $i < $num; $i++) {
1731 if (
1732 empty($lines[$i]->subprice)
1733 || $lines[$i]->qty < 0
1734 || !in_array($lines[$i]->id, $selectedLines)
1735 || $lines[$i]->special_code == SUBTOTALS_SPECIAL_CODE
1736 ) {
1737 continue;
1738 }
1739
1740 $label = (!empty($lines[$i]->label) ? $lines[$i]->label : '');
1741 $desc = (!empty($lines[$i]->desc) ? $lines[$i]->desc : '');
1742 $product_type = (!empty($lines[$i]->product_type) ? $lines[$i]->product_type : 0);
1743 // Reset fk_parent_line for no child products and special product
1744 if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
1745 $fk_parent_line = 0;
1746 }
1747
1748 // Extrafields
1749 if (method_exists($lines[$i], 'fetch_optionals')) { // For avoid conflicts if
1750 $lines[$i]->fetch_optionals();
1751 $array_option = $lines[$i]->array_options;
1752 } else {
1753 $array_option = array();
1754 }
1755
1756 $ref_supplier = '';
1757 $product_fourn_price_id = 0;
1758 if ($origin == "commande") {
1759 $productsupplier = new ProductFournisseur($db);
1760 $result = $productsupplier->find_min_price_product_fournisseur($lines[$i]->fk_product, $lines[$i]->qty, $object->socid);
1761 $lines[$i]->subprice = 0;
1762 if ($result > 0) {
1763 $ref_supplier = $productsupplier->ref_supplier;
1764 $product_fourn_price_id = $productsupplier->product_fourn_price_id;
1765 // we need supplier subprice
1766 foreach ($srcobject->lines as $li) {
1767 $sql = 'SELECT price, unitprice, tva_tx, remise_percent, entity, ref_fourn';
1768 $sql .= ' FROM '.MAIN_DB_PREFIX.'product_fournisseur_price';
1769 $sql .= ' WHERE fk_product = '.((int) $li->fk_product);
1770 $sql .= ' AND entity IN ('.getEntity('product_fournisseur_price').')';
1771 $sql .= ' AND fk_soc = '.((int) $object->socid);
1772 $sql .= ' ORDER BY unitprice ASC';
1773
1774 $resql = $db->query($sql);
1775 if ($resql) {
1776 $num_row = $db->num_rows($resql);
1777 if (empty($num_row)) {
1778 $li->remise_percent = 0;
1779 } else {
1780 $obj = $db->fetch_object($resql);
1781 $li->subprice = $obj->unitprice;
1782 $li->remise_percent = $obj->remise_percent;
1783 }
1784 } else {
1785 dol_print_error($db);
1786 }
1787 $db->free($resql);
1788 }
1789 }
1790 } else {
1791 $ref_supplier = $lines[$i]->ref_fourn;
1792 $product_fourn_price_id = 0;
1793 }
1794
1795 $tva_tx = $lines[$i]->tva_tx;
1796
1797 if ($origin == "commande") {
1798 $soc = new Societe($db);
1799 $soc->fetch($socid);
1800 $tva_tx = get_default_tva($soc, $mysoc, $lines[$i]->fk_product, $product_fourn_price_id);
1801 }
1802
1803 // Preserve the original entry mode of the line so the total is computed from the typed value (no rounding drift).
1804 $line_price_base_type = $lines[$i]->getPriceBaseType();
1805 $result = $object->addline(
1806 $desc,
1807 $lines[$i]->subprice,
1808 $lines[$i]->qty,
1809 $tva_tx,
1810 $lines[$i]->localtax1_tx,
1811 $lines[$i]->localtax2_tx,
1812 $lines[$i]->fk_product > 0 ? $lines[$i]->fk_product : 0,
1813 $product_fourn_price_id,
1814 $ref_supplier,
1815 $lines[$i]->remise_percent,
1816 $line_price_base_type,
1817 (float) $lines[$i]->subprice_ttc,
1818 $lines[$i]->product_type,
1819 0,
1820 0,
1821 null,
1822 null,
1823 $array_option,
1824 $lines[$i]->fk_unit,
1825 0,
1826 $element,
1827 !empty($lines[$i]->id) ? $lines[$i]->id : $lines[$i]->rowid,
1828 -1,
1829 $lines[$i]->special_code,
1830 $label
1831 );
1832
1833 if ($result < 0) {
1834 setEventMessages($object->error, $object->errors, 'errors');
1835 $error++;
1836 break;
1837 }
1838
1839 // Defined the new fk_parent_line
1840 if ($result > 0 && $lines[$i]->product_type == 9) {
1841 $fk_parent_line = $result;
1842 }
1843 }
1844
1845 // Add link between elements
1846
1847
1848 // Hooks
1849 $parameters = array('objFrom' => $srcobject);
1850 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been
1851
1852 if ($reshook < 0) {
1853 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1854 $error++;
1855 }
1856 } else {
1857 setEventMessages($srcobject->error, $srcobject->errors, 'errors');
1858 $error++;
1859 }
1860 } else {
1861 setEventMessages($object->error, $object->errors, 'errors');
1862 $error++;
1863 }
1864 } else {
1865 $id = $object->create($user);
1866 if ($id < 0) {
1867 $error++;
1868 setEventMessages($object->error, $object->errors, 'errors');
1869 }
1870 }
1871 }
1872
1873 if (isModEnabled('category')) {
1874 $categories = GETPOST('categories', 'array:int');
1875 if (method_exists($object, 'setCategories')) {
1876 $object->setCategories($categories);
1877 }
1878 }
1879
1880 if ($error) {
1881 $langs->load("errors");
1882 $db->rollback();
1883 $action = 'create';
1884 } else {
1885 $db->commit();
1886 header("Location: ".$_SERVER['PHP_SELF']."?id=".urlencode((string) ($id)));
1887 exit;
1888 }
1889 }
1890 }
1891
1892 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
1893 if ($action == 'addcontact' && $permissiontoadd) {
1894 if ($object->id > 0) {
1895 $contactid = (GETPOST('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid'));
1896 $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
1897 $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
1898 }
1899
1900 if ($result >= 0) {
1901 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1902 exit;
1903 } else {
1904 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1905 $langs->load("errors");
1906 setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
1907 } else {
1908 setEventMessages($object->error, $object->errors, 'errors');
1909 }
1910 }
1911 } elseif ($action == 'swapstatut' && $object->id > 0 && $permissiontoadd) {
1912 // bascule du statut d'un contact
1913 $result = $object->swapContactStatus(GETPOSTINT('ligne'));
1914 } elseif ($action == 'deletecontact' && $object->id > 0 && $permissiontoadd) {
1915 // Efface un contact
1916 $result = $object->delete_contact(GETPOSTINT("lineid"));
1917
1918 if ($result >= 0) {
1919 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1920 exit;
1921 } else {
1922 dol_print_error($db);
1923 }
1924 }
1925 }
1926}
1927
1928
1929/*
1930 * View
1931 */
1932
1933$form = new Form($db);
1934$formfile = new FormFile($db);
1935$formorder = new FormOrder($db);
1936$productstatic = new Product($db);
1937if (isModEnabled('project')) {
1938 $formproject = new FormProjets($db);
1939}
1940
1941$title = $object->ref." - ".$langs->trans('Card');
1942if ($action == 'create') {
1943 $title = $langs->trans("NewOrderSupplier");
1944}
1945$help_url = 'EN:Module_Suppliers_Orders|FR:CommandeFournisseur|ES:Módulo_Pedidos_a_proveedores';
1946llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-supplier-order page-card');
1947
1948$now = dol_now();
1949
1950if ($action == 'create') {
1951 print load_fiche_titre($langs->trans('NewOrderSupplier'), '', 'supplier_order');
1952
1954
1955 $currency_code = $conf->currency;
1956
1957 $societe = '';
1958 $objectsrc = null;
1959
1960 if ($socid > 0) {
1961 $societe = new Societe($db);
1962 $societe->fetch($socid);
1963 }
1964
1965 if (!empty($origin) && !empty($originid)) {
1966 // Parse element/subelement (ex: project_task)
1967 $element = $subelement = $origin;
1968 $classname = ucfirst($subelement);
1969 $regs = array();
1970 if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
1971 $element = $regs[1];
1972 $subelement = $regs[2];
1973 }
1974
1975 if ($origin == 'propal' || $origin == 'proposal') {
1976 $classname = 'Propal';
1977 $element = 'comm/propal';
1978 $subelement = 'propal';
1979 }
1980 if ($origin == 'order' || $origin == 'commande') {
1981 $classname = 'Commande';
1982 $element = $subelement = 'commande';
1983 }
1984 if ($origin == 'supplier_proposal') {
1985 $classname = 'SupplierProposal';
1986 $element = 'supplier_proposal';
1987 $subelement = 'supplier_proposal';
1988 }
1989
1990
1991 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1992
1993 $objectsrc = new $classname($db);
1994 $objectsrc->fetch($originid);
1995 if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
1996 $objectsrc->fetch_lines();
1997 }
1998 $objectsrc->fetch_thirdparty();
1999
2000 // Replicate extrafields
2001 $objectsrc->fetch_optionals();
2002 $object->array_options = $objectsrc->array_options;
2003
2004 $projectid = (int) $objectsrc->fk_project;
2005 $ref_client = (!empty($objectsrc->ref_client) ? $objectsrc->ref_client : '');
2006 $fk_account = 0;
2007 if ($origin == "commande") {
2008 $cond_reglement_id = 0;
2009 $deposit_percent = 0;
2010 $mode_reglement_id = 0;
2011 $objectsrc->note_private = '';
2012 $objectsrc->note_public = '';
2013 if ($societe = $object->thirdparty) {
2014 $cond_reglement_id = $societe->cond_reglement_supplier_id;
2015 $deposit_percent = $societe->deposit_percent;
2016 $mode_reglement_id = $societe->mode_reglement_supplier_id;
2017 if (isModEnabled("multicurrency")) {
2018 $currency_code = $societe->multicurrency_code;
2019 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX')) {
2020 $currency_tx = $societe->multicurrency_tx;
2021 }
2022 }
2023 }
2024 } else {
2025 $soc = $objectsrc->thirdparty;
2026
2027 $cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0));
2028 $deposit_percent = (!empty($objectsrc->deposit_percent) ? $objectsrc->deposit_percent : (!empty($soc->deposit_percent) ? $soc->deposit_percent : 0));
2029 $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0));
2030 $fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0));
2031 $availability_id = (!empty($objectsrc->availability_id) ? $objectsrc->availability_id : (!empty($soc->availability_id) ? $soc->availability_id : 0));
2032 $shipping_method_id = (!empty($objectsrc->shipping_method_id) ? $objectsrc->shipping_method_id : (!empty($soc->shipping_method_id) ? $soc->shipping_method_id : 0));
2033 $demand_reason_id = (!empty($objectsrc->demand_reason_id) ? $objectsrc->demand_reason_id : (!empty($soc->demand_reason_id) ? $soc->demand_reason_id : 0));
2034 $dateinvoice = getDolGlobalString('MAIN_AUTOFILL_DATE') ? '' : -1;
2035
2036 $datelivraison = (!empty($objectsrc->delivery_date) ? $objectsrc->delivery_date : '');
2037
2038 if (isModEnabled("multicurrency")) {
2039 if (!empty($objectsrc->multicurrency_code)) {
2040 $currency_code = $objectsrc->multicurrency_code;
2041 }
2042 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
2043 $currency_tx = $objectsrc->multicurrency_tx;
2044 }
2045 }
2046
2047 $note_private = $object->getDefaultCreateValueFor('note_private', (!empty($objectsrc->note_private) ? $objectsrc->note_private : null));
2048 $note_public = $object->getDefaultCreateValueFor('note_public', (!empty($objectsrc->note_public) ? $objectsrc->note_public : null));
2049
2050 // Object source contacts list
2051 $srccontactslist = $objectsrc->liste_contact(-1, 'external', 1);
2052 }
2053 } else {
2054 $cond_reglement_id = !empty($societe->cond_reglement_supplier_id) ? $societe->cond_reglement_supplier_id : 0;
2055 $deposit_percent = !empty($societe->deposit_percent) ? $societe->deposit_percent : 0;
2056 $mode_reglement_id = !empty($societe->mode_reglement_supplier_id) ? $societe->mode_reglement_supplier_id : 0;
2057
2058 if (isModEnabled("multicurrency") && !empty($societe->multicurrency_code)) {
2059 $currency_code = $societe->multicurrency_code;
2060 }
2061
2062 $note_private = $object->getDefaultCreateValueFor('note_private');
2063 $note_public = $object->getDefaultCreateValueFor('note_public');
2064 }
2065
2066 // If not defined, set default value from constant
2067 if (empty($cond_reglement_id) && getDolGlobalString('SUPPLIER_ORDER_DEFAULT_PAYMENT_TERM_ID')) {
2068 $cond_reglement_id = getDolGlobalString('SUPPLIER_ORDER_DEFAULT_PAYMENT_TERM_ID');
2069 }
2070 if (empty($mode_reglement_id) && getDolGlobalString('SUPPLIER_ORDER_DEFAULT_PAYMENT_MODE_ID')) {
2071 $mode_reglement_id = getDolGlobalString('SUPPLIER_ORDER_DEFAULT_PAYMENT_MODE_ID');
2072 }
2073 if (GETPOSTISSET('cond_reglement_id_deposit_percent')) {
2074 $deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
2075 }
2076
2077 print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="post">';
2078 print '<input type="hidden" name="token" value="'.newToken().'">';
2079 print '<input type="hidden" name="action" value="add">';
2080 print '<input type="hidden" name="remise_percent" value="'.(empty($soc->remise_supplier_percent) ? '' : $soc->remise_supplier_percent).'">';
2081 print '<input type="hidden" name="origin" value="'.$origin.'">';
2082 print '<input type="hidden" name="originid" value="'.$originid.'">';
2083 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
2084 if ($backtopage) {
2085 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2086 }
2087 if ($backtopageforcancel) {
2088 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
2089 }
2090
2091 if (!empty($currency_tx)) {
2092 print '<input type="hidden" name="originmulticurrency_tx" value="'.$currency_tx.'">';
2093 }
2094
2095 print dol_get_fiche_head(array());
2096
2097 // Call Hook tabContentCreateSupplierOrder
2098 $parameters = array();
2099 // Note that $action and $object may be modified by hook
2100 $reshook = $hookmanager->executeHooks('tabContentCreateSupplierOrder', $parameters, $object, $action);
2101 if (empty($reshook)) {
2102 print '<table class="border centpercent">';
2103
2104 // Ref
2105 print '<tr><td class="titlefieldcreate">'.$langs->trans('Ref').'</td><td>'.$langs->trans('Draft').'</td></tr>';
2106
2107 // Third party
2108 print '<tr><td class="fieldrequired">'.$langs->trans('Supplier').'</td>';
2109 print '<td>';
2110
2111 if (!empty($societe->id) && $societe->id > 0) {
2112 print $societe->getNomUrl(1, 'supplier');
2113 print '<input type="hidden" name="socid" value="'.$societe->id.'">';
2114 } else {
2115 $filter = '((s.fournisseur:=:1) AND (s.status:=:1))';
2116 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company((empty($socid) ? '' : $socid), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
2117 // reload page to retrieve customer information
2118 if (!getDolGlobalString('RELOAD_PAGE_ON_SUPPLIER_CHANGE_DISABLED')) {
2119 print '<script>
2120 $(document).ready(function() {
2121 $("#socid").change(function() {
2122 console.log("We have changed the company - Reload page");
2123 // reload page
2124 $("input[name=action]").val("create");
2125 $("input[name=changecompany]").val("1");
2126 $("form[name=add]").submit();
2127 });
2128 });
2129 </script>';
2130 }
2131 print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&client=0&fournisseur=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddThirdParty").'"></span></a>';
2132 }
2133 print '</td>';
2134
2135 // Ref purchase order on vendor side
2136 if (getDolGlobalString('MAIN_ASK_SUPPLIER_REF_OF_PURCHASE_ORDER_AT_CREATION')) {
2137 print '<tr><td>'.$form->textwithpicto($langs->trans('RefSupplier'), $langs->trans('RefOfOnVendorSide', $langs->transnoentitiesnoconv("SupplierOrder")));
2138 print '</td><td><input name="refsupplier" type="text"></td>';
2139 print '</tr>';
2140 }
2141
2142 if (!empty($societe->id) && $societe->id > 0) {
2143 // Discounts for third party
2144 print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
2145
2146 $absolute_discount = $societe->getAvailableDiscounts(null, '', 0, 1);
2147
2148 $thirdparty = $societe;
2149 $discount_type = 1;
2150 $backtopage = urlencode($_SERVER["PHP_SELF"].'?socid='.$thirdparty->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid'));
2151 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2152
2153 print '</td></tr>';
2154 }
2155
2156 // Payment term
2157 print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
2158 print img_picto('', 'payment', 'class="pictofixedwidth"');
2159 print $form->getSelectConditionsPaiements((GETPOSTISSET('cond_reglement_id') && GETPOST('cond_reglement_id') != 0) ? GETPOSTINT('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', $deposit_percent);
2160 print '</td></tr>';
2161
2162 // Payment mode
2163 print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
2164 print img_picto('', 'bank', 'class="pictofixedwidth"');
2165 $form->select_types_paiements((GETPOSTISSET('mode_reglement_id') && GETPOSTINT('mode_reglement_id') != 0) ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id');
2166 print '</td></tr>';
2167
2168 // Planned delivery date
2169 print '<tr><td>';
2170 print $langs->trans('DateDeliveryPlanned');
2171 print '</td>';
2172 print '<td>';
2173 $usehourmin = 0;
2174 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2175 $usehourmin = 1;
2176 }
2177 print img_picto('', 'action', 'class="pictofixedwidth"');
2178 print $form->selectDate($datelivraison ? $datelivraison : -1, 'liv_', $usehourmin, $usehourmin, 0, "set", 1, 1);
2179 print '</td></tr>';
2180
2181 // Default destination warehouse for the goods to receive
2182 if (isModEnabled('stock')) {
2183 $formproductcreate = new FormProduct($db);
2184 print '<tr><td>';
2185 print $form->textwithpicto($langs->trans('DefaultWarehouse'), $langs->trans('SupplierOrderDefaultWarehouseHelp'));
2186 print '</td>';
2187 print '<td>';
2188 print img_picto('', 'stock', 'class="pictofixedwidth"');
2189 print $formproductcreate->selectWarehouses(GETPOSTISSET('fk_warehouse') ? GETPOSTINT('fk_warehouse') : '', 'fk_warehouse', '', 1, 0, 0, '', 0, 0, array(), 'maxwidth500 widthcentpercentminusxx');
2190 print '</td></tr>';
2191 }
2192
2193 // Bank Account
2194 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER') && isModEnabled("bank")) {
2195 $langs->load("bank");
2196 print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
2197 print img_picto('', 'bank_account', 'class="pictofixedwidth"');
2198 $form->select_comptes($fk_account ?? '', 'fk_account', 0, '', 1);
2199 print '</td></tr>';
2200 }
2201
2202 // Project
2203 if (isModEnabled('project')) {
2204 $formproject = new FormProjets($db);
2205
2206 $langs->load('projects');
2207 print '<tr><td>'.$langs->trans('Project').'</td><td>';
2208 if (!empty($user->socid)) { // external user: restrict to their own third party
2209 $projSocFilter = $user->socid;
2210 } elseif (getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') || (int) $socid == 0) {
2211 // Give priority to the constant (as on supplier invoice), so a supplier document created from a
2212 // customer project keeps that project selected after the supplier is chosen.
2213 $projSocFilter = -1;
2214 } else {
2215 $projSocFilter = $socid;
2216 }
2217 print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects($projSocFilter, $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
2218 print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?action=create&status=1'.(!empty($societe->id) ? '&socid='.$societe->id : "").'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create'.(!empty($societe->id) ? '&socid='.$societe->id : "")).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
2219 print '</td></tr>';
2220 }
2221
2222 // Incoterms
2223 if (isModEnabled('incoterm')) {
2224 $fkincoterms = (!empty($object->fk_incoterms) ? $object->fk_incoterms : ($socid > 0 ? $societe->fk_incoterms : ''));
2225 $locincoterms = (!empty($object->location_incoterms) ? $object->location_incoterms : ($socid > 0 ? $societe->location_incoterms : ''));
2226 print '<tr>';
2227 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $object->label_incoterms, 1).'</label></td>';
2228 print '<td class="maxwidthonsmartphone">';
2229 print img_picto('', 'incoterm', 'class="pictofixedwidth"');
2230 print $form->select_incoterms($fkincoterms, $locincoterms);
2231 print '</td></tr>';
2232 }
2233
2234 // Multicurrency
2235 if (isModEnabled("multicurrency")) {
2236 print '<tr>';
2237 print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
2238 print '<td class="maxwidthonsmartphone">';
2239 print img_picto('', 'currency', 'class="pictofixedwidth"');
2240 print $form->selectMultiCurrency($currency_code, 'multicurrency_code');
2241 print '</td></tr>';
2242 }
2243
2244 // Categories
2245 if (isModEnabled("category")) {
2246 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
2247 print $form->selectCategories(Categorie::TYPE_SUPPLIER_ORDER, 'categories', $object);
2248 print "</td></tr>";
2249 }
2250
2251 print '<tr><td>'.$langs->trans('NotePublic').'</td>';
2252 print '<td>';
2253 $doleditor = new DolEditor('note_public', isset($note_public) ? $note_public : GETPOST('note_public', 'restricthtml'), '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
2254 print $doleditor->Create(1);
2255 print '</td>';
2256 //print '<textarea name="note_public" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea>';
2257 print '</tr>';
2258
2259 print '<tr><td>'.$langs->trans('NotePrivate').'</td>';
2260 print '<td>';
2261 $doleditor = new DolEditor('note_private', isset($note_private) ? $note_private : GETPOST('note_private', 'restricthtml'), '', 80, 'dolibarr_notes', 'In', false, false, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
2262 print $doleditor->Create(1);
2263 print '</td>';
2264 //print '<td><textarea name="note_private" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
2265 print '</tr>';
2266
2267 if (!empty($origin) && !empty($originid) && is_object($objectsrc) && $classname !== null) {
2268 print "\n<!-- ".$classname." info -->";
2269 print "\n";
2270 print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
2271 print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
2272 print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
2273 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
2274 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
2275
2276 $newclassname = $classname;
2277 print '<tr><td>'.$langs->trans($newclassname).'</td><td>'.$objectsrc->getNomUrl(1, 'supplier').'</td></tr>';
2278 print '<tr><td>'.$langs->trans('AmountHT').'</td><td>'.price($objectsrc->total_ht).'</td></tr>';
2279 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($objectsrc->total_tva)."</td></tr>";
2280 if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0) { // Localtax1 RE
2281 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax1)."</td></tr>";
2282 }
2283
2284 if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) { // Localtax2 IRPF
2285 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax2)."</td></tr>";
2286 }
2287
2288 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($objectsrc->total_ttc)."</td></tr>";
2289
2290 if (isModEnabled("multicurrency")) {
2291 print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td>'.price($objectsrc->multicurrency_total_ht, 0, $langs, 1, -1, -1, $objectsrc->multicurrency_code).'</td></tr>';
2292 print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td>'.price($objectsrc->multicurrency_total_tva, 0, $langs, 1, -1, -1, $objectsrc->multicurrency_code).'</td></tr>';
2293 print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td>'.price($objectsrc->multicurrency_total_ttc, 0, $langs, 1, -1, -1, $objectsrc->multicurrency_code).'</td></tr>';
2294 }
2295 }
2296
2297 // Other options
2298 $parameters = array();
2299 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2300 print $hookmanager->resPrint;
2301
2302 if (empty($reshook)) {
2303 if (getDolGlobalString('THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_SUPPLIER_ORDER') && !empty($societe->id)) {
2304 // copy from thirdparty
2305 $tpExtrafields = new ExtraFields($db);
2306 $tpExtrafieldLabels = $tpExtrafields->fetch_name_optionals_label($societe->table_element);
2307 if ($societe->fetch_optionals() > 0) {
2308 $object->array_options = array_merge($object->array_options, $societe->array_options);
2309 }
2310 }
2311
2312 print $object->showOptionals($extrafields, 'create');
2313 }
2314
2315 // Bouton "Create Draft"
2316 print "</table>\n";
2317 }
2318 print dol_get_fiche_end();
2319
2320 print $form->buttonsSaveCancel("CreateDraft");
2321
2322 // Show origin lines
2323 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
2324 $title = $langs->trans('ProductsAndServices');
2325 print load_fiche_titre($title);
2326
2327 print '<div class="div-table-responsive-no-min">';
2328 print '<table class="noborder centpercent">';
2329
2330 $selectedLines = array();
2331
2332 $objectsrc->printOriginLinesList('', $selectedLines);
2333
2334 print '</table>';
2335 print '</div>';
2336 }
2337 print "</form>\n";
2338} elseif (!empty($object->id)) {
2339 // view
2340 $result = $object->fetch($id, $ref);
2341 $object->fetch_thirdparty();
2342
2343 $num = 0;
2344
2345 $societe = $object->thirdparty;
2346
2347 $author = new User($db);
2348 $author->fetch($object->user_author_id);
2349
2350 $head = ordersupplier_prepare_head($object);
2351
2352 $title = $langs->trans("SupplierOrder");
2353 print dol_get_fiche_head($head, 'card', $title, -1, 'order', 0, '', '', 0, '', 1);
2354
2355
2356 $formconfirm = '';
2357
2358 // Confirmation of deletion of order
2359 if ($action == 'delete') {
2360 $arrayAjouts = array();
2361 $heightModal = 0;
2362 $widthModal = 500;
2363
2364 // TODO We must find line already recorded in stock, not lines dispatched (stock recording may not have been done
2365 // even if dispatched in llx_receptiondet_batch).
2366 // For example to know if stock movement were already record, we may look at stock movements in llx_stock_movement linked to a reception
2367 // that is linked to the purchase order.
2368 /* $dispatchedLines = $object->getStockMovementLines();
2369
2370 if (!empty($dispatchedLines)) {
2371 $arrayAjouts = array(
2372 array(
2373 'type' => 'other',
2374 'value' => img_warning() . " " . $langs->trans('ExistingDipatchLines')
2375 ),
2376 array('type' => 'separator'),
2377 array(
2378 'type' => 'select',
2379 'id' => 'stockDeleteSelect',
2380 'name' => 'stockDelete',
2381 'label' => $langs->trans('ConfirmDeleteDispatchedLines'),
2382 'values' => array(1 => $langs->trans('Yes'), 0 => $langs->trans('No')),
2383 'select_show_empty' => false
2384 )
2385 );
2386 $heightModal = 300;
2387 $widthModal = "70%";
2388 }
2389 */
2390
2391 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.((int) $object->id), $langs->trans('DeleteOrder'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', $arrayAjouts, 0, 2, $heightModal, $widthModal);
2392 }
2393
2394 // Clone confirmation
2395 if ($action == 'clone') {
2396 $filter = '(s.fournisseur:=:1)';
2397 // Create an array for form
2398 $formquestion = array(
2399 array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter))
2400 );
2401 // Payment incomplete. Requesting reason: discount or other?
2402 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
2403 }
2404
2405 // Confirm validation
2406 if ($action == 'valid') {
2407 $object->date_commande = dol_now();
2408
2409 // We check if number is temporary number
2410 if (preg_match('/^[\‍(]?PROV/i', (string) $object->ref) || empty($object->ref)) { // empty should not happened, but when it occurs, the test save life
2411 $newref = $object->getNextNumRef($object->thirdparty);
2412 } else {
2413 $newref = (string) $object->ref;
2414 }
2415
2416 if ($newref < 0) {
2417 setEventMessages($object->error, $object->errors, 'errors');
2418 $action = '';
2419 } else {
2420 $text = $langs->trans('ConfirmValidateOrder', $newref);
2421 if (isModEnabled('notification')) {
2422 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2423 $notify = new Notify($db);
2424 $text .= '<br>';
2425 $text .= $notify->confirmMessage('ORDER_SUPPLIER_VALIDATE', $object->socid, $object);
2426 }
2427
2428 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_valid', '', 0, 1);
2429 }
2430 }
2431
2432 // Confirm approval
2433 if ($action == 'approve' || $action == 'approve2') {
2434 $qualified_for_stock_change = 0;
2435 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2436 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2437 } else {
2438 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2439 }
2440
2441 $formquestion = array();
2442 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') && $qualified_for_stock_change) {
2443 $langs->load("stocks");
2444 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2445 $formproduct = new FormProduct($db);
2446 $forcecombo = 0;
2447 if ($conf->browser->name == 'ie') {
2448 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
2449 }
2450 $formquestion = array(
2451 //'text' => $langs->trans("ConfirmClone"),
2452 //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
2453 //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
2454 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockIncrease"), 'value' => $formproduct->selectWarehouses(GETPOSTINT('idwarehouse'), 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
2455 );
2456 }
2457 $text = $langs->trans("ConfirmApproveThisOrder", $object->ref);
2458 if (isModEnabled('notification')) {
2459 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2460 $notify = new Notify($db);
2461 $text .= '<br>';
2462 $text .= $notify->confirmMessage('ORDER_SUPPLIER_APPROVE', $object->socid, $object);
2463 }
2464
2465 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ApproveThisOrder"), $text, "confirm_".$action, $formquestion, 1, 1, 240);
2466 }
2467
2468 // Confirmation of disapproval
2469 if ($action == 'refuse') {
2470 $formquestion = array(
2471 array(
2472 'type' => 'text',
2473 'name' => 'refuse_note',
2474 'label' => $langs->trans("Reason"),
2475 'value' => '',
2476 'morecss' => 'minwidth300'
2477 )
2478 );
2479 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("DenyingThisOrder"), $langs->trans("ConfirmDenyingThisOrder", $object->ref), "confirm_refuse", $formquestion, 0, 1);
2480 }
2481
2482 // Confirmation of cancellation
2483 if ($action == 'cancel') {
2484 $formquestion = array(
2485 array(
2486 'type' => 'text',
2487 'name' => 'cancel_note',
2488 'label' => $langs->trans("Reason"),
2489 'value' => '',
2490 'morecss' => 'minwidth300'
2491 )
2492 );
2493 if (isModEnabled('notification')) {
2494 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2495 $notify = new Notify($db);
2496 $text = '';
2497 $text .= '<br>';
2498 $text .= $notify->confirmMessage('ORDER_SUPPLIER_CANCEL', $object->socid, $object);
2499 }
2500 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("Cancel"), $langs->trans("ConfirmCancelThisOrder", $object->ref), "confirm_cancel", $formquestion, 0, 1);
2501 }
2502
2503 // Confirmation de l'envoi de la commande
2504 if ($action == 'commande') {
2505 $formquestion = array();
2506 $date_com = dol_mktime(GETPOSTINT('rehour'), GETPOSTINT('remin'), GETPOSTINT('resec'), GETPOSTINT("remonth"), GETPOSTINT("reday"), GETPOSTINT("reyear"));
2507 if (isModEnabled('notification')) {
2508 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2509 $notify = new Notify($db);
2510 $text = '';
2511 $text .= '<br>';
2512 $text .= $notify->confirmMessage('ORDER_SUPPLIER_SUBMIT', $object->socid, $object);
2513 }
2514 if (isModEnabled('webhook')) {
2515 require_once DOL_DOCUMENT_ROOT.'/webhook/class/target.class.php';
2516 $targetstatic = new Target($db);
2517 if ($targetstatic->isTriggerCodeManualTarget('ORDER_SUPPLIER_SUBMIT') > 0) {
2518 $formquestion[] = array('type' => 'checkbox', 'name' => 'manual_trigger_send', 'label' => $langs->trans("QuestionSendManualTrigger"));
2519 }
2520 }
2521 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id."&datecommande=".$date_com."&methode=".GETPOST("methodecommande")."&comment=".urlencode(GETPOST("comment")), $langs->trans("MakeOrder"), $langs->trans("ConfirmMakeOrder", dol_print_date($date_com, 'day')), "confirm_commande", $formquestion, 0, 2);
2522 }
2523
2524 // Confirmation to delete line
2525 if ($action == 'ask_deleteline') {
2526 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
2527 }
2528
2529 // Confirmation to delete a subtotal / title / text line (subtotals module)
2530 if ($action == 'ask_subtotal_deleteline') {
2531 $langs->load('subtotals');
2532 $subtotaltitle = 'DeleteSubtotalLine';
2533 $subtotalquestion = 'ConfirmDeleteSubtotalLine';
2534 $subtotalformquestion = array();
2535 if (GETPOST('type') == 'title') {
2536 $subtotalformquestion = array(array('type' => 'checkbox', 'name' => 'deletecorrespondingsubtotalline', 'label' => $langs->trans('DeleteCorrespondingSubtotalLine'), 'value' => 0));
2537 $subtotaltitle = 'DeleteTitleLine';
2538 $subtotalquestion = 'ConfirmDeleteTitleLine';
2539 }
2540 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans($subtotaltitle), $langs->trans($subtotalquestion), 'confirm_delete_subtotalline', $subtotalformquestion, 'no', 1);
2541 }
2542
2543 // Subtotal line form
2544 if ($action == 'add_title_line') {
2545 $langs->load('subtotals');
2546 $type = 'title';
2547 $depth_array = $object->getPossibleLevels($langs);
2548 require DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_create.tpl.php';
2549 } elseif ($action == 'add_subtotal_line') {
2550 $langs->load('subtotals');
2551 $type = 'subtotal';
2552 $titles = $object->getPossibleTitles();
2553 require DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_create.tpl.php';
2554 } elseif ($action == 'add_text_line') {
2555 $langs->load('subtotals');
2556 $type = 'text';
2557 require DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_create.tpl.php';
2558 }
2559
2560 // Call Hook formConfirm
2561 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
2562 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2563 if (empty($reshook)) {
2564 $formconfirm .= $hookmanager->resPrint;
2565 } elseif ($reshook > 0) {
2566 $formconfirm = $hookmanager->resPrint;
2567 }
2568
2569 // Print form confirm
2570 print $formconfirm;
2571
2572
2573 // Supplier order card
2574
2575 $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
2576
2577 $morehtmlref = '<div class="refidno">';
2578 // Ref supplier
2579 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, (int) $usercancreate, 'string', '', 0, 1);
2580 $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreate, 'string'.(isset($conf->global->THIRDPARTY_REF_INPUT_SIZE) ? ':' . getDolGlobalString('THIRDPARTY_REF_INPUT_SIZE') : ''), '', null, null, '', 1);
2581 // Thirdparty
2582 $morehtmlref .= '<br>';
2583 if (getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') && !empty($usercancreate) && $action == 'edit_thirdparty') {
2584 $morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
2585 $morehtmlref .= '<input type="hidden" name="action" value="set_thirdparty">';
2586 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
2587 $filter = '(s.fournisseur:=:1)';
2588 $morehtmlref .= $form->select_company($object->thirdparty->id, 'new_socid', $filter, '', 0, 0, array(), 0, 'minwidth300');
2589 $morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
2590 $morehtmlref .= '</form>';
2591 }
2592 if (!getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') || $action != 'edit_thirdparty') {
2593 if (getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') && $object->status == CommandeFournisseur::STATUS_DRAFT) {
2594 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=edit_thirdparty&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetThirdParty')).'</a>';
2595 }
2596 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'supplier');
2597 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
2598 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
2599 }
2600 }
2601
2602 // Project
2603 if (isModEnabled('project')) {
2604 $langs->load("projects");
2605 $morehtmlref .= '<br>';
2606 if ($permissiontoadd) {
2607 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2608 if ($action != 'classify' && $caneditproject) {
2609 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2610 }
2611 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') ? $object->socid : -1), (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 1, 0, 0, 1, '', 'maxwidth300');
2612 } else {
2613 if (!empty($object->fk_project)) {
2614 $proj = new Project($db);
2615 $proj->fetch($object->fk_project);
2616 $morehtmlref .= $proj->getNomUrl(1);
2617 if ($proj->title) {
2618 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2619 }
2620 }
2621 }
2622 }
2623 $morehtmlref .= '</div>';
2624
2625
2626 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
2627
2628 // Call Hook tabContentViewSupplierOrder
2629 $parameters = array();
2630 // Note that $action and $object may be modified by hook
2631 $reshook = $hookmanager->executeHooks('tabContentViewSupplierOrder', $parameters, $object, $action);
2632 if (empty($reshook)) {
2633 print '<div class="fichecenter">';
2634 print '<div class="fichehalfleft">';
2635 print '<div class="underbanner clearboth"></div>';
2636
2637 print '<table class="border tableforfield centpercent">';
2638
2639 // Date
2640 if ($object->methode_commande_id > 0) {
2641 $usehourmin = 0;
2642 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2643 $usehourmin = 1;
2644 }
2645 print '<tr><td class="titlefield">'.$langs->trans("Date").'</td><td>';
2646 print $object->date_commande ? dol_print_date($object->date_commande, $usehourmin ? 'dayhour' : 'day') : '';
2647 if ($object->hasDelay() && !empty($object->delivery_date) && !empty($object->date_commande)) {
2648 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
2649 }
2650 print "</td></tr>";
2651
2652 if ($object->methode_commande) {
2653 print '<tr><td>'.$langs->trans("Method").'</td><td>'.$object->getInputMethod().'</td></tr>';
2654 }
2655 }
2656
2657 // Author
2658 print '<tr><td class="titlefield">'.$langs->trans("AuthorRequest").'</td>';
2659 print '<td>'.$author->getNomUrl(-1, '', 0, 0, 0).'</td>';
2660 print '</tr>';
2661
2662 // Relative and absolute discounts
2663 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
2664 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2665 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2666 } else {
2667 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
2668 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
2669 }
2670
2671 $absolute_discount = $societe->getAvailableDiscounts(null, $filterabsolutediscount, 0, 1);
2672 $absolute_creditnote = $societe->getAvailableDiscounts(null, $filtercreditnote, 0, 1);
2673 $absolute_discount = price2num($absolute_discount, 'MT');
2674 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
2675
2676 print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td>';
2677
2678 $thirdparty = $societe;
2679 $discount_type = 1;
2680 $backtopage = urlencode($_SERVER["PHP_SELF"].'?id='.$object->id);
2681 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2682
2683 print '</td></tr>';
2684
2685 // Default terms of the settlement
2686 $langs->load('bills');
2687 print '<tr><td class="nowrap">';
2688 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
2689 print $langs->trans('PaymentConditions');
2690 print '<td>';
2691 if ($action != 'editconditions' && $permissiontoadd) {
2692 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editconditions&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetConditions'), 1).'</a></td>';
2693 }
2694 print '</tr></table>';
2695 print '</td><td>';
2696 if ($action == 'editconditions') {
2697 $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent);
2698 } else {
2699 $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->cond_reglement_id, 'none', 1, '', 1, $object->deposit_percent);
2700 }
2701 print "</td>";
2702 print '</tr>';
2703
2704 // Mode of payment
2705 $langs->load('bills');
2706 print '<tr><td class="nowrap">';
2707 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
2708 print $langs->trans('PaymentMode');
2709 print '</td>';
2710 if ($action != 'editmode' && $permissiontoadd) {
2711 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmode&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetMode'), 1).'</a></td>';
2712 }
2713 print '</tr></table>';
2714 print '</td><td>';
2715 if ($action == 'editmode') {
2716 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', 'DBIT', 1, 1);
2717 } else {
2718 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'none');
2719 }
2720 print '</td></tr>';
2721
2722 // Bank Account
2723 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER') && isModEnabled("bank")) {
2724 print '<tr><td class="nowrap">';
2725 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
2726 print $langs->trans('BankAccount');
2727 print '<td>';
2728 if ($action != 'editbankaccount' && $permissiontoadd) {
2729 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'), 1).'</a></td>';
2730 }
2731 print '</tr></table>';
2732 print '</td><td>';
2733 if ($action == 'editbankaccount') {
2734 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'fk_account', 1);
2735 } else {
2736 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'none');
2737 }
2738 print '</td>';
2739 print '</tr>';
2740 }
2741
2742 // Delivery delay (in days)
2743 print '<tr>';
2744 print '<td>'.$langs->trans('NbDaysToDelivery').'&nbsp;'.img_picto($langs->trans('DescNbDaysToDelivery'), 'info', 'style="cursor:help"').'</td>';
2745 print '<td>'.$object->getMaxDeliveryTimeDay($langs).'</td>';
2746 print '</tr>';
2747
2748 // Default destination warehouse for the goods to receive
2749 if (isModEnabled('stock')) {
2750 $formproductcard = new FormProduct($db);
2751 print '<tr><td>';
2752 print '<table class="nobordernopadding centpercent"><tr><td>';
2753 print $form->textwithpicto($langs->trans('DefaultWarehouse'), $langs->trans('SupplierOrderDefaultWarehouseHelp'));
2754 print '</td>';
2755 if ($action != 'editwarehouse' && $usercancreate) {
2756 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editwarehouse&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetWarehouse'), 1).'</a></td>';
2757 }
2758 print '</tr></table>';
2759 print '</td><td>';
2760 if ($action == 'editwarehouse') {
2761 print '<form name="setwarehouse" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2762 print '<input type="hidden" name="token" value="'.newToken().'">';
2763 print '<input type="hidden" name="action" value="setwarehouse">';
2764 print $formproductcard->selectWarehouses($object->fk_warehouse, 'fk_warehouse', '', 1, 0, 0, '', 0, 0, array(), 'maxwidth300');
2765 print '<input type="submit" class="button button-edit smallpaddingimp valign middle" value="'.$langs->trans('Modify').'">';
2766 print '</form>';
2767 } elseif ($object->fk_warehouse > 0) {
2768 $warehousestatic = new Entrepot($db);
2769 if ($warehousestatic->fetch($object->fk_warehouse) > 0) {
2770 print $warehousestatic->getNomUrl(1);
2771 }
2772 } else {
2773 print '&nbsp;';
2774 }
2775 print '</td></tr>';
2776 }
2777
2778 // Delivery date planned
2779 print '<tr><td>';
2780 print '<table class="nobordernopadding centpercent"><tr><td>';
2781 print $langs->trans('DateDeliveryPlanned');
2782 print '</td>';
2783 if ($action != 'editdate_livraison') {
2784 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editdate_livraison&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->trans('SetDeliveryDate'), 1).'</a></td>';
2785 }
2786 print '</tr></table>';
2787 print '</td><td>';
2788 if ($action == 'editdate_livraison') {
2789 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2790 print '<input type="hidden" name="token" value="'.newToken().'">';
2791 print '<input type="hidden" name="action" value="setdate_livraison">';
2792 $usehourmin = 0;
2793 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2794 $usehourmin = 1;
2795 }
2796 print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', $usehourmin, $usehourmin, 0, "setdate_livraison");
2797 print '<input type="submit" class="button button-edit smallpaddingimp valign middle" value="'.$langs->trans('Modify').'">';
2798 print '</form>';
2799 } else {
2800 $usehourmin = 'day';
2801 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2802 $usehourmin = 'dayhour';
2803 }
2804 print $object->delivery_date ? dol_print_date($object->delivery_date, $usehourmin) : '&nbsp;';
2805 if ($object->hasDelay() && !empty($object->delivery_date) && ($object->status == $object::STATUS_ORDERSENT || $object->status == $object::STATUS_RECEIVED_PARTIALLY)) {
2806 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
2807 }
2808 }
2809 print '</td></tr>';
2810
2811 // Incoterms
2812 if (isModEnabled('incoterm')) {
2813 print '<tr><td>';
2814 print '<table class="nobordernopadding centpercent"><tr><td>';
2815 print $langs->trans('IncotermLabel');
2816 print '<td><td class="right">';
2817 if ($usercancreate) {
2818 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?id='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
2819 } else {
2820 print '&nbsp;';
2821 }
2822 print '</td></tr></table>';
2823 print '</td>';
2824 print '<td>';
2825 if ($action != 'editincoterm') {
2826 print $form->textwithpicto(dol_escape_htmltag($object->display_incoterms()), $object->label_incoterms, 1);
2827 } else {
2828 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
2829 }
2830 print '</td></tr>';
2831 }
2832
2833 // Tags-Categories
2834 if (isModEnabled('category')) {
2835 print '<tr><td>';
2836 print '<table class="nobordernopadding centpercent"><tr><td>';
2837 print $langs->trans("Categories");
2838 print '<td><td class="right">';
2839 if ($usercancreate) {
2840 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?id='.$object->id.'&action=edittags&token='.newToken().'">'.img_edit().'</a>';
2841 } else {
2842 print '&nbsp;';
2843 }
2844 print '</td></tr></table>';
2845 print '</td>';
2846 print '<td>';
2847 if ($action == 'edittags') {
2848 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
2849 print '<input type="hidden" name="action" value="settags">';
2850 print '<input type="hidden" name="token" value="'.newToken().'">';
2851 print $form->selectCategories(Categorie::TYPE_SUPPLIER_ORDER, 'categories', $object);
2852 print '<input type="submit" class="button valignmiddle smallpaddingimp" value="'.$langs->trans("Modify").'">';
2853 print '</form>';
2854 } else {
2855 print $form->showCategories($object->id, Categorie::TYPE_SUPPLIER_ORDER, 1);
2856 }
2857 print "</td></tr>";
2858 }
2859
2860 // Other attributes
2861 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2862
2863 print '</table>';
2864
2865 print '</div>';
2866 print '<div class="fichehalfright">';
2867 print '<div class="underbanner clearboth"></div>';
2868
2869 print '<table class="border tableforfield centpercent">';
2870
2871 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
2872
2873 print '<tr>';
2874 // Amount HT
2875 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
2876 print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2877 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2878 // Multicurrency Amount HT
2879 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2880 }
2881 print '</tr>';
2882
2883 print '<tr>';
2884 // Amount VAT
2885 print '<td class="titlefieldmiddle">' . $langs->trans('AmountVAT') . '</td>';
2886 print '<td class="nowrap amountcard right">' . price($object->total_tva, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2887 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2888 // Multicurrency Amount VAT
2889 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2890 }
2891 print '</tr>';
2892
2893 // Amount Local Taxes
2894 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) {
2895 print '<tr>';
2896 print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
2897 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2898 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2899 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2900 }
2901 print '</tr>';
2902
2903 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
2904 print '<tr>';
2905 print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
2906 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2907 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2908 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2909 }
2910 print '</tr>';
2911 }
2912 }
2913
2914 $alert = '';
2915 if (getDolGlobalString('ORDER_MANAGE_MIN_AMOUNT') && $object->total_ht < $object->thirdparty->supplier_order_min_amount) {
2916 $alert = ' ' . img_warning($langs->trans('OrderMinAmount') . ': ' . price($object->thirdparty->supplier_order_min_amount));
2917 }
2918
2919 print '<tr>';
2920 // Amount TTC
2921 print '<td>' . $langs->trans('AmountTTC') . '</td>';
2922 print '<td class="nowrap amountcard right">' . price($object->total_ttc, 0, $langs, 0, -1, -1, $conf->currency) . $alert . '</td>';
2923 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2924 // Multicurrency Amount TTC
2925 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ttc, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2926 }
2927 print '</tr>';
2928
2929 print '</table>';
2930
2931 // Margin Infos
2932 /*if (isModEnabled('margin')) {
2933 $formmargin->displayMarginInfos($object);
2934 }*/
2935
2936
2937 print '</div>';
2938 print '</div>';
2939
2940 print '<div class="clearboth"></div><br>';
2941
2942 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
2943 $blocname = 'contacts';
2944 $title = $langs->trans('ContactsAddresses');
2945 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2946 }
2947
2948 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
2949 $blocname = 'notes';
2950 $title = $langs->trans('Notes');
2951 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2952 }
2953
2954 /*
2955 * Lines
2956 */
2957 //$result = $object->getLinesArray();
2958
2959
2960 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
2961 <input type="hidden" name="token" value="'.newToken().'">
2962 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
2963 <input type="hidden" name="mode" value="">
2964 <input type="hidden" name="page_y" value="">
2965 <input type="hidden" name="id" value="'.$object->id.'">
2966 <input type="hidden" name="socid" value="'.$societe->id.'">
2967 ';
2968
2969 if (!empty($conf->use_javascript_ajax) && $object->status == CommandeFournisseur::STATUS_DRAFT) {
2970 if (isModEnabled('subtotals')) {
2971 include DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_ajaxrow.tpl.php';
2972 } else {
2973 include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
2974 }
2975 }
2976
2977 print '<div class="div-table-responsive-no-min">';
2978 print '<table id="tablelines" class="noborder noshadow centpercent">';
2979
2980 // Add free products/services form
2981 global $forceall, $senderissupplier, $dateSelector, $inputalsopricewithtax;
2982 $forceall = 1;
2983 $dateSelector = 0;
2984 $inputalsopricewithtax = 1;
2985 $senderissupplier = 2; // $senderissupplier=2 is same than 1 but disable test on minimum qty and disable autofill qty with minimum.
2986 if (getDolGlobalInt('SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY')) {
2987 $senderissupplier = getDolGlobalInt('SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY');
2988 }
2989
2990 // Show object lines
2991 if (!empty($object->lines)) {
2992 $object->printObjectLines($action, $object->thirdparty, $mysoc, $lineid, 1);
2993 }
2994
2995 $num = count($object->lines);
2996
2997 // Form to add new line
2998 if ($object->status == CommandeFournisseur::STATUS_DRAFT && $usercancreate) {
2999 if ($action != 'editline') {
3000 // Add free products/services
3001
3002 $parameters = array();
3003 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
3004 if ($reshook < 0) {
3005 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
3006 }
3007 if (empty($reshook)) {
3008 $object->formAddObjectLine(1, $societe, $mysoc);
3009 }
3010 }
3011 }
3012 print '</table>';
3013 print '</div>';
3014 print '</form>';
3015 }
3016
3017 print dol_get_fiche_end();
3018
3023 if ($user->socid == 0 && $action != 'delete') {
3024 if ($action != 'createorder' && $action != 'presend' && $action != 'editline') {
3025 print '<div class="tabsAction">';
3026
3027 $parameters = array();
3028 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
3029 // modified by hook
3030 if (empty($reshook)) {
3031 $object->fetchObjectLinked(); // Links are used to show or not button, so we load them now.
3032
3033 // Subtotal
3034 if ($object->status == CommandeFournisseur::STATUS_DRAFT && isModEnabled('subtotals')
3035 && (getDolGlobalString('SUBTOTAL_TITLE_'.strtoupper($object->element)) || getDolGlobalString('SUBTOTAL_'.strtoupper($object->element)) || getDolGlobalString('SUBTOTAL_TEXT_'.strtoupper($object->element)))) {
3036 $langs->load('subtotals');
3037
3038 $url_button = array();
3039
3040 $url_button[] = array(
3041 'lang' => 'subtotals',
3042 'enabled' => $object->status == CommandeFournisseur::STATUS_DRAFT,
3043 'perm' => (bool) $usercancreate,
3044 'label' => $langs->trans('AddTitleLine'),
3045 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_title_line'], true)
3046 );
3047
3048 $url_button[] = array(
3049 'lang' => 'subtotals',
3050 'enabled' => $object->status == CommandeFournisseur::STATUS_DRAFT,
3051 'perm' => (bool) $usercancreate,
3052 'label' => $langs->trans('AddSubtotalLine'),
3053 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_subtotal_line'], true)
3054 );
3055
3056 $url_button[] = array(
3057 'lang' => 'subtotals',
3058 'enabled' => $object->status == CommandeFournisseur::STATUS_DRAFT,
3059 'perm' => (bool) $usercancreate,
3060 'label' => $langs->trans('AddTextLine'),
3061 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_text_line'], true)
3062 );
3063
3064 print dolGetButtonAction('', $langs->trans('SubTotal'), 'default', $url_button, '', true);
3065 }
3066 // Validate
3067 if ($object->status == 0) {
3068 if ($num > 0) {
3069 if ($usercanvalidate) {
3070 $tmpbuttonlabel = $langs->trans('Validate');
3071 if ($usercanapprove && !getDolGlobalString('SUPPLIER_ORDER_NO_DIRECT_APPROVE')) {
3072 $tmpbuttonlabel = $langs->trans("ValidateAndApprove");
3073 }
3074
3075 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken().'">';
3076 print $tmpbuttonlabel;
3077 print '</a>';
3078 }
3079 } else {
3080 $langs->load("errors");
3081 print dolGetButtonAction($langs->trans("ErrorObjectMustHaveLinesToBeValidated", $object->ref), $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"] . '?action=validate&token=' . newToken() . '&id=' . $object->id, (string) $object->id, -1);
3082 }
3083 }
3084 // Create event
3085 /*if (isModEnabled('agenda') && getDolGlobalString('MAIN_ADD_EVENT_ON_ELEMENT_CARD')) // Add hidden condition because this is not a "workflow" action so should appears somewhere else on page.
3086 {
3087 print '<div class="inline-block divButAction"><a class="butAction" href="' . DOL_URL_ROOT . '/comm/action/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '">' . $langs->trans("AddAction") . '</a></div>';
3088 }*/
3089
3090 // Modify
3092 if ($usercanorder) {
3093 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("Modify").'</a>';
3094 }
3095 }
3096
3097 // Approve
3099 if ($usercanapprove) {
3100 if (getDolGlobalString('SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED') && $object->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED && !empty($object->user_approve_id)) {
3101 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("FirstApprovalAlreadyDone")).'">'.$langs->trans("ApproveOrder").'</a>';
3102 } else {
3103 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=approve&amp;token='.newToken().'">'.$langs->trans("ApproveOrder").'</a>';
3104 }
3105 } else {
3106 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("ApproveOrder").'</a>';
3107 }
3108 }
3109
3110 // Second approval (if option SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set)
3111 if (getDolGlobalString('SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED') && $object->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) {
3113 if ($usercanapprovesecond) {
3114 if (!empty($object->user_approve_id2)) {
3115 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("SecondApprovalAlreadyDone")).'">'.$langs->trans("Approve2Order").'</a>';
3116 } else {
3117 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=approve2&amp;token='.newToken().'">'.$langs->trans("Approve2Order").'</a>';
3118 }
3119 } else {
3120 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("Approve2Order").'</a>';
3121 }
3122 }
3123 }
3124
3125 // Refuse
3127 if ($usercanapprove || $usercanapprovesecond) {
3128 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=refuse&amp;token='.newToken().'">'.$langs->trans("RefuseOrder").'</a>';
3129 } else {
3130 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("RefuseOrder").'</a>';
3131 }
3132 }
3133
3134 // Send
3135 if (empty($user->socid)) {
3136 if (in_array($object->status, array(CommandeFournisseur::STATUS_ACCEPTED, 3, 4, 5)) || getDolGlobalString('SUPPLIER_ORDER_SENDBYEMAIL_FOR_ALL_STATUS')) {
3137 if ($usercanorder) {
3138 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle', '');
3139 }
3140 }
3141 }
3142
3143 // Reopen
3144 if (in_array($object->status, array(CommandeFournisseur::STATUS_ACCEPTED))) {
3145 $buttonshown = 0;
3146 if (!$buttonshown && $usercanapprove) {
3147 if (!getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER_ONLY')
3148 || (getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER_ONLY') && $user->id == $object->user_approve_id)) {
3149 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("Disapprove").'</a>';
3150 $buttonshown++;
3151 }
3152 }
3153 if (!$buttonshown && $usercanapprovesecond && getDolGlobalString('SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED')) {
3154 if (!getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER2_ONLY')
3155 || (getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER2_ONLY') && $user->id == $object->user_approve_id2)) {
3156 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("Disapprove").'</a>';
3157 }
3158 }
3159 }
3160 if (in_array($object->status, array(3, 4, 5, 6, 7, 9))) {
3161 if ($usercanorder) {
3162 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("ReOpen").'</a>';
3163 }
3164 }
3165
3166 // Ship
3167 $hasreception = 0;
3168 if (isModEnabled('stock') && (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE'))) {
3169 $labelofbutton = $langs->trans('ReceiveProducts');
3170 if (isModEnabled('reception')) {
3171 $labelofbutton = $langs->trans("CreateReception");
3172 if (!empty($object->linkedObjects['reception'])) {
3173 foreach ($object->linkedObjects['reception'] as $element) {
3174 if ($element->statut >= 0) {
3175 $hasreception = 1;
3176 break;
3177 }
3178 }
3179 }
3180 }
3181
3182 // To avoid delete order with dispatched lines
3183 if (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER')) {
3184 if (empty($object->lines)) {
3185 $object->fetch_lines();
3186 }
3187 $dispachedLines = $object->getDispachedLines(1);
3188 $nbDispachedLines = count($dispachedLines);
3189 if ($nbDispachedLines > 0) {
3190 $hasreception = 1;
3191 }
3192 }
3193
3194 if (in_array($object->status, array(3, 4, 5))) {
3195 if (isModEnabled("supplier_order") && $usercanreceive) {
3196 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fourn/commande/dispatch.php?id='.$object->id.'">'.$labelofbutton.'</a></div>';
3197 } else {
3198 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$labelofbutton.'</a></div>';
3199 }
3200 }
3201 }
3202
3204 if ($usercanorder) {
3205 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=createorder&token='.newToken().'#makeorder">'.$langs->trans("MakeOrder").'</a></div>';
3206 } else {
3207 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">'.$langs->trans("MakeOrder").'</a></div>';
3208 }
3209 }
3210
3211 // Classify received (this does not record reception)
3213 if ($usercanreceive) {
3214 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&token='.newToken().'&action=classifyreception#classifyreception">'.$langs->trans("ClassifyReception").'</a></div>';
3215 }
3216 }
3217
3218 // Create bill
3219 //if (isModEnabled('facture')) {
3220 if (isModEnabled("supplier_invoice") && ($object->status >= 2 && $object->status != 7 && $object->billed != 1)) { // statut 2 means approved, 7 means canceled
3221 if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight("supplier_invoice", "creer")) {
3222 print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->socid.'">'.$langs->trans("SupplierOrderCreateBill").'</a>';
3223 }
3224 }
3225 //}
3226
3227 // Classify billed manually (need one invoice if module invoice is on, no condition on invoice if not)
3228 if ($usercancreate && $object->status >= 2 && $object->status != 7 && $object->billed != 1) { // statut 2 means approved
3229 if (!isModEnabled('invoice')) {
3230 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled&token='.newToken().'">'.$langs->trans("ClassifyBilled").'</a>';
3231 } else {
3232 if (!empty($object->linkedObjectsIds['invoice_supplier']) || (empty($object->linkedObjectsIds['invoice_supplier']) && !getDolGlobalInt('SUPPLIER_ORDER_DISABLE_CLASSIFY_BILLED_FROM_SUPPLIER_ORDER'))) {
3233 if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight("supplier_invoice", "creer")) {
3234 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled&token='.newToken().'">'.$langs->trans("ClassifyBilled").'</a>';
3235 }
3236 } else {
3237 print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NeedAtLeastOneInvoice")).'">'.$langs->trans("ClassifyBilled").'</a>';
3238 }
3239 }
3240 }
3241
3242 // Classify unbilled manually
3243 if ($usercancreate && $object->billed > 0 && $object->status > $object::STATUS_DRAFT) {
3244 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifyunbilled&token='.newToken().'">'.$langs->trans("ClassifyUnbilled").'</a>';
3245 }
3246
3247 // Clone
3248 if ($usercancreate) {
3249 print dolGetButtonAction($langs->trans("ToClone"), $langs->trans("ToClone"), 'clone', $_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&token='.newToken().'&object=order', '', true, array('attr' => array('class' => 'reposition')));
3250 }
3251
3252 // Cancel
3254 if ($usercanorder) {
3255 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=cancel&amp;token='.newToken().'">'.$langs->trans("CancelOrder").'</a>';
3256 }
3257 }
3258
3259 // Delete
3260 if (!empty($usercandelete)) {
3261 if ($hasreception) {
3262 print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("ReceptionExist").'">'.$langs->trans("Delete").'</a>';
3263 } else {
3264 print dolGetButtonAction($langs->trans("Delete"), $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), '', true, array('attr' => array('class' => 'reposition')))."\n";
3265 }
3266 }
3267 }
3268
3269 print "</div>";
3270 }
3271
3272 if ($usercanorder && $object->status == CommandeFournisseur::STATUS_ACCEPTED && $action == 'createorder') {
3273 // Set status to ordered (action=commande)
3274 print '<!-- form to record supplier order -->'."\n";
3275 print '<form name="commande" id="makeorder" action="card.php?id='.$object->id.'&amp;action=commande" method="POST">';
3276
3277 print '<input type="hidden" name="token" value="'.newToken().'">';
3278 print '<input type="hidden" name="action" value="commande">';
3279 print load_fiche_titre($langs->trans("ToOrder"), '', '');
3280 print '<table class="noborder centpercent">';
3281 //print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("ToOrder").'</td></tr>';
3282 print '<tr><td class="fieldrequired">'.$langs->trans("OrderDate").'</td><td>';
3283 $date_com = dol_mktime(GETPOSTINT('rehour'), GETPOSTINT('remin'), GETPOSTINT('resec'), GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
3284 print $form->selectDate($date_com ?: '', '', 0, 0, 0, "commande", 1, 1);
3285 print '</td></tr>';
3286
3287 // Force mandatory order method
3288 print '<tr><td class="fieldrequired">'.$langs->trans("OrderMode").'</td><td>';
3289 $formorder->selectInputMethod(GETPOST('methodecommande'), "methodecommande", 1);
3290 print '</td></tr>';
3291
3292 print '<tr><td>'.$langs->trans("Comment").'</td><td><input class="quatrevingtpercent" type="text" name="comment" value="'.GETPOST('comment').'"></td></tr>';
3293
3294 print '<tr><td class="center" colspan="2">';
3295 print '<input type="submit" name="makeorder" class="button" value="'.$langs->trans("ToOrder").'">';
3296 print ' &nbsp; &nbsp; ';
3297 print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
3298 print '</td></tr>';
3299 print '</table>';
3300
3301 print '</form>';
3302 print "<br>";
3303 }
3304
3305 // Select mail models is same action as presend
3306 if (GETPOST('modelselected')) {
3307 $action = 'presend';
3308 }
3309
3310 if ($action != 'createorder' && $action != 'presend') {
3311 print '<div class="fichecenter"><div class="fichehalfleft">';
3312
3313 // Generated documents
3314 $objref = dol_sanitizeFileName($object->ref);
3315 $file = getMultidirOutput($object).'/'.$objref.'/'.$objref.'.pdf';
3316 $relativepath = $objref.'/'.$objref.'.pdf';
3317 $filedir = getMultidirOutput($object).'/'.$objref;
3318 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
3319 $genallowed = $usercanread;
3320 $delallowed = $usercancreate;
3321 $modelpdf = (!empty($object->model_pdf) ? $object->model_pdf : (!getDolGlobalString('COMMANDE_SUPPLIER_ADDON_PDF') ? '' : $conf->global->COMMANDE_SUPPLIER_ADDON_PDF));
3322
3323 print $formfile->showdocuments('commande_fournisseur', $objref, $filedir, $urlsource, (int) $genallowed, (int) $delallowed, $modelpdf, 1, 0, 0, 0, 0, '', '', '', $object->thirdparty->default_lang, '', $object);
3324 $somethingshown = $formfile->numoffiles;
3325
3326 // Show links to link elements
3327 $tmparray = $form->showLinkToObjectBlock($object, array(), array('supplier_order', 'order_supplier'), 1);
3328 $linktoelem = $tmparray['linktoelem'];
3329 $htmltoenteralink = $tmparray['htmltoenteralink'];
3330 print $htmltoenteralink;
3331
3332 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
3333
3334 print '</div><div class="fichehalfright">';
3335
3336 if ($action == 'classifyreception') {
3338 // Set status to received (action=livraison)
3339 print '<!-- form to record purchase order received -->'."\n";
3340 print '<form id="classifyreception" action="card.php?id='.$object->id.'" method="post">';
3341 print '<input type="hidden" name="token" value="'.newToken().'">';
3342 print '<input type="hidden" name="action" value="livraison">';
3343 print load_fiche_titre($langs->trans("Receive"), '', '');
3344
3345 print '<table class="noborder centpercent">';
3346 //print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Receive").'</td></tr>';
3347 print '<tr><td>'.$langs->trans("DeliveryDate").'</td><td>';
3348 $datepreselected = dol_now();
3349 print $form->selectDate($datepreselected, '', 1, 1, 0, "commande", 1, 1);
3350 print "</td></tr>\n";
3351
3352 print '<tr><td class="fieldrequired">'.$langs->trans("Delivery")."</td><td>\n";
3353 $liv = array();
3354 $liv[''] = '&nbsp;';
3355 $liv['tot'] = $langs->trans("CompleteOrNoMoreReceptionExpected");
3356 $liv['par'] = $langs->trans("PartialWoman");
3357 $liv['nev'] = $langs->trans("NeverReceived");
3358 $liv['can'] = $langs->trans("Canceled");
3359
3360 print $form->selectarray("type", $liv);
3361
3362 print '</td></tr>';
3363 print '<tr><td>'.$langs->trans("Comment").'</td><td><input class="quatrevingtpercent" type="text" name="comment"></td></tr>';
3364 print '<tr><td class="center" colspan="2">';
3365 print '<input type="submit" name="receive" class="button" value="'.$langs->trans("Receive").'">';
3366 print ' &nbsp; &nbsp; ';
3367 print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
3368 print '</td></tr>';
3369 print "</table>\n";
3370 print "</form>\n";
3371 print "<br>";
3372 }
3373 }
3374
3375 // List of actions on element
3376 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
3377 $formactions = new FormActions($db);
3378 $somethingshown = $formactions->showactions($object, 'order_supplier', $socid, 1, 'listaction'.($genallowed ? 'largetitle' : ''));
3379
3380 print '</div></div>';
3381 }
3382
3383 // Presend form
3384 $modelmail = 'order_supplier_send';
3385 $defaulttopic = 'SendOrderRef';
3386 $diroutput = getMultidirOutput($object);
3387 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO';
3388 $trackid = 'sord'.$object->id;
3389
3390 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
3391 }
3392}
3393
3394// End of page
3395llxFooter();
3396$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
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 predefined suppliers products.
const STATUS_RECEIVED_PARTIALLY
Received partially.
const STATUS_VALIDATED
Validated status.
const STATUS_RECEIVED_COMPLETELY
Received completely.
const STATUS_ORDERSENT
Order sent, shipment on process.
Class to manage line orders.
Class to manage a WYSIWYG editor.
Class to manage warehouses.
Class to manage standard extra fields.
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 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.
Class to manage the table of subscription to notifications.
Class ProductCombination Used to represent the relation between a product and one of its variants.
Class to manage predefined suppliers products.
Class to manage products or services.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class for Target.
Class to manage translations.
Class to manage Dolibarr users.
global $mysoc
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.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
$date_start
Variables from include:
ordersupplier_prepare_head(CommandeFournisseur $object)
Prepare array with list of tabs.
dol_now($mode='gmt')
Return date for now.
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...
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
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.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.: VAT NPR in France)
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...
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular VAT rate, when selling a product with vat $vatrate,...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
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.
Definition html.lib.php:540
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:738
dol_htmloutput_events($disabledoutputofmessages=0)
Print formatted messages to output (Used to show messages on html output).
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Definition html.lib.php:181
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
Check permissions of a user to show a page and an object.