dolibarr 25.0.0-alpha
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
5 * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
6 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
8 * Copyright (C) 2010-2014 Juanjo Menent <jmenent@2byte.es>
9 * Copyright (C) 2010-2019 Philippe Grand <philippe.grand@atoo-net.com>
10 * Copyright (C) 2012-2013 Christophe Battarel <christophe.battarel@altairis.fr>
11 * Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
12 * Copyright (C) 2014 Ferran Marcet <fmarcet@2byte.es>
13 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
14 * Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com>
15 * Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
16 * Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
17 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
18 * Copyright (C) 2026 Lionel Vessiller <lvessiller@open-dsi.fr>
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 3 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program. If not, see <https://www.gnu.org/licenses/>.
32 */
33
40// Load Dolibarr environment
41require '../main.inc.php';
42require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
43require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
44require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
45require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php';
46require_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php';
47require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
48require_once DOL_DOCUMENT_ROOT.'/core/modules/supplier_proposal/modules_supplier_proposal.php';
49require_once DOL_DOCUMENT_ROOT.'/core/lib/supplier_proposal.lib.php';
50require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
51require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
52if (isModEnabled('project')) {
53 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
54 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
55}
56
66// Load translation files required by the page
67$langs->loadLangs(array('companies', 'supplier_proposal', 'compta', 'bills', 'propal', 'orders', 'products', 'sendings'));
68if (isModEnabled('margin')) {
69 $langs->load('margins');
70}
71
72$error = 0;
73
74$id = GETPOSTINT('id');
75$ref = GETPOST('ref', 'alpha');
76$socid = GETPOSTINT('socid');
77$action = GETPOST('action', 'aZ09');
78$cancel = GETPOST('cancel', 'alpha');
79$backtopage = GETPOST('backtopage', 'alpha');
80$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
81
82$origin = GETPOST('origin', 'alpha');
83$originid = GETPOSTINT('originid');
84$confirm = GETPOST('confirm', 'alpha');
85$lineid = GETPOSTINT('lineid');
86$contactid = GETPOSTINT('contactid');
87$projectid = GETPOSTINT('projectid');
88$rank = (GETPOSTINT('rank') > 0) ? GETPOSTINT('rank') : -1;
89
90// PDF
91$hidedetails = (GETPOSTINT('hidedetails') ? GETPOSTINT('hidedetails') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0));
92$hidedesc = (GETPOSTINT('hidedesc') ? GETPOSTINT('hidedesc') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0));
93$hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0));
94
95// Number of line to choose predefined product/service from
96$NBLINES = 4;
97
98// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
99$hookmanager->initHooks(array('supplier_proposalcard', 'globalcard'));
100
101$object = new SupplierProposal($db);
102$extrafields = new ExtraFields($db);
103
104$objectsrc = null;
105$classname = null;
106
107// fetch optionals attributes and labels
108$extrafields->fetch_name_optionals_label($object->table_element);
109
110// Load object
111if ($id > 0 || !empty($ref)) {
112 $ret = $object->fetch($id, $ref);
113 if ($ret > 0) {
114 $ret = $object->fetch_thirdparty();
115 }
116 if ($ret <= 0) {
117 setEventMessages($object->error, $object->errors, 'errors');
118 $action = '';
119 }
120}
121
122// Common permissions
123$usercanread = $user->hasRight('supplier_proposal', 'lire');
124$usercancreate = $user->hasRight('supplier_proposal', 'creer');
125$usercandelete = $user->hasRight('supplier_proposal', 'supprimer');
126
127// Advanced permissions
128$usercanvalidate = ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !empty($usercancreate)) || (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('supplier_proposal', 'validate_advance')));
129$usercansend = (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('supplier_proposal', 'send_advance'));
130
131// Additional area permissions
132$usercanclose = $user->hasRight('supplier_proposal', 'cloturer');
133$usercancreateorder = ($user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer'));
134
135// Permissions for includes
136$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
137$permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
138$permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php
139$permissiontoadd = $usercancreate;
140$permissiontoeditextra = $permissiontoadd;
141if (GETPOST('attribute', 'aZ09') && isset($extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')])) {
142 // For action 'update_extras', is there a specific permission set for the attribute to update
143 $permissiontoeditextra = dol_eval((string) $extrafields->attributes[$object->table_element]['perms'][GETPOST('attribute', 'aZ09')]);
144}
145
146// Security check
147if (!empty($user->socid)) {
148 $socid = $user->socid;
149}
150$result = restrictedArea($user, 'supplier_proposal', $object->id);
151
152
153/*
154 * Actions
155 */
156
157$parameters = array('socid' => $socid);
158$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
159if ($reshook < 0) {
160 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
161}
162
163$fournprice = 0;
164$buyingprice = 0;
165
166if (empty($reshook)) {
167 $backurlforlist = DOL_URL_ROOT.'/supplier_proposal/list.php';
168
169 if (empty($backtopage) || ($cancel && empty($id))) {
170 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
171 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
172 $backtopage = $backurlforlist;
173 } else {
174 $backtopage = DOL_URL_ROOT.'/supplier_proposal/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
175 }
176 }
177 }
178
179 if ($cancel && !($action == 'updateline' && $usercancreate)) {
180 if (!empty($backtopageforcancel)) {
181 header("Location: ".$backtopageforcancel);
182 exit;
183 } elseif (!empty($backtopage)) {
184 header("Location: ".$backtopage);
185 exit;
186 }
187 $action = '';
188 }
189
190 include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be 'include', not 'include_once'
191
192 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be 'include', not 'include_once'
193
194 include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
195
196 // Action clone object
197 if ($action == 'confirm_clone' && $confirm == 'yes' && $usercancreate) {
198 if (false && !GETPOST('clone_content') && !GETPOST('clone_receivers')) {
199 setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
200 } else {
201 if ($object->id > 0) {
202 $result = $object->createFromClone($user, $socid);
203 if ($result > 0) {
204 header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
205 exit();
206 } else {
207 setEventMessages($object->error, $object->errors, 'errors');
208 $action = '';
209 }
210 }
211 }
212 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $usercandelete) {
213 // Delete askprice
214 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
215 $result = $object->delete($user);
216 if ($result > 0) {
217 header('Location: '.DOL_URL_ROOT.'/supplier_proposal/list.php');
218 exit();
219 } else {
220 $langs->load("errors");
221 setEventMessages($langs->trans($object->error), null, 'errors');
222 }
223 } elseif ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate) {
224 // Remove line
225 $result = $object->deleteLine($lineid);
226 // reorder lines
227 if ($result > 0) {
228 $object->line_order(true);
229 } else {
230 $langs->load("errors");
231 setEventMessages($object->error, $object->errors, 'errors');
232 }
233
234 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
235 // Define output language
236 $outputlangs = $langs;
237 if (getDolGlobalInt('MAIN_MULTILANGS')) {
238 $outputlangs = new Translate("", $conf);
239 $newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $object->thirdparty->default_lang);
240 $outputlangs->setDefaultLang($newlang);
241 }
242 $ret = $object->fetch($id); // Reload to get new records
243 if ($ret > 0) {
244 $object->fetch_thirdparty();
245 }
246 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
247 }
248
249 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
250 exit();
251 } elseif ($action == 'confirm_delete_subtotalline' && $confirm == 'yes' && $usercancreate) {
252 // Delete line
253 $object->fetch($id);
254 $object->fetch_thirdparty();
255
256 $result = $object->deleteSubtotalLine($langs, GETPOSTINT('lineid'), (bool) GETPOST('deletecorrespondingsubtotalline'));
257 if ($result > 0) {
258 // reorder lines
259 $object->line_order(true);
260 // Define output language
261 $outputlangs = $langs;
262 $newlang = '';
263 if (getDolGlobalInt('MAIN_MULTILANGS') && GETPOST('lang_id')) {
264 $newlang = GETPOST('lang_id');
265 }
266 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
267 $newlang = $object->thirdparty->default_lang;
268 }
269 if (!empty($newlang)) {
270 $outputlangs = new Translate("", $conf);
271 $outputlangs->setDefaultLang($newlang);
272 $outputlangs->load('products');
273 }
274 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
275 $ret = $object->fetch($id); // Reload to get new records
276 $result = $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
277 }
278 if ($result >= 0) {
279 header('Location: '.dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $id]));
280 exit();
281 }
282 } else {
283 setEventMessages($object->error, $object->errors, 'errors');
284 $action = '';
285 }
286 } elseif ($action == 'confirm_validate' && $confirm == 'yes' && $usercanvalidate) {
287 // Validation
288 $result = $object->valid($user);
289 if ($result >= 0) {
290 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
291 $outputlangs = $langs;
292 $newlang = '';
293 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
294 $newlang = GETPOST('lang_id', 'aZ09');
295 }
296 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
297 $newlang = $object->thirdparty->default_lang;
298 }
299 if (!empty($newlang)) {
300 $outputlangs = new Translate("", $conf);
301 $outputlangs->setDefaultLang($newlang);
302 }
303 $model = $object->model_pdf;
304 $ret = $object->fetch($id); // Reload to get new records
305 if ($ret > 0) {
306 $object->fetch_thirdparty();
307 }
308
309 $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
310 }
311 } else {
312 $langs->load("errors");
313 if (count($object->errors) > 0) {
314 setEventMessages($object->error, $object->errors, 'errors');
315 } else {
316 setEventMessages($langs->trans($object->error), null, 'errors');
317 }
318 }
319 } elseif ($action == 'setdate_livraison' && $usercancreate) {
320 $result = $object->setDeliveryDate($user, dol_mktime(12, 0, 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year')));
321 if ($result < 0) {
322 dol_print_error($db, $object->error);
323 }
324 } elseif ($action == 'add' && $usercancreate) {
325 // Create supplier proposal
326 $object->socid = $socid;
327 $object->fetch_thirdparty();
328
329 $date_delivery = dol_mktime(12, 0, 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
330
331 if ($socid < 1) {
332 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Supplier")), null, 'errors');
333 $action = 'create';
334 $error++;
335 }
336
337 if (!$error) {
338 $db->begin();
339
340 $model_pdf = (GETPOST('model') != '0' && GETPOST('model') != '-1') ? GETPOST('model') : '';
341
342 // When a copy request was made, make the copy
343 if (GETPOST('createmode') == 'copy' && GETPOSTINT('copie_supplier_proposal') > 0) {
344 if ($object->fetch(GETPOSTINT('copie_supplier_proposal')) > 0) {
345 $object->ref = GETPOST('ref');
346 $object->delivery_date = $date_delivery;
347 $object->shipping_method_id = GETPOSTINT('shipping_method_id');
348 $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
349 $object->deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
350 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
351 $object->fk_account = GETPOSTINT('fk_account');
352 $object->socid = GETPOSTINT('socid');
353 $object->fk_project = GETPOSTINT('projectid');
354 $object->model_pdf = $model_pdf;
355 $object->author = $user->id; // deprecated
356 $object->user_creation_id = $user->id;
357 $object->note = GETPOST('note', 'restricthtml');
358 $object->note_private = GETPOST('note', 'restricthtml');
361 } else {
362 setEventMessages($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_supplier_proposal')), null, 'errors');
363 }
364 } else {
365 $object->ref = GETPOST('ref');
366 $object->delivery_date = $date_delivery;
367 $object->demand_reason_id = GETPOSTINT('demand_reason_id');
368 $object->shipping_method_id = GETPOSTINT('shipping_method_id');
369 $object->cond_reglement_id = GETPOSTINT('cond_reglement_id');
370 $object->deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
371 $object->mode_reglement_id = GETPOSTINT('mode_reglement_id');
372 $object->fk_account = GETPOSTINT('fk_account');
373 $object->fk_project = GETPOSTINT('projectid');
374 $object->model_pdf = $model_pdf;
375 $object->author = $user->id; // deprecated
376 $object->user_creation_id = $user->id;
377 $object->note = GETPOST('note', 'restricthtml');
378 $object->note_private = GETPOST('note', 'restricthtml');
379
380 $object->origin = GETPOST('origin');
381 $object->origin_id = GETPOSTINT('originid');
382
383 // Multicurrency
384 if (isModEnabled("multicurrency")) {
385 $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
386 }
387
388 // Fill array 'array_options' with data from add form
389 $ret = $extrafields->setOptionalsFromPost(null, $object);
390 if ($ret < 0) {
391 $error++;
392 $action = 'create';
393 }
394 }
395
396 if (!$error) {
397 if ($origin && $originid) {
398 $object->origin = $origin;
399 $object->origin_type = $origin;
400 $object->origin_id = $originid;
401
402 // Possibility to add external linked objects with hooks
403 $object->linked_objects [$object->origin_type] = $object->origin_id;
404 if (GETPOSTISARRAY('other_linked_objects')) {
405 $object->linked_objects = array_merge($object->linked_objects, GETPOST('other_linked_objects', 'array:int'));
406 }
407
408 $id = $object->create($user);
409 if ($id > 0) {
410 dol_syslog("Try to find source object origin=".$object->origin_type." originid=".$object->origin_id." to add lines");
411
412 // Resolve and load the source object from its element type (propal, commande, contract, ...)
413 $srcobject = fetchObjectByElement($object->origin_id, $origin);
414
415 if (is_object($srcobject) && $srcobject->id > 0) {
416 '@phan-var-force Commande|Propal|Contrat|Fichinter|Expedition $srcobject'; // Maybe other class but CommonObject is too generic
417 $lines = $srcobject->lines;
418 if (empty($lines) && method_exists($srcobject, 'fetch_lines')) {
419 $srcobject->fetch_lines();
420 $lines = $srcobject->lines;
421 }
422
423 $fk_parent_line = 0;
424 $num = count($lines);
425 for ($i = 0; $i < $num; $i++) {
426 $label = (!empty($lines[$i]->label) ? $lines[$i]->label : '');
427 $desc = (!empty($lines[$i]->desc) ? $lines[$i]->desc : '');
428
429 // Positive line
430 $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
431
432 // Reset fk_parent_line for no child products and special product
433 if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
434 $fk_parent_line = 0;
435 }
436
437 // Extrafields
438 if (method_exists($lines[$i], 'fetch_optionals')) {
439 $lines[$i]->fetch_optionals();
440 $array_options = $lines[$i]->array_options;
441 } else {
442 $array_options = array();
443 }
444
445 // Preserve the TTC entry mode of the source line: a line entered including tax must
446 // stay in TTC so its total is computed from the typed value, without rounding drift.
447 $line_price_base_type = $lines[$i]->getPriceBaseType();
448 $result = $object->addline(
449 $desc,
450 $lines[$i]->subprice,
451 $lines[$i]->qty,
452 $lines[$i]->tva_tx,
453 $lines[$i]->localtax1_tx,
454 $lines[$i]->localtax2_tx,
455 $lines[$i]->fk_product,
456 $lines[$i]->remise_percent,
457 $line_price_base_type,
458 (float) $lines[$i]->subprice_ttc,
459 $lines[$i]->info_bits,
460 $product_type,
461 $lines[$i]->rang,
462 $lines[$i]->special_code,
463 $fk_parent_line,
464 $lines[$i]->fk_fournprice,
465 $lines[$i]->pa_ht,
466 $label,
467 $array_options,
468 $lines[$i]->ref_supplier,
469 $lines[$i]->fk_unit
470 );
471
472 if ($result > 0) {
473 $lineid = $result;
474 } else {
475 $lineid = 0;
476 $error++;
477 break;
478 }
479
480 // Defined the new fk_parent_line
481 if ($result > 0 && $lines[$i]->product_type == 9) {
482 $fk_parent_line = $result;
483 }
484 }
485
486 // Hooks
487 $parameters = array('objFrom' => $srcobject);
488 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been
489 // modified by hook
490 if ($reshook < 0) {
491 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
492 $error++;
493 }
494 } else {
495 if (is_object($srcobject) && !empty($srcobject->error)) {
496 setEventMessages($srcobject->error, $srcobject->errors, 'errors');
497 } else {
498 $langs->load("errors");
499 setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors');
500 }
501 $error++;
502 }
503 } else {
504 setEventMessages($object->error, $object->errors, 'errors');
505 $error++;
506 }
507 } else {
508 // Standard creation
509 $id = $object->create($user);
510 }
511
512 if ($id > 0) {
513 if (isModEnabled('category')) {
514 $categories = GETPOST('categories', 'array');
515 $object->setCategories($categories);
516 }
517 if (!$error) {
518 $db->commit();
519
520 // Define output language
521 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
522 $outputlangs = $langs;
523 $newlang = '';
524 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
525 $newlang = GETPOST('lang_id', 'aZ09');
526 }
527 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
528 $newlang = $object->thirdparty->default_lang;
529 }
530 if (!empty($newlang)) {
531 $outputlangs = new Translate("", $conf);
532 $outputlangs->setDefaultLang($newlang);
533 }
534 $model = $object->model_pdf;
535
536 if (!empty($model)) {
537 $ret = $object->fetch($id); // Reload to get new records
538 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
539 if ($result < 0) {
540 dol_print_error($db, $object->error, $object->errors);
541 }
542 }
543 }
544
545 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
546 exit();
547 } else {
548 $db->rollback();
549 $action = 'create';
550 }
551 } else {
552 setEventMessages($object->error, $object->errors, 'errors');
553 $db->rollback();
554 $action = 'create';
555 }
556 }
557 }
558 } elseif ($action == 'confirm_reopen' && $usercanclose && !GETPOST('cancel', 'alpha')) {
559 // Reopen proposal
560 // prevent browser refresh from reopening proposal several times
563 }
564 } elseif ($action == 'close' && $usercanclose && !GETPOST('cancel', 'alpha')) {
565 // Close proposal
566 // prevent browser refresh from reopening proposal several times
569 }
570 } elseif ($action == 'setstatut' && $usercanclose && !GETPOST('cancel', 'alpha')) {
571 // Set accepted/refused
572 if (!GETPOST('statut')) {
573 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), null, 'errors');
574 $action = 'statut';
575 } else {
576 // prevent browser refresh from closing proposal several times
578 $object->cloture($user, GETPOSTINT('statut'), GETPOST('note', 'restricthtml'));
579 }
580 }
581 } elseif ($action == 'addline' && GETPOST('updateallvatlinesblock', 'alpha') && GETPOST('vatforblocklines', 'alpha') !== '' && $usercancreate) {
582 $tx_tva = GETPOST('vatforblocklines') ? GETPOST('vatforblocklines') : 0;
583 $object->updateSubtotalLineBlockLines($langs, $object->getRangOfLine($lineid), 'tva', $tx_tva);
584 } elseif ($action == 'addline' && GETPOST('updatealldiscountlinesblock', 'alpha') && GETPOST('discountforblocklines', 'alpha') !== '' && $usercancreate) {
585 $discount = GETPOST('discountforblocklines') ? GETPOST('discountforblocklines') : 0;
586 $object->updateSubtotalLineBlockLines($langs, $object->getRangOfLine($lineid), 'discount', $discount);
587 } elseif ($action == 'settags' && isModEnabled('category') && $usercancreate) { // Set tags
588 $result = $object->setCategories(GETPOST('categories', 'array'));
589 }
590
591 // Actions when printing a doc from card
592 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
593
594 // Actions to send emails
595 $triggersendname = 'PROPOSAL_SUPPLIER_SENTBYMAIL';
596 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO';
597 $trackid = 'spro'.$object->id;
598 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
599
600 // Actions to build doc
601 $upload_dir = $conf->supplier_proposal->dir_output;
602 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
603
604 // Go back to draft
605 if ($action == 'modif' && $usercancreate) {
606 $object->setDraft($user);
607
608 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
609 // Define output language
610 $outputlangs = $langs;
611 if (getDolGlobalInt('MAIN_MULTILANGS')) {
612 $outputlangs = new Translate("", $conf);
613 $newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $object->thirdparty->default_lang);
614 $outputlangs->setDefaultLang($newlang);
615 }
616 $ret = $object->fetch($id); // Reload to get new records
617 if ($ret > 0) {
618 $object->fetch_thirdparty();
619 }
620 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
621 }
622 } elseif ($action == "setabsolutediscount" && $usercancreate) {
623 if (GETPOSTINT("remise_id")) {
624 if ($object->id > 0) {
625 $result = $object->insert_discount(GETPOSTINT("remise_id"));
626 if ($result < 0) {
627 setEventMessages($object->error, $object->errors, 'errors');
628 }
629 }
630 }
631 }
632
633 // Add a product line
634 if ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && GETPOST('vatforalllines', 'alpha') && $usercancreate) {
635 // Define vat_rate
636 $vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
637 $vat_rate = str_replace('*', '', $vat_rate);
638 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
639 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
640 foreach ($object->lines as $line) {
641 if ($line->special_code == SUBTOTALS_SPECIAL_CODE) {
642 continue;
643 }
644 // Preserve the original entry mode of the line so the total is not drifted by rounding.
645 $line_price_base_type = $line->getPriceBaseType();
646 $line_pu = ($line_price_base_type === 'TTC') ? (float) $line->subprice_ttc : (float) $line->subprice;
647 // In TTC mode, do not forward the HT currency price: under multicurrency updateline() would reset
648 // the local price and recompute from the HT currency amount (read as TTC) -> the TTC value is lost.
649 $line_pu_devise = ($line_price_base_type === 'TTC') ? 0 : (float) $line->multicurrency_subprice;
650 $result = $object->updateline($line->id, $line_pu, $line->qty, (float) $line->remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $line->desc, $line_price_base_type, $line->info_bits, $line->special_code, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->array_options, $line->ref_fourn, $line->fk_unit, $line_pu_devise);
651 }
652 } elseif ($action == 'confirm_addtextline' && $usercancreate) {
653 // Handling adding a new text line for subtotals module
654
655 $langs->load('subtotals');
656
657 $desc = GETPOST('subtotaltextcontent', 'restricthtml');
658
659 // Insert line
660 $result = $object->addSubtotalLine($langs, $desc, 0, array());
661
662 if ($result >= 0) {
663 if ($result == 0) {
664 setEventMessages($object->error, $object->errors, 'warnings');
665 }
666 $ret = $object->fetch($object->id); // Reload to get new records
667 $object->fetch_thirdparty();
668
669 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
670 // Define output language
671 $outputlangs = $langs;
672 $newlang = GETPOST('lang_id', 'alpha');
673 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
674 $newlang = $object->thirdparty->default_lang;
675 }
676 if (!empty($newlang)) {
677 $outputlangs = new Translate("", $conf);
678 $outputlangs->setDefaultLang($newlang);
679 }
680
681 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
682 }
683 } else {
684 setEventMessages($object->error, $object->errors, 'errors');
685 }
686 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
687 exit();
688 } elseif ($action == 'confirm_addtitleline' && $usercancreate) {
689 // Handling adding a new title line for subtotals module
690
691 $langs->load('subtotals');
692
693 $desc = GETPOST('subtotallinedesc', 'alphanohtml');
694 $depth = GETPOSTINT('subtotallinelevel') ?? 1;
695
696 $subtotal_options = array();
697
698 foreach (SupplierProposal::$TITLE_OPTIONS as $option) {
699 $value = GETPOST($option, 'alphanohtml');
700 if ($value) {
701 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
702 }
703 }
704
705 // Insert line
706 $result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
707
708 if ($result >= 0) {
709 if ($result == 0) {
710 setEventMessages($object->error, $object->errors, 'warnings');
711 }
712 $ret = $object->fetch($object->id); // Reload to get new records
713 $object->fetch_thirdparty();
714
715 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
716 // Define output language
717 $outputlangs = $langs;
718 $newlang = GETPOST('lang_id', 'alpha');
719 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
720 $newlang = $object->thirdparty->default_lang;
721 }
722 if (!empty($newlang)) {
723 $outputlangs = new Translate("", $conf);
724 $outputlangs->setDefaultLang($newlang);
725 }
726
727 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
728 }
729 } else {
730 setEventMessages($object->error, $object->errors, 'errors');
731 }
732 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
733 exit();
734 } elseif ($action == 'confirm_addsubtotalline' && $usercancreate) {
735 // Handling adding a new subtotal line for subtotals module
736
737 $langs->load('subtotals');
738
739 $choosen_line = GETPOST('subtotaltitleline', 'alphanohtml');
740 foreach ($object->lines as $line) {
741 if ($line->desc == $choosen_line && $line->special_code == SUBTOTALS_SPECIAL_CODE) {
742 $desc = $line->desc;
743 $depth = -$line->qty;
744 }
745 }
746
747 $subtotal_options = array();
748
749 foreach (SupplierProposal::$SUBTOTAL_OPTIONS as $option) {
750 $value = GETPOST($option, 'alphanohtml');
751 if ($value) {
752 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
753 }
754 }
755
756 // Insert line
757 if (isset($desc) && isset($depth)) {
758 $result = $object->addSubtotalLine($langs, $desc, (int) $depth, $subtotal_options);
759 } else {
760 $result = -1;
761 $object->errors[] = $langs->trans("CorrespondingTitleNotFound");
762 }
763
764 if ($result >= 0) {
765 $ret = $object->fetch($object->id); // Reload to get new records
766 $object->fetch_thirdparty();
767
768 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
769 // Define output language
770 $outputlangs = $langs;
771 $newlang = GETPOST('lang_id', 'alpha');
772 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
773 $newlang = $object->thirdparty->default_lang;
774 }
775 if (!empty($newlang)) {
776 $outputlangs = new Translate("", $conf);
777 $outputlangs->setDefaultLang($newlang);
778 }
779
780 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
781 }
782 } else {
783 setEventMessages($object->error, $object->errors, 'errors');
784 }
785 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
786 exit();
787 } elseif ($action == 'addline' && $usercancreate) {
788 $langs->load('errors');
789 $error = 0;
790
791 // Set if we used free entry or predefined product
792 $predef = '';
793 $line_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
794 $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'));
795 $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'));
796
797 $ref_supplier = GETPOST('fourn_ref', 'alpha');
798
799 $prod_entry_mode = GETPOST('prod_entry_mode', 'aZ09');
800 if ($prod_entry_mode == 'free') {
801 $idprod = 0;
802 } else {
803 $idprod = GETPOSTINT('idprod');
804 }
805
806 $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)'
807
808 $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
809 $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
810 $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
811 $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
812
813 $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2);
814
815 $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0);
816 if (empty($remise_percent)) {
817 $remise_percent = 0;
818 }
819
820 // Extrafields
821 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
822 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
823 // Unset extrafield
824 if (is_array($extralabelsline)) {
825 // Get extra fields
826 foreach ($extralabelsline as $key => $value) {
827 unset($_POST["options_".$key]);
828 }
829 }
830
831 if ($prod_entry_mode == 'free' && GETPOST('price_ht') < 0 && $qty < 0) {
832 setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPrice'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
833 $error++;
834 }
835 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) {
836 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
837 $error++;
838 }
839
840 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && GETPOST('multicurrency_price_ht') === '') { // Unit price can be 0 but not ''. Also price can be negative for proposal.
841 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPrice")), null, 'errors');
842 $error++;
843 }
844 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($line_desc)) {
845 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors');
846 $error++;
847 }
848 if (!$error && ($qty >= 0)) {
849 $pu_ht = price2num($price_ht, 'MU');
850 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
851 $price_min = 0;
852 $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
853
854 $db->begin();
855
856 if ($prod_entry_mode != 'free' && empty($error)) { // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or ''
857 $productsupplier = new ProductFournisseur($db);
858
859 $idprod = 0;
860 if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') {
861 $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, ...)
862 }
863
864 $reg = array();
865 if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) {
866 $idprod = (int) $reg[1];
867 $res = $productsupplier->fetch($idprod); // Load product from its id
868 // Call to init some price properties of $productsupplier
869 // So if a supplier price already exists for another thirdparty (first one found), we use it as reference price
870 if (getDolGlobalString('SUPPLIER_TAKE_FIRST_PRICE_IF_NO_PRICE_FOR_CURRENT_SUPPLIER')) {
871 $fksoctosearch = 0;
872 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
873 if ($productsupplier->fourn_socid != $socid) { // The price we found is for another supplier, so we clear supplier price
874 $productsupplier->ref_supplier = '';
875 }
876 } else {
877 $fksoctosearch = $object->thirdparty->id;
878 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
879 }
880 } elseif (GETPOSTINT('idprodfournprice') > 0) { // id here.
881 //$qtytosearch=$qty; // Just to see if a price exists for the quantity. Not used to found vat.
882 $qtytosearch = -1; // We force qty to -1 to be sure to find if the supplier price that exists
883 $idprod = $productsupplier->get_buyprice(GETPOSTINT('idprodfournprice'), $qtytosearch);
884 $res = $productsupplier->fetch($idprod);
885 }
886
887 if ($idprod > 0) {
888 $label = $productsupplier->label;
889
890 // Define output language
891 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
892 $outputlangs = $langs;
893 $newlang = '';
894 if (/* empty($newlang) && */ GETPOST('lang_id', 'aZ09')) {
895 $newlang = GETPOST('lang_id', 'aZ09');
896 }
897 if (empty($newlang)) {
898 $newlang = $object->thirdparty->default_lang;
899 }
900 if (!empty($newlang)) {
901 $outputlangs = new Translate("", $conf);
902 $outputlangs->setDefaultLang($newlang);
903 }
904 $desc = (!empty($productsupplier->multilangs[$outputlangs->defaultlang]["description"])) ? $productsupplier->multilangs[$outputlangs->defaultlang]["description"] : $productsupplier->description;
905 } else {
906 $desc = $productsupplier->description;
907 }
908 // if we use supplier description of the products
909 if (!empty($productsupplier->desc_supplier) && getDolGlobalString('PRODUIT_FOURN_TEXTS')) {
910 $desc = $productsupplier->desc_supplier;
911 }
912
913 if (getDolGlobalInt('PRODUIT_AUTOFILL_DESC') == 0) {
914 // 'DoNotAutofillButAutoConcat'
915 $desc = dol_concatdesc($desc, $line_desc, false, getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION') ? true : false);
916 } else {
917 //'AutoFillFormFieldBeforeSubmit' or 'DoNotUseDescriptionOfProdut' => User has already done the modification they want
918 $desc = $line_desc;
919 }
920
921 $ref_supplier = $productsupplier->ref_supplier;
922
923 // Get vat rate
924 $tva_npr = 0;
925 if (!GETPOSTISSET('tva_tx')) { // If vat rate not provided from the form (the form has the priority)
926 $tmpidprodfournprice = GETPOST('idprodfournprice', 'alpha'); // can be an id of price, or -1, -2, -99 or 'idprod_...'
927 if (is_numeric($tmpidprodfournprice) && (int) $tmpidprodfournprice > 0) {
928 $tmpidprodfournprice = (int) $tmpidprodfournprice;
929 } else {
930 $tmpidprodfournprice = 0;
931 }
932
933 $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
934 $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
935 }
936 if (empty($tva_tx)) {
937 $tva_npr = 0;
938 }
939 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
940 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
941
942 $type = $productsupplier->type;
943 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
944 $price_base_type = 'HT';
945 $pu = price2num($price_ht, 'MU');
946 $pu_devise = price2num($price_ht_devise, 'CU');
947 } elseif (GETPOST('price_ttc') != '' || GETPOST('multicurrency_price_ttc') != '') {
948 $price_base_type = 'TTC';
949 $pu = price2num($price_ttc, 'MU');
950 $pu_devise = price2num($price_ttc_devise, 'CU');
951 } else {
952 $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT');
953 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
954 $pu = $productsupplier->fourn_pu;
955 $pu_devise = 0;
956 } else {
957 $pu = $productsupplier->fourn_pu;
958 $pu_devise = $productsupplier->fourn_multicurrency_unitprice;
959 }
960 }
961
962 if (empty($pu)) {
963 $pu = 0; // If pu is '' or null, we force to have a numeric value
964 }
965
966 // If GETPOST('idprodfournprice') is a numeric, we can use it. If it is empty or if it is 'idprod_123', we should use -1 (not used)
967 $fournprice = (is_numeric(GETPOST('idprodfournprice', 'alpha')) ? GETPOST('idprodfournprice', 'alpha') : -1);
968 $buyingprice = 0;
969
970 $result = $object->addline(
971 $desc,
972 ($price_base_type == 'HT' ? $pu : 0),
973 (float) $qty,
974 $tva_tx,
975 $localtax1_tx,
976 $localtax2_tx,
977 $productsupplier->id,
978 $remise_percent,
979 $price_base_type,
980 ($price_base_type == 'TTC' ? $pu : 0),
981 $tva_npr,
982 $type,
983 min($rank, count($object->lines) + 1),
984 0,
985 GETPOSTINT('fk_parent_line'),
986 (int) $fournprice,
987 $buyingprice,
988 $label,
989 $array_options,
990 $ref_supplier,
991 $productsupplier->fk_unit,
992 '',
993 0,
994 $pu_devise,
996 $date_end
997 );
998
999 //var_dump($tva_tx);
1000 //var_dump($productsupplier->fourn_pu);
1001 //var_dump($price_base_type);exit;
1002 if ($result < 0) {
1003 $error++;
1004 setEventMessages($object->error, $object->errors, 'errors');
1005 }
1006 }
1007 if ($idprod == -99 || $idprod == 0) {
1008 // Product not selected
1009 $error++;
1010 $langs->load("errors");
1011 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")).' '.$langs->trans("or").' '.$langs->trans("NoPriceDefinedForThisSupplier"), null, 'errors');
1012 }
1013 if ($idprod == -1) {
1014 // Quantity too low
1015 $error++;
1016 $langs->load("errors");
1017 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors');
1018 }
1019 } elseif ((GETPOST('price_ht') !== '' || GETPOST('price_ttc') !== '' || GETPOST('multicurrency_price_ht') != '') && empty($error)) { // Free product. // $price_ht is already set
1020 $pu_ht = price2num($price_ht, 'MU');
1021 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
1022
1023 $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
1024 $tva_tx = str_replace('*', '', $tva_tx);
1025 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1026 $desc = $line_desc;
1027 $type = GETPOSTINT('type');
1028
1029 $fk_unit = GETPOSTINT('units');
1030
1031 if (!preg_match('/\‍((.*)\‍)/', $tva_tx)) {
1032 $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'
1033 }
1034
1035 // Local Taxes
1036 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
1037 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
1038
1039 // Keep the entry mode chosen by the user so the total is computed from the typed value (no rounding drift).
1040 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
1041 $price_base_type = 'HT';
1042 $pu_ht = price2num($price_ht, 'MU'); // $pu_ht must be rounded according to settings
1043 $pu_ttc = 0;
1044 $pu_ht_devise = price2num($price_ht_devise, 'CU');
1045 } else {
1046 $price_base_type = 'TTC';
1047 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
1048 $pu_ht = 0;
1049 $pu_ht_devise = price2num($price_ttc_devise, 'CU');
1050 }
1051 $info_bits = 0;
1052
1053 $result = $object->addline(
1054 $desc,
1055 (float) $pu_ht,
1056 (float) $qty,
1057 $tva_tx, // don't cast to float
1058 $localtax1_tx,
1059 $localtax2_tx,
1060 $idprod,
1061 $remise_percent,
1062 $price_base_type,
1063 (float) $pu_ttc,
1064 $info_bits,
1065 $type,
1066 -1, // rang
1067 0, // special_code
1068 GETPOSTINT('fk_parent_line'),
1069 (int) $fournprice,
1070 $buyingprice,
1071 $label,
1072 $array_options,
1073 $ref_supplier,
1074 $fk_unit,
1075 '', // origin
1076 0, // origin_id
1077 (float) $pu_ht_devise
1078 );
1079 }
1080
1081
1082 if (!$error && $result > 0) {
1083 $db->commit();
1084
1085 $ret = $object->fetch($object->id); // Reload to get new records
1086
1087 // Define output language
1088 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1089 $outputlangs = $langs;
1090 $newlang = '';
1091 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
1092 $newlang = GETPOST('lang_id', 'aZ09');
1093 }
1094 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1095 $newlang = $object->thirdparty->default_lang;
1096 }
1097 if (!empty($newlang)) {
1098 $outputlangs = new Translate("", $conf);
1099 $outputlangs->setDefaultLang($newlang);
1100 }
1101 $model = $object->model_pdf;
1102 $ret = $object->fetch($id); // Reload to get new records
1103 if ($ret > 0) {
1104 $object->fetch_thirdparty();
1105 }
1106
1107 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
1108 if ($result < 0) {
1109 dol_print_error($db, $object->error, $object->errors);
1110 }
1111 }
1112
1113 unset($_POST['prod_entry_mode']);
1114
1115 unset($_POST['qty']);
1116 unset($_POST['type']);
1117 unset($_POST['remise_percent']);
1118 unset($_POST['pu']);
1119 unset($_POST['price_ht']);
1120 unset($_POST['multicurrency_price_ht']);
1121 unset($_POST['price_ttc']);
1122 unset($_POST['fourn_ref']);
1123 unset($_POST['tva_tx']);
1124 unset($_POST['label']);
1125 unset($_POST['product_ref']);
1126 unset($_POST['product_label']);
1127 unset($_POST['product_desc']);
1128 unset($_POST['fournprice']);
1129 unset($_POST['buying_price']);
1130 unset($localtax1_tx);
1131 unset($localtax2_tx);
1132 unset($_POST['np_marginRate']);
1133 unset($_POST['np_markRate']);
1134 unset($_POST['dp_desc']);
1135 unset($_POST['idprodfournprice']);
1136 unset($_POST['units']);
1137
1138 unset($_POST['idprod']);
1139
1140 unset($_POST['date_starthour']);
1141 unset($_POST['date_startmin']);
1142 unset($_POST['date_startsec']);
1143 unset($_POST['date_startday']);
1144 unset($_POST['date_startmonth']);
1145 unset($_POST['date_startyear']);
1146 unset($_POST['date_endhour']);
1147 unset($_POST['date_endmin']);
1148 unset($_POST['date_endsec']);
1149 unset($_POST['date_endday']);
1150 unset($_POST['date_endmonth']);
1151 unset($_POST['date_endyear']);
1152 } else {
1153 $db->rollback();
1154
1155 setEventMessages($object->error, $object->errors, 'errors');
1156 }
1157 }
1158 } elseif ($action == 'updatetitleline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1159 // Handling updating a title line for subtotals module
1160
1161 $langs->load('subtotals');
1162
1163 $desc = GETPOST('line_desc', 'alphanohtml') ?? $langs->trans("Title");
1164 $depth = GETPOSTINT('line_depth') ?? 1;
1165
1166 $subtotal_options = array();
1167
1168 foreach (SupplierProposal::$TITLE_OPTIONS as $option) {
1169 $value = GETPOST($option, 'alphanohtml');
1170 if ($value) {
1171 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
1172 }
1173 }
1174
1175 // Update line
1176 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
1177
1178 if ($result >= 0) {
1179 if ($result == 0) {
1180 setEventMessages($object->error, $object->errors, 'warnings');
1181 }
1182 $ret = $object->fetch($object->id); // Reload to get new records
1183 $object->fetch_thirdparty();
1184
1185 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1186 // Define output language
1187 $outputlangs = $langs;
1188 $newlang = GETPOST('lang_id', 'alpha');
1189 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1190 $newlang = $object->thirdparty->default_lang;
1191 }
1192 if (!empty($newlang)) {
1193 $outputlangs = new Translate("", $conf);
1194 $outputlangs->setDefaultLang($newlang);
1195 }
1196
1197 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1198 }
1199 } else {
1200 setEventMessages($object->error, $object->errors, 'errors');
1201 }
1202 } elseif ($action == 'updatetextline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1203 // Handling updating a text line for subtotals module
1204
1205 $langs->load('subtotals');
1206
1207 $desc = GETPOST('line_desc', 'restricthtml');
1208
1209 // Update line
1210 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, 0, array());
1211
1212 if ($result >= 0) {
1213 if ($result == 0) {
1214 setEventMessages($object->error, $object->errors, 'warnings');
1215 }
1216 $ret = $object->fetch($object->id); // Reload to get new records
1217 $object->fetch_thirdparty();
1218
1219 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1220 // Define output language
1221 $outputlangs = $langs;
1222 $newlang = GETPOST('lang_id', 'alpha');
1223 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1224 $newlang = $object->thirdparty->default_lang;
1225 }
1226 if (!empty($newlang)) {
1227 $outputlangs = new Translate("", $conf);
1228 $outputlangs->setDefaultLang($newlang);
1229 }
1230
1231 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1232 }
1233 } else {
1234 setEventMessages($object->error, $object->errors, 'errors');
1235 }
1236 } elseif ($action == 'updatesubtotalline' && GETPOSTISSET("save") && $usercancreate && !GETPOST('cancel', 'alpha')) {
1237 // Handling updating a subtotal line for subtotals module
1238
1239 $langs->load('subtotals');
1240
1241 $desc = GETPOST('line_desc', 'alphanohtml');
1242 $depth = GETPOSTINT('line_depth');
1243
1244 $subtotal_options = array();
1245
1246 foreach (SupplierProposal::$SUBTOTAL_OPTIONS as $option) {
1247 $value = GETPOST($option, 'alphanohtml');
1248 if ($value) {
1249 $subtotal_options[$option] = $value == 'on' ? 1 : $value;
1250 }
1251 }
1252
1253 // Update line
1254 $result = $object->updateSubtotalLine($langs, GETPOSTINT('lineid'), $desc, $depth, $subtotal_options);
1255
1256 if ($result > 0) {
1257 $ret = $object->fetch($object->id); // Reload to get new records
1258 $object->fetch_thirdparty();
1259
1260 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1261 // Define output language
1262 $outputlangs = $langs;
1263 $newlang = GETPOST('lang_id', 'alpha');
1264 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
1265 $newlang = $object->thirdparty->default_lang;
1266 }
1267 if (!empty($newlang)) {
1268 $outputlangs = new Translate("", $conf);
1269 $outputlangs->setDefaultLang($newlang);
1270 }
1271
1272 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1273 }
1274 } else {
1275 setEventMessages($object->error, $object->errors, 'errors');
1276 }
1277 } elseif ($action == 'updateline' && $usercancreate && GETPOST('save') == $langs->trans("Save")) {
1278 // Update a line within proposal
1279 $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
1280 $pu_ht = price2num(GETPOST('price_ht'), '', 2);
1281 $pu_ttc = price2num(GETPOST('price_ttc'), '', 2);
1282
1283 // Define info_bits
1284 $info_bits = 0;
1285 if (preg_match('/\*/', $vat_rate)) {
1286 $info_bits |= 0x01;
1287 }
1288
1289 // Clean parameters
1290 $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml'));
1291
1292 // Define vat_rate
1293 $vat_rate = str_replace('*', '', $vat_rate);
1294 $localtax1_rate = get_localtax($vat_rate, 1, $mysoc, $object->thirdparty);
1295 $localtax2_rate = get_localtax($vat_rate, 2, $mysoc, $object->thirdparty);
1296
1297 $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), 'CU', 2);
1298
1299 // Add buying price
1300 $fournprice = (int) (GETPOST('fournprice') ? GETPOSTINT('fournprice') : ''); // This can be id of supplier price, or 'pmpprice' or 'costprice', or 'inputprice', we force to keep ID only
1301 $buyingprice = price2num((GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''), '', 2); // If buying_price is '0', we must keep this value
1302
1303 // Extrafields Lines
1304 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1305 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
1306 // Unset extrafield POST Data
1307 if (is_array($extralabelsline)) {
1308 foreach ($extralabelsline as $key => $value) {
1309 unset($_POST["options_".$key]);
1310 }
1311 }
1312
1313 // Define special_code for special lines
1314 $special_code = GETPOST('special_code');
1315 if (!GETPOST('qty')) {
1316 $special_code = 3;
1317 }
1318
1319 // The form JS clears the other field when the user edits one of them: only the modified field is filled.
1320 // When both fields are submitted, the user did not change the price - we must preserve the original
1321 // storage mode of the line, otherwise a no-op save would shift the total by rounding.
1322 $ht = $pu_ht;
1323 $price_base_type = 'HT';
1324 if (empty($pu_ht) && !empty($pu_ttc)) {
1325 $ht = $pu_ttc;
1326 $price_base_type = 'TTC';
1327 } elseif (!empty($pu_ht) && !empty($pu_ttc)) {
1328 foreach ($object->lines as $line_obj) {
1329 if ($line_obj->id == GETPOSTINT('lineid')) {
1330 // Line was originally entered in TTC mode (subprice_ttc filled by addline)
1331 if ($line_obj->wasEnteredIncludingTax()) {
1332 $ht = $pu_ttc;
1333 $price_base_type = 'TTC';
1334 }
1335 break;
1336 }
1337 }
1338 }
1339
1340 // Check minimum price
1341 $productid = GETPOSTINT('productid');
1342 if (!empty($productid)) {
1343 $productsupplier = new ProductFournisseur($db);
1344 if (getDolGlobalInt('SUPPLIER_PROPOSAL_WITH_PREDEFINED_PRICES_ONLY') == 1) { // Not the common case
1345 if ($productid > 0 && $productsupplier->get_buyprice(0, (float) price2num(GETPOST('qty')), $productid, 'none', GETPOSTINT('socid')) < 0) {
1346 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings');
1347 }
1348 }
1349
1350 $product = new Product($db);
1351 $res = $product->fetch($productid);
1352
1353 $type = $product->type;
1354
1355 $price_min = $product->price_min;
1356 if (getDolGlobalString('PRODUIT_MULTIPRICES') && !empty($object->thirdparty->price_level)) {
1357 $price_min = $product->multiprices_min [$object->thirdparty->price_level];
1358 }
1359
1360 $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
1361 } else {
1362 $type = GETPOST('type');
1363 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1364
1365 // Check parameters
1366 if (GETPOST('type') < 0) {
1367 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
1368 $error++;
1369 }
1370 }
1371
1372 if (!$error) {
1373 $db->begin();
1374
1375 $ref_supplier = GETPOST('fourn_ref', 'alpha');
1376 $fk_unit = GETPOSTINT('units');
1377
1378 // In TTC mode, do not forward the HT currency price: under multicurrency updateline() would reset
1379 // the local price and recompute from the HT currency amount (read as TTC) -> the TTC value is lost.
1380 if ($price_base_type === 'TTC') {
1381 $pu_ht_devise = 0;
1382 }
1383
1384 $result = $object->updateline(
1385 GETPOSTINT('lineid'),
1386 (float) $ht,
1387 (float) price2num(GETPOST('qty'), 'MS', 2),
1388 (float) price2num(GETPOST('remise_percent'), '', 2),
1389 $vat_rate,
1390 $localtax1_rate,
1391 $localtax2_rate,
1392 $description,
1393 $price_base_type,
1394 $info_bits,
1395 $special_code,
1396 GETPOSTINT('fk_parent_line'),
1397 0,
1398 (int) $fournprice,
1399 $buyingprice,
1400 $label,
1401 $type,
1402 $array_options,
1403 $ref_supplier,
1404 $fk_unit,
1405 (float) $pu_ht_devise
1406 );
1407
1408 if ($result >= 0) {
1409 $db->commit();
1410
1411 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1412 // Define output language
1413 $outputlangs = $langs;
1414 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1415 $outputlangs = new Translate("", $conf);
1416 $newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $object->thirdparty->default_lang);
1417 $outputlangs->setDefaultLang($newlang);
1418 }
1419 $ret = $object->fetch($id); // Reload to get new records
1420 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1421 }
1422
1423 unset($_POST['qty']);
1424 unset($_POST['type']);
1425 unset($_POST['productid']);
1426 unset($_POST['remise_percent']);
1427 unset($_POST['price_ht']);
1428 unset($_POST['multicurrency_price_ht']);
1429 unset($_POST['price_ttc']);
1430 unset($_POST['tva_tx']);
1431 unset($_POST['product_ref']);
1432 unset($_POST['product_label']);
1433 unset($_POST['product_desc']);
1434 unset($_POST['fournprice']);
1435 unset($_POST['buying_price']);
1436
1437 unset($_POST['date_starthour']);
1438 unset($_POST['date_startmin']);
1439 unset($_POST['date_startsec']);
1440 unset($_POST['date_startday']);
1441 unset($_POST['date_startmonth']);
1442 unset($_POST['date_startyear']);
1443 unset($_POST['date_endhour']);
1444 unset($_POST['date_endmin']);
1445 unset($_POST['date_endsec']);
1446 unset($_POST['date_endday']);
1447 unset($_POST['date_endmonth']);
1448 unset($_POST['date_endyear']);
1449 } else {
1450 $db->rollback();
1451
1452 setEventMessages($object->error, $object->errors, 'errors');
1453 }
1454 }
1455 } elseif ($action == 'updateline' && $usercancreate && $cancel) {
1456 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To re-display card in edit mode
1457 exit();
1458 } elseif ($action == 'classin' && $usercancreate) {
1459 // Set project
1460 $object->setProject(GETPOSTINT('projectid'));
1461 } elseif ($action == 'setavailability' && $usercancreate) {
1462 // Delivery delay
1463 $result = $object->availability(GETPOST('availability_id'));
1464 } elseif ($action == 'setconditions' && $usercancreate) {
1465 // Terms of payments
1466 $sql = "SELECT code ";
1467 $sql .= "FROM " . $db->prefix() . "c_payment_term";
1468 $sql .= " WHERE rowid = " . GETPOSTINT('cond_reglement_id');
1469 $result = $db->query($sql);
1470 if ($result) {
1471 $obj = $db->fetch_object($result);
1472 if ($obj->code == 'DEP30PCTDEL') {
1473 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'), GETPOSTFLOAT('cond_reglement_id_deposit_percent'));
1474 } else {
1475 $object->deposit_percent = 0;
1476 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'), $object->deposit_percent);
1477 }
1478 }
1479 } elseif ($action == 'setmode' && $usercancreate) {
1480 // Payment mode
1481 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
1482 } elseif ($action == 'setmulticurrencycode' && $usercancreate) {
1483 // Multicurrency Code
1484 $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
1485 } elseif ($action == 'setmulticurrencyrate' && $usercancreate) {
1486 // Multicurrency rate
1487 $result = $object->setMulticurrencyRate(GETPOSTFLOAT('multicurrency_tx'), GETPOSTINT('calculation_mode'));
1488 } elseif ($action == 'update_extras' && $permissiontoeditextra) {
1489 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
1490
1491 $attribute_name = GETPOST('attribute', 'aZ09');
1492
1493 // Fill array 'array_options' with data from update form
1494 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
1495 if ($ret < 0) {
1496 $error++;
1497 }
1498
1499 if (!$error) {
1500 $result = $object->updateExtraField($attribute_name, 'PROPOSAL_SUPPLIER_MODIFY');
1501 if ($result < 0) {
1502 setEventMessages($object->error, $object->errors, 'errors');
1503 $error++;
1504 }
1505 }
1506
1507 if ($error) {
1508 $action = 'edit_extras';
1509 }
1510 }
1511}
1512
1513
1514/*
1515 * View
1516 */
1517
1518$title = $object->ref." - ".$langs->trans('Card');
1519if ($action == 'create') {
1520 $title = $langs->trans("SupplierProposalNew");
1521}
1522$help_url = 'EN:Ask_Price_Supplier|FR:Demande_de_prix_fournisseur';
1523
1524llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-supplierproposal page-card');
1525
1526$form = new Form($db);
1527$formother = new FormOther($db);
1528$formfile = new FormFile($db);
1529$formmargin = new FormMargin($db);
1530$companystatic = new Societe($db);
1531if (isModEnabled('project')) {
1532 $formproject = new FormProjets($db);
1533}
1534
1535$now = dol_now();
1536
1537// Add new askprice
1538if ($action == 'create') {
1539 $currency_code = $conf->currency;
1540
1541 print load_fiche_titre($langs->trans("SupplierProposalNew"), '', 'supplier_proposal');
1542
1543 $soc = new Societe($db);
1544 if ($socid > 0) {
1545 $res = $soc->fetch($socid);
1546 }
1547
1548 // Load objectsrc
1549 if (!empty($origin) && !empty($originid)) {
1550 // Resolve and load the source object from its element type (propal, commande, ...)
1551 $objectsrc = fetchObjectByElement($originid, $origin);
1552
1553 if (is_object($objectsrc)) {
1554 '@phan-var-force Commande|Propal|CommandeFournisseur|SupplierProposal $objectsrc'; // Could be other classes, but CommonObject is too generic
1556 $classname = get_class($objectsrc);
1557
1558 if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
1559 $objectsrc->fetch_lines();
1560 }
1561 $objectsrc->fetch_thirdparty();
1562
1563 $projectid = (int) $objectsrc->fk_project;
1564 $soc = $objectsrc->thirdparty;
1565
1566 $cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0)); // TODO maybe add default value option
1567 $deposit_percent = (!empty($objectsrc->deposit_percent) ? $objectsrc->deposit_percent : (!empty($soc->deposit_percent) ? $soc->deposit_percent : 0));
1568 $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0));
1569 $fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0));
1570
1571 // Replicate extrafields
1572 $objectsrc->fetch_optionals();
1573 $object->array_options = $objectsrc->array_options;
1574
1575 if (isModEnabled("multicurrency")) {
1576 if (!empty($objectsrc->multicurrency_code)) {
1577 $currency_code = $objectsrc->multicurrency_code;
1578 }
1579 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
1580 $currency_tx = $objectsrc->multicurrency_tx;
1581 }
1582 }
1583 } else {
1584 $objectsrc = null;
1585 $cond_reglement_id = (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0);
1586 $deposit_percent = (!empty($soc->deposit_percent) ? $soc->deposit_percent : 0);
1587 $mode_reglement_id = (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0);
1588 $fk_account = (!empty($soc->fk_account) ? $soc->fk_account : 0);
1589 }
1590 } else {
1591 $cond_reglement_id = $soc->cond_reglement_supplier_id;
1592 $deposit_percent = !empty($soc->deposit_percent) ? $soc->deposit_percent : 0;
1593 $mode_reglement_id = $soc->mode_reglement_supplier_id;
1594 $fk_account = !empty($soc->fk_account) ? $soc->fk_account : 0;
1595 if (isModEnabled("multicurrency") && !empty($soc->multicurrency_code)) {
1596 $currency_code = $soc->multicurrency_code;
1597 }
1598 }
1599 if (GETPOSTISSET('cond_reglement_id_deposit_percent')) {
1600 $deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
1601 }
1602
1603 $object = new SupplierProposal($db);
1604
1605 print '<form name="addprop" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1606 print '<input type="hidden" name="token" value="'.newToken().'">';
1607 print '<input type="hidden" name="action" value="add">';
1608 if ($origin != 'project' && $originid) {
1609 print '<input type="hidden" name="origin" value="'.$origin.'">';
1610 print '<input type="hidden" name="originid" value="'.$originid.'">';
1611 }
1612 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1613
1614 print dol_get_fiche_head();
1615
1616 // Call Hook tabContentCreateSupplierProposal
1617 $parameters = array();
1618 // Note that $action and $object may be modified by hook
1619 $reshook = $hookmanager->executeHooks('tabContentCreateSupplierProposal', $parameters, $object, $action);
1620 if (empty($reshook)) {
1621 print '<table class="border centpercent">';
1622
1623 // Reference
1624 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Ref').'</td><td colspan="2">'.$langs->trans("Draft").'</td></tr>';
1625
1626 // Third party
1627 print '<tr>';
1628 print '<td class="fieldrequired">'.$langs->trans('Supplier').'</td>';
1629 if ($socid > 0) {
1630 print '<td colspan="2">';
1631 print $soc->getNomUrl(1, 'supplier');
1632 print '<input type="hidden" name="socid" value="'.$soc->id.'">';
1633 print '</td>';
1634 } else {
1635 print '<td colspan="2">';
1636 $filter = '((s.fournisseur:=:1) AND (s.status:=:1))';
1637 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company((empty($socid) ? '' : $socid), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
1638 // reload page to retrieve customer information
1639 if (!getDolGlobalString('RELOAD_PAGE_ON_SUPPLIER_CHANGE_DISABLED')) {
1640 print '<script>
1641 $(document).ready(function() {
1642 $("#socid").change(function() {
1643 console.log("We have changed the company - Reload page");
1644 // reload page
1645 $("input[name=action]").val("create");
1646 $("form[name=addprop]").submit();
1647 });
1648 });
1649 </script>';
1650 }
1651 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>';
1652 print '</td>';
1653 }
1654 print '</tr>'."\n";
1655
1656 if ($soc->id > 0) {
1657 // Discounts for third party
1658 print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
1659
1660 $absolute_discount = $soc->getAvailableDiscounts(null, '', 0, 1);
1661
1662 $thirdparty = $soc;
1663 $discount_type = 1;
1664 $backtopage = urlencode($_SERVER["PHP_SELF"].'?socid='.$thirdparty->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid'));
1665 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
1666
1667 print '</td></tr>';
1668 }
1669
1670 // Terms of payment
1671 print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td colspan="2">';
1672 print img_picto('', 'payment', 'class="pictofixedwidth"');
1673 print $form->getSelectConditionsPaiements(GETPOSTISSET('cond_reglement_id') ? GETPOSTINT('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', -1, 1, 0, '', $deposit_percent);
1674 print '</td></tr>';
1675
1676 // Mode of payment
1677 print '<tr><td>'.$langs->trans('PaymentMode').'</td><td colspan="2">';
1678 print img_picto('', 'bank', 'class="pictofixedwidth"');
1679 $form->select_types_paiements(GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id');
1680 print '</td></tr>';
1681
1682 // Bank Account
1683 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL') && isModEnabled("bank")) {
1684 print '<tr><td>'.$langs->trans('BankAccount').'</td><td colspan="2">';
1685 print img_picto('', 'bank', 'class="pictofixedwidth"');
1686 $form->select_comptes(GETPOST('fk_account') > 0 ? GETPOSTINT('fk_account') : $fk_account, 'fk_account', 0, '', 1);
1687 print '</td></tr>';
1688 }
1689
1690 // Shipping Method
1691 if (isModEnabled("shipping")) {
1692 print '<tr><td>'.$langs->trans('SendingMethod').'</td><td colspan="2">';
1693 print img_picto('', 'dolly', 'class="pictofixedwidth"');
1694 $form->selectShippingMethod(GETPOST('shipping_method_id') > 0 ? GETPOSTINT('shipping_method_id') : "", 'shipping_method_id', '', 1);
1695 print '</td></tr>';
1696 }
1697
1698 // Delivery date (or manufacturing)
1699 print '<tr><td>'.$langs->trans("DeliveryDate").'</td>';
1700 print '<td colspan="2">';
1701 print img_picto('', 'action', 'class="pictofixedwidth"');
1702 $datedelivery = dol_mktime(0, 0, 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
1703 if (is_numeric(getDolGlobalString('DATE_LIVRAISON_WEEK_DELAY'))) { // If value set to 0 or a num, not empty
1704 $tmpdte = dol_now() + (7 * getDolGlobalInt('DATE_LIVRAISON_WEEK_DELAY') * 24 * 60 * 60);
1705 $syear = dol_print_date($tmpdte, "Y");
1706 $smonth = dol_print_date($tmpdte, "m");
1707 $sday = dol_print_date($tmpdte, "d");
1708 print $form->selectDate($syear."-".$smonth."-".$sday, 'liv_', 0, 0, 0, "addask");
1709 } else {
1710 print $form->selectDate($datedelivery ? $datedelivery : -1, 'liv_', 0, 0, 0, "addask", 1, 1);
1711 }
1712 print '</td></tr>';
1713
1714
1715 // Model
1717 if (count($list) > 0) {
1718 print '<tr>';
1719 print '<td>'.$langs->trans("DefaultModel").'</td>';
1720 print '<td colspan="2">';
1721 print img_picto('', 'pdf', 'class="pictofixedwidth"');
1722 $preselected = getDolGlobalString('SUPPLIER_PROPOSAL_ADDON_PDF_ODT_DEFAULT', getDolGlobalString('SUPPLIER_PROPOSAL_ADDON_PDF'));
1723 print $form->selectarray('model', $list, $preselected, 0, 0, 0, '', 0, 0, 0, '', '', 1);
1724 print "</td></tr>";
1725 }
1726
1727 // Project
1728 if (isModEnabled('project')) {
1729 $langs->load("projects");
1730
1731 $formproject = new FormProjets($db);
1732
1733 if ($origin == 'project') {
1734 $projectid = ($originid ? $originid : 0);
1735 }
1736
1737 print '<tr>';
1738 print '<td>'.$langs->trans("Project").'</td><td colspan="2">';
1739 if (!empty($user->socid)) { // external user: restrict to their own third party
1740 $projSocFilter = $user->socid;
1741 } elseif (getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') || $socid == 0) {
1742 // Give priority to the constant (as on supplier invoice), so a supplier document created from a
1743 // customer project keeps that project selected after the supplier is chosen.
1744 $projSocFilter = -1;
1745 } else {
1746 $projSocFilter = $socid;
1747 }
1748 print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects($projSocFilter, $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
1749 print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.((int) $soc->id).'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
1750 print '</td>';
1751 print '</tr>';
1752 }
1753
1754 // Multicurrency
1755 if (isModEnabled("multicurrency")) {
1756 print '<tr>';
1757 print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
1758 print '<td colspan="3" class="maxwidthonsmartphone">';
1759 print img_picto('', 'currency', 'class="pictofixedwidth"');
1760 print $form->selectMultiCurrency($currency_code, 'multicurrency_code');
1761 print '</td></tr>';
1762 }
1763 // Categories
1764 if (isModEnabled('category')) {
1765 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
1766 print $form->selectCategories(Categorie::TYPE_SUPPLIER_PROPOSAL, 'categories', $object);
1767 print "</td></tr>";
1768 }
1769
1770 // Other attributes
1771 $parameters = array('colspan' => ' colspan="3"', 'cols' => 3);
1772 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1773 print $hookmanager->resPrint;
1774 if (empty($reshook)) {
1775 print $object->showOptionals($extrafields, 'create', $parameters);
1776 }
1777
1778
1779 // Lines from source
1780 if (!empty($origin) && !empty($originid) && is_object($objectsrc) && $classname !== null) {
1781 // TODO for compatibility
1782 if ($origin == 'contrat') {
1783 // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
1784 $objectsrc->update_price(1, 'auto', 1);
1785 }
1786
1787 print "\n<!-- ".$classname." info -->";
1788 print "\n";
1789 print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
1790 print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
1791 print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
1792 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
1793 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
1794
1795 print '<tr><td>'.$langs->trans('CommRequest').'</td><td colspan="2">'.$objectsrc->getNomUrl(1).'</td></tr>';
1796 print '<tr><td>'.$langs->trans('AmountHT').'</td><td colspan="2">'.price($objectsrc->total_ht).'</td></tr>';
1797 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td colspan="2">'.price($objectsrc->total_tva)."</td></tr>";
1798 if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0) { // Localtax1
1799 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td colspan="2">'.price($objectsrc->total_localtax1)."</td></tr>";
1800 }
1801
1802 if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) { // Localtax2
1803 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td colspan="2">'.price($objectsrc->total_localtax2)."</td></tr>";
1804 }
1805 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td colspan="2">'.price($objectsrc->total_ttc)."</td></tr>";
1806
1807 if (isModEnabled("multicurrency")) {
1808 print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td colspan="2">'.price($objectsrc->multicurrency_total_ht, 0, $langs, 1, -1, -1, $objectsrc->multicurrency_code).'</td></tr>';
1809 print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td colspan="2">'.price($objectsrc->multicurrency_total_tva, 0, $langs, 1, -1, -1, $objectsrc->multicurrency_code)."</td></tr>";
1810 print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td colspan="2">'.price($objectsrc->multicurrency_total_ttc, 0, $langs, 1, -1, -1, $objectsrc->multicurrency_code)."</td></tr>";
1811 }
1812 }
1813
1814 print "</table>\n";
1815
1816
1817 /*
1818 * Combobox for copy function
1819 */
1820
1821 if (!getDolGlobalString('SUPPLIER_PROPOSAL_CLONE_ON_CREATE_PAGE')) {
1822 print '<input type="hidden" name="createmode" value="empty">';
1823 }
1824
1825 if (getDolGlobalString('SUPPLIER_PROPOSAL_CLONE_ON_CREATE_PAGE')) {
1826 print '<br><table>';
1827
1828 // For backward compatibility
1829 print '<tr>';
1830 print '<td><input type="radio" name="createmode" value="copy"></td>';
1831 print '<td>'.$langs->trans("CopyAskFrom").' </td>';
1832 print '<td>';
1833 $liste_ask = array();
1834 $liste_ask [0] = '';
1835
1836 $sql = "SELECT p.rowid as id, p.ref, s.nom";
1837 $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal p";
1838 $sql .= ", ".MAIN_DB_PREFIX."societe s";
1839 $sql .= " WHERE s.rowid = p.fk_soc";
1840 $sql .= " AND p.entityy IN (".getEntity('supplier_proposal').")";
1841 $sql .= " AND p.fk_statut <> ".SupplierProposal::STATUS_DRAFT;
1842 $sql .= " ORDER BY Id";
1843
1844 $resql = $db->query($sql);
1845 if ($resql) {
1846 $num = $db->num_rows($resql);
1847 $i = 0;
1848 while ($i < $num) {
1849 $row = $db->fetch_row($resql);
1850 $askPriceSupplierRefAndSocName = $row[1]." - ".$row[2];
1851 $liste_ask[$row[0]] = $askPriceSupplierRefAndSocName;
1852 $i++;
1853 }
1854 print $form->selectarray("copie_supplier_proposal", $liste_ask, 0);
1855 } else {
1856 dol_print_error($db);
1857 }
1858 print '</td></tr>';
1859
1860 print '<tr><td class="tdtop"><input type="radio" name="createmode" value="empty" checked></td>';
1861 print '<td valign="top" colspan="2">'.$langs->trans("CreateEmptyAsk").'</td></tr>';
1862 }
1863
1864 if (getDolGlobalString('SUPPLIER_PROPOSAL_CLONE_ON_CREATE_PAGE')) {
1865 print '</table>';
1866 }
1867 }
1868
1869 print dol_get_fiche_end();
1870
1871 print $form->buttonsSaveCancel("CreateDraft");
1872
1873 print "</form>";
1874
1875
1876 // Show origin lines
1877 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
1878 print '<br>';
1879
1880 $title = $langs->trans('ProductsAndServices');
1881 print load_fiche_titre($title);
1882
1883 print '<div class="div-table-responsive-no-min">';
1884 print '<table class="noborder centpercent">';
1885
1886 $objectsrc->printOriginLinesList();
1887
1888 print '</table>';
1889 print '</div>';
1890 }
1891} else {
1892 /*
1893 * Show object in view mode
1894 */
1895
1896 $soc = new Societe($db);
1897 $soc->fetch($object->socid);
1898
1899 $head = supplier_proposal_prepare_head($object);
1900 print dol_get_fiche_head($head, 'comm', $langs->trans('CommRequest'), -1, 'supplier_proposal', 0, '', '', 0, '', 1);
1901
1902 $formconfirm = '';
1903
1904 // Clone confirmation
1905 if ($action == 'clone') {
1906 $filter = '(s.fournisseur:=:1)';
1907 // Create an array for form
1908 $formquestion = array(
1909 // 'text' => $langs->trans("ConfirmClone"),
1910 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
1911 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' =>
1912 // 1),
1913 array(
1914 'type' => 'other',
1915 'name' => 'socid',
1916 'label' => $langs->trans("SelectThirdParty"),
1917 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter))
1918 );
1919 // Paiement incomplet. On demande si motif = escompte ou autre
1920 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
1921 } elseif ($action == 'delete') {
1922 // Confirm delete
1923 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteAsk'), $langs->trans('ConfirmDeleteAsk', $object->ref), 'confirm_delete', '', 0, 1);
1924 } elseif ($action == 'reopen') {
1925 // Confirm reopen
1926 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $langs->trans('ConfirmReOpenAsk', $object->ref), 'confirm_reopen', '', 0, 1);
1927 } elseif ($action == 'ask_deleteline') {
1928 // Confirmation delete product/service line
1929 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
1930 } elseif ($action == 'ask_subtotal_deleteline') {
1931 // Generate form to ask confirmation to delete a subtotal line
1932 $langs->load("subtotals");
1933 $title = "DeleteSubtotalLine";
1934 $question = "ConfirmDeleteSubtotalLine";
1935 if (GETPOST('type') == 'title') {
1936 $formconfirm = [
1937 [
1938 'type' => 'checkbox',
1939 'name' => 'deletecorrespondingsubtotalline',
1940 'label' => $langs->trans("DeleteCorrespondingSubtotalLine"),
1941 'value' => 0,
1942 ],
1943 ];
1944 $title = "DeleteTitleLine";
1945 $question = "ConfirmDeleteTitleLine";
1946 }
1947 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans($title), $langs->trans($question), 'confirm_delete_subtotalline', $formconfirm, 'no', 1);
1948 } elseif ($action == 'validate') {
1949 // Confirm validate askprice
1950 $error = 0;
1951
1952 // Verify if the object has a temporary number
1953 $ref = substr($object->ref, 1, 4);
1954 if ($ref == 'PROV') {
1955 $numref = $object->getNextNumRef($soc);
1956 if (empty($numref)) {
1957 $error++;
1958 setEventMessages($object->error, $object->errors, 'errors');
1959 }
1960 } else {
1961 $numref = (string) $object->ref;
1962 }
1963
1964 $text = $langs->trans('ConfirmValidateAsk', $numref);
1965 if (isModEnabled('notification')) {
1966 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
1967 $notify = new Notify($db);
1968 $text .= '<br>';
1969 $text .= $notify->confirmMessage('PROPOSAL_SUPPLIER_VALIDATE', $object->socid, $object);
1970 }
1971
1972 if (!$error) {
1973 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateAsk'), $text, 'confirm_validate', '', 0, 1);
1974 }
1975 }
1976 // Subtotal line form
1977 if ($action == 'add_title_line') {
1978 $langs->load('subtotals');
1979 $type = 'title';
1980 $depth_array = $object->getPossibleLevels($langs);
1981 require dol_buildpath('/core/tpl/subtotal_create.tpl.php');
1982 } elseif ($action == 'add_subtotal_line') {
1983 $langs->load('subtotals');
1984 $type = 'subtotal';
1985 $titles = $object->getPossibleTitles();
1986 require dol_buildpath('/core/tpl/subtotal_create.tpl.php');
1987 } elseif ($action == 'add_text_line') {
1988 $langs->load('subtotals');
1989 $type = 'text';
1990 require dol_buildpath('/core/tpl/subtotal_create.tpl.php');
1991 }
1992
1993 // Call Hook formConfirm
1994 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
1995 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1996 if (empty($reshook)) {
1997 $formconfirm .= $hookmanager->resPrint;
1998 } elseif ($reshook > 0) {
1999 $formconfirm = $hookmanager->resPrint;
2000 }
2001
2002 // Print form confirm
2003 print $formconfirm;
2004
2005
2006 // Supplier proposal card
2007 $linkback = '<a href="'.DOL_URL_ROOT.'/supplier_proposal/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
2008
2009
2010 $morehtmlref = '<div class="refidno">';
2011 // Ref supplier
2012 //$morehtmlref.=$form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreateorder, 'string', '', 0, 1);
2013 //$morehtmlref.=$form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreateorder, 'string', '', null, null, '', 1);
2014 // Thirdparty
2015 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'supplier');
2016 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
2017 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/supplier_proposal/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherProposals").'</a>)';
2018 }
2019 // Project
2020 if (isModEnabled('project')) {
2021 $langs->load("projects");
2022 $morehtmlref .= '<br>';
2023 if ($usercancreate) {
2024 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
2025 if ($action != 'classify') {
2026 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
2027 }
2028 $canLinkAll = getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS');
2029 $canLinkAll = ($canLinkAll === '' || $canLinkAll === false) ? 0 : $canLinkAll;
2030 $currentSocId = ($object->id > 0) ? $object->socid : $socid;
2031 $projectSocId = ((int) $canLinkAll == 1) ? -1 : $currentSocId;
2032 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $projectSocId, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
2033 } else {
2034 if (!empty($object->fk_project)) {
2035 $proj = new Project($db);
2036 $proj->fetch($object->fk_project);
2037 $morehtmlref .= $proj->getNomUrl(1);
2038 if ($proj->title) {
2039 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
2040 }
2041 }
2042 }
2043 }
2044 $morehtmlref .= '</div>';
2045
2046
2047 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
2048
2049 // Call Hook tabContentViewSupplierProposal
2050 $parameters = array();
2051 // Note that $action and $object may be modified by hook
2052 $reshook = $hookmanager->executeHooks('tabContentViewSupplierProposal', $parameters, $object, $action);
2053 if (empty($reshook)) {
2054 print '<div class="fichecenter">';
2055 print '<div class="fichehalfleft">';
2056 print '<div class="underbanner clearboth"></div>';
2057
2058 print '<table class="border tableforfield centpercent">';
2059
2060 // Relative and absolute discounts
2061 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
2062 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
2063 $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
2064 } else {
2065 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
2066 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
2067 }
2068
2069 print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td>';
2070
2071 $absolute_discount = $soc->getAvailableDiscounts(null, $filterabsolutediscount, 0, 1);
2072 $absolute_creditnote = $soc->getAvailableDiscounts(null, $filtercreditnote, 0, 1);
2073 $absolute_discount = price2num($absolute_discount, 'MT');
2074 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
2075
2076 $thirdparty = $soc;
2077 $discount_type = 1;
2078 $backtopage = urlencode($_SERVER["PHP_SELF"].'?id='.$object->id);
2079 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
2080
2081 print '</td></tr>';
2082
2083 // Payment term
2084 print '<tr><td class="titlefield">';
2085 print '<table class="nobordernopadding" width="100%"><tr><td>';
2086 print $langs->trans('PaymentConditionsShort');
2087 print '</td>';
2088 if ($action != 'editconditions' && $object->status != SupplierProposal::STATUS_NOTSIGNED) {
2089 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editconditions&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetConditions'), 1).'</a></td>';
2090 }
2091 print '</tr></table>';
2092 print '</td><td class="valuefield">';
2093 if ($action == 'editconditions') {
2094 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent);
2095 } else {
2096 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'none', 1, '', 1, $object->deposit_percent);
2097 }
2098 print '</td>';
2099 print '</tr>';
2100
2101 // Delivery date
2102 print '<tr><td>';
2103 print '<table class="nobordernopadding" width="100%"><tr><td>';
2104 print $langs->trans('DeliveryDate');
2105 print '</td>';
2106 if ($action != 'editdate_livraison' && $object->status != SupplierProposal::STATUS_NOTSIGNED) {
2107 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editdate_livraison&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetDeliveryDate'), 1).'</a></td>';
2108 }
2109 print '</tr></table>';
2110 print '</td><td class="valuefield">';
2111 if ($action == 'editdate_livraison') {
2112 print '<form name="editdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post" class="formconsumeproduce">';
2113 print '<input type="hidden" name="token" value="'.newToken().'">';
2114 print '<input type="hidden" name="action" value="setdate_livraison">';
2115 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2116 print $form->selectDate($object->delivery_date, 'liv_', 0, 0, 0, "editdate_livraison");
2117 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
2118 print '</form>';
2119 } else {
2120 print dol_print_date($object->delivery_date, 'daytext');
2121 }
2122 print '</td>';
2123 print '</tr>';
2124
2125 // Payment mode
2126 print '<tr>';
2127 print '<td>';
2128 print '<table class="nobordernopadding" width="100%"><tr><td>';
2129 print $langs->trans('PaymentMode');
2130 print '</td>';
2131 if ($action != 'editmode' && $object->status != SupplierProposal::STATUS_NOTSIGNED) {
2132 print '<td class="right"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=editmode&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetMode'), 1).'</a></td>';
2133 }
2134 print '</tr></table>';
2135 print '</td><td class="valuefield">';
2136 if ($action == 'editmode') {
2137 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', 'DBIT', 1, 1);
2138 } else {
2139 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'none');
2140 }
2141 print '</td></tr>';
2142
2143 /* Not for supplier proposals
2144 if ($soc->outstanding_limit) {
2145 // Outstanding Bill
2146 print '<tr><td>';
2147 print $langs->trans('OutstandingBill');
2148 print '</td><td class="valuefield">';
2149 $arrayoutstandingbills = $soc->getOutstandingBills('supplier');
2150 $outstandingBills = $arrayoutstandingbills['opened'];
2151 print price($soc->outstanding_limit, 0, '', 1, - 1, - 1, $conf->currency);
2152 print '</td>';
2153 print '</tr>';
2154 }*/
2155
2156 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL') && isModEnabled("bank")) {
2157 // Bank Account
2158 print '<tr><td>';
2159 print '<table width="100%" class="nobordernopadding"><tr><td>';
2160 print $langs->trans('BankAccount');
2161 print '</td>';
2162 if ($action != 'editbankaccount' && $usercancreate) {
2163 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>';
2164 }
2165 print '</tr></table>';
2166 print '</td><td class="valuefield">';
2167 if ($action == 'editbankaccount') {
2168 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'fk_account', 1);
2169 } else {
2170 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'none');
2171 }
2172 print '</td>';
2173 print '</tr>';
2174 }
2175 // Categories
2176 if (isModEnabled('category')) {
2177 print '<tr><td>';
2178 print '<table class="nobordernopadding centpercent"><tr><td>';
2179 print $langs->trans("Categories");
2180 print '<td><td class="right">';
2181 if ($usercancreate) {
2182 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/supplier_proposal/card.php?id='.$object->id.'&action=edittags&token='.newToken().'">'.img_edit().'</a>';
2183 } else {
2184 print '&nbsp;';
2185 }
2186 print '</td></tr></table>';
2187 print '</td>';
2188 print '<td>';
2189 if ($action == 'edittags') {
2190 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
2191 print '<input type="hidden" name="action" value="settags">';
2192 print '<input type="hidden" name="token" value="'.newToken().'">';
2193 print $form->selectCategories(Categorie::TYPE_SUPPLIER_PROPOSAL, 'categories', $object);
2194 print '<input type="submit" class="button valignmiddle smallpaddingimp" value="'.$langs->trans("Modify").'">';
2195 print '</form>';
2196 } else {
2197 print $form->showCategories($object->id, Categorie::TYPE_SUPPLIER_PROPOSAL, 1);
2198 }
2199 print "</td></tr>";
2200 }
2201 // Other attributes
2202 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
2203
2204 print '</table>';
2205
2206 print '</div>';
2207 print '<div class="fichehalfright">';
2208 print '<div class="underbanner clearboth"></div>';
2209
2210 print '<table class="border tableforfield centpercent">';
2211
2212 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
2213
2214 print '<tr>';
2215 // Amount HT
2216 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
2217 print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2218 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2219 // Multicurrency Amount HT
2220 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2221 }
2222 print '</tr>';
2223
2224 print '<tr>';
2225 // Amount VAT
2226 print '<td class="titlefieldmiddle">' . $langs->trans('AmountVAT') . '</td>';
2227 print '<td class="nowrap amountcard right">' . price($object->total_tva, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2228 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2229 // Multicurrency Amount VAT
2230 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2231 }
2232 print '</tr>';
2233
2234 // Amount Local Taxes
2235 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) {
2236 print '<tr>';
2237 print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
2238 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2239 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2240 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2241 }
2242 print '</tr>';
2243
2244 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
2245 print '<tr>';
2246 print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
2247 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2248 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2249 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2250 }
2251 print '</tr>';
2252 }
2253 }
2254
2255 print '<tr>';
2256 // Amount TTC
2257 print '<td>' . $langs->trans('AmountTTC') . '</td>';
2258 print '<td class="nowrap amountcard right">' . price($object->total_ttc, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
2259 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
2260 // Multicurrency Amount TTC
2261 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ttc, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
2262 }
2263 print '</tr>';
2264
2265 print '</table>';
2266
2267 // Margin Infos
2268 /*if (isModEnabled('margin')) {
2269 $formmargin->displayMarginInfos($object);
2270 }*/
2271
2272 print '</div>';
2273 print '</div>';
2274
2275 print '<div class="clearboth"></div><br>';
2276
2277 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
2278 $blocname = 'contacts';
2279 $title = $langs->trans('ContactsAddresses');
2280 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2281 }
2282
2283 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
2284 $blocname = 'notes';
2285 $title = $langs->trans('Notes');
2286 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
2287 }
2288
2289 /*
2290 * Lines
2291 */
2292
2293 // Show object lines
2294 $result = $object->getLinesArray();
2295
2296 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#add' : '').'" method="POST">
2297 <input type="hidden" name="token" value="' . newToken().'">
2298 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
2299 <input type="hidden" name="mode" value="">
2300 <input type="hidden" name="id" value="' . $object->id.'">
2301 <input type="hidden" name="backtopage" value="'.dol_escape_htmltag($backtopage).'">
2302 ';
2303
2304 if (!empty($conf->use_javascript_ajax) && $object->status == SupplierProposal::STATUS_DRAFT) {
2305 if (isModEnabled('subtotals')) {
2306 include DOL_DOCUMENT_ROOT . '/core/tpl/subtotal_ajaxrow.tpl.php';
2307 } else {
2308 include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
2309 }
2310 }
2311
2312 print '<div class="div-table-responsive-no-min">';
2313 print '<table id="tablelines" class="noborder noshadow centpercent">';
2314
2315 // Add free products/services form
2316 global $forceall, $senderissupplier, $inputalsopricewithtax;
2317 $forceall = 1;
2318 $dateSelector = 0;
2319 $inputalsopricewithtax = 1;
2320 $senderissupplier = 2; // $senderissupplier=2 is same than 1 but disable test on minimum qty.
2321 if (getDolGlobalInt('SUPPLIER_PROPOSAL_WITH_PREDEFINED_PRICES_ONLY')) {
2322 $senderissupplier = getDolGlobalInt('SUPPLIER_PROPOSAL_WITH_PREDEFINED_PRICES_ONLY');
2323 }
2324
2325 if (!empty($object->lines)) {
2326 $object->printObjectLines($action, $soc, $mysoc, $lineid, $dateSelector);
2327 }
2328
2329 // Form to add new line
2330 if ($object->status == SupplierProposal::STATUS_DRAFT && $usercancreate) {
2331 if ($action != 'editline') {
2332 // Add products/services form
2333
2334 $parameters = array('dateSelector' => $dateSelector);
2335 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2336 if ($reshook < 0) {
2337 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2338 }
2339 if (empty($reshook)) {
2340 $object->formAddObjectLine($dateSelector, $soc, $mysoc);
2341 }
2342 }
2343 }
2344
2345 print '</table>';
2346 print '</div>';
2347 print "</form>\n";
2348 }
2349
2350 print dol_get_fiche_end();
2351
2352 if ($action == 'statut') {
2353 // Form to set proposal accepted/refused
2354 $form_close = '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST" id="formacceptrefuse" class="formconsumeproduce paddingbottom paddingleft paddingright">';
2355 $form_close .= '<input type="hidden" name="token" value="'.newToken().'">';
2356 $form_close .= '<input type="hidden" name="action" value="setstatut">';
2357
2358 if (getDolGlobalString('SUPPLIER_PROPOSAL_UPDATE_PRICE_ON_SUPPlIER_PROPOSAL')) {
2359 $form_close .= '<p class="notice">'.$langs->trans('SupplierProposalRefFournNotice').'</p>'; // TODO Suggest a permanent checkbox instead of option
2360 }
2361 $form_close .= '<table class="border centpercent marginleftonly marginrightonly">';
2362 $form_close .= '<tr><td>'.$langs->trans("CloseAs").'</td><td class="left">';
2363 $form_close .= '<select id="statut" name="statut" class="flat">';
2364 $form_close .= '<option value="0">&nbsp;</option>';
2365 $form_close .= '<option value="2">'.$langs->trans('SupplierProposalStatusSigned').'</option>';
2366 $form_close .= '<option value="3">'.$langs->trans('SupplierProposalStatusNotSigned').'</option>';
2367 $form_close .= '</select>';
2368 $form_close .= '</td></tr>';
2369 $form_close .= '<tr><td class="left">'.$langs->trans('Note').'</td><td class="left"><textarea cols="70" rows="'.ROWS_3.'" wrap="soft" name="note">';
2370 $form_close .= $object->note_private;
2371 $form_close .= '</textarea></td></tr>';
2372 $form_close .= '</table>';
2373 $form_close .= $form->buttonsSaveCancel();
2374 $form_close .= '<a id="acceptedrefused">&nbsp;</a>';
2375 $form_close .= '</form>';
2376
2377 print $form_close;
2378 }
2379
2380 /*
2381 * Boutons Actions
2382 */
2383 if ($action != 'presend') {
2384 print '<div class="tabsAction">';
2385
2386 $parameters = array();
2387 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
2388 // modified by hook
2389 if (empty($reshook)) {
2390 if ($action != 'statut' && $action != 'editline') {
2391 // Subtotal
2392 if ($object->status == SupplierProposal::STATUS_DRAFT && isModEnabled('subtotals')
2393 && (getDolGlobalString('SUBTOTAL_TITLE_'.strtoupper($object->element)) || getDolGlobalString('SUBTOTAL_'.strtoupper($object->element)) || getDolGlobalString('SUBTOTAL_TEXT_'.strtoupper($object->element)))) {
2394 $langs->load('subtotals');
2395
2396 $url_button = array();
2397
2398 $url_button[] = array(
2399 'lang' => 'subtotals',
2400 'enabled' => $object->status == SupplierProposal::STATUS_DRAFT,
2401 'perm' => (bool) $usercancreate,
2402 'label' => $langs->trans('AddTitleLine'),
2403 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_title_line'], true)
2404 );
2405
2406 $url_button[] = array(
2407 'lang' => 'subtotals',
2408 'enabled' => $object->status == SupplierProposal::STATUS_DRAFT,
2409 'perm' => (bool) $usercancreate,
2410 'label' => $langs->trans('AddSubtotalLine'),
2411 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_subtotal_line'], true)
2412 );
2413
2414 $url_button[] = array(
2415 'lang' => 'subtotals',
2416 'enabled' => $object->status == SupplierProposal::STATUS_DRAFT,
2417 'perm' => (bool) $usercancreate,
2418 'label' => $langs->trans('AddTextLine'),
2419 'url' => dolBuildUrl($_SERVER['PHP_SELF'], ['id' => $object->id, 'action' => 'add_text_line'], true)
2420 );
2421
2422 print dolGetButtonAction('', $langs->trans('SubTotal'), 'default', $url_button, '', true);
2423 }
2424 // Validate
2425 if ($object->status == SupplierProposal::STATUS_DRAFT && $object->total_ttc >= 0 && count($object->lines) > 0 && $usercanvalidate) {
2426 if (count($object->lines) > 0) {
2427 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=validate&token='.newToken().'">'.$langs->trans('Validate').'</a></div>';
2428 }
2429 // else print '<a class="butActionRefused classfortooltip" href="#">'.$langs->trans('Validate').'</a>';
2430 }
2431
2432 // Edit
2433 if ($object->status == SupplierProposal::STATUS_VALIDATED && $usercancreate) {
2434 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=modif&token='.newToken().'">'.$langs->trans('Modify').'</a></div>';
2435 }
2436
2437 // ReOpen
2439 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().(!getDolGlobalString('MAIN_JUMP_TAG') ? '' : '#reopen').'"';
2440 print '>'.$langs->trans('ReOpen').'</a></div>';
2441 }
2442
2443 // Send
2444 if (empty($user->socid)) {
2446 if ($usercansend) {
2447 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle', '');
2448 } else {
2449 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', '#', '', false);
2450 }
2451 }
2452 }
2453
2454 // Create an order
2455 if (isModEnabled("supplier_order") && $object->status == SupplierProposal::STATUS_SIGNED) {
2456 if ($usercancreateorder) {
2457 print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/fourn/commande/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->socid.'&amp;token='.newToken().'">'.$langs->trans("AddSupplierOrderShort").'</a></div>';
2458 }
2459 }
2460
2461 // Set accepted/refused
2462 if ($object->status == SupplierProposal::STATUS_VALIDATED && $usercanclose) {
2463 print '<div class="inline-block divButAction"><a class="butAction reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;token='.newToken().'&amp;action=statut'.(!getDolGlobalString('MAIN_JUMP_TAG') ? '' : '#acceptedrefused').'"';
2464 print '>'.$langs->trans('SetAcceptedRefused').'</a></div>';
2465 }
2466
2467 // Close
2468 if ($object->status == SupplierProposal::STATUS_SIGNED && $usercanclose) {
2469 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;token='.newToken().'&amp;action=close'.(!getDolGlobalString('MAIN_JUMP_TAG') ? '' : '#close').'"';
2470 print '>'.$langs->trans('Close').'</a></div>';
2471 }
2472
2473 // Clone
2474 if ($usercancreate) {
2475 print '<div class="inline-block divButAction">'.dolGetButtonAction($langs->trans("ToClone"), $langs->trans("ToClone"), 'clone', $_SERVER['PHP_SELF'].'?id='.((int) $object->id).'&socid='.((int) $object->socid).'&action=clone&object='.urlencode($object->element).'&token='.newToken(), '', true, array('attr' => array('class' => 'reposition'))).'</div>';
2476 }
2477
2478 // Delete
2479 print dolGetButtonAction($langs->trans("Delete"), $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', (($object->status == SupplierProposal::STATUS_DRAFT && $usercancreate) || $usercandelete), array('attr' => array('class' => 'reposition')))."\n";
2480 }
2481 }
2482
2483 print '</div>';
2484 }
2485
2486 if ($action != 'presend') {
2487 print '<div class="fichecenter"><div class="fichehalfleft">';
2488
2489 /*
2490 * Generated documents
2491 */
2492 $filename = dol_sanitizeFileName($object->ref);
2493 $filedir = $conf->supplier_proposal->dir_output."/".dol_sanitizeFileName($object->ref);
2494 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2495 $genallowed = $usercanread;
2496 $delallowed = $usercancreate;
2497
2498 print $formfile->showdocuments('supplier_proposal', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang);
2499
2500
2501 // Show links to link elements
2502 $tmparray = $form->showLinkToObjectBlock($object, array(), array('supplier_proposal'), 1);
2503 $linktoelem = $tmparray['linktoelem'];
2504 $htmltoenteralink = $tmparray['htmltoenteralink'];
2505 print $htmltoenteralink;
2506
2507 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2508
2509 $MAXEVENT = 10;
2510
2511 print '</div><div class="fichehalfright">';
2512
2513 // List of actions on element
2514 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2515 $formactions = new FormActions($db);
2516 $somethingshown = $formactions->showactions($object, 'supplier_proposal', $socid, 1, '', $MAXEVENT);
2517
2518 print '</div></div>';
2519 }
2520
2521 // Select mail models is same action as presend
2522 if (GETPOST('modelselected')) {
2523 $action = 'presend';
2524 }
2525
2526 // Presend form
2527 $modelmail = 'supplier_proposal_send';
2528 $defaulttopic = 'SendAskRef';
2529 $diroutput = $conf->supplier_proposal->dir_output;
2530 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO';
2531 $trackid = 'spro'.$object->id;
2532
2533 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2534}
2535
2536// End of page
2537llxFooter();
2538$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage 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 "other" html components Only common components are here.
Class to help generate other html components Only common components are here.
Class to manage building of HTML components.
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
Class to manage the table of subscription to notifications.
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 price ask supplier.
const STATUS_NOTSIGNED
Not signed quote, canceled.
const STATUS_DRAFT
Draft status.
const STATUS_VALIDATED
Validated status.
const STATUS_SIGNED
Signed quote.
const STATUS_CLOSE
Billed or closed/processed quote.
Class to manage translations.
global $mysoc
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
$date_start
Variables from include:
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
GETPOSTISARRAY($paramname, $method=0)
Return true if the parameter $paramname is submit from a POST OR GET as an array.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
dol_htmlcleanlastbr($stringtodecode)
This function remove all ending and br at end.
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...
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular VAT rate, when selling a product with vat $vatrate,...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
Definition html.lib.php:540
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:738
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Definition html.lib.php:181
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
Check permissions of a user to show a page and an object.
supplier_proposal_prepare_head($object)
Prepare array with list of tabs.