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 $object->fetch_thirdparty(); // fetch() reset thirdparty to null, reload it before reading default_lang
680
681 // Define output language
682 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
683 $outputlangs = $langs;
684 $newlang = '';
685 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */) {
686 $newlang = $object->thirdparty->default_lang;
687 if (GETPOST('lang_id', 'aZ09')) {
688 $newlang = GETPOST('lang_id', 'aZ09');
689 }
690 }
691 if (!empty($newlang)) {
692 $outputlangs = new Translate("", $conf);
693 $outputlangs->setDefaultLang($newlang);
694 }
695 $model = $object->model_pdf;
696 $ret = $object->fetch($id); // Reload to get new records
697
698 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
699 if ($result < 0) {
700 setEventMessages($object->error, $object->errors, 'errors');
701 }
702 }
703
704 unset($_POST ['prod_entry_mode']);
705
706 unset($_POST['qty']);
707 unset($_POST['type']);
708 unset($_POST['remise_percent']);
709 unset($_POST['pu']);
710 unset($_POST['price_ht']);
711 unset($_POST['multicurrency_price_ht']);
712 unset($_POST['price_ttc']);
713 unset($_POST['fourn_ref']);
714 unset($_POST['tva_tx']);
715 unset($_POST['label']);
716 unset($localtax1_tx);
717 unset($localtax2_tx);
718 unset($_POST['np_marginRate']);
719 unset($_POST['np_markRate']);
720 unset($_POST['dp_desc']);
721 unset($_POST['idprodfournprice']);
722 unset($_POST['units']);
723
724 unset($_POST['date_starthour']);
725 unset($_POST['date_startmin']);
726 unset($_POST['date_startsec']);
727 unset($_POST['date_startday']);
728 unset($_POST['date_startmonth']);
729 unset($_POST['date_startyear']);
730 unset($_POST['date_endhour']);
731 unset($_POST['date_endmin']);
732 unset($_POST['date_endsec']);
733 unset($_POST['date_endday']);
734 unset($_POST['date_endmonth']);
735 unset($_POST['date_endyear']);
736 } else {
737 $db->rollback();
738 setEventMessages($object->error, $object->errors, 'errors');
739 }
740
741 $action = '';
742 }
743
744 /*
745 * Updating a line in the order
746 */
747 if ($action == 'updateline' && $usercancreate && !GETPOST('cancel', 'alpha')) {
748 $db->begin();
749
750 $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
751
752 if ($lineid) {
753 $line = new CommandeFournisseurLigne($db);
754 $res = $line->fetch($lineid);
755 if (!$res) {
756 dol_print_error($db);
757 }
758 }
759
760 $productsupplier = new ProductFournisseur($db);
761 if (getDolGlobalInt('SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY') == 1) { // Not the common case
762 if ($line->fk_product > 0 && $productsupplier->get_buyprice(0, (float) price2num(GETPOSTFLOAT('qty')), $line->fk_product, 'none', GETPOSTINT('socid')) < 0) {
763 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings');
764 }
765 }
766
767 $date_start = dol_mktime(GETPOSTINT('date_starthour'), GETPOSTINT('date_startmin'), GETPOSTINT('date_startsec'), GETPOSTINT('date_startmonth'), GETPOSTINT('date_startday'), GETPOSTINT('date_startyear'));
768 $date_end = dol_mktime(GETPOSTINT('date_endhour'), GETPOSTINT('date_endmin'), GETPOSTINT('date_endsec'), GETPOSTINT('date_endmonth'), GETPOSTINT('date_endday'), GETPOSTINT('date_endyear'));
769
770 // Define info_bits
771 $info_bits = 0;
772 if (preg_match('/\*/', $vat_rate)) {
773 $info_bits |= 0x01;
774 }
775
776 // Define vat_rate
777 $vat_rate = str_replace('*', '', $vat_rate);
778 $localtax1_rate = get_localtax($vat_rate, 1, $mysoc, $object->thirdparty);
779 $localtax2_rate = get_localtax($vat_rate, 2, $mysoc, $object->thirdparty);
780
781 if (GETPOST('price_ht') != '') {
782 $price_base_type = 'HT';
783 $ht = price2num(GETPOST('price_ht'), '', 2);
784 } else {
785 $reg = array();
786 $vatratecleaned = $vat_rate;
787 if (preg_match('/^(.*)\s*\‍((.*)\‍)$/', $vat_rate, $reg)) { // If vat is "xx (yy)"
788 $vatratecleaned = trim($reg[1]);
789 $vatratecode = $reg[2];
790 }
791
792 $ttc = price2num(GETPOST('price_ttc'), '', 2);
793 $ht = (float) $ttc / (1 + ((float) $vatratecleaned / 100));
794 $price_base_type = 'HT';
795 }
796
797 $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), 'CU', 2);
798
799 // Extrafields Lines
800 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
801 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
802 // Unset extrafield POST Data
803 if (is_array($extralabelsline)) {
804 foreach ($extralabelsline as $key => $value) {
805 unset($_POST["options_".$key]);
806 }
807 }
808
809 $result = $object->updateline(
810 $lineid,
811 GETPOST('product_desc', 'restricthtml'),
812 $ht,
813 (float) price2num(GETPOST('qty'), 'MS'),
814 (float) price2num(GETPOST('remise_percent'), '', 2),
815 $vat_rate,
816 $localtax1_rate,
817 $localtax2_rate,
818 $price_base_type,
819 0,
820 GETPOSTISSET("type") ? GETPOST("type") : $line->product_type,
821 0,
822 $date_start,
823 $date_end,
824 $array_options,
825 ((string) GETPOST('units') === '') ? null : GETPOSTINT('units'),
826 (float) $pu_ht_devise,
827 GETPOST('fourn_ref', 'alpha')
828 );
829 unset($_POST['qty']);
830 unset($_POST['type']);
831 unset($_POST['idprodfournprice']);
832 unset($_POST['remmise_percent']);
833 unset($_POST['dp_desc']);
834 unset($_POST['np_desc']);
835 unset($_POST['pu']);
836 unset($_POST['fourn_ref']);
837 unset($_POST['tva_tx']);
838 unset($_POST['date_start']);
839 unset($_POST['date_end']);
840 unset($_POST['units']);
841 unset($localtax1_tx);
842 unset($localtax2_tx);
843
844 unset($_POST['date_starthour']);
845 unset($_POST['date_startmin']);
846 unset($_POST['date_startsec']);
847 unset($_POST['date_startday']);
848 unset($_POST['date_startmonth']);
849 unset($_POST['date_startyear']);
850 unset($_POST['date_endhour']);
851 unset($_POST['date_endmin']);
852 unset($_POST['date_endsec']);
853 unset($_POST['date_endday']);
854 unset($_POST['date_endmonth']);
855 unset($_POST['date_endyear']);
856
857 if ($result >= 0) {
858 // Define output language
859 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
860 $outputlangs = $langs;
861 $newlang = '';
862 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
863 $newlang = GETPOST('lang_id', 'aZ09');
864 }
865 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
866 $newlang = $object->thirdparty->default_lang;
867 }
868 if (!empty($newlang)) {
869 $outputlangs = new Translate("", $conf);
870 $outputlangs->setDefaultLang($newlang);
871 }
872 $model = $object->model_pdf;
873 $ret = $object->fetch($id); // Reload to get new records
874
875 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
876 if ($result < 0) {
877 dol_print_error($db, $object->error, $object->errors);
878 }
879 }
880
881 $db->commit();
882 } else {
883 $db->rollback();
884
885 setEventMessages($object->error, $object->errors, 'errors');
886 }
887 }
888
889 // Remove a product line
890 if ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate) {
891 $db->begin();
892
893 $result = $object->deleteLine($lineid);
894 if ($result > 0) {
895 // reorder lines
896 $object->line_order(true);
897 // Define output language
898 $outputlangs = $langs;
899 $newlang = '';
900 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
901 $newlang = GETPOST('lang_id', 'aZ09');
902 }
903 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
904 $newlang = $object->thirdparty->default_lang;
905 }
906 if (!empty($newlang)) {
907 $outputlangs = new Translate("", $conf);
908 $outputlangs->setDefaultLang($newlang);
909 }
910 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
911 $ret = $object->fetch($object->id); // Reload to get new records
912 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
913 }
914 } else {
915 $error++;
916 setEventMessages($object->error, $object->errors, 'errors');
917 // Reset action to avoid asking again confirmation on failure
918 $action = '';
919 }
920
921 if (!$error) {
922 // reopen order if necessary
924 if ($object->setStatus($user, CommandeFournisseur::STATUS_RECEIVED_PARTIALLY) < 0) {
925 setEventMessages($object->error, $object->errors, 'errors');
926 $error++;
927 $action = '';
928 }
929 }
930 }
931
932 if (!$error) {
933 $db->commit();
934 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
935 exit;
936 } else {
937 $db->rollback();
938 }
939 }
940
941 // Validate
942 if ($action == 'confirm_valid' && $confirm == 'yes' && $usercanvalidate) {
943 $db->begin();
944
945 $object->date_commande = dol_now();
946 $result = $object->valid($user);
947 if ($result >= 0) {
948 // Define output language
949 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
950 $outputlangs = $langs;
951 $newlang = '';
952 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
953 $newlang = GETPOST('lang_id', 'aZ09');
954 }
955 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
956 $newlang = $object->thirdparty->default_lang;
957 }
958 if (!empty($newlang)) {
959 $outputlangs = new Translate("", $conf);
960 $outputlangs->setDefaultLang($newlang);
961 }
962 $model = $object->model_pdf;
963 $ret = $object->fetch($id); // Reload to get new records
964
965 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
966 if ($result < 0) {
967 $error++;
968 dol_print_error($db, $object->error, $object->errors);
969 }
970 }
971 } else {
972 $error++;
973 setEventMessages($object->error, $object->errors, 'errors');
974 }
975
976 // If we have permission, and if we don't need to provide the idwarehouse, we go directly on approved step
977 if (!$error && !getDolGlobalString('SUPPLIER_ORDER_NO_DIRECT_APPROVE') && $usercanapprove && !(getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') && $object->hasProductsOrServices(1))) {
978 $action = 'confirm_approve'; // can make standard or first level approval also if permission is set
979 }
980
981 if (!$error) {
982 $db->commit();
983 } else {
984 $db->rollback();
985 }
986 }
987
988 if (($action == 'confirm_approve' || $action == 'confirm_approve2') && $confirm == 'yes' && $usercanapprove) {
989 $db->begin();
990
991 $idwarehouse = GETPOSTINT('idwarehouse');
992
993 $qualified_for_stock_change = 0;
994 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
995 $qualified_for_stock_change = $object->hasProductsOrServices(2);
996 } else {
997 $qualified_for_stock_change = $object->hasProductsOrServices(1);
998 }
999
1000 // Check parameters
1001 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
1002 if (!$idwarehouse || $idwarehouse == -1) {
1003 $error++;
1004 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Warehouse")), null, 'errors');
1005 $action = '';
1006 }
1007 }
1008
1009 if (!$error) {
1010 $result = $object->approve($user, $idwarehouse, ($action == 'confirm_approve2' ? 1 : 0));
1011 if ($result > 0) {
1012 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1013 $outputlangs = $langs;
1014 $newlang = '';
1015 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1016 $newlang = GETPOST('lang_id', 'aZ09');
1017 }
1018 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1019 $newlang = $object->thirdparty->default_lang;
1020 }
1021 if (!empty($newlang)) {
1022 $outputlangs = new Translate("", $conf);
1023 $outputlangs->setDefaultLang($newlang);
1024 }
1025 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1026 }
1027 } else {
1028 $error++;
1029 setEventMessages($object->error, $object->errors, 'errors');
1030 }
1031 }
1032
1033 if (!$error) {
1034 $db->commit();
1035
1036 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
1037 exit;
1038 } else {
1039 $db->rollback();
1040 }
1041 }
1042
1043 if ($action == 'confirm_refuse' && $confirm == 'yes' && $usercanapprove) {
1044 if (GETPOST('refuse_note')) {
1045 $object->refuse_note = GETPOST('refuse_note');
1046 }
1047 $result = $object->refuse($user);
1048 if ($result > 0) {
1049 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
1050 exit;
1051 } else {
1052 setEventMessages($object->error, $object->errors, 'errors');
1053 }
1054 }
1055
1056 // Force mandatory order method
1057 if ($action == 'commande') { // Test on permission not required here
1058 $methodecommande = GETPOSTINT('methodecommande');
1059
1060 if ($cancel) {
1061 $action = '';
1062 } elseif ($methodecommande <= 0 && !getDolGlobalInt('SUPPLIER_ORDER_MODE_OPTIONAL')) {
1063 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("OrderMode")), null, 'errors');
1064 $action = 'createorder';
1065 }
1066 }
1067
1068 if ($action == 'confirm_commande' && $confirm == 'yes' && $usercanorder) {
1069 $db->begin();
1070 $object->context["sendmanualtriggers"] = GETPOST("manual_trigger_send");
1071 $result = $object->commande($user, GETPOSTINT("datecommande"), GETPOSTINT("methode"), GETPOST('comment'));
1072 if ($result > 0) {
1073 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1074 $outputlangs = $langs;
1075 $newlang = '';
1076 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1077 $newlang = GETPOST('lang_id', 'aZ09');
1078 }
1079 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1080 $newlang = $object->thirdparty->default_lang;
1081 }
1082 if (!empty($newlang)) {
1083 $outputlangs = new Translate("", $conf);
1084 $outputlangs->setDefaultLang($newlang);
1085 }
1086 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1087 }
1088 $action = '';
1089 } else {
1090 $error++;
1091 setEventMessages($object->error, $object->errors, 'errors');
1092 }
1093
1094 if (!$error) {
1095 $db->commit();
1096
1097 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
1098 exit;
1099 } else {
1100 $db->rollback();
1101 }
1102 }
1103
1104
1105 if ($action == 'confirm_delete' && $confirm == 'yes' && $usercandelete) {
1106 // Delete existing dispatched lines
1107 $errOnDelete = 0;
1108 $errorsOnDelete = array();
1109
1110 $db->begin();
1111
1112 if ($stockDelete) {
1113 // TODO We must find line already recorded in stock, not lines dispatched (stock recording may not have been done
1114 // even if dispatched in llx_receptiondet_batch)
1115 // For example to know if stock movement were already record, we may look at stock movements in llx_stock_movement linked to a reception
1116 // that is linked to the purchase order.
1117
1118 /*
1119 $dispatchedLines = $object->getDispachedLines();
1120
1121 if (!empty($dispatchedLines)) {
1122 foreach ($dispatchedLines as $dispatchedLine) {
1123 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
1124 $result = $supplierorderdispatch->fetch($dispatchedLine['id']);
1125 if ($result > 0) {
1126 $result = $supplierorderdispatch->delete($user);
1127 }
1128 if ($result < 0) {
1129 $errorsOnDelete = $object->errors;
1130 $errOnDelete++;
1131 }
1132 }
1133 }
1134
1135 if ($entrepot > 0 && $product > 0 && isModEnabled('enabled')) {
1136 $stockMovementLines = $object->getstockMovementLines()
1137
1138 if (!empty($stockMovementLines)) {
1139 foreach($stockMovementLines as $stockmovementline) {
1140 $qty = $stockmovementline->qty;
1141 $entrepot = $stockmovementline->fk_entrepot;
1142 $product = $stockmovementline->fk_product;
1143 $price = $stockmovementline->price;
1144 $comment = $langs->trans('SupplierOrderDeletion', $object->ref);
1145 $eatby = $stockmovementline->eatby;
1146 $sellby = $stockmovementline->sellby;
1147 $batch = $stockmovementline->batch;
1148
1149 $mouv = new MouvementStock($db);
1150 $mouv->setOrigin($object->element, $object->id);
1151 $result = $mouv->livraison($user, $product, $entrepot, $qty, $price, $comment, '', $eatby, $sellby, $batch);
1152 if ($result < 0) {
1153 $errorsOnDelete = $mouv->errors;
1154 $errOnDelete++;
1155 }
1156 }
1157 }
1158 }
1159 */
1160 }
1161
1162 // @phpstan-ignore-next-line
1163 if (empty($errOnDelete)) {
1164 $result = $object->delete($user);
1165 if ($result > 0) {
1166 $db->commit();
1167 header("Location: " . DOL_URL_ROOT . '/fourn/commande/list.php?restore_lastsearch_values=1');
1168 exit;
1169 } else {
1170 $db->rollback();
1171 setEventMessages($object->error, $object->errors, 'errors');
1172 }
1173 } else {
1174 $db->rollback();
1175 setEventMessages('', $errorsOnDelete, 'errors');
1176 }
1177 }
1178
1179 // Action clone object
1180 if ($action == 'confirm_clone' && $confirm == 'yes' && $usercancreate) {
1181 // @phan-suppress-next-line PhanPluginBothLiteralsBinaryOp
1182 if (1 == 0 && !GETPOST('clone_content') && !GETPOST('clone_receivers')) {
1183 setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
1184 } else {
1185 if ($object->id > 0) {
1186 $orig = clone $object;
1187
1188 $result = $object->createFromClone($user, $socid);
1189 if ($result > 0) {
1190 header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
1191 exit;
1192 } else {
1193 setEventMessages($object->error, $object->errors, 'errors');
1194 $object = $orig;
1195 $action = '';
1196 }
1197 }
1198 }
1199 }
1200
1201 // Set status of reception (complete, partial, ...)
1202 if ($action == 'livraison' && $usercanreceive) {
1203 if ($cancel) {
1204 $action = '';
1205 } else {
1206 $db->begin();
1207
1208 if (GETPOST("type") != '') {
1209 $date_liv = dol_mktime(GETPOSTINT('rehour'), GETPOSTINT('remin'), GETPOSTINT('resec'), GETPOSTINT("remonth"), GETPOSTINT("reday"), GETPOSTINT("reyear"));
1210
1211 $result = $object->Livraison($user, $date_liv, GETPOST("type"), GETPOST("comment")); // GETPOST("type") is 'tot', 'par', 'nev', 'can'
1212 if ($result > 0) {
1213 $langs->load("deliveries");
1214 setEventMessages($langs->trans("DeliveryStateSaved"), null);
1215 $action = '';
1216 } else {
1217 //if ($result == -3) {}
1218 $error++;
1219 setEventMessages($object->error, $object->errors, 'errors');
1220 }
1221 } else {
1222 $error++;
1223 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Delivery")), null, 'errors');
1224 }
1225
1226 if (!$error) {
1227 $db->commit();
1228 } else {
1229 $db->rollback();
1230 }
1231 }
1232 }
1233
1234 if ($action == 'confirm_cancel' && $confirm == 'yes' && $usercanorder) {
1235 if (GETPOST('cancel_note')) {
1236 $object->cancel_note = GETPOST('cancel_note');
1237 }
1238 $result = $object->cancel($user);
1239 if ($result > 0) {
1240 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
1241 exit;
1242 } else {
1243 setEventMessages($object->error, $object->errors, 'errors');
1244 }
1245 }
1246
1247 // Actions when printing a doc from card
1248 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
1249
1250 // Actions to send emails
1251 $triggersendname = 'ORDER_SUPPLIER_SENTBYMAIL';
1252 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO';
1253 $trackid = 'sord'.$object->id;
1254 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1255
1256 // Actions to build doc
1257 $upload_dir = $conf->fournisseur->commande->dir_output;
1258 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1259
1260
1261 if ($action == 'update_extras' && $permissiontoeditextra) {
1262 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
1263
1264 $attribute_name = GETPOST('attribute', 'aZ09');
1265
1266 // Fill array 'array_options' with data from update form
1267 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
1268 if ($ret < 0) {
1269 $error++;
1270 }
1271
1272 if (!$error) {
1273 $result = $object->updateExtraField($attribute_name, 'ORDER_SUPPLIER_MODIFY');
1274 if ($result < 0) {
1275 setEventMessages($object->error, $object->errors, 'errors');
1276 $error++;
1277 }
1278 }
1279
1280 if ($error) {
1281 $action = 'edit_extras';
1282 }
1283 }
1284
1285 /*
1286 * Create an order
1287 */
1288 if ($action == 'add' && $permissiontoadd) {
1289 $error = 0;
1290 $selectedLines = GETPOST('toselect', 'array');
1291 if ($socid < 1) {
1292 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentities('Supplier')), null, 'errors');
1293 $action = 'create';
1294 $error++;
1295 }
1296
1297 if (!$error) {
1298 $db->begin();
1299
1300 // Creation commande
1301 $object->ref_supplier = GETPOST('refsupplier');
1302 $object->socid = $socid;
1303 $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
1304 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
1305 $object->fk_account = GETPOSTINT('fk_account');
1306 $object->note_private = GETPOST('note_private', 'restricthtml');
1307 $object->note_public = GETPOST('note_public', 'restricthtml');
1308 $object->delivery_date = $datelivraison;
1309 $object->fk_incoterms = GETPOSTINT('incoterm_id');
1310 $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
1311 $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
1312 $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx');
1313 $object->fk_project = GETPOSTINT('projectid');
1314
1315 // Fill array 'array_options' with data from add form
1316 if (!$error) {
1317 $ret = $extrafields->setOptionalsFromPost(null, $object);
1318 if ($ret < 0) {
1319 $error++;
1320 }
1321 }
1322
1323 if (!$error) {
1324 // If creation from another object of another module (Example: origin=propal, originid=1)
1325 if (!empty($origin) && !empty($originid)) {
1326 $element = $subelement = $origin;
1327 $classname = ucfirst($subelement);
1328 if ($origin == 'propal' || $origin == 'proposal') {
1329 $element = 'comm/propal';
1330 $subelement = 'propal';
1331 $classname = 'Propal';
1332 }
1333 if ($origin == 'order' || $origin == 'commande') {
1334 $element = $subelement = 'commande';
1335 $classname = 'Commande';
1336 }
1337 if ($origin == 'supplier_proposal') {
1338 $classname = 'SupplierProposal';
1339 $element = 'supplier_proposal';
1340 $subelement = 'supplier_proposal';
1341 }
1342
1343 $object->origin = $origin;
1344 $object->origin_id = $originid;
1345
1346 // Possibility to add external linked objects with hooks
1347 $object->linked_objects[$object->origin] = $object->origin_id;
1348 $other_linked_objects = GETPOST('other_linked_objects', 'array');
1349 if (!empty($other_linked_objects)) {
1350 $object->linked_objects = array_merge($object->linked_objects, $other_linked_objects);
1351 }
1352
1353 $id = $object->create($user);
1354 if ($id > 0) {
1355 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1356
1357 $srcobject = new $classname($db);
1358
1359 dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines");
1360 $result = $srcobject->fetch($object->origin_id);
1361 if ($result > 0) {
1362 if (empty($object->delivery_date)) {
1363 $tmpdate = $srcobject->delivery_date;
1364 $object->setDeliveryDate($user, $tmpdate);
1365 }
1366 $object->set_id_projet($user, $srcobject->fk_project);
1367
1368 $lines = $srcobject->lines;
1369 if (empty($lines) && method_exists($srcobject, 'fetch_lines')) {
1370 $srcobject->fetch_lines();
1371 $lines = $srcobject->lines;
1372 }
1373
1374 $fk_parent_line = 0;
1375 $num = count($lines);
1376
1377 for ($i = 0; $i < $num; $i++) {
1378 if (
1379 empty($lines[$i]->subprice)
1380 || $lines[$i]->qty < 0
1381 || !in_array($lines[$i]->id, $selectedLines)
1382 || $lines[$i]->special_code == SUBTOTALS_SPECIAL_CODE
1383 ) {
1384 continue;
1385 }
1386
1387 $label = (!empty($lines[$i]->label) ? $lines[$i]->label : '');
1388 $desc = (!empty($lines[$i]->desc) ? $lines[$i]->desc : '');
1389 $product_type = (!empty($lines[$i]->product_type) ? $lines[$i]->product_type : 0);
1390 // Reset fk_parent_line for no child products and special product
1391 if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
1392 $fk_parent_line = 0;
1393 }
1394
1395 // Extrafields
1396 if (method_exists($lines[$i], 'fetch_optionals')) { // For avoid conflicts if
1397 $lines[$i]->fetch_optionals();
1398 $array_option = $lines[$i]->array_options;
1399 } else {
1400 $array_option = array();
1401 }
1402
1403 $ref_supplier = '';
1404 $product_fourn_price_id = 0;
1405 if ($origin == "commande") {
1406 $productsupplier = new ProductFournisseur($db);
1407 $result = $productsupplier->find_min_price_product_fournisseur($lines[$i]->fk_product, $lines[$i]->qty, $object->socid);
1408 $lines[$i]->subprice = 0;
1409 if ($result > 0) {
1410 $ref_supplier = $productsupplier->ref_supplier;
1411 $product_fourn_price_id = $productsupplier->product_fourn_price_id;
1412 // we need supplier subprice
1413 foreach ($srcobject->lines as $li) {
1414 $sql = 'SELECT price, unitprice, tva_tx, remise_percent, entity, ref_fourn';
1415 $sql .= ' FROM '.MAIN_DB_PREFIX.'product_fournisseur_price';
1416 $sql .= ' WHERE fk_product = '.((int) $li->fk_product);
1417 $sql .= ' AND entity IN ('.getEntity('product_fournisseur_price').')';
1418 $sql .= ' AND fk_soc = '.((int) $object->socid);
1419 $sql .= ' ORDER BY unitprice ASC';
1420
1421 $resql = $db->query($sql);
1422 if ($resql) {
1423 $num_row = $db->num_rows($resql);
1424 if (empty($num_row)) {
1425 $li->remise_percent = 0;
1426 } else {
1427 $obj = $db->fetch_object($resql);
1428 $li->subprice = $obj->unitprice;
1429 $li->remise_percent = $obj->remise_percent;
1430 }
1431 } else {
1432 dol_print_error($db);
1433 }
1434 $db->free($resql);
1435 }
1436 }
1437 } else {
1438 $ref_supplier = $lines[$i]->ref_fourn;
1439 $product_fourn_price_id = 0;
1440 }
1441
1442 $tva_tx = $lines[$i]->tva_tx;
1443
1444 if ($origin == "commande") {
1445 $soc = new Societe($db);
1446 $soc->fetch($socid);
1447 $tva_tx = get_default_tva($soc, $mysoc, $lines[$i]->fk_product, $product_fourn_price_id);
1448 }
1449
1450 $result = $object->addline(
1451 $desc,
1452 $lines[$i]->subprice,
1453 $lines[$i]->qty,
1454 $tva_tx,
1455 $lines[$i]->localtax1_tx,
1456 $lines[$i]->localtax2_tx,
1457 $lines[$i]->fk_product > 0 ? $lines[$i]->fk_product : 0,
1458 $product_fourn_price_id,
1459 $ref_supplier,
1460 $lines[$i]->remise_percent,
1461 'HT',
1462 0,
1463 $lines[$i]->product_type,
1464 0,
1465 0,
1466 null,
1467 null,
1468 $array_option,
1469 $lines[$i]->fk_unit,
1470 0,
1471 $element,
1472 !empty($lines[$i]->id) ? $lines[$i]->id : $lines[$i]->rowid,
1473 -1,
1474 $lines[$i]->special_code
1475 );
1476
1477 if ($result < 0) {
1478 setEventMessages($object->error, $object->errors, 'errors');
1479 $error++;
1480 break;
1481 }
1482
1483 // Defined the new fk_parent_line
1484 if ($result > 0 && $lines[$i]->product_type == 9) {
1485 $fk_parent_line = $result;
1486 }
1487 }
1488
1489 // Add link between elements
1490
1491
1492 // Hooks
1493 $parameters = array('objFrom' => $srcobject);
1494 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been
1495
1496 if ($reshook < 0) {
1497 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1498 $error++;
1499 }
1500 } else {
1501 setEventMessages($srcobject->error, $srcobject->errors, 'errors');
1502 $error++;
1503 }
1504 } else {
1505 setEventMessages($object->error, $object->errors, 'errors');
1506 $error++;
1507 }
1508 } else {
1509 $id = $object->create($user);
1510 if ($id < 0) {
1511 $error++;
1512 setEventMessages($object->error, $object->errors, 'errors');
1513 }
1514 }
1515 }
1516
1517 if (isModEnabled('category')) {
1518 $categories = GETPOST('categories', 'array');
1519 if (method_exists($object, 'setCategories')) {
1520 $object->setCategories($categories);
1521 }
1522 }
1523
1524 if ($error) {
1525 $langs->load("errors");
1526 $db->rollback();
1527 $action = 'create';
1528 } else {
1529 $db->commit();
1530 header("Location: ".$_SERVER['PHP_SELF']."?id=".urlencode((string) ($id)));
1531 exit;
1532 }
1533 }
1534 }
1535
1536 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
1537 if ($action == 'addcontact' && $permissiontoadd) {
1538 if ($object->id > 0) {
1539 $contactid = (GETPOST('userid') ? GETPOSTINT('userid') : GETPOSTINT('contactid'));
1540 $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
1541 $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
1542 }
1543
1544 if ($result >= 0) {
1545 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1546 exit;
1547 } else {
1548 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1549 $langs->load("errors");
1550 setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
1551 } else {
1552 setEventMessages($object->error, $object->errors, 'errors');
1553 }
1554 }
1555 } elseif ($action == 'swapstatut' && $object->id > 0 && $permissiontoadd) {
1556 // bascule du statut d'un contact
1557 $result = $object->swapContactStatus(GETPOSTINT('ligne'));
1558 } elseif ($action == 'deletecontact' && $object->id > 0 && $permissiontoadd) {
1559 // Efface un contact
1560 $result = $object->delete_contact(GETPOSTINT("lineid"));
1561
1562 if ($result >= 0) {
1563 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1564 exit;
1565 } else {
1566 dol_print_error($db);
1567 }
1568 }
1569 }
1570}
1571
1572
1573/*
1574 * View
1575 */
1576
1577$form = new Form($db);
1578$formfile = new FormFile($db);
1579$formorder = new FormOrder($db);
1580$productstatic = new Product($db);
1581if (isModEnabled('project')) {
1582 $formproject = new FormProjets($db);
1583}
1584
1585$title = $object->ref." - ".$langs->trans('Card');
1586if ($action == 'create') {
1587 $title = $langs->trans("NewOrderSupplier");
1588}
1589$help_url = 'EN:Module_Suppliers_Orders|FR:CommandeFournisseur|ES:Módulo_Pedidos_a_proveedores';
1590llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-supplier-order page-card');
1591
1592$now = dol_now();
1593
1594if ($action == 'create') {
1595 print load_fiche_titre($langs->trans('NewOrderSupplier'), '', 'supplier_order');
1596
1598
1599 $currency_code = $conf->currency;
1600
1601 $societe = '';
1602 $objectsrc = null;
1603
1604 if ($socid > 0) {
1605 $societe = new Societe($db);
1606 $societe->fetch($socid);
1607 }
1608
1609 if (!empty($origin) && !empty($originid)) {
1610 // Parse element/subelement (ex: project_task)
1611 $element = $subelement = $origin;
1612 $classname = ucfirst($subelement);
1613 $regs = array();
1614 if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
1615 $element = $regs[1];
1616 $subelement = $regs[2];
1617 }
1618
1619 if ($origin == 'propal' || $origin == 'proposal') {
1620 $classname = 'Propal';
1621 $element = 'comm/propal';
1622 $subelement = 'propal';
1623 }
1624 if ($origin == 'order' || $origin == 'commande') {
1625 $classname = 'Commande';
1626 $element = $subelement = 'commande';
1627 }
1628 if ($origin == 'supplier_proposal') {
1629 $classname = 'SupplierProposal';
1630 $element = 'supplier_proposal';
1631 $subelement = 'supplier_proposal';
1632 }
1633
1634
1635 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1636
1637 $objectsrc = new $classname($db);
1638 $objectsrc->fetch($originid);
1639 if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
1640 $objectsrc->fetch_lines();
1641 }
1642 $objectsrc->fetch_thirdparty();
1643
1644 // Replicate extrafields
1645 $objectsrc->fetch_optionals();
1646 $object->array_options = $objectsrc->array_options;
1647
1648 $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
1649 $ref_client = (!empty($objectsrc->ref_client) ? $objectsrc->ref_client : '');
1650 $fk_account = 0;
1651 if ($origin == "commande") {
1652 $cond_reglement_id = 0;
1653 $mode_reglement_id = 0;
1654 $datelivraison = '';
1655 $objectsrc->note_private = '';
1656 $objectsrc->note_public = '';
1657 if ($societe = $object->thirdparty) {
1658 $cond_reglement_id = $societe->cond_reglement_supplier_id;
1659 $mode_reglement_id = $societe->mode_reglement_supplier_id;
1660 if (isModEnabled("multicurrency")) {
1661 $currency_code = $societe->multicurrency_code;
1662 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX')) {
1663 $currency_tx = $societe->multicurrency_tx;
1664 }
1665 }
1666 }
1667 } else {
1668 $soc = $objectsrc->thirdparty;
1669
1670 $cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0));
1671 $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0));
1672 $fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0));
1673 $availability_id = (!empty($objectsrc->availability_id) ? $objectsrc->availability_id : (!empty($soc->availability_id) ? $soc->availability_id : 0));
1674 $shipping_method_id = (!empty($objectsrc->shipping_method_id) ? $objectsrc->shipping_method_id : (!empty($soc->shipping_method_id) ? $soc->shipping_method_id : 0));
1675 $demand_reason_id = (!empty($objectsrc->demand_reason_id) ? $objectsrc->demand_reason_id : (!empty($soc->demand_reason_id) ? $soc->demand_reason_id : 0));
1676 //$remise_percent = (!empty($objectsrc->remise_percent) ? $objectsrc->remise_percent : (!empty($soc->remise_supplier_percent) ? $soc->remise_supplier_percent : 0));
1677 //$remise_absolue = (!empty($objectsrc->remise_absolue) ? $objectsrc->remise_absolue : (!empty($soc->remise_absolue) ? $soc->remise_absolue : 0));
1678 $dateinvoice = getDolGlobalString('MAIN_AUTOFILL_DATE') ? '' : -1;
1679
1680 $datelivraison = (!empty($objectsrc->delivery_date) ? $objectsrc->delivery_date : '');
1681
1682 if (isModEnabled("multicurrency")) {
1683 if (!empty($objectsrc->multicurrency_code)) {
1684 $currency_code = $objectsrc->multicurrency_code;
1685 }
1686 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
1687 $currency_tx = $objectsrc->multicurrency_tx;
1688 }
1689 }
1690
1691 $note_private = $object->getDefaultCreateValueFor('note_private', (!empty($objectsrc->note_private) ? $objectsrc->note_private : null));
1692 $note_public = $object->getDefaultCreateValueFor('note_public', (!empty($objectsrc->note_public) ? $objectsrc->note_public : null));
1693
1694 // Object source contacts list
1695 $srccontactslist = $objectsrc->liste_contact(-1, 'external', 1);
1696 }
1697 } else {
1698 $cond_reglement_id = !empty($societe->cond_reglement_supplier_id) ? $societe->cond_reglement_supplier_id : 0;
1699 $mode_reglement_id = !empty($societe->mode_reglement_supplier_id) ? $societe->mode_reglement_supplier_id : 0;
1700
1701 if (isModEnabled("multicurrency") && !empty($societe->multicurrency_code)) {
1702 $currency_code = $societe->multicurrency_code;
1703 }
1704
1705 $note_private = $object->getDefaultCreateValueFor('note_private');
1706 $note_public = $object->getDefaultCreateValueFor('note_public');
1707 }
1708
1709 // If not defined, set default value from constant
1710 if (empty($cond_reglement_id) && getDolGlobalString('SUPPLIER_ORDER_DEFAULT_PAYMENT_TERM_ID')) {
1711 $cond_reglement_id = getDolGlobalString('SUPPLIER_ORDER_DEFAULT_PAYMENT_TERM_ID');
1712 }
1713 if (empty($mode_reglement_id) && getDolGlobalString('SUPPLIER_ORDER_DEFAULT_PAYMENT_MODE_ID')) {
1714 $mode_reglement_id = getDolGlobalString('SUPPLIER_ORDER_DEFAULT_PAYMENT_MODE_ID');
1715 }
1716
1717 print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="post">';
1718 print '<input type="hidden" name="token" value="'.newToken().'">';
1719 print '<input type="hidden" name="action" value="add">';
1720 print '<input type="hidden" name="remise_percent" value="'.(empty($soc->remise_supplier_percent) ? '' : $soc->remise_supplier_percent).'">';
1721 print '<input type="hidden" name="origin" value="'.$origin.'">';
1722 print '<input type="hidden" name="originid" value="'.$originid.'">';
1723 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
1724 if ($backtopage) {
1725 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1726 }
1727 if ($backtopageforcancel) {
1728 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
1729 }
1730
1731 if (!empty($currency_tx)) {
1732 print '<input type="hidden" name="originmulticurrency_tx" value="'.$currency_tx.'">';
1733 }
1734
1735 print dol_get_fiche_head(array());
1736
1737 // Call Hook tabContentCreateSupplierOrder
1738 $parameters = array();
1739 // Note that $action and $object may be modified by hook
1740 $reshook = $hookmanager->executeHooks('tabContentCreateSupplierOrder', $parameters, $object, $action);
1741 if (empty($reshook)) {
1742 print '<table class="border centpercent">';
1743
1744 // Ref
1745 print '<tr><td class="titlefieldcreate">'.$langs->trans('Ref').'</td><td>'.$langs->trans('Draft').'</td></tr>';
1746
1747 // Third party
1748 print '<tr><td class="fieldrequired">'.$langs->trans('Supplier').'</td>';
1749 print '<td>';
1750
1751 if (!empty($societe->id) && $societe->id > 0) {
1752 print $societe->getNomUrl(1, 'supplier');
1753 print '<input type="hidden" name="socid" value="'.$societe->id.'">';
1754 } else {
1755 $filter = '((s.fournisseur:=:1) AND (s.status:=:1))';
1756 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company((empty($socid) ? '' : $socid), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
1757 // reload page to retrieve customer information
1758 if (!getDolGlobalString('RELOAD_PAGE_ON_SUPPLIER_CHANGE_DISABLED')) {
1759 print '<script>
1760 $(document).ready(function() {
1761 $("#socid").change(function() {
1762 console.log("We have changed the company - Reload page");
1763 // reload page
1764 $("input[name=action]").val("create");
1765 $("input[name=changecompany]").val("1");
1766 $("form[name=add]").submit();
1767 });
1768 });
1769 </script>';
1770 }
1771 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>';
1772 }
1773 print '</td>';
1774
1775 if (!empty($societe->id) && $societe->id > 0) {
1776 // Discounts for third party
1777 print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
1778
1779 $absolute_discount = $societe->getAvailableDiscounts(null, '', 0, 1);
1780
1781 $thirdparty = $societe;
1782 $discount_type = 1;
1783 $backtopage = urlencode($_SERVER["PHP_SELF"].'?socid='.$thirdparty->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid'));
1784 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
1785
1786 print '</td></tr>';
1787 }
1788
1789 // Ref supplier
1790 print '<tr><td>'.$langs->trans('RefSupplier').'</td><td><input name="refsupplier" type="text"></td>';
1791 print '</tr>';
1792
1793 // Payment term
1794 print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
1795 print img_picto('', 'payment', 'class="pictofixedwidth"');
1796 print $form->getSelectConditionsPaiements((GETPOSTISSET('cond_reglement_id') && GETPOST('cond_reglement_id') != 0) ? GETPOSTINT('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', -1, 1);
1797 print '</td></tr>';
1798
1799 // Payment mode
1800 print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
1801 print img_picto('', 'bank', 'class="pictofixedwidth"');
1802 $form->select_types_paiements((GETPOSTISSET('mode_reglement_id') && GETPOSTINT('mode_reglement_id') != 0) ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id');
1803 print '</td></tr>';
1804
1805 // Planned delivery date
1806 print '<tr><td>';
1807 print $langs->trans('DateDeliveryPlanned');
1808 print '</td>';
1809 print '<td>';
1810 $usehourmin = 0;
1811 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
1812 $usehourmin = 1;
1813 }
1814 print img_picto('', 'action', 'class="pictofixedwidth"');
1815
1816 print $form->selectDate($datelivraison ? $datelivraison : -1, 'liv_', $usehourmin, $usehourmin, 0, "set");
1817
1818 print '</td></tr>';
1819
1820 // Bank Account
1821 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER') && isModEnabled("bank")) {
1822 $langs->load("bank");
1823 print '<tr><td>'.$langs->trans('BankAccount').'</td><td>';
1824 print img_picto('', 'bank_account', 'class="pictofixedwidth"');
1825 $form->select_comptes($fk_account ?? '', 'fk_account', 0, '', 1);
1826 print '</td></tr>';
1827 }
1828
1829 // Project
1830 if (isModEnabled('project')) {
1831 $formproject = new FormProjets($db);
1832
1833 $langs->load('projects');
1834 print '<tr><td>'.$langs->trans('Project').'</td><td>';
1835 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');
1836 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>';
1837 print '</td></tr>';
1838 }
1839
1840 // Incoterms
1841 if (isModEnabled('incoterm')) {
1842 $fkincoterms = (!empty($object->fk_incoterms) ? $object->fk_incoterms : ($socid > 0 ? $societe->fk_incoterms : ''));
1843 $locincoterms = (!empty($object->location_incoterms) ? $object->location_incoterms : ($socid > 0 ? $societe->location_incoterms : ''));
1844 print '<tr>';
1845 print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $object->label_incoterms, 1).'</label></td>';
1846 print '<td class="maxwidthonsmartphone">';
1847 print img_picto('', 'incoterm', 'class="pictofixedwidth"');
1848 print $form->select_incoterms($fkincoterms, $locincoterms);
1849 print '</td></tr>';
1850 }
1851
1852 // Multicurrency
1853 if (isModEnabled("multicurrency")) {
1854 print '<tr>';
1855 print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
1856 print '<td class="maxwidthonsmartphone">';
1857 print img_picto('', 'currency', 'class="pictofixedwidth"');
1858 print $form->selectMultiCurrency($currency_code, 'multicurrency_code');
1859 print '</td></tr>';
1860 }
1861
1862 // Categories
1863 if (isModEnabled("category")) {
1864 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
1865 print $form->selectCategories(Categorie::TYPE_SUPPLIER_ORDER, 'categories', $object);
1866 print "</td></tr>";
1867 }
1868
1869 print '<tr><td>'.$langs->trans('NotePublic').'</td>';
1870 print '<td>';
1871 $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%');
1872 print $doleditor->Create(1);
1873 print '</td>';
1874 //print '<textarea name="note_public" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea>';
1875 print '</tr>';
1876
1877 print '<tr><td>'.$langs->trans('NotePrivate').'</td>';
1878 print '<td>';
1879 $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%');
1880 print $doleditor->Create(1);
1881 print '</td>';
1882 //print '<td><textarea name="note_private" wrap="soft" cols="60" rows="'.ROWS_5.'"></textarea></td>';
1883 print '</tr>';
1884
1885 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
1886 print "\n<!-- ".$classname." info -->";
1887 print "\n";
1888 print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
1889 print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
1890 print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
1891 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
1892 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
1893
1894 $newclassname = $classname;
1895 print '<tr><td>'.$langs->trans($newclassname).'</td><td>'.$objectsrc->getNomUrl(1, 'supplier').'</td></tr>';
1896 print '<tr><td>'.$langs->trans('AmountHT').'</td><td>'.price($objectsrc->total_ht).'</td></tr>';
1897 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td>'.price($objectsrc->total_tva)."</td></tr>";
1898 if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0) { // Localtax1 RE
1899 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax1)."</td></tr>";
1900 }
1901
1902 if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) { // Localtax2 IRPF
1903 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td>'.price($objectsrc->total_localtax2)."</td></tr>";
1904 }
1905
1906 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td>'.price($objectsrc->total_ttc)."</td></tr>";
1907
1908 if (isModEnabled("multicurrency")) {
1909 print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td>'.price($objectsrc->multicurrency_total_ht).'</td></tr>';
1910 print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td>'.price($objectsrc->multicurrency_total_tva).'</td></tr>';
1911 print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td>'.price($objectsrc->multicurrency_total_ttc).'</td></tr>';
1912 }
1913 }
1914
1915 // Other options
1916 $parameters = array();
1917 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1918 print $hookmanager->resPrint;
1919
1920 if (empty($reshook)) {
1921 if (getDolGlobalString('THIRDPARTY_PROPAGATE_EXTRAFIELDS_TO_SUPPLIER_ORDER') && !empty($societe->id)) {
1922 // copy from thirdparty
1923 $tpExtrafields = new ExtraFields($db);
1924 $tpExtrafieldLabels = $tpExtrafields->fetch_name_optionals_label($societe->table_element);
1925 if ($societe->fetch_optionals() > 0) {
1926 $object->array_options = array_merge($object->array_options, $societe->array_options);
1927 }
1928 }
1929
1930 print $object->showOptionals($extrafields, 'create');
1931 }
1932
1933 // Bouton "Create Draft"
1934 print "</table>\n";
1935 }
1936 print dol_get_fiche_end();
1937
1938 print $form->buttonsSaveCancel("CreateDraft");
1939
1940 // Show origin lines
1941 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
1942 $title = $langs->trans('ProductsAndServices');
1943 print load_fiche_titre($title);
1944
1945 print '<div class="div-table-responsive-no-min">';
1946 print '<table class="noborder centpercent">';
1947
1948 $selectedLines = array();
1949
1950 $objectsrc->printOriginLinesList('', $selectedLines);
1951
1952 print '</table>';
1953 print '</div>';
1954 }
1955 print "</form>\n";
1956} elseif (!empty($object->id)) {
1957 // view
1958 $result = $object->fetch($id, $ref);
1959 $object->fetch_thirdparty();
1960
1961 $societe = $object->thirdparty;
1962
1963 $author = new User($db);
1964 $author->fetch($object->user_author_id);
1965
1967
1968 $title = $langs->trans("SupplierOrder");
1969 print dol_get_fiche_head($head, 'card', $title, -1, 'order');
1970
1971
1972 $formconfirm = '';
1973
1974 // Confirmation de la suppression de la commande
1975 if ($action == 'delete') {
1976 $arrayAjouts = array();
1977 $heightModal = 0;
1978 $widthModal = 500;
1979
1980 // TODO We must find line already recorded in stock, not lines dispatched (stock recording may not have been done
1981 // even if dispatched in llx_receptiondet_batch).
1982 // For example to know if stock movement were already record, we may look at stock movements in llx_stock_movement linked to a reception
1983 // that is linked to the purchase order.
1984 /* $dispatchedLines = $object->getStockMovementLines();
1985
1986 if (!empty($dispatchedLines)) {
1987 $arrayAjouts = array(
1988 array(
1989 'type' => 'other',
1990 'value' => img_warning() . " " . $langs->trans('ExistingDipatchLines')
1991 ),
1992 array('type' => 'separator'),
1993 array(
1994 'type' => 'select',
1995 'id' => 'stockDeleteSelect',
1996 'name' => 'stockDelete',
1997 'label' => $langs->trans('ConfirmDeleteDispatchedLines'),
1998 'values' => array(1 => $langs->trans('Yes'), 0 => $langs->trans('No')),
1999 'select_show_empty' => false
2000 )
2001 );
2002 $heightModal = 300;
2003 $widthModal = "70%";
2004 }
2005 */
2006
2007 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.((int) $object->id), $langs->trans('DeleteOrder'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', $arrayAjouts, 0, 2, $heightModal, $widthModal);
2008 }
2009
2010 // Clone confirmation
2011 if ($action == 'clone') {
2012 $filter = '(s.fournisseur:=:1)';
2013 // Create an array for form
2014 $formquestion = array(
2015 array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter))
2016 );
2017 // Paiement incomplet. On demande si motif = escompte ou autre
2018 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
2019 }
2020
2021 // Confirmation de la validation
2022 if ($action == 'valid') {
2023 $object->date_commande = dol_now();
2024
2025 // We check if number is temporary number
2026 if (preg_match('/^[\‍(]?PROV/i', $object->ref) || empty($object->ref)) { // empty should not happened, but when it occurs, the test save life
2027 $newref = $object->getNextNumRef($object->thirdparty);
2028 } else {
2029 $newref = $object->ref;
2030 }
2031
2032 if ($newref < 0) {
2033 setEventMessages($object->error, $object->errors, 'errors');
2034 $action = '';
2035 } else {
2036 $text = $langs->trans('ConfirmValidateOrder', $newref);
2037 if (isModEnabled('notification')) {
2038 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2039 $notify = new Notify($db);
2040 $text .= '<br>';
2041 $text .= $notify->confirmMessage('ORDER_SUPPLIER_VALIDATE', $object->socid, $object);
2042 }
2043
2044 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_valid', '', 0, 1);
2045 }
2046 }
2047
2048 // Confirm approval
2049 if ($action == 'approve' || $action == 'approve2') {
2050 $qualified_for_stock_change = 0;
2051 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES')) {
2052 $qualified_for_stock_change = $object->hasProductsOrServices(2);
2053 } else {
2054 $qualified_for_stock_change = $object->hasProductsOrServices(1);
2055 }
2056
2057 $formquestion = array();
2058 if (isModEnabled('stock') && getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER') && $qualified_for_stock_change) {
2059 $langs->load("stocks");
2060 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
2061 $formproduct = new FormProduct($db);
2062 $forcecombo = 0;
2063 if ($conf->browser->name == 'ie') {
2064 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
2065 }
2066 $formquestion = array(
2067 //'text' => $langs->trans("ConfirmClone"),
2068 //array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
2069 //array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
2070 array('type' => 'other', 'name' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockIncrease"), 'value' => $formproduct->selectWarehouses(GETPOSTINT('idwarehouse'), 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo))
2071 );
2072 }
2073 $text = $langs->trans("ConfirmApproveThisOrder", $object->ref);
2074 if (isModEnabled('notification')) {
2075 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2076 $notify = new Notify($db);
2077 $text .= '<br>';
2078 $text .= $notify->confirmMessage('ORDER_SUPPLIER_APPROVE', $object->socid, $object);
2079 }
2080
2081 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ApproveThisOrder"), $text, "confirm_".$action, $formquestion, 1, 1, 240);
2082 }
2083
2084 // Confirmation of disapproval
2085 if ($action == 'refuse') {
2086 $formquestion = array(
2087 array(
2088 'type' => 'text',
2089 'name' => 'refuse_note',
2090 'label' => $langs->trans("Reason"),
2091 'value' => '',
2092 'morecss' => 'minwidth300'
2093 )
2094 );
2095 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("DenyingThisOrder"), $langs->trans("ConfirmDenyingThisOrder", $object->ref), "confirm_refuse", $formquestion, 0, 1);
2096 }
2097
2098 // Confirmation of cancellation
2099 if ($action == 'cancel') {
2100 $formquestion = array(
2101 array(
2102 'type' => 'text',
2103 'name' => 'cancel_note',
2104 'label' => $langs->trans("Reason"),
2105 'value' => '',
2106 'morecss' => 'minwidth300'
2107 )
2108 );
2109 if (isModEnabled('notification')) {
2110 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2111 $notify = new Notify($db);
2112 $text = '';
2113 $text .= '<br>';
2114 $text .= $notify->confirmMessage('ORDER_SUPPLIER_CANCEL', $object->socid, $object);
2115 }
2116 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=$object->id", $langs->trans("Cancel"), $langs->trans("ConfirmCancelThisOrder", $object->ref), "confirm_cancel", $formquestion, 0, 1);
2117 }
2118
2119 // Confirmation de l'envoi de la commande
2120 if ($action == 'commande') {
2121 $formquestion = array();
2122 $date_com = dol_mktime(GETPOSTINT('rehour'), GETPOSTINT('remin'), GETPOSTINT('resec'), GETPOSTINT("remonth"), GETPOSTINT("reday"), GETPOSTINT("reyear"));
2123 if (isModEnabled('notification')) {
2124 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
2125 $notify = new Notify($db);
2126 $text = '';
2127 $text .= '<br>';
2128 $text .= $notify->confirmMessage('ORDER_SUPPLIER_SUBMIT', $object->socid, $object);
2129 }
2130 if (isModEnabled('webhook')) {
2131 require_once DOL_DOCUMENT_ROOT.'/webhook/class/target.class.php';
2132 $targetstatic = new Target($db);
2133 if ($targetstatic->isTriggerCodeManualTarget('ORDER_SUPPLIER_SUBMIT') > 0) {
2134 $formquestion[] = array('type' => 'checkbox', 'name' => 'manual_trigger_send', 'label' => $langs->trans("QuestionSendManualTrigger"));
2135 }
2136 }
2137 $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);
2138 }
2139
2140 // Confirmation to delete line
2141 if ($action == 'ask_deleteline') {
2142 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
2143 }
2144
2145 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
2146 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2147 if (empty($reshook)) {
2148 $formconfirm .= $hookmanager->resPrint;
2149 } elseif ($reshook > 0) {
2150 $formconfirm = $hookmanager->resPrint;
2151 }
2152
2153 // Print form confirm
2154 print $formconfirm;
2155
2156
2157 // Supplier order card
2158
2159 $linkback = '<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
2160
2161 $morehtmlref = '<div class="refidno">';
2162 // Ref supplier
2163 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, (int) $usercancreate, 'string', '', 0, 1);
2164 $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);
2165 // Thirdparty
2166 $morehtmlref .= '<br>';
2167 if (getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') && !empty($usercancreate) && $action == 'edit_thirdparty') {
2168 $morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
2169 $morehtmlref .= '<input type="hidden" name="action" value="set_thirdparty">';
2170 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
2171 $filter = '(s.fournisseur:=:1)';
2172 $morehtmlref .= $form->select_company($object->thirdparty->id, 'new_socid', $filter, '', 0, 0, array(), 0, 'minwidth300');
2173 $morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
2174 $morehtmlref .= '</form>';
2175 }
2176 if (!getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') || $action != 'edit_thirdparty') {
2177 if (getDolGlobalString('MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER') && $object->status == CommandeFournisseur::STATUS_DRAFT) {
2178 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=edit_thirdparty&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetThirdParty')).'</a>';
2179 }
2180 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'supplier');
2181 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
2182 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/fourn/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
2183 }
2184 }
2185
2186 // Project
2187 if (isModEnabled('project')) {
2188 $langs->load("projects");
2189 $morehtmlref .= '<br>';
2190 if ($permissiontoadd) {
2191 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2192 if ($action != 'classify' && $caneditproject) {
2193 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2194 }
2195 $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');
2196 } else {
2197 if (!empty($object->fk_project)) {
2198 $proj = new Project($db);
2199 $proj->fetch($object->fk_project);
2200 $morehtmlref .= $proj->getNomUrl(1);
2201 if ($proj->title) {
2202 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2203 }
2204 }
2205 }
2206 }
2207 $morehtmlref .= '</div>';
2208
2209
2210 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
2211
2212 // Call Hook tabContentViewSupplierOrder
2213 $parameters = array();
2214 // Note that $action and $object may be modified by hook
2215 $reshook = $hookmanager->executeHooks('tabContentViewSupplierOrder', $parameters, $object, $action);
2216 if (empty($reshook)) {
2217 print '<div class="fichecenter">';
2218 print '<div class="fichehalfleft">';
2219 print '<div class="underbanner clearboth"></div>';
2220
2221 print '<table class="border tableforfield centpercent">';
2222
2223 // Date
2224 if ($object->methode_commande_id > 0) {
2225 $usehourmin = 0;
2226 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2227 $usehourmin = 1;
2228 }
2229 print '<tr><td class="titlefield">'.$langs->trans("Date").'</td><td>';
2230 print $object->date_commande ? dol_print_date($object->date_commande, $usehourmin ? 'dayhour' : 'day') : '';
2231 if ($object->hasDelay() && !empty($object->delivery_date) && !empty($object->date_commande)) {
2232 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
2233 }
2234 print "</td></tr>";
2235
2236 if ($object->methode_commande) {
2237 print '<tr><td>'.$langs->trans("Method").'</td><td>'.$object->getInputMethod().'</td></tr>';
2238 }
2239 }
2240
2241 // Author
2242 print '<tr><td class="titlefield">'.$langs->trans("AuthorRequest").'</td>';
2243 print '<td>'.$author->getNomUrl(-1, '', 0, 0, 0).'</td>';
2244 print '</tr>';
2245
2246 // Relative and absolute discounts
2247 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
2248 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2249 $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
2250 } else {
2251 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
2252 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
2253 }
2254
2255 $absolute_discount = $societe->getAvailableDiscounts(null, $filterabsolutediscount, 0, 1);
2256 $absolute_creditnote = $societe->getAvailableDiscounts(null, $filtercreditnote, 0, 1);
2257 $absolute_discount = price2num($absolute_discount, 'MT');
2258 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
2259
2260 print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td>';
2261
2262 $thirdparty = $societe;
2263 $discount_type = 1;
2264 $backtopage = urlencode($_SERVER["PHP_SELF"].'?id='.$object->id);
2265 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2266
2267 print '</td></tr>';
2268
2269 // Default terms of the settlement
2270 $langs->load('bills');
2271 print '<tr><td class="nowrap">';
2272 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
2273 print $langs->trans('PaymentConditions');
2274 print '<td>';
2275 if ($action != 'editconditions' && $permissiontoadd) {
2276 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>';
2277 }
2278 print '</tr></table>';
2279 print '</td><td>';
2280 if ($action == 'editconditions') {
2281 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'cond_reglement_id');
2282 } else {
2283 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'none');
2284 }
2285 print "</td>";
2286 print '</tr>';
2287
2288 // Mode of payment
2289 $langs->load('bills');
2290 print '<tr><td class="nowrap">';
2291 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
2292 print $langs->trans('PaymentMode');
2293 print '</td>';
2294 if ($action != 'editmode' && $permissiontoadd) {
2295 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>';
2296 }
2297 print '</tr></table>';
2298 print '</td><td>';
2299 if ($action == 'editmode') {
2300 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', 'DBIT', 1, 1);
2301 } else {
2302 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'none');
2303 }
2304 print '</td></tr>';
2305
2306 // Bank Account
2307 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER') && isModEnabled("bank")) {
2308 print '<tr><td class="nowrap">';
2309 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
2310 print $langs->trans('BankAccount');
2311 print '<td>';
2312 if ($action != 'editbankaccount' && $permissiontoadd) {
2313 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>';
2314 }
2315 print '</tr></table>';
2316 print '</td><td>';
2317 if ($action == 'editbankaccount') {
2318 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'fk_account', 1);
2319 } else {
2320 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'none');
2321 }
2322 print '</td>';
2323 print '</tr>';
2324 }
2325
2326 // Delivery delay (in days)
2327 print '<tr>';
2328 print '<td>'.$langs->trans('NbDaysToDelivery').'&nbsp;'.img_picto($langs->trans('DescNbDaysToDelivery'), 'info', 'style="cursor:help"').'</td>';
2329 print '<td>'.$object->getMaxDeliveryTimeDay($langs).'</td>';
2330 print '</tr>';
2331
2332 // Delivery date planned
2333 print '<tr><td>';
2334 print '<table class="nobordernopadding centpercent"><tr><td>';
2335 print $langs->trans('DateDeliveryPlanned');
2336 print '</td>';
2337 if ($action != 'editdate_livraison') {
2338 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>';
2339 }
2340 print '</tr></table>';
2341 print '</td><td>';
2342 if ($action == 'editdate_livraison') {
2343 print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2344 print '<input type="hidden" name="token" value="'.newToken().'">';
2345 print '<input type="hidden" name="action" value="setdate_livraison">';
2346 $usehourmin = 0;
2347 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2348 $usehourmin = 1;
2349 }
2350 print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', $usehourmin, $usehourmin, 0, "setdate_livraison");
2351 print '<input type="submit" class="button button-edit smallpaddingimp valign middle" value="'.$langs->trans('Modify').'">';
2352 print '</form>';
2353 } else {
2354 $usehourmin = 'day';
2355 if (getDolGlobalString('SUPPLIER_ORDER_USE_HOUR_FOR_DELIVERY_DATE')) {
2356 $usehourmin = 'dayhour';
2357 }
2358 print $object->delivery_date ? dol_print_date($object->delivery_date, $usehourmin) : '&nbsp;';
2359 if ($object->hasDelay() && !empty($object->delivery_date) && ($object->status == $object::STATUS_ORDERSENT || $object->status == $object::STATUS_RECEIVED_PARTIALLY)) {
2360 print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning");
2361 }
2362 }
2363 print '</td></tr>';
2364
2365 // Incoterms
2366 if (isModEnabled('incoterm')) {
2367 print '<tr><td>';
2368 print '<table class="nobordernopadding centpercent"><tr><td>';
2369 print $langs->trans('IncotermLabel');
2370 print '<td><td class="right">';
2371 if ($usercancreate) {
2372 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?id='.$object->id.'&action=editincoterm&token='.newToken().'">'.img_edit().'</a>';
2373 } else {
2374 print '&nbsp;';
2375 }
2376 print '</td></tr></table>';
2377 print '</td>';
2378 print '<td>';
2379 if ($action != 'editincoterm') {
2380 print $form->textwithpicto(dol_escape_htmltag($object->display_incoterms()), $object->label_incoterms, 1);
2381 } else {
2382 print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id);
2383 }
2384 print '</td></tr>';
2385 }
2386
2387 // Tags-Categories
2388 if (isModEnabled('category')) {
2389 print '<tr><td>';
2390 print '<table class="nobordernopadding centpercent"><tr><td>';
2391 print $langs->trans("Categories");
2392 print '<td><td class="right">';
2393 if ($usercancreate) {
2394 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?id='.$object->id.'&action=edittags&token='.newToken().'">'.img_edit().'</a>';
2395 } else {
2396 print '&nbsp;';
2397 }
2398 print '</td></tr></table>';
2399 print '</td>';
2400 print '<td>';
2401 if ($action == 'edittags') {
2402 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
2403 print '<input type="hidden" name="action" value="settags">';
2404 print '<input type="hidden" name="token" value="'.newToken().'">';
2405 print $form->selectCategories(Categorie::TYPE_SUPPLIER_ORDER, 'categories', $object);
2406 print '<input type="submit" class="button valignmiddle smallpaddingimp" value="'.$langs->trans("Modify").'">';
2407 print '</form>';
2408 } else {
2409 print $form->showCategories($object->id, Categorie::TYPE_SUPPLIER_ORDER, 1);
2410 }
2411 print "</td></tr>";
2412 }
2413
2414 // Other attributes
2415 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2416
2417 print '</table>';
2418
2419 print '</div>';
2420 print '<div class="fichehalfright">';
2421 print '<div class="underbanner clearboth"></div>';
2422
2423 print '<table class="border tableforfield centpercent">';
2424
2425 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
2426
2427 print '<tr>';
2428 // Amount HT
2429 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
2430 print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2431 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2432 // Multicurrency Amount HT
2433 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2434 }
2435 print '</tr>';
2436
2437 print '<tr>';
2438 // Amount VAT
2439 print '<td class="titlefieldmiddle">' . $langs->trans('AmountVAT') . '</td>';
2440 print '<td class="nowrap amountcard right">' . price($object->total_tva, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2441 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2442 // Multicurrency Amount VAT
2443 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2444 }
2445 print '</tr>';
2446
2447 // Amount Local Taxes
2448 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) {
2449 print '<tr>';
2450 print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
2451 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2452 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2453 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2454 }
2455 print '</tr>';
2456
2457 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
2458 print '<tr>';
2459 print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
2460 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2461 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2462 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2463 }
2464 print '</tr>';
2465 }
2466 }
2467
2468 $alert = '';
2469 if (getDolGlobalString('ORDER_MANAGE_MIN_AMOUNT') && $object->total_ht < $object->thirdparty->supplier_order_min_amount) {
2470 $alert = ' ' . img_warning($langs->trans('OrderMinAmount') . ': ' . price($object->thirdparty->supplier_order_min_amount));
2471 }
2472
2473 print '<tr>';
2474 // Amount TTC
2475 print '<td>' . $langs->trans('AmountTTC') . '</td>';
2476 print '<td class="nowrap amountcard right">' . price($object->total_ttc, 0, $langs, 0, -1, -1, $conf->currency) . $alert . '</td>';
2477 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2478 // Multicurrency Amount TTC
2479 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ttc, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2480 }
2481 print '</tr>';
2482
2483 print '</table>';
2484
2485 // Margin Infos
2486 /*if (isModEnabled('margin')) {
2487 $formmargin->displayMarginInfos($object);
2488 }*/
2489
2490
2491 print '</div>';
2492 print '</div>';
2493
2494 print '<div class="clearboth"></div><br>';
2495
2496 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
2497 $blocname = 'contacts';
2498 $title = $langs->trans('ContactsAddresses');
2499 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2500 }
2501
2502 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
2503 $blocname = 'notes';
2504 $title = $langs->trans('Notes');
2505 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2506 }
2507
2508 /*
2509 * Lines
2510 */
2511 //$result = $object->getLinesArray();
2512
2513
2514 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
2515 <input type="hidden" name="token" value="'.newToken().'">
2516 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
2517 <input type="hidden" name="mode" value="">
2518 <input type="hidden" name="page_y" value="">
2519 <input type="hidden" name="id" value="'.$object->id.'">
2520 <input type="hidden" name="socid" value="'.$societe->id.'">
2521 ';
2522
2523 if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
2524 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
2525 }
2526
2527 print '<div class="div-table-responsive-no-min">';
2528 print '<table id="tablelines" class="noborder noshadow centpercent">';
2529
2530 // Add free products/services form
2531 global $forceall, $senderissupplier, $dateSelector, $inputalsopricewithtax;
2532 $forceall = 1;
2533 $dateSelector = 0;
2534 $inputalsopricewithtax = 1;
2535 $senderissupplier = 2; // $senderissupplier=2 is same than 1 but disable test on minimum qty and disable autofill qty with minimum.
2536 if (getDolGlobalInt('SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY')) {
2537 $senderissupplier = getDolGlobalInt('SUPPLIER_ORDER_WITH_PREDEFINED_PRICES_ONLY');
2538 }
2539
2540 // Show object lines
2541 if (!empty($object->lines)) {
2542 $object->printObjectLines($action, $object->thirdparty, $mysoc, $lineid, 1);
2543 }
2544
2545 $num = count($object->lines);
2546
2547 // Form to add new line
2548 if ($object->status == CommandeFournisseur::STATUS_DRAFT && $usercancreate) {
2549 if ($action != 'editline') {
2550 // Add free products/services
2551
2552 $parameters = array();
2553 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2554 if ($reshook < 0) {
2555 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2556 }
2557 if (empty($reshook)) {
2558 $object->formAddObjectLine(1, $societe, $mysoc);
2559 }
2560 }
2561 }
2562 print '</table>';
2563 print '</div>';
2564 print '</form>';
2565 }
2566
2567 print dol_get_fiche_end();
2568
2573 if ($user->socid == 0 && $action != 'delete') {
2574 if ($action != 'createorder' && $action != 'presend' && $action != 'editline') {
2575 print '<div class="tabsAction">';
2576
2577 $parameters = array();
2578 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
2579 // modified by hook
2580 if (empty($reshook)) {
2581 $object->fetchObjectLinked(); // Links are used to show or not button, so we load them now.
2582
2583 // Validate
2584 if ($object->status == 0 && $num > 0) {
2585 if ($usercanvalidate) {
2586 $tmpbuttonlabel = $langs->trans('Validate');
2587 if ($usercanapprove && !getDolGlobalString('SUPPLIER_ORDER_NO_DIRECT_APPROVE')) {
2588 $tmpbuttonlabel = $langs->trans("ValidateAndApprove");
2589 }
2590
2591 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=valid&token='.newToken().'">';
2592 print $tmpbuttonlabel;
2593 print '</a>';
2594 }
2595 }
2596 // Create event
2597 /*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.
2598 {
2599 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>';
2600 }*/
2601
2602 // Modify
2604 if ($usercanorder) {
2605 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("Modify").'</a>';
2606 }
2607 }
2608
2609 // Approve
2611 if ($usercanapprove) {
2612 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)) {
2613 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("FirstApprovalAlreadyDone")).'">'.$langs->trans("ApproveOrder").'</a>';
2614 } else {
2615 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=approve">'.$langs->trans("ApproveOrder").'</a>';
2616 }
2617 } else {
2618 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("ApproveOrder").'</a>';
2619 }
2620 }
2621
2622 // Second approval (if option SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set)
2623 if (getDolGlobalString('SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED') && $object->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) {
2625 if ($usercanapprovesecond) {
2626 if (!empty($object->user_approve_id2)) {
2627 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("SecondApprovalAlreadyDone")).'">'.$langs->trans("Approve2Order").'</a>';
2628 } else {
2629 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=approve2">'.$langs->trans("Approve2Order").'</a>';
2630 }
2631 } else {
2632 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("Approve2Order").'</a>';
2633 }
2634 }
2635 }
2636
2637 // Refuse
2639 if ($usercanapprove || $usercanapprovesecond) {
2640 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=refuse">'.$langs->trans("RefuseOrder").'</a>';
2641 } else {
2642 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans("RefuseOrder").'</a>';
2643 }
2644 }
2645
2646 // Send
2647 if (empty($user->socid)) {
2648 if (in_array($object->status, array(CommandeFournisseur::STATUS_ACCEPTED, 3, 4, 5)) || getDolGlobalString('SUPPLIER_ORDER_SENDBYEMAIL_FOR_ALL_STATUS')) {
2649 if ($usercanorder) {
2650 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendMail').'</a>';
2651 }
2652 }
2653 }
2654
2655 // Reopen
2656 if (in_array($object->status, array(CommandeFournisseur::STATUS_ACCEPTED))) {
2657 $buttonshown = 0;
2658 if (!$buttonshown && $usercanapprove) {
2659 if (!getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER_ONLY')
2660 || (getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER_ONLY') && $user->id == $object->user_approve_id)) {
2661 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("Disapprove").'</a>';
2662 $buttonshown++;
2663 }
2664 }
2665 if (!$buttonshown && $usercanapprovesecond && getDolGlobalString('SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED')) {
2666 if (!getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER2_ONLY')
2667 || (getDolGlobalString('SUPPLIER_ORDER_REOPEN_BY_APPROVER2_ONLY') && $user->id == $object->user_approve_id2)) {
2668 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("Disapprove").'</a>';
2669 }
2670 }
2671 }
2672 if (in_array($object->status, array(3, 4, 5, 6, 7, 9))) {
2673 if ($usercanorder) {
2674 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().'">'.$langs->trans("ReOpen").'</a>';
2675 }
2676 }
2677
2678 // Ship
2679 $hasreception = 0;
2680 if (isModEnabled('stock') && (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION') || getDolGlobalString('STOCK_CALCULATE_ON_RECEPTION_CLOSE'))) {
2681 $labelofbutton = $langs->trans('ReceiveProducts');
2682 if (isModEnabled('reception')) {
2683 $labelofbutton = $langs->trans("CreateReception");
2684 if (!empty($object->linkedObjects['reception'])) {
2685 foreach ($object->linkedObjects['reception'] as $element) {
2686 if ($element->statut >= 0) {
2687 $hasreception = 1;
2688 break;
2689 }
2690 }
2691 }
2692 }
2693
2694 // To avoid delete order with dispatched lines
2695 if (getDolGlobalString('STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER')) {
2696 if (empty($object->lines)) {
2697 $object->fetch_lines();
2698 }
2699 $dispachedLines = $object->getDispachedLines(1);
2700 $nbDispachedLines = count($dispachedLines);
2701 if ($nbDispachedLines > 0) {
2702 $hasreception = 1;
2703 }
2704 }
2705
2706 if (in_array($object->status, array(3, 4, 5))) {
2707 if (isModEnabled("supplier_order") && $usercanreceive) {
2708 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fourn/commande/dispatch.php?id='.$object->id.'">'.$labelofbutton.'</a></div>';
2709 } else {
2710 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$labelofbutton.'</a></div>';
2711 }
2712 }
2713 }
2714
2716 if ($usercanorder) {
2717 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>';
2718 } else {
2719 print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">'.$langs->trans("MakeOrder").'</a></div>';
2720 }
2721 }
2722
2723 // Classify received (this does not record reception)
2725 if ($usercanreceive) {
2726 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>';
2727 }
2728 }
2729
2730 // Create bill
2731 //if (isModEnabled('facture'))
2732 //{
2733 if (isModEnabled("supplier_invoice") && ($object->status >= 2 && $object->status != 7 && $object->billed != 1)) { // statut 2 means approved, 7 means canceled
2734 if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight("supplier_invoice", "creer")) {
2735 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>';
2736 }
2737 }
2738 //}
2739
2740 // Classify billed manually (need one invoice if module invoice is on, no condition on invoice if not)
2741 if ($usercancreate && $object->status >= 2 && $object->status != 7 && $object->billed != 1) { // statut 2 means approved
2742 if (!isModEnabled('invoice')) {
2743 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled&token='.newToken().'">'.$langs->trans("ClassifyBilled").'</a>';
2744 } else {
2745 if (!empty($object->linkedObjectsIds['invoice_supplier']) || (empty($object->linkedObjectsIds['invoice_supplier']) && !getDolGlobalInt('SUPPLIER_ORDER_DISABLE_CLASSIFY_BILLED_FROM_SUPPLIER_ORDER'))) {
2746 if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight("supplier_invoice", "creer")) {
2747 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifybilled&token='.newToken().'">'.$langs->trans("ClassifyBilled").'</a>';
2748 }
2749 } else {
2750 print '<a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NeedAtLeastOneInvoice")).'">'.$langs->trans("ClassifyBilled").'</a>';
2751 }
2752 }
2753 }
2754
2755 // Classify unbilled manually
2756 if ($usercancreate && $object->billed > 0 && $object->status > $object::STATUS_DRAFT) {
2757 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=classifyunbilled&token='.newToken().'">'.$langs->trans("ClassifyUnbilled").'</a>';
2758 }
2759
2760 // Clone
2761 if ($usercancreate) {
2762 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>';
2763 }
2764
2765 // Cancel
2767 if ($usercanorder) {
2768 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=cancel&amp;token='.newToken().'">'.$langs->trans("CancelOrder").'</a>';
2769 }
2770 }
2771
2772 // Delete
2773 if (!empty($usercandelete)) {
2774 if ($hasreception) {
2775 print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("ReceptionExist").'">'.$langs->trans("Delete").'</a>';
2776 } else {
2777 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'">'.$langs->trans("Delete").'</a>';
2778 }
2779 }
2780 }
2781
2782 print "</div>";
2783 }
2784
2785 if ($usercanorder && $object->status == CommandeFournisseur::STATUS_ACCEPTED && $action == 'createorder') {
2786 // Set status to ordered (action=commande)
2787 print '<!-- form to record supplier order -->'."\n";
2788 print '<form name="commande" id="makeorder" action="card.php?id='.$object->id.'&amp;action=commande" method="POST">';
2789
2790 print '<input type="hidden" name="token" value="'.newToken().'">';
2791 print '<input type="hidden" name="action" value="commande">';
2792 print load_fiche_titre($langs->trans("ToOrder"), '', '');
2793 print '<table class="noborder centpercent">';
2794 //print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("ToOrder").'</td></tr>';
2795 print '<tr><td class="fieldrequired">'.$langs->trans("OrderDate").'</td><td>';
2796 $date_com = dol_mktime(GETPOSTINT('rehour'), GETPOSTINT('remin'), GETPOSTINT('resec'), GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
2797 print $form->selectDate($date_com ?: '', '', 0, 0, 0, "commande", 1, 1);
2798 print '</td></tr>';
2799
2800 // Force mandatory order method
2801 print '<tr><td class="fieldrequired">'.$langs->trans("OrderMode").'</td><td>';
2802 $formorder->selectInputMethod(GETPOST('methodecommande'), "methodecommande", 1);
2803 print '</td></tr>';
2804
2805 print '<tr><td>'.$langs->trans("Comment").'</td><td><input class="quatrevingtpercent" type="text" name="comment" value="'.GETPOST('comment').'"></td></tr>';
2806
2807 print '<tr><td class="center" colspan="2">';
2808 print '<input type="submit" name="makeorder" class="button" value="'.$langs->trans("ToOrder").'">';
2809 print ' &nbsp; &nbsp; ';
2810 print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
2811 print '</td></tr>';
2812 print '</table>';
2813
2814 print '</form>';
2815 print "<br>";
2816 }
2817
2818 // Select mail models is same action as presend
2819 if (GETPOST('modelselected')) {
2820 $action = 'presend';
2821 }
2822
2823 if ($action != 'createorder' && $action != 'presend') {
2824 print '<div class="fichecenter"><div class="fichehalfleft">';
2825
2826 // Generated documents
2827 $objref = dol_sanitizeFileName($object->ref);
2828 $file = $conf->fournisseur->dir_output.'/commande/'.$objref.'/'.$objref.'.pdf';
2829 $relativepath = $objref.'/'.$objref.'.pdf';
2830 $filedir = $conf->fournisseur->dir_output.'/commande/'.$objref;
2831 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2832 $genallowed = $usercanread;
2833 $delallowed = $usercancreate;
2834 $modelpdf = (!empty($object->model_pdf) ? $object->model_pdf : (!getDolGlobalString('COMMANDE_SUPPLIER_ADDON_PDF') ? '' : $conf->global->COMMANDE_SUPPLIER_ADDON_PDF));
2835
2836 print $formfile->showdocuments('commande_fournisseur', $objref, $filedir, $urlsource, (int) $genallowed, (int) $delallowed, $modelpdf, 1, 0, 0, 0, 0, '', '', '', $object->thirdparty->default_lang, '', $object);
2837 $somethingshown = $formfile->numoffiles;
2838
2839 // Show links to link elements
2840 $tmparray = $form->showLinkToObjectBlock($object, array(), array('supplier_order', 'order_supplier'), 1);
2841 $linktoelem = $tmparray['linktoelem'];
2842 $htmltoenteralink = $tmparray['htmltoenteralink'];
2843 print $htmltoenteralink;
2844
2845 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2846
2847 print '</div><div class="fichehalfright">';
2848
2849 if ($action == 'classifyreception') {
2851 // Set status to received (action=livraison)
2852 print '<!-- form to record purchase order received -->'."\n";
2853 print '<form id="classifyreception" action="card.php?id='.$object->id.'" method="post">';
2854 print '<input type="hidden" name="token" value="'.newToken().'">';
2855 print '<input type="hidden" name="action" value="livraison">';
2856 print load_fiche_titre($langs->trans("Receive"), '', '');
2857
2858 print '<table class="noborder centpercent">';
2859 //print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Receive").'</td></tr>';
2860 print '<tr><td>'.$langs->trans("DeliveryDate").'</td><td>';
2861 $datepreselected = dol_now();
2862 print $form->selectDate($datepreselected, '', 1, 1, 0, "commande", 1, 1);
2863 print "</td></tr>\n";
2864
2865 print '<tr><td class="fieldrequired">'.$langs->trans("Delivery")."</td><td>\n";
2866 $liv = array();
2867 $liv[''] = '&nbsp;';
2868 $liv['tot'] = $langs->trans("CompleteOrNoMoreReceptionExpected");
2869 $liv['par'] = $langs->trans("PartialWoman");
2870 $liv['nev'] = $langs->trans("NeverReceived");
2871 $liv['can'] = $langs->trans("Canceled");
2872
2873 print $form->selectarray("type", $liv);
2874
2875 print '</td></tr>';
2876 print '<tr><td>'.$langs->trans("Comment").'</td><td><input class="quatrevingtpercent" type="text" name="comment"></td></tr>';
2877 print '<tr><td class="center" colspan="2">';
2878 print '<input type="submit" name="receive" class="button" value="'.$langs->trans("Receive").'">';
2879 print ' &nbsp; &nbsp; ';
2880 print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
2881 print '</td></tr>';
2882 print "</table>\n";
2883 print "</form>\n";
2884 print "<br>";
2885 }
2886 }
2887
2888 // List of actions on element
2889 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2890 $formactions = new FormActions($db);
2891 $somethingshown = $formactions->showactions($object, 'order_supplier', $socid, 1, 'listaction'.($genallowed ? 'largetitle' : ''));
2892
2893 print '</div></div>';
2894 }
2895
2896 /*
2897 * Action webservice
2898 */
2899 if ($action == 'webservice' && GETPOST('mode', 'alpha') != "send" && !GETPOST('cancel', 'alpha')) {
2900 $mode = GETPOST('mode', 'alpha');
2901 $ws_url = $object->thirdparty->webservices_url;
2902 $ws_key = $object->thirdparty->webservices_key;
2903 $ws_user = GETPOST('ws_user', 'alpha');
2904 $ws_password = GETPOST('ws_password', 'alpha');
2905 $error_occurred = false;
2906
2907 // NS and Authentication parameters
2908 $ws_ns = 'http://www.dolibarr.org/ns/';
2909 $ws_authentication = array(
2910 'dolibarrkey' => $ws_key,
2911 'sourceapplication' => 'DolibarrWebServiceClient',
2912 'login' => $ws_user,
2913 'password' => $ws_password,
2914 'entity' => ''
2915 );
2916
2917 print load_fiche_titre($langs->trans('CreateRemoteOrder'), '');
2918
2919 //Is everything filled?
2920 if (empty($ws_url) || empty($ws_key)) {
2921 setEventMessages($langs->trans("ErrorWebServicesFieldsRequired"), null, 'errors');
2922 $mode = "init";
2923 $error_occurred = true; //Don't allow to set the user/pass if thirdparty fields are not filled
2924 } elseif ($mode != "init" && (empty($ws_user) || empty($ws_password))) {
2925 setEventMessages($langs->trans("ErrorFieldsRequired"), null, 'errors');
2926 $mode = "init";
2927 }
2928
2929 if ($mode == "init") {
2930 //Table/form header
2931 print '<table class="border centpercent">';
2932 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
2933 print '<input type="hidden" name="token" value="'.newToken().'">';
2934 print '<input type="hidden" name="action" value="webservice">';
2935 print '<input type="hidden" name="mode" value="check">';
2936
2937 if ($error_occurred) {
2938 print "<br>".$langs->trans("ErrorOccurredReviseAndRetry")."<br>";
2939 print '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
2940 } else {
2941 // Webservice url
2942 print '<tr><td>'.$langs->trans("WebServiceURL").'</td><td colspan="3">'.dol_print_url($ws_url).'</td></tr>';
2943 //Remote User
2944 print '<tr><td>'.$langs->trans("User").'</td><td><input class="width100" type="text" name="ws_user"></td></tr>';
2945 //Remote Password
2946 print '<tr><td>'.$langs->trans("Password").'</td><td><input class="width100" type="text" name="ws_password"></td></tr>';
2947 //Submit button
2948 print '<tr><td class="center" colspan="2">';
2949 print '<input type="submit" class="button" id="ws_submit" name="ws_submit" value="'.$langs->trans("CreateRemoteOrder").'">';
2950 print ' &nbsp; &nbsp; ';
2951 //Cancel button
2952 print '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
2953 print '</td></tr>';
2954 }
2955
2956 //End table/form
2957 print '</form>';
2958 print '</table>';
2959 } elseif ($mode == "check") {
2960 $ws_entity = '';
2961 $ws_thirdparty = '';
2962 $error_occurred = false;
2963
2964 //Create SOAP client and connect it to user
2965 $soapclient_user = new nusoap_client($ws_url."/webservices/server_user.php");
2966 $soapclient_user->soap_defencoding = 'UTF-8';
2967 $soapclient_user->decodeUTF8(false);
2968
2969 //Get the thirdparty associated to user
2970 $ws_parameters = array('authentication' => $ws_authentication, 'id' => '', 'ref' => $ws_user);
2971 $result_user = $soapclient_user->call("getUser", $ws_parameters, $ws_ns, '');
2972 $user_status_code = $result_user["result"]["result_code"];
2973
2974 if ($user_status_code == "OK") {
2975 //Fill the variables
2976 $ws_entity = $result_user["user"]["entity"];
2977 $ws_authentication['entity'] = $ws_entity;
2978 $ws_thirdparty = $result_user["user"]["fk_thirdparty"];
2979 if (empty($ws_thirdparty)) {
2980 setEventMessages($langs->trans("RemoteUserMissingAssociatedSoc"), null, 'errors');
2981 $error_occurred = true;
2982 } else {
2983 //Create SOAP client and connect it to product/service
2984 $soapclient_product = new nusoap_client($ws_url."/webservices/server_productorservice.php");
2985 $soapclient_product->soap_defencoding = 'UTF-8';
2986 $soapclient_product->decodeUTF8(false);
2987
2988 // Iterate each line and get the reference that uses the supplier of that product/service
2989 $i = 0;
2990 foreach ($object->lines as $line) {
2991 $i += 1;
2992 $ref_supplier = $line->ref_supplier;
2993 $line_id = $i."º) ".$line->product_ref.": ";
2994 if (empty($ref_supplier)) {
2995 continue;
2996 }
2997 $ws_parameters = array('authentication' => $ws_authentication, 'id' => '', 'ref' => $ref_supplier);
2998 $result_product = $soapclient_product->call("getProductOrService", $ws_parameters, $ws_ns, '');
2999 if (!$result_product) {
3000 setEventMessages($line_id.$langs->trans("Error")." SOAP ".$soapclient_product->error_str." - ".$soapclient_product->response, null, 'errors');
3001 $error_occurred = true;
3002 break;
3003 }
3004
3005 // Check the result code
3006 $status_code = $result_product["result"]["result_code"];
3007 if (empty($status_code)) { //No result, check error str
3008 setEventMessages($langs->trans("Error")." SOAP '".$soapclient_product->error_str."'", null, 'errors');
3009 } elseif ($status_code != "OK") { //Something went wrong
3010 if ($status_code == "NOT_FOUND") {
3011 setEventMessages($line_id.$langs->trans("SupplierMissingRef")." '".$ref_supplier."'", null, 'warnings');
3012 } else {
3013 setEventMessages($line_id.$langs->trans("ResponseNonOK")." '".$status_code."' - '".$result_product["result"]["result_label"]."'", null, 'errors');
3014 $error_occurred = true;
3015 break;
3016 }
3017 }
3018
3019
3020 // Ensure that price is equal and warn user if it's not
3021 $supplier_price = price($result_product["product"]["price_net"]); //Price of client tab in supplier dolibarr
3022 $local_price = null; //Price of supplier as stated in product suppliers tab on this dolibarr, NULL if not found
3023
3024 $product_fourn = new ProductFournisseur($db);
3025 $product_fourn_list = $product_fourn->list_product_fournisseur_price($line->fk_product);
3026 if (count($product_fourn_list) > 0) {
3027 foreach ($product_fourn_list as $product_fourn_line) {
3028 //Only accept the line where the supplier is the same at this order and has the same ref
3029 if ($product_fourn_line->fourn_id == $object->socid && $product_fourn_line->fourn_ref == $ref_supplier) {
3030 $local_price = price($product_fourn_line->fourn_price);
3031 }
3032 }
3033 }
3034
3035 if ($local_price != null && $local_price != $supplier_price) {
3036 setEventMessages($line_id.$langs->trans("RemotePriceMismatch")." ".$supplier_price." - ".$local_price, null, 'warnings');
3037 }
3038
3039 // Check if is in sale
3040 if (empty($result_product["product"]["status_tosell"])) {
3041 setEventMessages($line_id.$langs->trans("ProductStatusNotOnSellShort")." '".$ref_supplier."'", null, 'warnings');
3042 }
3043 }
3044 }
3045 } elseif ($user_status_code == "PERMISSION_DENIED") {
3046 setEventMessages($langs->trans("RemoteUserNotPermission"), null, 'errors');
3047 $error_occurred = true;
3048 } elseif ($user_status_code == "BAD_CREDENTIALS") {
3049 setEventMessages($langs->trans("RemoteUserBadCredentials"), null, 'errors');
3050 $error_occurred = true;
3051 } else {
3052 setEventMessages($langs->trans("ResponseNonOK")." '".$user_status_code."'", null, 'errors');
3053 $error_occurred = true;
3054 }
3055
3056 //Form
3057 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
3058 print '<input type="hidden" name="token" value="'.newToken().'">';
3059 print '<input type="hidden" name="action" value="webservice">';
3060 print '<input type="hidden" name="mode" value="send">';
3061 print '<input type="hidden" name="ws_user" value="'.$ws_user.'">';
3062 print '<input type="hidden" name="ws_password" value="'.$ws_password.'">';
3063 print '<input type="hidden" name="ws_entity" value="'.$ws_entity.'">';
3064 print '<input type="hidden" name="ws_thirdparty" value="'.$ws_thirdparty.'">';
3065 if ($error_occurred) {
3066 print "<br>".$langs->trans("ErrorOccurredReviseAndRetry")."<br>";
3067 } else {
3068 print '<input type="submit" class="button" id="ws_submit" name="ws_submit" value="'.$langs->trans("Confirm").'">';
3069 print ' &nbsp; &nbsp; ';
3070 }
3071 print '<input class="button button-cancel" type="submit" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
3072 print '</form>';
3073 }
3074 }
3075
3076 // Presend form
3077 $modelmail = 'order_supplier_send';
3078 $defaulttopic = 'SendOrderRef';
3079 $diroutput = $conf->fournisseur->commande->dir_output;
3080 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO';
3081 $trackid = 'sord'.$object->id;
3082
3083 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
3084 }
3085}
3086
3087// End of page
3088llxFooter();
3089$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.