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