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