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