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