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