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