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