dolibarr 23.0.3
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 // Defined the new fk_parent_line
466 if ($result > 0 && $lines[$i]->product_type == 9) {
467 $fk_parent_line = $result;
468 }
469 }
470
471 // Hooks
472 $parameters = array('objFrom' => $srcobject);
473 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been
474 // modified by hook
475 if ($reshook < 0) {
476 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
477 $error++;
478 }
479 } else {
480 setEventMessages($srcobject->error, $srcobject->errors, 'errors');
481 $error++;
482 }
483 } else {
484 setEventMessages($object->error, $object->errors, 'errors');
485 $error++;
486 }
487 } else {
488 // Standard creation
489 $id = $object->create($user);
490 }
491
492 if ($id > 0) {
493 if (isModEnabled('category')) {
494 $categories = GETPOST('categories', 'array');
495 $object->setCategories($categories);
496 }
497 if (!$error) {
498 $db->commit();
499
500 // Define output language
501 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
502 $outputlangs = $langs;
503 $newlang = '';
504 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
505 $newlang = GETPOST('lang_id', 'aZ09');
506 }
507 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
508 $newlang = $object->thirdparty->default_lang;
509 }
510 if (!empty($newlang)) {
511 $outputlangs = new Translate("", $conf);
512 $outputlangs->setDefaultLang($newlang);
513 }
514 $model = $object->model_pdf;
515
516 if (!empty($model)) {
517 $ret = $object->fetch($id); // Reload to get new records
518 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
519 if ($result < 0) {
520 dol_print_error($db, $object->error, $object->errors);
521 }
522 }
523 }
524
525 header('Location: '.$_SERVER["PHP_SELF"].'?id='.$id);
526 exit();
527 } else {
528 $db->rollback();
529 $action = 'create';
530 }
531 } else {
532 setEventMessages($object->error, $object->errors, 'errors');
533 $db->rollback();
534 $action = 'create';
535 }
536 }
537 }
538 } elseif ($action == 'confirm_reopen' && $usercanclose && !GETPOST('cancel', 'alpha')) {
539 // Reopen proposal
540 // prevent browser refresh from reopening proposal several times
543 }
544 } elseif ($action == 'close' && $usercanclose && !GETPOST('cancel', 'alpha')) {
545 // Close proposal
546 // prevent browser refresh from reopening proposal several times
549 }
550 } elseif ($action == 'setstatut' && $usercanclose && !GETPOST('cancel', 'alpha')) {
551 // Set accepted/refused
552 if (!GETPOST('statut')) {
553 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("CloseAs")), null, 'errors');
554 $action = 'statut';
555 } else {
556 // prevent browser refresh from closing proposal several times
558 $object->cloture($user, GETPOSTINT('statut'), GETPOST('note', 'restricthtml'));
559 }
560 }
561 } elseif ($action == 'settags' && isModEnabled('category') && $usercancreate) { // Set tags
562 $result = $object->setCategories(GETPOST('categories', 'array'));
563 }
564
565 // Actions when printing a doc from card
566 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
567
568 // Actions to send emails
569 $triggersendname = 'PROPOSAL_SUPPLIER_SENTBYMAIL';
570 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO';
571 $trackid = 'spro'.$object->id;
572 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
573
574 // Actions to build doc
575 $upload_dir = $conf->supplier_proposal->dir_output;
576 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
577
578
579 // Go back to draft
580 if ($action == 'modif' && $usercancreate) {
581 $object->setDraft($user);
582
583 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
584 // Define output language
585 $outputlangs = $langs;
586 if (getDolGlobalInt('MAIN_MULTILANGS')) {
587 $outputlangs = new Translate("", $conf);
588 $newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $object->thirdparty->default_lang);
589 $outputlangs->setDefaultLang($newlang);
590 }
591 $ret = $object->fetch($id); // Reload to get new records
592 if ($ret > 0) {
593 $object->fetch_thirdparty();
594 }
595 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
596 }
597 } elseif ($action == "setabsolutediscount" && $usercancreate) {
598 if (GETPOSTINT("remise_id")) {
599 if ($object->id > 0) {
600 $result = $object->insert_discount(GETPOSTINT("remise_id"));
601 if ($result < 0) {
602 setEventMessages($object->error, $object->errors, 'errors');
603 }
604 }
605 }
606 }
607
608 // Add a product line
609 if ($action == 'addline' && GETPOST('submitforalllines', 'aZ09') && GETPOST('vatforalllines', 'alpha') && $usercancreate) {
610 // Define vat_rate
611 $vat_rate = (GETPOST('vatforalllines') ? GETPOST('vatforalllines') : 0);
612 $vat_rate = str_replace('*', '', $vat_rate);
613 $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
614 $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
615 foreach ($object->lines as $line) {
616 $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);
617 }
618 } elseif ($action == 'addline' && $usercancreate) {
619 $langs->load('errors');
620 $error = 0;
621
622 // Set if we used free entry or predefined product
623 $predef = '';
624 $line_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
625 $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'));
626 $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'));
627
628 $ref_supplier = GETPOST('fourn_ref', 'alpha');
629
630 $prod_entry_mode = GETPOST('prod_entry_mode', 'aZ09');
631 if ($prod_entry_mode == 'free') {
632 $idprod = 0;
633 } else {
634 $idprod = GETPOSTINT('idprod');
635 }
636
637 $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)'
638
639 $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
640 $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
641 $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
642 $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
643
644 $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2);
645
646 $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0);
647 if (empty($remise_percent)) {
648 $remise_percent = 0;
649 }
650
651 // Extrafields
652 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
653 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
654 // Unset extrafield
655 if (is_array($extralabelsline)) {
656 // Get extra fields
657 foreach ($extralabelsline as $key => $value) {
658 unset($_POST["options_".$key]);
659 }
660 }
661
662 if ($prod_entry_mode == 'free' && GETPOST('price_ht') < 0 && $qty < 0) {
663 setEventMessages($langs->trans('ErrorBothFieldCantBeNegative', $langs->transnoentitiesnoconv('UnitPrice'), $langs->transnoentitiesnoconv('Qty')), null, 'errors');
664 $error++;
665 }
666 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && GETPOST('type') < 0) {
667 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
668 $error++;
669 }
670
671 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.
672 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPrice")), null, 'errors');
673 $error++;
674 }
675 if ($prod_entry_mode == 'free' && (empty($idprod) || $idprod < 0) && empty($line_desc)) {
676 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors');
677 $error++;
678 }
679 if (!$error && ($qty >= 0)) {
680 $pu_ht = price2num($price_ht, 'MU');
681 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
682 $price_min = 0;
683 $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
684
685 $db->begin();
686
687 if ($prod_entry_mode != 'free' && empty($error)) { // With combolist mode idprodfournprice is > 0 or -1. With autocomplete, idprodfournprice is > 0 or ''
688 $productsupplier = new ProductFournisseur($db);
689
690 $idprod = 0;
691 if (GETPOST('idprodfournprice', 'alpha') == -1 || GETPOST('idprodfournprice', 'alpha') == '') {
692 $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, ...)
693 }
694
695 $reg = array();
696 if (preg_match('/^idprod_([0-9]+)$/', GETPOST('idprodfournprice', 'alpha'), $reg)) {
697 $idprod = (int) $reg[1];
698 $res = $productsupplier->fetch($idprod); // Load product from its id
699 // Call to init some price properties of $productsupplier
700 // So if a supplier price already exists for another thirdparty (first one found), we use it as reference price
701 if (getDolGlobalString('SUPPLIER_TAKE_FIRST_PRICE_IF_NO_PRICE_FOR_CURRENT_SUPPLIER')) {
702 $fksoctosearch = 0;
703 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
704 if ($productsupplier->fourn_socid != $socid) { // The price we found is for another supplier, so we clear supplier price
705 $productsupplier->ref_supplier = '';
706 }
707 } else {
708 $fksoctosearch = $object->thirdparty->id;
709 $productsupplier->get_buyprice(0, -1, $idprod, 'none', $fksoctosearch); // We force qty to -1 to be sure to find if a supplier price exist
710 }
711 } elseif (GETPOSTINT('idprodfournprice') > 0) { // id here.
712 //$qtytosearch=$qty; // Just to see if a price exists for the quantity. Not used to found vat.
713 $qtytosearch = -1; // We force qty to -1 to be sure to find if the supplier price that exists
714 $idprod = $productsupplier->get_buyprice(GETPOSTINT('idprodfournprice'), $qtytosearch);
715 $res = $productsupplier->fetch($idprod);
716 }
717
718 if ($idprod > 0) {
719 $label = $productsupplier->label;
720
721 // Define output language
722 if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
723 $outputlangs = $langs;
724 $newlang = '';
725 if (/* empty($newlang) && */ GETPOST('lang_id', 'aZ09')) {
726 $newlang = GETPOST('lang_id', 'aZ09');
727 }
728 if (empty($newlang)) {
729 $newlang = $object->thirdparty->default_lang;
730 }
731 if (!empty($newlang)) {
732 $outputlangs = new Translate("", $conf);
733 $outputlangs->setDefaultLang($newlang);
734 }
735 $desc = (!empty($productsupplier->multilangs[$outputlangs->defaultlang]["description"])) ? $productsupplier->multilangs[$outputlangs->defaultlang]["description"] : $productsupplier->description;
736 } else {
737 $desc = $productsupplier->description;
738 }
739 // if we use supplier description of the products
740 if (!empty($productsupplier->desc_supplier) && getDolGlobalString('PRODUIT_FOURN_TEXTS')) {
741 $desc = $productsupplier->desc_supplier;
742 }
743
744 if (getDolGlobalInt('PRODUIT_AUTOFILL_DESC') == 0) {
745 // 'DoNotAutofillButAutoConcat'
746 $desc = dol_concatdesc($desc, $line_desc, false, getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION') ? true : false);
747 } else {
748 //'AutoFillFormFieldBeforeSubmit' or 'DoNotUseDescriptionOfProdut' => User has already done the modification they want
749 $desc = $line_desc;
750 }
751
752 $ref_supplier = $productsupplier->ref_supplier;
753
754 // Get vat rate
755 $tva_npr = 0;
756 if (!GETPOSTISSET('tva_tx')) { // If vat rate not provided from the form (the form has the priority)
757 $tmpidprodfournprice = GETPOST('idprodfournprice', 'alpha'); // can be an id of price, or -1, -2, -99 or 'idprod_...'
758 if (is_numeric($tmpidprodfournprice) && (int) $tmpidprodfournprice > 0) {
759 $tmpidprodfournprice = (int) $tmpidprodfournprice;
760 } else {
761 $tmpidprodfournprice = 0;
762 }
763
764 $tva_tx = get_default_tva($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
765 $tva_npr = get_default_npr($object->thirdparty, $mysoc, $productsupplier->id, $tmpidprodfournprice);
766 }
767 if (empty($tva_tx)) {
768 $tva_npr = 0;
769 }
770 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty, $tva_npr);
771 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty, $tva_npr);
772
773 $type = $productsupplier->type;
774 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
775 $price_base_type = 'HT';
776 $pu = price2num($price_ht, 'MU');
777 $pu_devise = price2num($price_ht_devise, 'CU');
778 } elseif (GETPOST('price_ttc') != '' || GETPOST('multicurrency_price_ttc') != '') {
779 $price_base_type = 'TTC';
780 $pu = price2num($price_ttc, 'MU');
781 $pu_devise = price2num($price_ttc_devise, 'CU');
782 } else {
783 $price_base_type = ($productsupplier->fourn_price_base_type ? $productsupplier->fourn_price_base_type : 'HT');
784 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
785 $pu = $productsupplier->fourn_pu;
786 $pu_devise = 0;
787 } else {
788 $pu = $productsupplier->fourn_pu;
789 $pu_devise = $productsupplier->fourn_multicurrency_unitprice;
790 }
791 }
792
793 if (empty($pu)) {
794 $pu = 0; // If pu is '' or null, we force to have a numeric value
795 }
796
797 // 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)
798 $fournprice = (is_numeric(GETPOST('idprodfournprice', 'alpha')) ? GETPOST('idprodfournprice', 'alpha') : -1);
799 $buyingprice = 0;
800
801 $result = $object->addline(
802 $desc,
803 ($price_base_type == 'HT' ? $pu : 0),
804 (float) $qty,
805 $tva_tx,
806 $localtax1_tx,
807 $localtax2_tx,
808 $productsupplier->id,
809 $remise_percent,
810 $price_base_type,
811 ($price_base_type == 'TTC' ? $pu : 0),
812 $tva_npr,
813 $type,
814 min($rank, count($object->lines) + 1),
815 0,
816 GETPOSTINT('fk_parent_line'),
817 (int) $fournprice,
818 $buyingprice,
819 $label,
820 $array_options,
821 $ref_supplier,
822 $productsupplier->fk_unit,
823 '',
824 0,
825 $pu_devise,
826 $date_start,
827 $date_end
828 );
829
830 //var_dump($tva_tx);
831 //var_dump($productsupplier->fourn_pu);
832 //var_dump($price_base_type);exit;
833 if ($result < 0) {
834 $error++;
835 setEventMessages($object->error, $object->errors, 'errors');
836 }
837 }
838 if ($idprod == -99 || $idprod == 0) {
839 // Product not selected
840 $error++;
841 $langs->load("errors");
842 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")).' '.$langs->trans("or").' '.$langs->trans("NoPriceDefinedForThisSupplier"), null, 'errors');
843 }
844 if ($idprod == -1) {
845 // Quantity too low
846 $error++;
847 $langs->load("errors");
848 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'errors');
849 }
850 } elseif ((GETPOST('price_ht') !== '' || GETPOST('price_ttc') !== '' || GETPOST('multicurrency_price_ht') != '') && empty($error)) { // Free product. // $price_ht is already set
851 $pu_ht = price2num($price_ht, 'MU');
852 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
853
854 $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
855 $tva_tx = str_replace('*', '', $tva_tx);
856 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
857 $desc = $line_desc;
858 $type = GETPOSTINT('type');
859
860 $fk_unit = GETPOSTINT('units');
861
862 if (!preg_match('/\‍((.*)\‍)/', $tva_tx)) {
863 $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'
864 }
865
866 // Local Taxes
867 $localtax1_tx = get_localtax($tva_tx, 1, $mysoc, $object->thirdparty);
868 $localtax2_tx = get_localtax($tva_tx, 2, $mysoc, $object->thirdparty);
869
870 if (GETPOST('price_ht') != '' || GETPOST('multicurrency_price_ht') != '') {
871 $pu_ht = price2num($price_ht, 'MU'); // $pu_ht must be rounded according to settings
872 } else {
873 $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
874 $pu_ht = price2num((float) $pu_ttc / (1 + ((float) $tva_tx / 100)), 'MU'); // $pu_ht must be rounded according to settings
875 }
876 $price_base_type = 'HT';
877 $pu_ht_devise = price2num($price_ht_devise, 'CU');
878 $info_bits = 0;
879
880 $result = $object->addline(
881 $desc,
882 (float) $pu_ht,
883 (float) $qty,
884 $tva_tx, // don't cast to float
885 $localtax1_tx,
886 $localtax2_tx,
887 $idprod,
888 $remise_percent,
889 $price_base_type,
890 (float) $pu_ttc,
891 $info_bits,
892 $type,
893 -1, // rang
894 0, // special_code
895 GETPOSTINT('fk_parent_line'),
896 (int) $fournprice,
897 $buyingprice,
898 $label,
899 $array_options,
900 $ref_supplier,
901 $fk_unit,
902 '', // origin
903 0, // origin_id
904 (float) $pu_ht_devise
905 );
906 }
907
908
909 if (!$error && $result > 0) {
910 $db->commit();
911
912 $ret = $object->fetch($object->id); // Reload to get new records
913
914 // Define output language
915 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
916 $outputlangs = $langs;
917 $newlang = '';
918 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
919 $newlang = GETPOST('lang_id', 'aZ09');
920 }
921 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
922 $newlang = $object->thirdparty->default_lang;
923 }
924 if (!empty($newlang)) {
925 $outputlangs = new Translate("", $conf);
926 $outputlangs->setDefaultLang($newlang);
927 }
928 $model = $object->model_pdf;
929 $ret = $object->fetch($id); // Reload to get new records
930 if ($ret > 0) {
931 $object->fetch_thirdparty();
932 }
933
934 $result = $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
935 if ($result < 0) {
936 dol_print_error($db, $object->error, $object->errors);
937 }
938 }
939
940 unset($_POST['prod_entry_mode']);
941
942 unset($_POST['qty']);
943 unset($_POST['type']);
944 unset($_POST['remise_percent']);
945 unset($_POST['pu']);
946 unset($_POST['price_ht']);
947 unset($_POST['multicurrency_price_ht']);
948 unset($_POST['price_ttc']);
949 unset($_POST['fourn_ref']);
950 unset($_POST['tva_tx']);
951 unset($_POST['label']);
952 unset($_POST['product_ref']);
953 unset($_POST['product_label']);
954 unset($_POST['product_desc']);
955 unset($_POST['fournprice']);
956 unset($_POST['buying_price']);
957 unset($localtax1_tx);
958 unset($localtax2_tx);
959 unset($_POST['np_marginRate']);
960 unset($_POST['np_markRate']);
961 unset($_POST['dp_desc']);
962 unset($_POST['idprodfournprice']);
963 unset($_POST['units']);
964
965 unset($_POST['idprod']);
966
967 unset($_POST['date_starthour']);
968 unset($_POST['date_startmin']);
969 unset($_POST['date_startsec']);
970 unset($_POST['date_startday']);
971 unset($_POST['date_startmonth']);
972 unset($_POST['date_startyear']);
973 unset($_POST['date_endhour']);
974 unset($_POST['date_endmin']);
975 unset($_POST['date_endsec']);
976 unset($_POST['date_endday']);
977 unset($_POST['date_endmonth']);
978 unset($_POST['date_endyear']);
979 } else {
980 $db->rollback();
981
982 setEventMessages($object->error, $object->errors, 'errors');
983 }
984 }
985 } elseif ($action == 'updateline' && $usercancreate && GETPOST('save') == $langs->trans("Save")) {
986 // Update a line within proposal
987 $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
988
989 // Define info_bits
990 $info_bits = 0;
991 if (preg_match('/\*/', $vat_rate)) {
992 $info_bits |= 0x01;
993 }
994
995 // Clean parameters
996 $description = dol_htmlcleanlastbr(GETPOST('product_desc', 'restricthtml'));
997
998 // Define vat_rate
999 $vat_rate = str_replace('*', '', $vat_rate);
1000 $localtax1_rate = get_localtax($vat_rate, 1, $mysoc, $object->thirdparty);
1001 $localtax2_rate = get_localtax($vat_rate, 2, $mysoc, $object->thirdparty);
1002
1003 if (GETPOST('price_ht') != '') {
1004 $price_base_type = 'HT';
1005 $ht = price2num(GETPOST('price_ht'), '', 2);
1006 } else {
1007 $reg = array();
1008 $vatratecleaned = $vat_rate;
1009 if (preg_match('/^(.*)\s*\‍((.*)\‍)$/', $vat_rate, $reg)) { // If vat is "xx (yy)"
1010 $vatratecleaned = trim($reg[1]);
1011 $vatratecode = $reg[2];
1012 }
1013
1014 $ttc = price2num(GETPOST('price_ttc'), '', 2);
1015 $ht = (float) $ttc / (1 + ((float) $vatratecleaned / 100));
1016 $price_base_type = 'HT';
1017 }
1018
1019 $pu_ht_devise = price2num(GETPOST('multicurrency_subprice'), 'CU', 2);
1020
1021 // Add buying price
1022 $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
1023 $buyingprice = price2num((GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''), '', 2); // If buying_price is '0', we must keep this value
1024
1025 // Extrafields Lines
1026 $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
1027 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line);
1028 // Unset extrafield POST Data
1029 if (is_array($extralabelsline)) {
1030 foreach ($extralabelsline as $key => $value) {
1031 unset($_POST["options_".$key]);
1032 }
1033 }
1034
1035 // Define special_code for special lines
1036 $special_code = GETPOST('special_code');
1037 if (!GETPOST('qty')) {
1038 $special_code = 3;
1039 }
1040
1041 // Check minimum price
1042 $productid = GETPOSTINT('productid');
1043 if (!empty($productid)) {
1044 $productsupplier = new ProductFournisseur($db);
1045 if (getDolGlobalInt('SUPPLIER_PROPOSAL_WITH_PREDEFINED_PRICES_ONLY') == 1) { // Not the common case
1046 if ($productid > 0 && $productsupplier->get_buyprice(0, (float) price2num(GETPOST('qty')), $productid, 'none', GETPOSTINT('socid')) < 0) {
1047 setEventMessages($langs->trans("ErrorQtyTooLowForThisSupplier"), null, 'warnings');
1048 }
1049 }
1050
1051 $product = new Product($db);
1052 $res = $product->fetch($productid);
1053
1054 $type = $product->type;
1055
1056 $price_min = $product->price_min;
1057 if (getDolGlobalString('PRODUIT_MULTIPRICES') && !empty($object->thirdparty->price_level)) {
1058 $price_min = $product->multiprices_min [$object->thirdparty->price_level];
1059 }
1060
1061 $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
1062 } else {
1063 $type = GETPOST('type');
1064 $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1065
1066 // Check parameters
1067 if (GETPOST('type') < 0) {
1068 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
1069 $error++;
1070 }
1071 }
1072
1073 if (!$error) {
1074 $db->begin();
1075
1076 $ref_supplier = GETPOST('fourn_ref', 'alpha');
1077 $fk_unit = GETPOSTINT('units');
1078
1079 $result = $object->updateline(
1080 GETPOSTINT('lineid'),
1081 $ht,
1082 (float) price2num(GETPOST('qty'), 'MS', 2),
1083 (float) price2num(GETPOST('remise_percent'), '', 2),
1084 $vat_rate,
1085 $localtax1_rate,
1086 $localtax2_rate,
1087 $description,
1088 $price_base_type,
1089 $info_bits,
1090 $special_code,
1091 GETPOSTINT('fk_parent_line'),
1092 0,
1093 (int) $fournprice,
1094 $buyingprice,
1095 $label,
1096 $type,
1097 $array_options,
1098 $ref_supplier,
1099 $fk_unit,
1100 (float) $pu_ht_devise
1101 );
1102
1103 if ($result >= 0) {
1104 $db->commit();
1105
1106 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
1107 // Define output language
1108 $outputlangs = $langs;
1109 if (getDolGlobalInt('MAIN_MULTILANGS')) {
1110 $outputlangs = new Translate("", $conf);
1111 $newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $object->thirdparty->default_lang);
1112 $outputlangs->setDefaultLang($newlang);
1113 }
1114 $ret = $object->fetch($id); // Reload to get new records
1115 $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1116 }
1117
1118 unset($_POST['qty']);
1119 unset($_POST['type']);
1120 unset($_POST['productid']);
1121 unset($_POST['remise_percent']);
1122 unset($_POST['price_ht']);
1123 unset($_POST['multicurrency_price_ht']);
1124 unset($_POST['price_ttc']);
1125 unset($_POST['tva_tx']);
1126 unset($_POST['product_ref']);
1127 unset($_POST['product_label']);
1128 unset($_POST['product_desc']);
1129 unset($_POST['fournprice']);
1130 unset($_POST['buying_price']);
1131
1132 unset($_POST['date_starthour']);
1133 unset($_POST['date_startmin']);
1134 unset($_POST['date_startsec']);
1135 unset($_POST['date_startday']);
1136 unset($_POST['date_startmonth']);
1137 unset($_POST['date_startyear']);
1138 unset($_POST['date_endhour']);
1139 unset($_POST['date_endmin']);
1140 unset($_POST['date_endsec']);
1141 unset($_POST['date_endday']);
1142 unset($_POST['date_endmonth']);
1143 unset($_POST['date_endyear']);
1144 } else {
1145 $db->rollback();
1146
1147 setEventMessages($object->error, $object->errors, 'errors');
1148 }
1149 }
1150 } elseif ($action == 'updateline' && $usercancreate && $cancel) {
1151 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$object->id); // To re-display card in edit mode
1152 exit();
1153 } elseif ($action == 'classin' && $usercancreate) {
1154 // Set project
1155 $object->setProject(GETPOSTINT('projectid'));
1156 } elseif ($action == 'setavailability' && $usercancreate) {
1157 // Delivery delay
1158 $result = $object->availability(GETPOST('availability_id'));
1159 } elseif ($action == 'setconditions' && $usercancreate) {
1160 // Terms of payments
1161 $sql = "SELECT code ";
1162 $sql .= "FROM " . $db->prefix() . "c_payment_term";
1163 $sql .= " WHERE rowid = " . GETPOSTINT('cond_reglement_id');
1164 $result = $db->query($sql);
1165 if ($result) {
1166 $obj = $db->fetch_object($result);
1167 if ($obj->code == 'DEP30PCTDEL') {
1168 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'), GETPOSTFLOAT('cond_reglement_id_deposit_percent'));
1169 } else {
1170 $object->deposit_percent = 0;
1171 $result = $object->setPaymentTerms(GETPOSTINT('cond_reglement_id'), $object->deposit_percent);
1172 }
1173 }
1174 //} elseif ($action == 'setremisepercent' && $usercancreate) {
1175 // $result = $object->set_remise_percent($user, price2num(GETPOST('remise_percent'), '', 2));
1176 //} elseif ($action == 'setremiseabsolue' && $usercancreate) {
1177 // $result = $object->set_remise_absolue($user, price2num(GETPOST('remise_absolue'), 'MU', 2));
1178 } elseif ($action == 'setmode' && $usercancreate) {
1179 // Payment mode
1180 $result = $object->setPaymentMethods(GETPOSTINT('mode_reglement_id'));
1181 } elseif ($action == 'setmulticurrencycode' && $usercancreate) {
1182 // Multicurrency Code
1183 $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
1184 } elseif ($action == 'setmulticurrencyrate' && $usercancreate) {
1185 // Multicurrency rate
1186 $result = $object->setMulticurrencyRate(GETPOSTFLOAT('multicurrency_tx'), GETPOSTINT('calculation_mode'));
1187 } elseif ($action == 'update_extras' && $permissiontoeditextra) {
1188 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
1189
1190 $attribute_name = GETPOST('attribute', 'aZ09');
1191
1192 // Fill array 'array_options' with data from update form
1193 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
1194 if ($ret < 0) {
1195 $error++;
1196 }
1197
1198 if (!$error) {
1199 $result = $object->updateExtraField($attribute_name, 'PROPOSAL_SUPPLIER_MODIFY');
1200 if ($result < 0) {
1201 setEventMessages($object->error, $object->errors, 'errors');
1202 $error++;
1203 }
1204 }
1205
1206 if ($error) {
1207 $action = 'edit_extras';
1208 }
1209 }
1210}
1211
1212
1213/*
1214 * View
1215 */
1216
1217$title = $object->ref." - ".$langs->trans('Card');
1218if ($action == 'create') {
1219 $title = $langs->trans("SupplierProposalNew");
1220}
1221$help_url = 'EN:Ask_Price_Supplier|FR:Demande_de_prix_fournisseur';
1222
1223llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-supplierproposal page-card');
1224
1225$form = new Form($db);
1226$formother = new FormOther($db);
1227$formfile = new FormFile($db);
1228$formmargin = new FormMargin($db);
1229$companystatic = new Societe($db);
1230if (isModEnabled('project')) {
1231 $formproject = new FormProjets($db);
1232}
1233
1234$now = dol_now();
1235
1236// Add new askprice
1237if ($action == 'create') {
1238 $currency_code = $conf->currency;
1239
1240 print load_fiche_titre($langs->trans("SupplierProposalNew"), '', 'supplier_proposal');
1241
1242 $soc = new Societe($db);
1243 if ($socid > 0) {
1244 $res = $soc->fetch($socid);
1245 }
1246
1247 // Load objectsrc
1248 if (!empty($origin) && !empty($originid)) {
1249 $element = $subelement = GETPOST('origin');
1250 $regs = array();
1251 if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'), $regs)) {
1252 $element = $regs[1];
1253 $subelement = $regs[2];
1254 }
1255
1256 // For compatibility
1257 if ($element == 'order' || $element == 'commande') {
1258 $element = $subelement = 'commande';
1259 }
1260 if ($element == 'propal') {
1261 $element = 'comm/propal';
1262 $subelement = 'propal';
1263 }
1264
1265 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1266
1267 $classname = ucfirst($subelement);
1268 $objectsrc = new $classname($db);
1269 '@phan-var-force Commande|Propal|CommandeFournisseur|SupplierProposal $objectsrc'; // Could be other classes, but CommonObject is too generic
1271 $objectsrc->fetch($originid);
1272 if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
1273 $objectsrc->fetch_lines();
1274 }
1275 $objectsrc->fetch_thirdparty();
1276
1277 $projectid = (int) $objectsrc->fk_project;
1278 $soc = $objectsrc->thirdparty;
1279
1280 $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
1281 $deposit_percent = (!empty($objectsrc->deposit_percent) ? $objectsrc->deposit_percent : (!empty($soc->deposit_percent) ? $soc->deposit_percent : 0));
1282 $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0));
1283
1284 // Replicate extrafields
1285 $objectsrc->fetch_optionals();
1286 $object->array_options = $objectsrc->array_options;
1287
1288 if (isModEnabled("multicurrency")) {
1289 if (!empty($objectsrc->multicurrency_code)) {
1290 $currency_code = $objectsrc->multicurrency_code;
1291 }
1292 if (getDolGlobalString('MULTICURRENCY_USE_ORIGIN_TX') && !empty($objectsrc->multicurrency_tx)) {
1293 $currency_tx = $objectsrc->multicurrency_tx;
1294 }
1295 }
1296 } else {
1297 $cond_reglement_id = $soc->cond_reglement_supplier_id;
1298 $deposit_percent = !empty($soc->deposit_percent) ? $soc->deposit_percent : 0;
1299 $mode_reglement_id = $soc->mode_reglement_supplier_id;
1300 if (isModEnabled("multicurrency") && !empty($soc->multicurrency_code)) {
1301 $currency_code = $soc->multicurrency_code;
1302 }
1303 }
1304 if (GETPOSTISSET('cond_reglement_id_deposit_percent')) {
1305 $deposit_percent = GETPOSTFLOAT('cond_reglement_id_deposit_percent');
1306 }
1307
1308 $object = new SupplierProposal($db);
1309
1310 print '<form name="addprop" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1311 print '<input type="hidden" name="token" value="'.newToken().'">';
1312 print '<input type="hidden" name="action" value="add">';
1313 if ($origin != 'project' && $originid) {
1314 print '<input type="hidden" name="origin" value="'.$origin.'">';
1315 print '<input type="hidden" name="originid" value="'.$originid.'">';
1316 }
1317 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1318
1319 print dol_get_fiche_head();
1320
1321 // Call Hook tabContentCreateSupplierProposal
1322 $parameters = array();
1323 // Note that $action and $object may be modified by hook
1324 $reshook = $hookmanager->executeHooks('tabContentCreateSupplierProposal', $parameters, $object, $action);
1325 if (empty($reshook)) {
1326 print '<table class="border centpercent">';
1327
1328 // Reference
1329 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Ref').'</td><td colspan="2">'.$langs->trans("Draft").'</td></tr>';
1330
1331 // Third party
1332 print '<tr>';
1333 print '<td class="fieldrequired">'.$langs->trans('Supplier').'</td>';
1334 if ($socid > 0) {
1335 print '<td colspan="2">';
1336 print $soc->getNomUrl(1, 'supplier');
1337 print '<input type="hidden" name="socid" value="'.$soc->id.'">';
1338 print '</td>';
1339 } else {
1340 print '<td colspan="2">';
1341 $filter = '((s.fournisseur:=:1) AND (s.status:=:1))';
1342 print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company((empty($socid) ? '' : $socid), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
1343 // reload page to retrieve customer information
1344 if (!getDolGlobalString('RELOAD_PAGE_ON_SUPPLIER_CHANGE_DISABLED')) {
1345 print '<script>
1346 $(document).ready(function() {
1347 $("#socid").change(function() {
1348 console.log("We have changed the company - Reload page");
1349 // reload page
1350 $("input[name=action]").val("create");
1351 $("form[name=addprop]").submit();
1352 });
1353 });
1354 </script>';
1355 }
1356 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>';
1357 print '</td>';
1358 }
1359 print '</tr>'."\n";
1360
1361 if ($soc->id > 0) {
1362 // Discounts for third party
1363 print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
1364
1365 $absolute_discount = $soc->getAvailableDiscounts(null, '', 0, 1);
1366
1367 $thirdparty = $soc;
1368 $discount_type = 1;
1369 $backtopage = urlencode($_SERVER["PHP_SELF"].'?socid='.$thirdparty->id.'&action='.$action.'&origin='.GETPOST('origin').'&originid='.GETPOST('originid'));
1370 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
1371
1372 print '</td></tr>';
1373 }
1374
1375 // Terms of payment
1376 print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td colspan="2">';
1377 print img_picto('', 'payment', 'class="pictofixedwidth"');
1378 print $form->getSelectConditionsPaiements(GETPOSTISSET('cond_reglement_id') ? GETPOSTINT('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', -1, 1, 0, '', $deposit_percent);
1379 print '</td></tr>';
1380
1381 // Mode of payment
1382 print '<tr><td>'.$langs->trans('PaymentMode').'</td><td colspan="2">';
1383 print img_picto('', 'bank', 'class="pictofixedwidth"');
1384 $form->select_types_paiements(GETPOST('mode_reglement_id') > 0 ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id');
1385 print '</td></tr>';
1386
1387 // Bank Account
1388 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL') && isModEnabled("bank")) {
1389 print '<tr><td>'.$langs->trans('BankAccount').'</td><td colspan="2">';
1390 print img_picto('', 'bank', 'class="pictofixedwidth"');
1391 $form->select_comptes(GETPOST('fk_account') > 0 ? GETPOSTINT('fk_account') : $fk_account, 'fk_account', 0, '', 1);
1392 print '</td></tr>';
1393 }
1394
1395 // Shipping Method
1396 if (isModEnabled("shipping")) {
1397 print '<tr><td>'.$langs->trans('SendingMethod').'</td><td colspan="2">';
1398 print img_picto('', 'dolly', 'class="pictofixedwidth"');
1399 $form->selectShippingMethod(GETPOST('shipping_method_id') > 0 ? GETPOSTINT('shipping_method_id') : "", 'shipping_method_id', '', 1);
1400 print '</td></tr>';
1401 }
1402
1403 // Delivery date (or manufacturing)
1404 print '<tr><td>'.$langs->trans("DeliveryDate").'</td>';
1405 print '<td colspan="2">';
1406 print img_picto('', 'action', 'class="pictofixedwidth"');
1407 $datedelivery = dol_mktime(0, 0, 0, GETPOSTINT('liv_month'), GETPOSTINT('liv_day'), GETPOSTINT('liv_year'));
1408 if (is_numeric(getDolGlobalString('DATE_LIVRAISON_WEEK_DELAY'))) { // If value set to 0 or a num, not empty
1409 $tmpdte = time() + (7 * getDolGlobalInt('DATE_LIVRAISON_WEEK_DELAY') * 24 * 60 * 60);
1410 $syear = date("Y", $tmpdte);
1411 $smonth = date("m", $tmpdte);
1412 $sday = date("d", $tmpdte);
1413 print $form->selectDate($syear."-".$smonth."-".$sday, 'liv_', 0, 0, 0, "addask");
1414 } else {
1415 print $form->selectDate($datedelivery ? $datedelivery : -1, 'liv_', 0, 0, 0, "addask", 1, 1);
1416 }
1417 print '</td></tr>';
1418
1419
1420 // Model
1421 print '<tr>';
1422 print '<td>'.$langs->trans("DefaultModel").'</td>';
1423 print '<td colspan="2">';
1424 print img_picto('', 'pdf', 'class="pictofixedwidth"');
1426 $preselected = getDolGlobalString('SUPPLIER_PROPOSAL_ADDON_PDF_ODT_DEFAULT', getDolGlobalString('SUPPLIER_PROPOSAL_ADDON_PDF'));
1427 print $form->selectarray('model', $list, $preselected, 0, 0, 0, '', 0, 0, 0, '', '', 1);
1428 print "</td></tr>";
1429
1430 // Project
1431 if (isModEnabled('project')) {
1432 $langs->load("projects");
1433
1434 $formproject = new FormProjets($db);
1435
1436 if ($origin == 'project') {
1437 $projectid = ($originid ? $originid : 0);
1438 }
1439
1440 print '<tr>';
1441 print '<td>'.$langs->trans("Project").'</td><td colspan="2">';
1442 if (!empty($user->socid)) { // external user: restrict to their own third party
1443 $projSocFilter = $user->socid;
1444 } elseif (getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') || $socid == 0) {
1445 // Give priority to the constant (as on supplier invoice), so a supplier document created from a
1446 // customer project keeps that project selected after the supplier is chosen.
1447 $projSocFilter = -1;
1448 } else {
1449 $projSocFilter = $socid;
1450 }
1451 print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects($projSocFilter, $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500');
1452 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>';
1453 print '</td>';
1454 print '</tr>';
1455 }
1456
1457 // Multicurrency
1458 if (isModEnabled("multicurrency")) {
1459 print '<tr>';
1460 print '<td>'.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).'</td>';
1461 print '<td colspan="3" class="maxwidthonsmartphone">';
1462 print img_picto('', 'currency', 'class="pictofixedwidth"');
1463 print $form->selectMultiCurrency($currency_code, 'multicurrency_code');
1464 print '</td></tr>';
1465 }
1466 // Categories
1467 if (isModEnabled('category')) {
1468 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
1469 print $form->selectCategories(Categorie::TYPE_SUPPLIER_PROPOSAL, 'categories', $object);
1470 print "</td></tr>";
1471 }
1472
1473 // Other attributes
1474 $parameters = array('colspan' => ' colspan="3"', 'cols' => 3);
1475 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1476 print $hookmanager->resPrint;
1477 if (empty($reshook)) {
1478 print $object->showOptionals($extrafields, 'create', $parameters);
1479 }
1480
1481
1482 // Lines from source
1483 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
1484 // TODO for compatibility
1485 if ($origin == 'contrat') {
1486 // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
1487 //$objectsrc->remise_absolue = $remise_absolue;
1488 //$objectsrc->remise_percent = $remise_percent;
1489 $objectsrc->update_price(1, 'auto', 1);
1490 }
1491
1492 print "\n<!-- ".$classname." info -->";
1493 print "\n";
1494 print '<input type="hidden" name="amount" value="'.$objectsrc->total_ht.'">'."\n";
1495 print '<input type="hidden" name="total" value="'.$objectsrc->total_ttc.'">'."\n";
1496 print '<input type="hidden" name="tva" value="'.$objectsrc->total_tva.'">'."\n";
1497 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
1498 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
1499
1500 print '<tr><td>'.$langs->trans('CommRequest').'</td><td colspan="2">'.$objectsrc->getNomUrl(1).'</td></tr>';
1501 print '<tr><td>'.$langs->trans('AmountHT').'</td><td colspan="2">'.price($objectsrc->total_ht).'</td></tr>';
1502 print '<tr><td>'.$langs->trans('AmountVAT').'</td><td colspan="2">'.price($objectsrc->total_tva)."</td></tr>";
1503 if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0) { // Localtax1
1504 print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td><td colspan="2">'.price($objectsrc->total_localtax1)."</td></tr>";
1505 }
1506
1507 if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) { // Localtax2
1508 print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td><td colspan="2">'.price($objectsrc->total_localtax2)."</td></tr>";
1509 }
1510 print '<tr><td>'.$langs->trans('AmountTTC').'</td><td colspan="2">'.price($objectsrc->total_ttc)."</td></tr>";
1511
1512 if (isModEnabled("multicurrency")) {
1513 print '<tr><td>'.$langs->trans('MulticurrencyAmountHT').'</td><td colspan="2">'.price($objectsrc->multicurrency_total_ht).'</td></tr>';
1514 print '<tr><td>'.$langs->trans('MulticurrencyAmountVAT').'</td><td colspan="2">'.price($objectsrc->multicurrency_total_tva)."</td></tr>";
1515 print '<tr><td>'.$langs->trans('MulticurrencyAmountTTC').'</td><td colspan="2">'.price($objectsrc->multicurrency_total_ttc)."</td></tr>";
1516 }
1517 }
1518
1519 print "</table>\n";
1520
1521
1522 /*
1523 * Combobox for copy function
1524 */
1525
1526 if (!getDolGlobalString('SUPPLIER_PROPOSAL_CLONE_ON_CREATE_PAGE')) {
1527 print '<input type="hidden" name="createmode" value="empty">';
1528 }
1529
1530 if (getDolGlobalString('SUPPLIER_PROPOSAL_CLONE_ON_CREATE_PAGE')) {
1531 print '<br><table>';
1532
1533 // For backward compatibility
1534 print '<tr>';
1535 print '<td><input type="radio" name="createmode" value="copy"></td>';
1536 print '<td>'.$langs->trans("CopyAskFrom").' </td>';
1537 print '<td>';
1538 $liste_ask = array();
1539 $liste_ask [0] = '';
1540
1541 $sql = "SELECT p.rowid as id, p.ref, s.nom";
1542 $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal p";
1543 $sql .= ", ".MAIN_DB_PREFIX."societe s";
1544 $sql .= " WHERE s.rowid = p.fk_soc";
1545 $sql .= " AND p.entityy IN (".getEntity('supplier_proposal').")";
1546 $sql .= " AND p.fk_statut <> ".SupplierProposal::STATUS_DRAFT;
1547 $sql .= " ORDER BY Id";
1548
1549 $resql = $db->query($sql);
1550 if ($resql) {
1551 $num = $db->num_rows($resql);
1552 $i = 0;
1553 while ($i < $num) {
1554 $row = $db->fetch_row($resql);
1555 $askPriceSupplierRefAndSocName = $row[1]." - ".$row[2];
1556 $liste_ask[$row[0]] = $askPriceSupplierRefAndSocName;
1557 $i++;
1558 }
1559 print $form->selectarray("copie_supplier_proposal", $liste_ask, 0);
1560 } else {
1561 dol_print_error($db);
1562 }
1563 print '</td></tr>';
1564
1565 print '<tr><td class="tdtop"><input type="radio" name="createmode" value="empty" checked></td>';
1566 print '<td valign="top" colspan="2">'.$langs->trans("CreateEmptyAsk").'</td></tr>';
1567 }
1568
1569 if (getDolGlobalString('SUPPLIER_PROPOSAL_CLONE_ON_CREATE_PAGE')) {
1570 print '</table>';
1571 }
1572 }
1573
1574 print dol_get_fiche_end();
1575
1576 print $form->buttonsSaveCancel("CreateDraft");
1577
1578 print "</form>";
1579
1580
1581 // Show origin lines
1582 if (!empty($origin) && !empty($originid) && is_object($objectsrc)) {
1583 print '<br>';
1584
1585 $title = $langs->trans('ProductsAndServices');
1586 print load_fiche_titre($title);
1587
1588 print '<div class="div-table-responsive-no-min">';
1589 print '<table class="noborder centpercent">';
1590
1591 $objectsrc->printOriginLinesList();
1592
1593 print '</table>';
1594 print '</div>';
1595 }
1596} else {
1597 /*
1598 * Show object in view mode
1599 */
1600
1601 $soc = new Societe($db);
1602 $soc->fetch($object->socid);
1603
1604 $head = supplier_proposal_prepare_head($object);
1605 print dol_get_fiche_head($head, 'comm', $langs->trans('CommRequest'), -1, 'supplier_proposal', 0, '', '', 0, '', 1);
1606
1607 $formconfirm = '';
1608
1609 // Clone confirmation
1610 if ($action == 'clone') {
1611 $filter = '(s.fournisseur:=:1)';
1612 // Create an array for form
1613 $formquestion = array(
1614 // 'text' => $langs->trans("ConfirmClone"),
1615 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
1616 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' =>
1617 // 1),
1618 array(
1619 'type' => 'other',
1620 'name' => 'socid',
1621 'label' => $langs->trans("SelectThirdParty"),
1622 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter))
1623 );
1624 // Paiement incomplet. On demande si motif = escompte ou autre
1625 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
1626 } elseif ($action == 'delete') {
1627 // Confirm delete
1628 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteAsk'), $langs->trans('ConfirmDeleteAsk', $object->ref), 'confirm_delete', '', 0, 1);
1629 } elseif ($action == 'reopen') {
1630 // Confirm reopen
1631 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $langs->trans('ConfirmReOpenAsk', $object->ref), 'confirm_reopen', '', 0, 1);
1632 } elseif ($action == 'ask_deleteline') {
1633 // Confirmation delete product/service line
1634 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
1635 } elseif ($action == 'validate') {
1636 // Confirm validate askprice
1637 $error = 0;
1638
1639 // Verify if the object has a temporary number
1640 $ref = substr($object->ref, 1, 4);
1641 if ($ref == 'PROV') {
1642 $numref = $object->getNextNumRef($soc);
1643 if (empty($numref)) {
1644 $error++;
1645 setEventMessages($object->error, $object->errors, 'errors');
1646 }
1647 } else {
1648 $numref = (string) $object->ref;
1649 }
1650
1651 $text = $langs->trans('ConfirmValidateAsk', $numref);
1652 if (isModEnabled('notification')) {
1653 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
1654 $notify = new Notify($db);
1655 $text .= '<br>';
1656 $text .= $notify->confirmMessage('PROPOSAL_SUPPLIER_VALIDATE', $object->socid, $object);
1657 }
1658
1659 if (!$error) {
1660 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateAsk'), $text, 'confirm_validate', '', 0, 1);
1661 }
1662 }
1663
1664 // Call Hook formConfirm
1665 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
1666 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1667 if (empty($reshook)) {
1668 $formconfirm .= $hookmanager->resPrint;
1669 } elseif ($reshook > 0) {
1670 $formconfirm = $hookmanager->resPrint;
1671 }
1672
1673 // Print form confirm
1674 print $formconfirm;
1675
1676
1677 // Supplier proposal card
1678 $linkback = '<a href="'.DOL_URL_ROOT.'/supplier_proposal/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1679
1680
1681 $morehtmlref = '<div class="refidno">';
1682 // Ref supplier
1683 //$morehtmlref.=$form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreateorder, 'string', '', 0, 1);
1684 //$morehtmlref.=$form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $usercancreateorder, 'string', '', null, null, '', 1);
1685 // Thirdparty
1686 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'supplier');
1687 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
1688 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/supplier_proposal/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherProposals").'</a>)';
1689 }
1690 // Project
1691 if (isModEnabled('project')) {
1692 $langs->load("projects");
1693 $morehtmlref .= '<br>';
1694 if ($usercancreate) {
1695 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
1696 if ($action != 'classify') {
1697 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
1698 }
1699 $canLinkAll = getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS');
1700 $canLinkAll = ($canLinkAll === '' || $canLinkAll === false) ? 0 : $canLinkAll;
1701 $currentSocId = ($object->id > 0) ? $object->socid : $socid;
1702 $projectSocId = ((int) $canLinkAll == 1) ? -1 : $currentSocId;
1703 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $projectSocId, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
1704 } else {
1705 if (!empty($object->fk_project)) {
1706 $proj = new Project($db);
1707 $proj->fetch($object->fk_project);
1708 $morehtmlref .= $proj->getNomUrl(1);
1709 if ($proj->title) {
1710 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
1711 }
1712 }
1713 }
1714 }
1715 $morehtmlref .= '</div>';
1716
1717
1718 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
1719
1720 // Call Hook tabContentViewSupplierProposal
1721 $parameters = array();
1722 // Note that $action and $object may be modified by hook
1723 $reshook = $hookmanager->executeHooks('tabContentViewSupplierProposal', $parameters, $object, $action);
1724 if (empty($reshook)) {
1725 print '<div class="fichecenter">';
1726 print '<div class="fichehalfleft">';
1727 print '<div class="underbanner clearboth"></div>';
1728
1729 print '<table class="border tableforfield centpercent">';
1730
1731 // Relative and absolute discounts
1732 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
1733 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL"; // If we want deposit to be subtracted to payments only and not to total of final invoice
1734 $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
1735 } else {
1736 $filterabsolutediscount = "fk_invoice_supplier_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS PAID)%')";
1737 $filtercreditnote = "fk_invoice_supplier_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS PAID)%')";
1738 }
1739
1740 print '<tr><td class="titlefield">'.$langs->trans('Discounts').'</td><td>';
1741
1742 $absolute_discount = $soc->getAvailableDiscounts(null, $filterabsolutediscount, 0, 1);
1743 $absolute_creditnote = $soc->getAvailableDiscounts(null, $filtercreditnote, 0, 1);
1744 $absolute_discount = price2num($absolute_discount, 'MT');
1745 $absolute_creditnote = price2num($absolute_creditnote, 'MT');
1746
1747 $thirdparty = $soc;
1748 $discount_type = 1;
1749 $backtopage = urlencode($_SERVER["PHP_SELF"].'?id='.$object->id);
1750 include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
1751
1752 print '</td></tr>';
1753
1754 // Payment term
1755 print '<tr><td class="titlefield">';
1756 print '<table class="nobordernopadding" width="100%"><tr><td>';
1757 print $langs->trans('PaymentConditionsShort');
1758 print '</td>';
1759 if ($action != 'editconditions' && $object->status != SupplierProposal::STATUS_NOTSIGNED) {
1760 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>';
1761 }
1762 print '</tr></table>';
1763 print '</td><td class="valuefield">';
1764 if ($action == 'editconditions') {
1765 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent);
1766 } else {
1767 $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->cond_reglement_id, 'none', 1, '', 1, $object->deposit_percent);
1768 }
1769 print '</td>';
1770 print '</tr>';
1771
1772 // Delivery date
1773 print '<tr><td>';
1774 print '<table class="nobordernopadding" width="100%"><tr><td>';
1775 print $langs->trans('DeliveryDate');
1776 print '</td>';
1777 if ($action != 'editdate_livraison' && $object->status != SupplierProposal::STATUS_NOTSIGNED) {
1778 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>';
1779 }
1780 print '</tr></table>';
1781 print '</td><td class="valuefield">';
1782 if ($action == 'editdate_livraison') {
1783 print '<form name="editdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post" class="formconsumeproduce">';
1784 print '<input type="hidden" name="token" value="'.newToken().'">';
1785 print '<input type="hidden" name="action" value="setdate_livraison">';
1786 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1787 print $form->selectDate($object->delivery_date, 'liv_', 0, 0, 0, "editdate_livraison");
1788 print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
1789 print '</form>';
1790 } else {
1791 print dol_print_date($object->delivery_date, 'daytext');
1792 }
1793 print '</td>';
1794 print '</tr>';
1795
1796 // Payment mode
1797 print '<tr>';
1798 print '<td>';
1799 print '<table class="nobordernopadding" width="100%"><tr><td>';
1800 print $langs->trans('PaymentMode');
1801 print '</td>';
1802 if ($action != 'editmode' && $object->status != SupplierProposal::STATUS_NOTSIGNED) {
1803 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>';
1804 }
1805 print '</tr></table>';
1806 print '</td><td class="valuefield">';
1807 if ($action == 'editmode') {
1808 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'mode_reglement_id', 'DBIT', 1, 1);
1809 } else {
1810 $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->mode_reglement_id, 'none');
1811 }
1812 print '</td></tr>';
1813
1814 /* Not for supplier proposals
1815 if ($soc->outstanding_limit) {
1816 // Outstanding Bill
1817 print '<tr><td>';
1818 print $langs->trans('OutstandingBill');
1819 print '</td><td class="valuefield">';
1820 $arrayoutstandingbills = $soc->getOutstandingBills('supplier');
1821 $outstandingBills = $arrayoutstandingbills['opened'];
1822 print price($soc->outstanding_limit, 0, '', 1, - 1, - 1, $conf->currency);
1823 print '</td>';
1824 print '</tr>';
1825 }*/
1826
1827 if (getDolGlobalString('BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL') && isModEnabled("bank")) {
1828 // Bank Account
1829 print '<tr><td>';
1830 print '<table width="100%" class="nobordernopadding"><tr><td>';
1831 print $langs->trans('BankAccount');
1832 print '</td>';
1833 if ($action != 'editbankaccount' && $usercancreate) {
1834 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>';
1835 }
1836 print '</tr></table>';
1837 print '</td><td class="valuefield">';
1838 if ($action == 'editbankaccount') {
1839 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'fk_account', 1);
1840 } else {
1841 $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, (string) $object->fk_account, 'none');
1842 }
1843 print '</td>';
1844 print '</tr>';
1845 }
1846 // Categories
1847 if (isModEnabled('category')) {
1848 print '<tr><td>';
1849 print '<table class="nobordernopadding centpercent"><tr><td>';
1850 print $langs->trans("Categories");
1851 print '<td><td class="right">';
1852 if ($usercancreate) {
1853 print '<a class="editfielda" href="'.DOL_URL_ROOT.'/supplier_proposal/card.php?id='.$object->id.'&action=edittags&token='.newToken().'">'.img_edit().'</a>';
1854 } else {
1855 print '&nbsp;';
1856 }
1857 print '</td></tr></table>';
1858 print '</td>';
1859 print '<td>';
1860 if ($action == 'edittags') {
1861 print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
1862 print '<input type="hidden" name="action" value="settags">';
1863 print '<input type="hidden" name="token" value="'.newToken().'">';
1864 print $form->selectCategories(Categorie::TYPE_SUPPLIER_PROPOSAL, 'categories', $object);
1865 print '<input type="submit" class="button valignmiddle smallpaddingimp" value="'.$langs->trans("Modify").'">';
1866 print '</form>';
1867 } else {
1868 print $form->showCategories($object->id, Categorie::TYPE_SUPPLIER_PROPOSAL, 1);
1869 }
1870 print "</td></tr>";
1871 }
1872 // Other attributes
1873 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1874
1875 print '</table>';
1876
1877 print '</div>';
1878 print '<div class="fichehalfright">';
1879 print '<div class="underbanner clearboth"></div>';
1880
1881 print '<table class="border tableforfield centpercent">';
1882
1883 include DOL_DOCUMENT_ROOT.'/core/tpl/object_currency_amount.tpl.php';
1884
1885 print '<tr>';
1886 // Amount HT
1887 print '<td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
1888 print '<td class="nowrap amountcard right">' . price($object->total_ht, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
1889 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1890 // Multicurrency Amount HT
1891 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ht, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1892 }
1893 print '</tr>';
1894
1895 print '<tr>';
1896 // Amount VAT
1897 print '<td class="titlefieldmiddle">' . $langs->trans('AmountVAT') . '</td>';
1898 print '<td class="nowrap amountcard right">' . price($object->total_tva, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
1899 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1900 // Multicurrency Amount VAT
1901 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_tva, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1902 }
1903 print '</tr>';
1904
1905 // Amount Local Taxes
1906 if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) {
1907 print '<tr>';
1908 print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
1909 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
1910 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1911 print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1912 }
1913 print '</tr>';
1914
1915 if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
1916 print '<tr>';
1917 print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
1918 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
1919 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1920 print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1921 }
1922 print '</tr>';
1923 }
1924 }
1925
1926 print '<tr>';
1927 // Amount TTC
1928 print '<td>' . $langs->trans('AmountTTC') . '</td>';
1929 print '<td class="nowrap amountcard right">' . price($object->total_ttc, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
1930 if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
1931 // Multicurrency Amount TTC
1932 print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_ttc, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
1933 }
1934 print '</tr>';
1935
1936 print '</table>';
1937
1938 // Margin Infos
1939 /*if (isModEnabled('margin')) {
1940 $formmargin->displayMarginInfos($object);
1941 }*/
1942
1943 print '</div>';
1944 print '</div>';
1945
1946 print '<div class="clearboth"></div><br>';
1947
1948 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
1949 $blocname = 'contacts';
1950 $title = $langs->trans('ContactsAddresses');
1951 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
1952 }
1953
1954 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
1955 $blocname = 'notes';
1956 $title = $langs->trans('Notes');
1957 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
1958 }
1959
1960 /*
1961 * Lines
1962 */
1963
1964 // Show object lines
1965 $result = $object->getLinesArray();
1966
1967 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '#add' : '').'" method="POST">
1968 <input type="hidden" name="token" value="' . newToken().'">
1969 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
1970 <input type="hidden" name="mode" value="">
1971 <input type="hidden" name="id" value="' . $object->id.'">
1972 <input type="hidden" name="backtopage" value="'.dol_escape_htmltag($backtopage).'">
1973 ';
1974
1975 if (!empty($conf->use_javascript_ajax) && $object->status == SupplierProposal::STATUS_DRAFT) {
1976 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
1977 }
1978
1979 print '<div class="div-table-responsive-no-min">';
1980 print '<table id="tablelines" class="noborder noshadow centpercent">';
1981
1982 // Add free products/services form
1983 global $forceall, $senderissupplier, $inputalsopricewithtax;
1984 $forceall = 1;
1985 $dateSelector = 0;
1986 $inputalsopricewithtax = 1;
1987 $senderissupplier = 2; // $senderissupplier=2 is same than 1 but disable test on minimum qty.
1988 if (getDolGlobalInt('SUPPLIER_PROPOSAL_WITH_PREDEFINED_PRICES_ONLY')) {
1989 $senderissupplier = getDolGlobalInt('SUPPLIER_PROPOSAL_WITH_PREDEFINED_PRICES_ONLY');
1990 }
1991
1992 if (!empty($object->lines)) {
1993 $object->printObjectLines($action, $soc, $mysoc, $lineid, $dateSelector);
1994 }
1995
1996 // Form to add new line
1997 if ($object->status == SupplierProposal::STATUS_DRAFT && $usercancreate) {
1998 if ($action != 'editline') {
1999 // Add products/services form
2000
2001 $parameters = array('dateSelector' => $dateSelector);
2002 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2003 if ($reshook < 0) {
2004 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2005 }
2006 if (empty($reshook)) {
2007 $object->formAddObjectLine($dateSelector, $soc, $mysoc);
2008 }
2009 }
2010 }
2011
2012 print '</table>';
2013 print '</div>';
2014 print "</form>\n";
2015 }
2016
2017 print dol_get_fiche_end();
2018
2019 if ($action == 'statut') {
2020 // Form to set proposal accepted/refused
2021 $form_close = '<form action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="POST" id="formacceptrefuse" class="formconsumeproduce paddingbottom paddingleft paddingright">';
2022 $form_close .= '<input type="hidden" name="token" value="'.newToken().'">';
2023 $form_close .= '<input type="hidden" name="action" value="setstatut">';
2024
2025 if (getDolGlobalString('SUPPLIER_PROPOSAL_UPDATE_PRICE_ON_SUPPlIER_PROPOSAL')) {
2026 $form_close .= '<p class="notice">'.$langs->trans('SupplierProposalRefFournNotice').'</p>'; // TODO Suggest a permanent checkbox instead of option
2027 }
2028 $form_close .= '<table class="border centpercent marginleftonly marginrightonly">';
2029 $form_close .= '<tr><td>'.$langs->trans("CloseAs").'</td><td class="left">';
2030 $form_close .= '<select id="statut" name="statut" class="flat">';
2031 $form_close .= '<option value="0">&nbsp;</option>';
2032 $form_close .= '<option value="2">'.$langs->trans('SupplierProposalStatusSigned').'</option>';
2033 $form_close .= '<option value="3">'.$langs->trans('SupplierProposalStatusNotSigned').'</option>';
2034 $form_close .= '</select>';
2035 $form_close .= '</td></tr>';
2036 $form_close .= '<tr><td class="left">'.$langs->trans('Note').'</td><td class="left"><textarea cols="70" rows="'.ROWS_3.'" wrap="soft" name="note">';
2037 $form_close .= $object->note_private;
2038 $form_close .= '</textarea></td></tr>';
2039 $form_close .= '</table>';
2040 $form_close .= $form->buttonsSaveCancel();
2041 $form_close .= '<a id="acceptedrefused">&nbsp;</a>';
2042 $form_close .= '</form>';
2043
2044 print $form_close;
2045 }
2046
2047 /*
2048 * Boutons Actions
2049 */
2050 if ($action != 'presend') {
2051 print '<div class="tabsAction">';
2052
2053 $parameters = array();
2054 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
2055 // modified by hook
2056 if (empty($reshook)) {
2057 if ($action != 'statut' && $action != 'editline') {
2058 // Validate
2059 if ($object->status == SupplierProposal::STATUS_DRAFT && $object->total_ttc >= 0 && count($object->lines) > 0 && $usercanvalidate) {
2060 if (count($object->lines) > 0) {
2061 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>';
2062 }
2063 // else print '<a class="butActionRefused classfortooltip" href="#">'.$langs->trans('Validate').'</a>';
2064 }
2065
2066 // Edit
2067 if ($object->status == SupplierProposal::STATUS_VALIDATED && $usercancreate) {
2068 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>';
2069 }
2070
2071 // ReOpen
2073 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').'"';
2074 print '>'.$langs->trans('ReOpen').'</a></div>';
2075 }
2076
2077 // Send
2078 if (empty($user->socid)) {
2080 if ($usercansend) {
2081 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'presend', 'mode' => 'init'], true).'#formmailbeforetitle', '');
2082 } else {
2083 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', '#', '', false);
2084 }
2085 }
2086 }
2087
2088 // Create an order
2089 if (isModEnabled("supplier_order") && $object->status == SupplierProposal::STATUS_SIGNED) {
2090 if ($usercancreateorder) {
2091 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>';
2092 }
2093 }
2094
2095 // Set accepted/refused
2096 if ($object->status == SupplierProposal::STATUS_VALIDATED && $usercanclose) {
2097 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').'"';
2098 print '>'.$langs->trans('SetAcceptedRefused').'</a></div>';
2099 }
2100
2101 // Close
2102 if ($object->status == SupplierProposal::STATUS_SIGNED && $usercanclose) {
2103 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').'"';
2104 print '>'.$langs->trans('Close').'</a></div>';
2105 }
2106
2107 // Clone
2108 if ($usercancreate) {
2109 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>';
2110 }
2111
2112 // Delete
2113 print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', (($object->status == SupplierProposal::STATUS_DRAFT && $usercancreate) || $usercandelete));
2114 }
2115 }
2116
2117 print '</div>';
2118 }
2119
2120 if ($action != 'presend') {
2121 print '<div class="fichecenter"><div class="fichehalfleft">';
2122
2123 /*
2124 * Generated documents
2125 */
2126 $filename = dol_sanitizeFileName($object->ref);
2127 $filedir = $conf->supplier_proposal->dir_output."/".dol_sanitizeFileName($object->ref);
2128 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2129 $genallowed = $usercanread;
2130 $delallowed = $usercancreate;
2131
2132 print $formfile->showdocuments('supplier_proposal', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang);
2133
2134
2135 // Show links to link elements
2136 $tmparray = $form->showLinkToObjectBlock($object, array(), array('supplier_proposal'), 1);
2137 $linktoelem = $tmparray['linktoelem'];
2138 $htmltoenteralink = $tmparray['htmltoenteralink'];
2139 print $htmltoenteralink;
2140
2141 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2142
2143 $MAXEVENT = 10;
2144
2145 print '</div><div class="fichehalfright">';
2146
2147 // List of actions on element
2148 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2149 $formactions = new FormActions($db);
2150 $somethingshown = $formactions->showactions($object, 'supplier_proposal', $socid, 1, '', $MAXEVENT);
2151
2152 print '</div></div>';
2153 }
2154
2155 // Select mail models is same action as presend
2156 if (GETPOST('modelselected')) {
2157 $action = 'presend';
2158 }
2159
2160 // Presend form
2161 $modelmail = 'supplier_proposal_send';
2162 $defaulttopic = 'SendAskRef';
2163 $diroutput = $conf->supplier_proposal->dir_output;
2164 $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_PROPOSAL_TO';
2165 $trackid = 'spro'.$object->id;
2166
2167 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2168}
2169
2170// End of page
2171llxFooter();
2172$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 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:464
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.