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