dolibarr 25.0.0-alpha
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005 Eric Seigne <eric.seigne@ryxeo.com>
5 * Copyright (C) 2005-2016 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2010-2015 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2011-2022 Philippe Grand <philippe.grand@atoo-net.com>
8 * Copyright (C) 2012-2016 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
10 * Copyright (C) 2014 Ion Agorria <ion@agorria.com>
11 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
13 * Copyright (C) 2022-2026 Charlene Benke <charlene@patas-monkey.com>
14 * Copyright (C) 2023 Joachim Kueter <git-jk@bloxera.com>
15 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
16 * Copyright (C) 2024 Nick Fragoulis
17 * Copyright (C) 2025-2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
18 * Copyright (C) 2026 William Mead <william@m34d.com>
19 *
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 if ($socid > 0) { // external user
2081 $projSocFilter = $socid;
2082 } elseif ((int) $socid == 0 || getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS')) {
2083 $projSocFilter = -1;
2084 } else {
2085 $projSocFilter = $socid;
2086 }
2087 print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects($projSocFilter, $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
2088 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>';
2089 print '</td></tr>';
2090 }
2091
2092 // Incoterms
2093 if (isModEnabled('incoterm')) {
2094 $fkincoterms = (!empty($object->fk_incoterms) ? $object->fk_incoterms : ($socid > 0 ? $societe->fk_incoterms : ''));
2095 $locincoterms = (!empty($object->location_incoterms) ? $object->location_incoterms : ($socid > 0 ? $societe->location_incoterms : ''));
2096 print '<tr>';
2097 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $object->label_incoterms, 1).'</label></td>';
2098 print '<td class="maxwidthonsmartphone">';
2099 print img_picto('', 'incoterm', 'class="pictofixedwidth"');
2100 print $form->select_incoterms($fkincoterms, $locincoterms);
2101 print '</td></tr>';
2102 }
2103
2104 // Multicurrency
2105 if (isModEnabled("multicurrency")) {
2106 print '<tr>';
2107 print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
2108 print '<td class="maxwidthonsmartphone">';
2109 print img_picto('', 'currency', 'class="pictofixedwidth"');
2110 print $form->selectMultiCurrency($currency_code, 'multicurrency_code');
2111 print '</td></tr>';
2112 }
2113
2114 // Categories
2115 if (isModEnabled("category")) {
2116 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
2117 print $form->selectCategories(Categorie::TYPE_SUPPLIER_ORDER, 'categories', $object);
2118 print "</td></tr>";
2119 }
2120
2121 print '<tr><td>'.$langs->trans('NotePublic').'</td>';
2122 print '<td>';
2123 $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%');
2124 print $doleditor->Create(1);
2125 print '</td>';
2126 //print '<textarea name="note_public" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea>';
2127 print '</tr>';
2128
2129 print '<tr><td>'.$langs->trans('NotePrivate').'</td>';
2130 print '<td>';
2131 $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%');
2132 print $doleditor->Create(1);
2133 print '</td>';
2134 //print '<td><textarea name="note_private" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
2135 print '</tr>';
2136
2137 if (!empty($origin) && !empty($originid) && is_object($objectsrc) && $classname !== null) {
2138 print "\n<!-- ".$classname." info -->";
2139 print "\n";
2140 print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
2141 print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
2142 print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
2143 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
2144 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
2145
2146 $newclassname = $classname;
2147 print '<tr><td>'.$langs->trans($newclassname).'</td><td>'.$objectsrc->getNomUrl(1, 'supplier').'</td></tr>';
2148 print '<tr><td>'.$langs->trans('AmountHT').'</td><td>'.price($objectsrc->total_ht).'</td></tr>';
2149 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($objectsrc->total_tva)."</td></tr>";
2150 if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0) { // Localtax1 RE
2151 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax1)."</td></tr>";
2152 }
2153
2154 if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) { // Localtax2 IRPF
2155 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax2)."</td></tr>";
2156 }
2157
2158 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($objectsrc->total_ttc)."</td></tr>";
2159
2160 if (isModEnabled("multicurrency")) {
2161 print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td>'.price($objectsrc->multicurrency_total_ht).'</td></tr>';
2162 print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td>'.price($objectsrc->multicurrency_total_tva).'</td></tr>';
2163 print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td>'.price($objectsrc->multicurrency_total_ttc).'</td></tr>';
2164 }
2165 }
2166
2167 // Other options
2168 $parameters = array();
2169 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2170 print $hookmanager->resPrint;
2171
2172 if (empty($reshook)) {
2173 if (getDolGlobalString('THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_SUPPLIER_ORDER') && !empty($societe->id)) {
2174 // copy from thirdparty
2175 $tpExtrafields = new ExtraFields($db);
2176 $tpExtrafieldLabels = $tpExtrafields->fetch_name_optionals_label($societe->table_element);
2177 if ($societe->fetch_optionals() > 0) {
2178 $object->array_options = array_merge($object->array_options, $societe->array_options);
2179 }
2180 }
2181
2182 print $object->showOptionals($extrafields, 'create');
2183 }
2184
2185 // Bouton "Create Draft"
2186 print "</table>\n";
2187 }
2188 print dol_get_fiche_end();
2189
2190 print $form->buttonsSaveCancel("CreateDraft");
2191
2192 // Show origin lines
2193 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
2194 $title = $langs->trans('ProductsAndServices');
2195 print load_fiche_titre($title);
2196
2197 print '<div class="div-table-responsive-no-min">';
2198 print '<table class="noborder centpercent">';
2199
2200 $selectedLines = array();
2201
2202 $objectsrc->printOriginLinesList('', $selectedLines);
2203
2204 print '</table>';
2205 print '</div>';
2206 }
2207 print "</form>\n";
2208} elseif (!empty($object->id)) {
2209 // view
2210 $result = $object->fetch($id, $ref);
2211 $object->fetch_thirdparty();
2212
2213 $num = 0;
2214
2215 $societe = $object->thirdparty;
2216
2217 $author = new User($db);
2218 $author->fetch($object->user_author_id);
2219
2220 $head = ordersupplier_prepare_head($object);
2221
2222 $title = $langs->trans("SupplierOrder");
2223 print dol_get_fiche_head($head, 'card', $title, -1, 'order', 0, '', '', 0, '', 1);
2224
2225
2226 $formconfirm = '';
2227
2228 // Confirmation of deletion of order
2229 if ($action == 'delete') {
2230 $arrayAjouts = array();
2231 $heightModal = 0;
2232 $widthModal = 500;
2233
2234 // TODO We must find line already recorded in stock, not lines dispatched (stock recording may not have been done
2235 // even if dispatched in llx_receptiondet_batch).
2236 // For example to know if stock movement were already record, we may look at stock movements in llx_stock_movement linked to a reception
2237 // that is linked to the purchase order.
2238 /* $dispatchedLines = $object->getStockMovementLines();
2239
2240 if (!empty($dispatchedLines)) {
2241 $arrayAjouts = array(
2242 array(
2243 'type' => 'other',
2244 'value' => img_warning() . " " . $langs->trans('ExistingDipatchLines')
2245 ),
2246 array('type' => 'separator'),
2247 array(
2248 'type' => 'select',
2249 'id' => 'stockDeleteSelect',
2250 'name' => 'stockDelete',
2251 'label' => $langs->trans('ConfirmDeleteDispatchedLines'),
2252 'values' => array(1 => $langs->trans('Yes'), 0 => $langs->trans('No')),
2253 'select_show_empty' => false
2254 )
2255 );
2256 $heightModal = 300;
2257 $widthModal = "70%";
2258 }
2259 */
2260
2261 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.((int) $object->id), $langs->trans('DeleteOrder'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', $arrayAjouts, 0, 2, $heightModal, $widthModal);
2262 }
2263
2264 // Clone confirmation
2265 if ($action == 'clone') {
2266 $filter = '(s.fournisseur:=:1)';
2267 // Create an array for form
2268 $formquestion = array(
2269 array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter))
2270 );
2271 // Payment incomplete. Requesting reason: discount or other?
2272 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
2273 }
2274
2275 // Confirm validation
2276 if ($action == 'valid') {
2277 $object->date_commande = dol_now();
2278
2279 // We check if number is temporary number
2280 if (preg_match('/^[\‍(]?PROV/i', (string) $object->ref) || empty($object->ref)) { // empty should not happened, but when it occurs, the test save life
2281 $newref = $object->getNextNumRef($object->thirdparty);
2282 } else {
2283 $newref = (string) $object->ref;
2284 }
2285
2286 if ($newref < 0) {
2287 setEventMessages($object->error, $object->errors, 'errors');
2288 $action = '';
2289 } else {
2290 $text = $langs->trans('ConfirmValidateOrder', $newref);
2291 if (isModEnabled('notification')) {
2292 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2293 $notify = new Notify($db);
2294 $text .= '<br>';
2295 $text .= $notify->confirmMessage('ORDER_SUPPLIER_VALIDATE', $object->socid, $object);
2296 }
2297
2298 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_valid', '', 0, 1);
2299 }
2300 }
2301
2302 // Confirm approval
2303 if ($action == 'approve' || $action == 'approve2') {
2304 $qualified_for_stock_change = 0;
2305 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2306 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2307 } else {
2308 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2309 }
2310
2311 $formquestion = array();
2312 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') && $qualified_for_stock_change) {
2313 $langs->load("stocks");
2314 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2315 $formproduct = new FormProduct($db);
2316 $forcecombo = 0;
2317 if ($conf->browser->name == 'ie') {
2318 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
2319 }
2320 $formquestion = array(
2321 //'text' => $langs->trans("ConfirmClone"),
2322 //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
2323 //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
2324 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockIncrease"), 'value' => $formproduct->selectWarehouses(GETPOSTINT('idwarehouse'), 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
2325 );
2326 }
2327 $text = $langs->trans("ConfirmApproveThisOrder", $object->ref);
2328 if (isModEnabled('notification')) {
2329 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2330 $notify = new Notify($db);
2331 $text .= '<br>';
2332 $text .= $notify->confirmMessage('ORDER_SUPPLIER_APPROVE', $object->socid, $object);
2333 }
2334
2335 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ApproveThisOrder"), $text, "confirm_".$action, $formquestion, 1, 1, 240);
2336 }
2337
2338 // Confirmation of disapproval
2339 if ($action == 'refuse') {
2340 $formquestion = array(
2341 array(
2342 'type' => 'text',
2343 'name' => 'refuse_note',
2344 'label' => $langs->trans("Reason"),
2345 'value' => '',
2346 'morecss' => 'minwidth300'
2347 )
2348 );
2349 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("DenyingThisOrder"), $langs->trans("ConfirmDenyingThisOrder", $object->ref), "confirm_refuse", $formquestion, 0, 1);
2350 }
2351
2352 // Confirmation of cancellation
2353 if ($action == 'cancel') {
2354 $formquestion = array(
2355 array(
2356 'type' => 'text',
2357 'name' => 'cancel_note',
2358 'label' => $langs->trans("Reason"),
2359 'value' => '',
2360 'morecss' => 'minwidth300'
2361 )
2362 );
2363 if (isModEnabled('notification')) {
2364 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2365 $notify = new Notify($db);
2366 $text = '';
2367 $text .= '<br>';
2368 $text .= $notify->confirmMessage('ORDER_SUPPLIER_CANCEL', $object->socid, $object);
2369 }
2370 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("Cancel"), $langs->trans("ConfirmCancelThisOrder", $object->ref), "confirm_cancel", $formquestion, 0, 1);
2371 }
2372
2373 // Confirmation de l'envoi de la commande
2374 if ($action == 'commande') {
2375 $formquestion = array();
2376 $date_com = dol_mktime(GETPOSTINT('rehour'), GETPOSTINT('remin'), GETPOSTINT('resec'), GETPOSTINT("remonth"), GETPOSTINT("reday"), GETPOSTINT("reyear"));
2377 if (isModEnabled('notification')) {
2378 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2379 $notify = new Notify($db);
2380 $text = '';
2381 $text .= '<br>';
2382 $text .= $notify->confirmMessage('ORDER_SUPPLIER_SUBMIT', $object->socid, $object);
2383 }
2384 if (isModEnabled('webhook')) {
2385 require_once DOL_DOCUMENT_ROOT.'/webhook/class/target.class.php';
2386 $targetstatic = new Target($db);
2387 if ($targetstatic->isTriggerCodeManualTarget('ORDER_SUPPLIER_SUBMIT') > 0) {
2388 $formquestion[] = array('type' => 'checkbox', 'name' => 'manual_trigger_send', 'label' => $langs->trans("QuestionSendManualTrigger"));
2389 }
2390 }
2391 $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);
2392 }
2393
2394 // Confirmation to delete line
2395 if ($action == 'ask_deleteline') {
2396 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
2397 }
2398
2399 // Subtotal line form
2400 if ($action == 'add_title_line') {
2401 $langs->load('subtotals');
2402 $type = 'title';
2403 $depth_array = $object->getPossibleLevels($langs);
2404 require DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_create.tpl.php';
2405 } elseif ($action == 'add_subtotal_line') {
2406 $langs->load('subtotals');
2407 $type = 'subtotal';
2408 $titles = $object->getPossibleTitles();
2409 require DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_create.tpl.php';
2410 }
2411
2412 // Call Hook formConfirm
2413 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
2414 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2415 if (empty($reshook)) {
2416 $formconfirm .= $hookmanager->resPrint;
2417 } elseif ($reshook > 0) {
2418 $formconfirm = $hookmanager->resPrint;
2419 }
2420
2421 // Print form confirm
2422 print $formconfirm;
2423
2424
2425 // Supplier order card
2426
2427 $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
2428
2429 $morehtmlref = '<div class="refidno">';
2430 // Ref supplier
2431 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, (int) $usercancreate, 'string', '', 0, 1);
2432 $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);
2433 // Thirdparty
2434 $morehtmlref .= '<br>';
2435 if (getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') && !empty($usercancreate) && $action == 'edit_thirdparty') {
2436 $morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
2437 $morehtmlref .= '<input type="hidden" name="action" value="set_thirdparty">';
2438 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
2439 $filter = '(s.fournisseur:=:1)';
2440 $morehtmlref .= $form->select_company($object->thirdparty->id, 'new_socid', $filter, '', 0, 0, array(), 0, 'minwidth300');
2441 $morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
2442 $morehtmlref .= '</form>';
2443 }
2444 if (!getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') || $action != 'edit_thirdparty') {
2445 if (getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') && $object->status == CommandeFournisseur::STATUS_DRAFT) {
2446 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=edit_thirdparty&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetThirdParty')).'</a>';
2447 }
2448 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'supplier');
2449 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
2450 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
2451 }
2452 }
2453
2454 // Project
2455 if (isModEnabled('project')) {
2456 $langs->load("projects");
2457 $morehtmlref .= '<br>';
2458 if ($permissiontoadd) {
2459 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2460 if ($action != 'classify' && $caneditproject) {
2461 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2462 }
2463 $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');
2464 } else {
2465 if (!empty($object->fk_project)) {
2466 $proj = new Project($db);
2467 $proj->fetch($object->fk_project);
2468 $morehtmlref .= $proj->getNomUrl(1);
2469 if ($proj->title) {
2470 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2471 }
2472 }
2473 }
2474 }
2475 $morehtmlref .= '</div>';
2476
2477
2478 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
2479
2480 // Call Hook tabContentViewSupplierOrder
2481 $parameters = array();
2482 // Note that $action and $object may be modified by hook
2483 $reshook = $hookmanager->executeHooks('tabContentViewSupplierOrder', $parameters, $object, $action);
2484 if (empty($reshook)) {
2485 print '<div class="fichecenter">';
2486 print '<div class="fichehalfleft">';
2487 print '<div class="underbanner clearboth"></div>';
2488
2489 print '<table class="border tableforfield centpercent">';
2490
2491 // Date
2492 if ($object->methode_commande_id > 0) {
2493 $usehourmin = 0;
2494 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2495 $usehourmin = 1;
2496 }
2497 print '<tr><td class="titlefield">'.$langs->trans("Date").'</td><td>';
2498 print $object->date_commande ? dol_print_date($object->date_commande, $usehourmin ? 'dayhour' : 'day') : '';
2499 if ($object->hasDelay() && !empty($object->delivery_date) && !empty($object->date_commande)) {
2500 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
2501 }
2502 print "</td></tr>";
2503
2504 if ($object->methode_commande) {
2505 print '<tr><td>'.$langs->trans("Method").'</td><td>'.$object->getInputMethod().'</td></tr>';
2506 }
2507 }
2508
2509 // Author
2510 print '<tr><td class="titlefield">'.$langs->trans("AuthorRequest").'</td>';
2511 print '<td>'.$author->getNomUrl(-1, '', 0, 0, 0).'</td>';
2512 print '</tr>';
2513
2514 // Relative and absolute discounts
2515 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
2516 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2517 $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
2518 } else {
2519 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
2520 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
2521 }
2522
2523 $absolute_discount = $societe->getAvailableDiscounts(null, $filterabsolutediscount, 0, 1);
2524 $absolute_creditnote = $societe->getAvailableDiscounts(null, $filtercreditnote, 0, 1);
2525 $absolute_discount = price2num($absolute_discount, 'MT');
2526 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
2527
2528 print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td>';
2529
2530 $thirdparty = $societe;
2531 $discount_type = 1;
2532 $backtopage = urlencode($_SERVER["PHP_SELF"].'?id='.$object->id);
2533 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2534
2535 print '</td></tr>';
2536
2537 // Default terms of the settlement
2538 $langs->load('bills');
2539 print '<tr><td class="nowrap">';
2540 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
2541 print $langs->trans('PaymentConditions');
2542 print '<td>';
2543 if ($action != 'editconditions' && $permissiontoadd) {
2544 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>';
2545 }
2546 print '</tr></table>';
2547 print '</td><td>';
2548 if ($action == 'editconditions') {
2549 $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent);
2550 } else {
2551 $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, (string) $object->cond_reglement_id, 'none', 1, '', 1, $object->deposit_percent);
2552 }
2553 print "</td>";
2554 print '</tr>';
2555
2556 // Mode of payment
2557 $langs->load('bills');
2558 print '<tr><td class="nowrap">';
2559 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
2560 print $langs->trans('PaymentMode');
2561 print '</td>';
2562 if ($action != 'editmode' && $permissiontoadd) {
2563 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>';
2564 }
2565 print '</tr></table>';
2566 print '</td><td>';
2567 if ($action == 'editmode') {
2568 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', 'DBIT', 1, 1);
2569 } else {
2570 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'none');
2571 }
2572 print '</td></tr>';
2573
2574 // Bank Account
2575 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER') && isModEnabled("bank")) {
2576 print '<tr><td class="nowrap">';
2577 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
2578 print $langs->trans('BankAccount');
2579 print '<td>';
2580 if ($action != 'editbankaccount' && $permissiontoadd) {
2581 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>';
2582 }
2583 print '</tr></table>';
2584 print '</td><td>';
2585 if ($action == 'editbankaccount') {
2586 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'fk_account', 1);
2587 } else {
2588 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'none');
2589 }
2590 print '</td>';
2591 print '</tr>';
2592 }
2593
2594 // Delivery delay (in days)
2595 print '<tr>';
2596 print '<td>'.$langs->trans('NbDaysToDelivery').'&nbsp;'.img_picto($langs->trans('DescNbDaysToDelivery'), 'info', 'style="cursor:help"').'</td>';
2597 print '<td>'.$object->getMaxDeliveryTimeDay($langs).'</td>';
2598 print '</tr>';
2599
2600 // Delivery date planned
2601 print '<tr><td>';
2602 print '<table class="nobordernopadding centpercent"><tr><td>';
2603 print $langs->trans('DateDeliveryPlanned');
2604 print '</td>';
2605 if ($action != 'editdate_livraison') {
2606 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>';
2607 }
2608 print '</tr></table>';
2609 print '</td><td>';
2610 if ($action == 'editdate_livraison') {
2611 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2612 print '<input type="hidden" name="token" value="'.newToken().'">';
2613 print '<input type="hidden" name="action" value="setdate_livraison">';
2614 $usehourmin = 0;
2615 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2616 $usehourmin = 1;
2617 }
2618 print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', $usehourmin, $usehourmin, 0, "setdate_livraison");
2619 print '<input type="submit" class="button button-edit smallpaddingimp valign middle" value="'.$langs->trans('Modify').'">';
2620 print '</form>';
2621 } else {
2622 $usehourmin = 'day';
2623 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2624 $usehourmin = 'dayhour';
2625 }
2626 print $object->delivery_date ? dol_print_date($object->delivery_date, $usehourmin) : '&nbsp;';
2627 if ($object->hasDelay() && !empty($object->delivery_date) && ($object->status == $object::STATUS_ORDERSENT || $object->status == $object::STATUS_RECEIVED_PARTIALLY)) {
2628 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
2629 }
2630 }
2631 print '</td></tr>';
2632
2633 // Incoterms
2634 if (isModEnabled('incoterm')) {
2635 print '<tr><td>';
2636 print '<table class="nobordernopadding centpercent"><tr><td>';
2637 print $langs->trans('IncotermLabel');
2638 print '<td><td class="right">';
2639 if ($usercancreate) {
2640 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?id='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
2641 } else {
2642 print '&nbsp;';
2643 }
2644 print '</td></tr></table>';
2645 print '</td>';
2646 print '<td>';
2647 if ($action != 'editincoterm') {
2648 print $form->textwithpicto(dol_escape_htmltag($object->display_incoterms()), $object->label_incoterms, 1);
2649 } else {
2650 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
2651 }
2652 print '</td></tr>';
2653 }
2654
2655 // Tags-Categories
2656 if (isModEnabled('category')) {
2657 print '<tr><td>';
2658 print '<table class="nobordernopadding centpercent"><tr><td>';
2659 print $langs->trans("Categories");
2660 print '<td><td class="right">';
2661 if ($usercancreate) {
2662 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?id='.$object->id.'&action=edittags&token='.newToken().'">'.img_edit().'</a>';
2663 } else {
2664 print '&nbsp;';
2665 }
2666 print '</td></tr></table>';
2667 print '</td>';
2668 print '<td>';
2669 if ($action == 'edittags') {
2670 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
2671 print '<input type="hidden" name="action" value="settags">';
2672 print '<input type="hidden" name="token" value="'.newToken().'">';
2673 print $form->selectCategories(Categorie::TYPE_SUPPLIER_ORDER, 'categories', $object);
2674 print '<input type="submit" class="button valignmiddle smallpaddingimp" value="'.$langs->trans("Modify").'">';
2675 print '</form>';
2676 } else {
2677 print $form->showCategories($object->id, Categorie::TYPE_SUPPLIER_ORDER, 1);
2678 }
2679 print "</td></tr>";
2680 }
2681
2682 // Other attributes
2683 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2684
2685 print '</table>';
2686
2687 print '</div>';
2688 print '<div class="fichehalfright">';
2689 print '<div class="underbanner clearboth"></div>';
2690
2691 print '<table class="border tableforfield centpercent">';
2692
2693 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
2694
2695 print '<tr>';
2696 // Amount HT
2697 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
2698 print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2699 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2700 // Multicurrency Amount HT
2701 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2702 }
2703 print '</tr>';
2704
2705 print '<tr>';
2706 // Amount VAT
2707 print '<td class="titlefieldmiddle">' . $langs->trans('AmountVAT') . '</td>';
2708 print '<td class="nowrap amountcard right">' . price($object->total_tva, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2709 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2710 // Multicurrency Amount VAT
2711 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2712 }
2713 print '</tr>';
2714
2715 // Amount Local Taxes
2716 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) {
2717 print '<tr>';
2718 print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
2719 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2720 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2721 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2722 }
2723 print '</tr>';
2724
2725 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
2726 print '<tr>';
2727 print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
2728 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2729 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2730 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2731 }
2732 print '</tr>';
2733 }
2734 }
2735
2736 $alert = '';
2737 if (getDolGlobalString('ORDER_MANAGE_MIN_AMOUNT') && $object->total_ht < $object->thirdparty->supplier_order_min_amount) {
2738 $alert = ' ' . img_warning($langs->trans('OrderMinAmount') . ': ' . price($object->thirdparty->supplier_order_min_amount));
2739 }
2740
2741 print '<tr>';
2742 // Amount TTC
2743 print '<td>' . $langs->trans('AmountTTC') . '</td>';
2744 print '<td class="nowrap amountcard right">' . price($object->total_ttc, 0, $langs, 0, -1, -1, $conf->currency) . $alert . '</td>';
2745 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2746 // Multicurrency Amount TTC
2747 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ttc, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2748 }
2749 print '</tr>';
2750
2751 print '</table>';
2752
2753 // Margin Infos
2754 /*if (isModEnabled('margin')) {
2755 $formmargin->displayMarginInfos($object);
2756 }*/
2757
2758
2759 print '</div>';
2760 print '</div>';
2761
2762 print '<div class="clearboth"></div><br>';
2763
2764 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
2765 $blocname = 'contacts';
2766 $title = $langs->trans('ContactsAddresses');
2767 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2768 }
2769
2770 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
2771 $blocname = 'notes';
2772 $title = $langs->trans('Notes');
2773 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2774 }
2775
2776 /*
2777 * Lines
2778 */
2779 //$result = $object->getLinesArray();
2780
2781
2782 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
2783 <input type="hidden" name="token" value="'.newToken().'">
2784 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
2785 <input type="hidden" name="mode" value="">
2786 <input type="hidden" name="page_y" value="">
2787 <input type="hidden" name="id" value="'.$object->id.'">
2788 <input type="hidden" name="socid" value="'.$societe->id.'">
2789 ';
2790
2791 if (!empty($conf->use_javascript_ajax) && $object->status == CommandeFournisseur::STATUS_DRAFT) {
2792 if (isModEnabled('subtotals')) {
2793 include DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_ajaxrow.tpl.php';
2794 } else {
2795 include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
2796 }
2797 }
2798
2799 print '<div class="div-table-responsive-no-min">';
2800 print '<table id="tablelines" class="noborder noshadow centpercent">';
2801
2802 // Add free products/services form
2803 global $forceall, $senderissupplier, $dateSelector, $inputalsopricewithtax;
2804 $forceall = 1;
2805 $dateSelector = 0;
2806 $inputalsopricewithtax = 1;
2807 $senderissupplier = 2; // $senderissupplier=2 is same than 1 but disable test on minimum qty and disable autofill qty with minimum.
2808 if (getDolGlobalInt('SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY')) {
2809 $senderissupplier = getDolGlobalInt('SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY');
2810 }
2811
2812 // Show object lines
2813 if (!empty($object->lines)) {
2814 $object->printObjectLines($action, $object->thirdparty, $mysoc, $lineid, 1);
2815 }
2816
2817 $num = count($object->lines);
2818
2819 // Form to add new line
2820 if ($object->status == CommandeFournisseur::STATUS_DRAFT && $usercancreate) {
2821 if ($action != 'editline') {
2822 // Add free products/services
2823
2824 $parameters = array();
2825 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2826 if ($reshook < 0) {
2827 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2828 }
2829 if (empty($reshook)) {
2830 $object->formAddObjectLine(1, $societe, $mysoc);
2831 }
2832 }
2833 }
2834 print '</table>';
2835 print '</div>';
2836 print '</form>';
2837 }
2838
2839 print dol_get_fiche_end();
2840
2845 if ($user->socid == 0 && $action != 'delete') {
2846 if ($action != 'createorder' && $action != 'presend' && $action != 'editline') {
2847 print '<div class="tabsAction">';
2848
2849 $parameters = array();
2850 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
2851 // modified by hook
2852 if (empty($reshook)) {
2853 $object->fetchObjectLinked(); // Links are used to show or not button, so we load them now.
2854
2855 // Subtotal
2856 if ($object->status == CommandeFournisseur::STATUS_DRAFT && isModEnabled('subtotals') && getDolGlobalString('SUBTOTAL_TITLE_'.strtoupper($object->element))) {
2857 $langs->load('subtotals');
2858
2859 $url_button = array();
2860
2861 $url_button[] = array(
2862 'lang' => 'subtotals',
2863 'enabled' => $object->status == CommandeFournisseur::STATUS_DRAFT,
2864 'perm' => (bool) $usercancreate,
2865 'label' => $langs->trans('AddTitleLine'),
2866 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_title_line'], true)
2867 );
2868
2869 $url_button[] = array(
2870 'lang' => 'subtotals',
2871 'enabled' => $object->status == CommandeFournisseur::STATUS_DRAFT,
2872 'perm' => (bool) $usercancreate,
2873 'label' => $langs->trans('AddSubtotalLine'),
2874 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_subtotal_line'], true)
2875 );
2876
2877 print dolGetButtonAction('', $langs->trans('Subtotal'), 'default', $url_button, '', true);
2878 }
2879 // Validate
2880 if ($object->status == 0) {
2881 if ($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.'&action=valid&token='.newToken().'">';
2889 print $tmpbuttonlabel;
2890 print '</a>';
2891 }
2892 } else {
2893 $langs->load("errors");
2894 print dolGetButtonAction($langs->trans("ErrorObjectMustHaveLinesToBeValidated", $object->ref), $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"] . '?action=validate&token=' . newToken() . '&id=' . $object->id, (string) $object->id, -1);
2895 }
2896 }
2897 // Create event
2898 /*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.
2899 {
2900 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>';
2901 }*/
2902
2903 // Modify
2905 if ($usercanorder) {
2906 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("Modify").'</a>';
2907 }
2908 }
2909
2910 // Approve
2912 if ($usercanapprove) {
2913 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)) {
2914 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("FirstApprovalAlreadyDone")).'">'.$langs->trans("ApproveOrder").'</a>';
2915 } else {
2916 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=approve">'.$langs->trans("ApproveOrder").'</a>';
2917 }
2918 } else {
2919 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("ApproveOrder").'</a>';
2920 }
2921 }
2922
2923 // Second approval (if option SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set)
2924 if (getDolGlobalString('SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED') && $object->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) {
2926 if ($usercanapprovesecond) {
2927 if (!empty($object->user_approve_id2)) {
2928 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("SecondApprovalAlreadyDone")).'">'.$langs->trans("Approve2Order").'</a>';
2929 } else {
2930 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=approve2">'.$langs->trans("Approve2Order").'</a>';
2931 }
2932 } else {
2933 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("Approve2Order").'</a>';
2934 }
2935 }
2936 }
2937
2938 // Refuse
2940 if ($usercanapprove || $usercanapprovesecond) {
2941 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=refuse">'.$langs->trans("RefuseOrder").'</a>';
2942 } else {
2943 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("RefuseOrder").'</a>';
2944 }
2945 }
2946
2947 // Send
2948 if (empty($user->socid)) {
2949 if (in_array($object->status, array(CommandeFournisseur::STATUS_ACCEPTED, 3, 4, 5)) || getDolGlobalString('SUPPLIER_ORDER_SENDBYEMAIL_FOR_ALL_STATUS')) {
2950 if ($usercanorder) {
2951 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle', '');
2952 }
2953 }
2954 }
2955
2956 // Reopen
2957 if (in_array($object->status, array(CommandeFournisseur::STATUS_ACCEPTED))) {
2958 $buttonshown = 0;
2959 if (!$buttonshown && $usercanapprove) {
2960 if (!getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER_ONLY')
2961 || (getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER_ONLY') && $user->id == $object->user_approve_id)) {
2962 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("Disapprove").'</a>';
2963 $buttonshown++;
2964 }
2965 }
2966 if (!$buttonshown && $usercanapprovesecond && getDolGlobalString('SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED')) {
2967 if (!getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER2_ONLY')
2968 || (getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER2_ONLY') && $user->id == $object->user_approve_id2)) {
2969 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("Disapprove").'</a>';
2970 }
2971 }
2972 }
2973 if (in_array($object->status, array(3, 4, 5, 6, 7, 9))) {
2974 if ($usercanorder) {
2975 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("ReOpen").'</a>';
2976 }
2977 }
2978
2979 // Ship
2980 $hasreception = 0;
2981 if (isModEnabled('stock') && (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE'))) {
2982 $labelofbutton = $langs->trans('ReceiveProducts');
2983 if (isModEnabled('reception')) {
2984 $labelofbutton = $langs->trans("CreateReception");
2985 if (!empty($object->linkedObjects['reception'])) {
2986 foreach ($object->linkedObjects['reception'] as $element) {
2987 if ($element->statut >= 0) {
2988 $hasreception = 1;
2989 break;
2990 }
2991 }
2992 }
2993 }
2994
2995 // To avoid delete order with dispatched lines
2996 if (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER')) {
2997 if (empty($object->lines)) {
2998 $object->fetch_lines();
2999 }
3000 $dispachedLines = $object->getDispachedLines(1);
3001 $nbDispachedLines = count($dispachedLines);
3002 if ($nbDispachedLines > 0) {
3003 $hasreception = 1;
3004 }
3005 }
3006
3007 if (in_array($object->status, array(3, 4, 5))) {
3008 if (isModEnabled("supplier_order") && $usercanreceive) {
3009 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fourn/commande/dispatch.php?id='.$object->id.'">'.$labelofbutton.'</a></div>';
3010 } else {
3011 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$labelofbutton.'</a></div>';
3012 }
3013 }
3014 }
3015
3017 if ($usercanorder) {
3018 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>';
3019 } else {
3020 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">'.$langs->trans("MakeOrder").'</a></div>';
3021 }
3022 }
3023
3024 // Classify received (this does not record reception)
3026 if ($usercanreceive) {
3027 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>';
3028 }
3029 }
3030
3031 // Create bill
3032 //if (isModEnabled('facture')) {
3033 if (isModEnabled("supplier_invoice") && ($object->status >= 2 && $object->status != 7 && $object->billed != 1)) { // statut 2 means approved, 7 means canceled
3034 if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight("supplier_invoice", "creer")) {
3035 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>';
3036 }
3037 }
3038 //}
3039
3040 // Classify billed manually (need one invoice if module invoice is on, no condition on invoice if not)
3041 if ($usercancreate && $object->status >= 2 && $object->status != 7 && $object->billed != 1) { // statut 2 means approved
3042 if (!isModEnabled('invoice')) {
3043 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled&token='.newToken().'">'.$langs->trans("ClassifyBilled").'</a>';
3044 } else {
3045 if (!empty($object->linkedObjectsIds['invoice_supplier']) || (empty($object->linkedObjectsIds['invoice_supplier']) && !getDolGlobalInt('SUPPLIER_ORDER_DISABLE_CLASSIFY_BILLED_FROM_SUPPLIER_ORDER'))) {
3046 if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight("supplier_invoice", "creer")) {
3047 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled&token='.newToken().'">'.$langs->trans("ClassifyBilled").'</a>';
3048 }
3049 } else {
3050 print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NeedAtLeastOneInvoice")).'">'.$langs->trans("ClassifyBilled").'</a>';
3051 }
3052 }
3053 }
3054
3055 // Classify unbilled manually
3056 if ($usercancreate && $object->billed > 0 && $object->status > $object::STATUS_DRAFT) {
3057 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifyunbilled&token='.newToken().'">'.$langs->trans("ClassifyUnbilled").'</a>';
3058 }
3059
3060 // Clone
3061 if ($usercancreate) {
3062 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>';
3063 }
3064
3065 // Cancel
3067 if ($usercanorder) {
3068 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=cancel&amp;token='.newToken().'">'.$langs->trans("CancelOrder").'</a>';
3069 }
3070 }
3071
3072 // Delete
3073 if (!empty($usercandelete)) {
3074 if ($hasreception) {
3075 print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("ReceptionExist").'">'.$langs->trans("Delete").'</a>';
3076 } else {
3077 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'">'.$langs->trans("Delete").'</a>';
3078 }
3079 }
3080 }
3081
3082 print "</div>";
3083 }
3084
3085 if ($usercanorder && $object->status == CommandeFournisseur::STATUS_ACCEPTED && $action == 'createorder') {
3086 // Set status to ordered (action=commande)
3087 print '<!-- form to record supplier order -->'."\n";
3088 print '<form name="commande" id="makeorder" action="card.php?id='.$object->id.'&amp;action=commande" method="POST">';
3089
3090 print '<input type="hidden" name="token" value="'.newToken().'">';
3091 print '<input type="hidden" name="action" value="commande">';
3092 print load_fiche_titre($langs->trans("ToOrder"), '', '');
3093 print '<table class="noborder centpercent">';
3094 //print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("ToOrder").'</td></tr>';
3095 print '<tr><td class="fieldrequired">'.$langs->trans("OrderDate").'</td><td>';
3096 $date_com = dol_mktime(GETPOSTINT('rehour'), GETPOSTINT('remin'), GETPOSTINT('resec'), GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
3097 print $form->selectDate($date_com ?: '', '', 0, 0, 0, "commande", 1, 1);
3098 print '</td></tr>';
3099
3100 // Force mandatory order method
3101 print '<tr><td class="fieldrequired">'.$langs->trans("OrderMode").'</td><td>';
3102 $formorder->selectInputMethod(GETPOST('methodecommande'), "methodecommande", 1);
3103 print '</td></tr>';
3104
3105 print '<tr><td>'.$langs->trans("Comment").'</td><td><input class="quatrevingtpercent" type="text" name="comment" value="'.GETPOST('comment').'"></td></tr>';
3106
3107 print '<tr><td class="center" colspan="2">';
3108 print '<input type="submit" name="makeorder" class="button" value="'.$langs->trans("ToOrder").'">';
3109 print ' &nbsp; &nbsp; ';
3110 print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
3111 print '</td></tr>';
3112 print '</table>';
3113
3114 print '</form>';
3115 print "<br>";
3116 }
3117
3118 // Select mail models is same action as presend
3119 if (GETPOST('modelselected')) {
3120 $action = 'presend';
3121 }
3122
3123 if ($action != 'createorder' && $action != 'presend') {
3124 print '<div class="fichecenter"><div class="fichehalfleft">';
3125
3126 // Generated documents
3127 $objref = dol_sanitizeFileName($object->ref);
3128 $file = getMultidirOutput($object).'/'.$objref.'/'.$objref.'.pdf';
3129 $relativepath = $objref.'/'.$objref.'.pdf';
3130 $filedir = getMultidirOutput($object).'/'.$objref;
3131 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
3132 $genallowed = $usercanread;
3133 $delallowed = $usercancreate;
3134 $modelpdf = (!empty($object->model_pdf) ? $object->model_pdf : (!getDolGlobalString('COMMANDE_SUPPLIER_ADDON_PDF') ? '' : $conf->global->COMMANDE_SUPPLIER_ADDON_PDF));
3135
3136 print $formfile->showdocuments('commande_fournisseur', $objref, $filedir, $urlsource, (int) $genallowed, (int) $delallowed, $modelpdf, 1, 0, 0, 0, 0, '', '', '', $object->thirdparty->default_lang, '', $object);
3137 $somethingshown = $formfile->numoffiles;
3138
3139 // Show links to link elements
3140 $tmparray = $form->showLinkToObjectBlock($object, array(), array('supplier_order', 'order_supplier'), 1);
3141 $linktoelem = $tmparray['linktoelem'];
3142 $htmltoenteralink = $tmparray['htmltoenteralink'];
3143 print $htmltoenteralink;
3144
3145 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
3146
3147 print '</div><div class="fichehalfright">';
3148
3149 if ($action == 'classifyreception') {
3151 // Set status to received (action=livraison)
3152 print '<!-- form to record purchase order received -->'."\n";
3153 print '<form id="classifyreception" action="card.php?id='.$object->id.'" method="post">';
3154 print '<input type="hidden" name="token" value="'.newToken().'">';
3155 print '<input type="hidden" name="action" value="livraison">';
3156 print load_fiche_titre($langs->trans("Receive"), '', '');
3157
3158 print '<table class="noborder centpercent">';
3159 //print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Receive").'</td></tr>';
3160 print '<tr><td>'.$langs->trans("DeliveryDate").'</td><td>';
3161 $datepreselected = dol_now();
3162 print $form->selectDate($datepreselected, '', 1, 1, 0, "commande", 1, 1);
3163 print "</td></tr>\n";
3164
3165 print '<tr><td class="fieldrequired">'.$langs->trans("Delivery")."</td><td>\n";
3166 $liv = array();
3167 $liv[''] = '&nbsp;';
3168 $liv['tot'] = $langs->trans("CompleteOrNoMoreReceptionExpected");
3169 $liv['par'] = $langs->trans("PartialWoman");
3170 $liv['nev'] = $langs->trans("NeverReceived");
3171 $liv['can'] = $langs->trans("Canceled");
3172
3173 print $form->selectarray("type", $liv);
3174
3175 print '</td></tr>';
3176 print '<tr><td>'.$langs->trans("Comment").'</td><td><input class="quatrevingtpercent" type="text" name="comment"></td></tr>';
3177 print '<tr><td class="center" colspan="2">';
3178 print '<input type="submit" name="receive" class="button" value="'.$langs->trans("Receive").'">';
3179 print ' &nbsp; &nbsp; ';
3180 print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
3181 print '</td></tr>';
3182 print "</table>\n";
3183 print "</form>\n";
3184 print "<br>";
3185 }
3186 }
3187
3188 // List of actions on element
3189 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
3190 $formactions = new FormActions($db);
3191 $somethingshown = $formactions->showactions($object, 'order_supplier', $socid, 1, 'listaction'.($genallowed ? 'largetitle' : ''));
3192
3193 print '</div></div>';
3194 }
3195
3196 /*
3197 * Action webservice
3198 */
3199 if ($action == 'webservice' && GETPOST('mode', 'alpha') != "send" && !GETPOST('cancel', 'alpha')) {
3200 $mode = GETPOST('mode', 'alpha');
3201 $ws_url = $object->thirdparty->webservices_url;
3202 $ws_key = $object->thirdparty->webservices_key;
3203 $ws_user = GETPOST('ws_user', 'alpha');
3204 $ws_password = GETPOST('ws_password', 'alpha');
3205 $error_occurred = false;
3206
3207 // NS and Authentication parameters
3208 $ws_ns = 'http://www.dolibarr.org/ns/';
3209 $ws_authentication = array(
3210 'dolibarrkey' => $ws_key,
3211 'sourceapplication' => 'DolibarrWebServiceClient',
3212 'login' => $ws_user,
3213 'password' => $ws_password,
3214 'entity' => ''
3215 );
3216
3217 print load_fiche_titre($langs->trans('CreateRemoteOrder'), '');
3218
3219 //Is everything filled?
3220 if (empty($ws_url) || empty($ws_key)) {
3221 setEventMessages($langs->trans("ErrorWebServicesFieldsRequired"), null, 'errors');
3222 $mode = "init";
3223 $error_occurred = true; //Don't allow to set the user/pass if thirdparty fields are not filled
3224 } elseif ($mode != "init" && (empty($ws_user) || empty($ws_password))) {
3225 setEventMessages($langs->trans("ErrorFieldsRequired"), null, 'errors');
3226 $mode = "init";
3227 }
3228
3229 if ($mode == "init") {
3230 //Table/form header
3231 print '<table class="border centpercent">';
3232 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
3233 print '<input type="hidden" name="token" value="'.newToken().'">';
3234 print '<input type="hidden" name="action" value="webservice">';
3235 print '<input type="hidden" name="mode" value="check">';
3236
3237 if ($error_occurred) {
3238 print "<br>".$langs->trans("ErrorOccurredReviseAndRetry")."<br>";
3239 print '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
3240 } else {
3241 // Webservice url
3242 print '<tr><td>'.$langs->trans("WebServiceURL").'</td><td colspan="3">'.dol_print_url($ws_url).'</td></tr>';
3243 //Remote User
3244 print '<tr><td>'.$langs->trans("User").'</td><td><input class="width100" type="text" name="ws_user"></td></tr>';
3245 //Remote Password
3246 print '<tr><td>'.$langs->trans("Password").'</td><td><input class="width100" type="text" name="ws_password"></td></tr>';
3247 //Submit button
3248 print '<tr><td class="center" colspan="2">';
3249 print '<input type="submit" class="button" id="ws_submit" name="ws_submit" value="'.$langs->trans("CreateRemoteOrder").'">';
3250 print ' &nbsp; &nbsp; ';
3251 //Cancel button
3252 print '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
3253 print '</td></tr>';
3254 }
3255
3256 //End table/form
3257 print '</form>';
3258 print '</table>';
3259 } elseif ($mode == "check") {
3260 $ws_entity = '';
3261 $ws_thirdparty = '';
3262 $error_occurred = false;
3263
3264 // Create SOAP client and connect it to user
3265 $soapclient_user = new nusoap_client($ws_url."/webservices/server_user.php");
3266 $soapclient_user->soap_defencoding = 'UTF-8';
3267 $soapclient_user->decodeUTF8(false);
3268
3269 // Get the thirdparty associated to user
3270 $ws_parameters = array('authentication' => $ws_authentication, 'id' => '', 'ref' => $ws_user);
3271 $result_user = $soapclient_user->call("getUser", $ws_parameters, $ws_ns, '');
3272 $user_status_code = $result_user["result"]["result_code"];
3273
3274 if ($user_status_code == "OK") {
3275 // Fill the variables
3276 $ws_entity = $result_user["user"]["entity"];
3277 $ws_authentication['entity'] = $ws_entity;
3278 $ws_thirdparty = $result_user["user"]["fk_thirdparty"];
3279 if (empty($ws_thirdparty)) {
3280 setEventMessages($langs->trans("RemoteUserMissingAssociatedSoc"), null, 'errors');
3281 $error_occurred = true;
3282 } else {
3283 //Create SOAP client and connect it to product/service
3284 $soapclient_product = new nusoap_client($ws_url."/webservices/server_productorservice.php");
3285 $soapclient_product->soap_defencoding = 'UTF-8';
3286 $soapclient_product->decodeUTF8(false);
3287
3288 // Iterate each line and get the reference that uses the supplier of that product/service
3289 $i = 0;
3290 $line = null;
3291 foreach ($object->lines as $line) {
3292 $i += 1;
3293 $ref_supplier = $line->ref_supplier;
3294 $line_id = $i."º) ".$line->product_ref.": ";
3295 if (empty($ref_supplier)) {
3296 continue;
3297 }
3298 $ws_parameters = array('authentication' => $ws_authentication, 'id' => '', 'ref' => $ref_supplier);
3299 $result_product = $soapclient_product->call("getProductOrService", $ws_parameters, $ws_ns, '');
3300 if (!$result_product) {
3301 setEventMessages($line_id.$langs->trans("Error")." SOAP ".$soapclient_product->error_str." - ".$soapclient_product->response, null, 'errors');
3302 $error_occurred = true;
3303 break;
3304 }
3305
3306 // Check the result code
3307 $status_code = $result_product["result"]["result_code"];
3308 if (empty($status_code)) { //No result, check error str
3309 setEventMessages($langs->trans("Error")." SOAP '".$soapclient_product->error_str."'", null, 'errors');
3310 } elseif ($status_code != "OK") { //Something went wrong
3311 if ($status_code == "NOT_FOUND") {
3312 setEventMessages($line_id.$langs->trans("SupplierMissingRef")." '".$ref_supplier."'", null, 'warnings');
3313 } else {
3314 setEventMessages($line_id.$langs->trans("ResponseNonOK")." '".$status_code."' - '".$result_product["result"]["result_label"]."'", null, 'errors');
3315 $error_occurred = true;
3316 break;
3317 }
3318 }
3319
3320
3321 // Ensure that price is equal and warn user if it's not
3322 $supplier_price = price($result_product["product"]["price_net"]); //Price of client tab in supplier dolibarr
3323 $local_price = null; //Price of supplier as stated in product suppliers tab on this dolibarr, NULL if not found
3324
3325 $product_fourn = new ProductFournisseur($db);
3326 $product_fourn_list = $product_fourn->list_product_fournisseur_price($line->fk_product);
3327 if (count($product_fourn_list) > 0) {
3328 foreach ($product_fourn_list as $product_fourn_line) {
3329 // Only accept the line where the supplier is the same at this order and has the same ref
3330 if ($product_fourn_line->fourn_id == $object->socid && $product_fourn_line->fourn_ref == $ref_supplier) {
3331 $local_price = price($product_fourn_line->fourn_price);
3332 }
3333 }
3334 }
3335
3336 if ($local_price != null && $local_price != $supplier_price) {
3337 setEventMessages($line_id.$langs->trans("RemotePriceMismatch")." ".$supplier_price." - ".$local_price, null, 'warnings');
3338 }
3339
3340 // Check if is in sale
3341 if (empty($result_product["product"]["status_tosell"])) {
3342 setEventMessages($line_id.$langs->trans("ProductStatusNotOnSellShort")." '".$ref_supplier."'", null, 'warnings');
3343 }
3344 }
3345 }
3346 } elseif ($user_status_code == "PERMISSION_DENIED") {
3347 setEventMessages($langs->trans("RemoteUserNotPermission"), null, 'errors');
3348 $error_occurred = true;
3349 } elseif ($user_status_code == "BAD_CREDENTIALS") {
3350 setEventMessages($langs->trans("RemoteUserBadCredentials"), null, 'errors');
3351 $error_occurred = true;
3352 } else {
3353 setEventMessages($langs->trans("ResponseNonOK")." '".$user_status_code."'", null, 'errors');
3354 $error_occurred = true;
3355 }
3356
3357 // Form
3358 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
3359 print '<input type="hidden" name="token" value="'.newToken().'">';
3360 print '<input type="hidden" name="action" value="webservice">';
3361 print '<input type="hidden" name="mode" value="send">';
3362 print '<input type="hidden" name="ws_user" value="'.$ws_user.'">';
3363 print '<input type="hidden" name="ws_password" value="'.$ws_password.'">';
3364 print '<input type="hidden" name="ws_entity" value="'.$ws_entity.'">';
3365 print '<input type="hidden" name="ws_thirdparty" value="'.$ws_thirdparty.'">';
3366 if ($error_occurred) {
3367 print "<br>".$langs->trans("ErrorOccurredReviseAndRetry")."<br>";
3368 } else {
3369 print '<input type="submit" class="button" id="ws_submit" name="ws_submit" value="'.$langs->trans("Confirm").'">';
3370 print ' &nbsp; &nbsp; ';
3371 }
3372 print '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
3373 print '</form>';
3374 }
3375 }
3376
3377 // Presend form
3378 $modelmail = 'order_supplier_send';
3379 $defaulttopic = 'SendOrderRef';
3380 $diroutput = getMultidirOutput($object);
3381 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO';
3382 $trackid = 'sord'.$object->id;
3383
3384 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
3385 }
3386}
3387
3388// End of page
3389llxFooter();
3390$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.
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.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
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).
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
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.