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