dolibarr  9.0.0
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-2014 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-2016 Juanjo Menent <jmenent@2byte.es>
9  * Copyright (C) 2010-2018 Philippe Grand <philippe.grand@atoo-net.com>
10  * Copyright (C) 2012-2013 Christophe Battarel <christophe.battarel@altairis.fr>
11  * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
12  * Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
13  * Copyright (C) 2014 Ferran Marcet <fmarcet@2byte.es>
14  * Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
15  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.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 <http://www.gnu.org/licenses/>.
29  */
30 
31 
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.formpropal.class.php';
42 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formmargin.class.php';
43 require_once DOL_DOCUMENT_ROOT . '/comm/propal/class/propal.class.php';
44 require_once DOL_DOCUMENT_ROOT . '/comm/action/class/actioncomm.class.php';
45 require_once DOL_DOCUMENT_ROOT . '/core/modules/propale/modules_propale.php';
46 require_once DOL_DOCUMENT_ROOT . '/core/lib/propal.lib.php';
47 require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
48 require_once DOL_DOCUMENT_ROOT . '/core/lib/signature.lib.php';
49 require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
50 require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
51 if (! empty($conf->projet->enabled)) {
52  require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php';
53  require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
54 }
55 
56 if (!empty($conf->variants->enabled)) {
57  require_once DOL_DOCUMENT_ROOT.'/variants/class/ProductCombination.class.php';
58 }
59 
60 // Load translation files required by the page
61 $langs->loadLangs(array('companies', 'propal', 'compta', 'bills', 'orders', 'products', 'deliveries', 'sendings'));
62 if (!empty($conf->incoterm->enabled)) $langs->load('incoterm');
63 if (! empty($conf->margin->enabled))
64  $langs->load('margins');
65 
66 $error = 0;
67 
68 $id = GETPOST('id', 'int');
69 $ref = GETPOST('ref', 'alpha');
70 $socid = GETPOST('socid', 'int');
71 $action = GETPOST('action', 'alpha');
72 $cancel = GETPOST('cancel', 'alpha');
73 $origin = GETPOST('origin', 'alpha');
74 $originid = GETPOST('originid', 'int');
75 $confirm = GETPOST('confirm', 'alpha');
76 $lineid = GETPOST('lineid', 'int');
77 $contactid = GETPOST('contactid','int');
78 $projectid = GETPOST('projectid','int');
79 
80 // PDF
81 $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
82 $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
83 $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
84 
85 // Nombre de ligne pour choix de produit/service predefinis
86 $NBLINES = 4;
87 
88 // Security check
89 if (! empty($user->societe_id)) $socid = $user->societe_id;
90 $result = restrictedArea($user, 'propal', $id);
91 
92 $object = new Propal($db);
93 $extrafields = new ExtraFields($db);
94 
95 // fetch optionals attributes and labels
96 $extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
97 
98 // Load object
99 if ($id > 0 || ! empty($ref)) {
100  $ret = $object->fetch($id, $ref);
101  if ($ret > 0)
102  $ret = $object->fetch_thirdparty();
103  if ($ret <= 0)
104  {
105  setEventMessages($object->error, $object->errors, 'errors');
106  $action = '';
107  }
108 }
109 
110 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
111 $hookmanager->initHooks(array('propalcard','globalcard'));
112 
113 $usercanread = $user->rights->propal->lire;
114 $usercancreate = $user->rights->propal->creer;
115 $usercanclose = $user->rights->propal->cloturer;
116 $usercandelete = $user->rights->propal->supprimer;
117 $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate)));
118 $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->propal->propal_advance->send);
119 
120 $usercancreateorder = $user->rights->commande->creer;
121 $usercancreateinvoice = $user->rights->facture->creer;
122 $usercancreatecontract = $user->rights->contrat->creer;
123 $usercancreateintervention = $user->rights->ficheinter->creer;
124 
125 $permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php
126 $permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php
127 $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php
128 
129 
130 /*
131  * Actions
132  */
133 
134 $parameters = array('socid' => $socid);
135 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
136 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
137 
138 if (empty($reshook))
139 {
140  if ($cancel)
141  {
142  if (! empty($backtopage))
143  {
144  header("Location: ".$backtopage);
145  exit;
146  }
147  $action='';
148  }
149 
150  include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once
151 
152  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
153 
154  include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once
155 
156  // Action clone object
157  if ($action == 'confirm_clone' && $confirm == 'yes' && $usercancreate)
158  {
159  if (! GETPOST('socid', 3))
160  {
161  setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
162  }
163  else
164  {
165  if ($object->id > 0) {
166  if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY)) {
167  //Get difference between old and new delivery date and change lines according to difference
168  $date_delivery = dol_mktime(12, 0, 0,
169  GETPOST('date_deliverymonth', 'int'),
170  GETPOST('date_deliveryday', 'int'),
171  GETPOST('date_deliveryyear', 'int')
172  );
173  if (!empty($object->date_livraison) && !empty($date_delivery))
174  {
175  //Attempt to get the date without possible hour rounding errors
176  $old_date_delivery = dol_mktime(12, 0, 0,
177  dol_print_date($object->date_livraison, '%m'),
178  dol_print_date($object->date_livraison, '%d'),
179  dol_print_date($object->date_livraison, '%Y')
180  );
181  //Calculate the difference and apply if necessary
182  $difference = $date_delivery - $old_date_delivery;
183  if ($difference != 0)
184  {
185  $object->date_livraison = $date_delivery;
186  foreach ($object->lines as $line)
187  {
188  if (isset($line->date_start)) $line->date_start = $line->date_start + $difference;
189  if (isset($line->date_end)) $line->date_end = $line->date_end + $difference;
190  }
191  }
192  }
193  }
194 
195  $result = $object->createFromClone($socid);
196  if ($result > 0) {
197  header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result);
198  exit();
199  } else {
200  if (count($object->errors) > 0) setEventMessages($object->error, $object->errors, 'errors');
201  $action = '';
202  }
203  }
204  }
205  }
206 
207  // Delete proposal
208  else if ($action == 'confirm_delete' && $confirm == 'yes' && $usercandelete)
209  {
210  $result = $object->delete($user);
211  if ($result > 0) {
212  header('Location: ' . DOL_URL_ROOT . '/comm/propal/list.php?restore_lastsearch_values=1');
213  exit();
214  } else {
215  $langs->load("errors");
216  setEventMessages($object->error, $object->errors, 'errors');
217  }
218  }
219 
220  // Remove line
221  else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $usercancreate)
222  {
223  $result = $object->deleteline($lineid);
224  // reorder lines
225  if ($result)
226  $object->line_order(true);
227 
228  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
229  // Define output language
230  $outputlangs = $langs;
231  if (! empty($conf->global->MAIN_MULTILANGS)) {
232  $outputlangs = new Translate("", $conf);
233  $newlang = (GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $object->thirdparty->default_lang);
234  $outputlangs->setDefaultLang($newlang);
235  }
236  $ret = $object->fetch($id); // Reload to get new records
237  $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
238  }
239 
240  header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
241  exit();
242  }
243 
244  // Validation
245  else if ($action == 'confirm_validate' && $confirm == 'yes' && $usercanvalidate)
246  {
247  $result = $object->valid($user);
248  if ($result >= 0)
249  {
250  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
251  {
252  $outputlangs = $langs;
253  $newlang = '';
254  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
255  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
256  if (! empty($newlang)) {
257  $outputlangs = new Translate("", $conf);
258  $outputlangs->setDefaultLang($newlang);
259  }
260  $model=$object->modelpdf;
261  $ret = $object->fetch($id); // Reload to get new records
262 
263  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
264  }
265  } else {
266  $langs->load("errors");
267  if (count($object->errors) > 0) setEventMessages($object->error, $object->errors, 'errors');
268  else setEventMessages($langs->trans($object->error), null, 'errors');
269  }
270  }
271 
272  else if ($action == 'setdate' && $usercancreate)
273  {
274  $datep = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
275 
276  if (empty($datep)) {
277  $error ++;
278  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
279  }
280 
281  if (! $error) {
282  $result = $object->set_date($user, $datep);
283  if ($result < 0)
284  dol_print_error($db, $object->error);
285  }
286  }
287  else if ($action == 'setecheance' && $usercancreate)
288  {
289  $result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear']));
290  if ($result < 0)
291  dol_print_error($db, $object->error);
292  }
293  else if ($action == 'setdate_livraison' && $usercancreate)
294  {
295  $result = $object->set_date_livraison($user, dol_mktime(12, 0, 0, $_POST['date_livraisonmonth'], $_POST['date_livraisonday'], $_POST['date_livraisonyear']));
296  if ($result < 0)
297  dol_print_error($db, $object->error);
298  }
299 
300  // Positionne ref client
301  else if ($action == 'setref_client' && $usercancreate)
302  {
303  $result = $object->set_ref_client($user, GETPOST('ref_client'));
304  if ($result < 0)
305  {
306  setEventMessages($object->error, $object->errors, 'errors');
307  }
308  }
309 
310  // Set incoterm
311  elseif ($action == 'set_incoterms' && !empty($conf->incoterm->enabled) && $usercancreate)
312  {
313  $result = $object->setIncoterms(GETPOST('incoterm_id', 'int'), GETPOST('location_incoterms', 'alpha'));
314  }
315 
316  // Create proposal
317  else if ($action == 'add' && $usercancreate)
318  {
319  $object->socid = $socid;
320  $object->fetch_thirdparty();
321 
322  $datep = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
323  $date_delivery = dol_mktime(12, 0, 0, GETPOST('date_livraisonmonth'), GETPOST('date_livraisonday'), GETPOST('date_livraisonyear'));
324  $duration = GETPOST('duree_validite');
325 
326  if (empty($datep)) {
327  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
328  $action = 'create';
329  $error ++;
330  }
331  if (empty($duration)) {
332  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ValidityDuration")), null, 'errors');
333  $action = 'create';
334  $error ++;
335  }
336 
337  if ($socid < 1) {
338  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Customer")), null, 'errors');
339 
340  $action = 'create';
341  $error ++;
342  }
343 
344  if (! $error)
345  {
346  $db->begin();
347 
348  // If we select proposal to clone during creation (when option PROPAL_CLONE_ON_CREATE_PAGE is on)
349  if (GETPOST('createmode') == 'copy' && GETPOST('copie_propal'))
350  {
351  if ($object->fetch(GETPOST('copie_propal','int')) > 0) {
352  $object->ref = GETPOST('ref');
353  $object->datep = $datep;
354  $object->date_livraison = $date_delivery;
355  $object->availability_id = GETPOST('availability_id');
356  $object->demand_reason_id = GETPOST('demand_reason_id');
357  $object->fk_delivery_address = GETPOST('fk_address','int');
358  $object->shipping_method_id = GETPOST('shipping_method_id', 'int');
359  $object->duree_validite = $duration;
360  $object->cond_reglement_id = GETPOST('cond_reglement_id');
361  $object->mode_reglement_id = GETPOST('mode_reglement_id');
362  $object->fk_account = GETPOST('fk_account', 'int');
363  $object->remise_percent = GETPOST('remise_percent');
364  $object->remise_absolue = GETPOST('remise_absolue');
365  $object->socid = GETPOST('socid','int');
366  $object->contactid = GETPOST('contactid','int');
367  $object->fk_project = GETPOST('projectid','int');
368  $object->modelpdf = GETPOST('model');
369  $object->author = $user->id; // deprecated
370  $object->note_private = GETPOST('note_private','none');
371  $object->note_public = GETPOST('note_public','none');
372  $object->statut = Propal::STATUS_DRAFT;
373  $object->fk_incoterms = GETPOST('incoterm_id', 'int');
374  $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
375 
376  // the create is done below and further more the existing create_from function is quite hilarating
377  //$id = $object->create_from($user);
378  } else {
379  setEventMessages($langs->trans("ErrorFailedToCopyProposal", GETPOST('copie_propal')), null, 'errors');
380  }
381  } else {
382  $object->ref = GETPOST('ref');
383  $object->entity = (GETPOSTISSET('entity')?GETPOST('entity', 'int'):$conf->entity);
384  $object->ref_client = GETPOST('ref_client');
385  $object->datep = $datep;
386  $object->date_livraison = $date_delivery;
387  $object->availability_id = GETPOST('availability_id');
388  $object->demand_reason_id = GETPOST('demand_reason_id');
389  $object->fk_delivery_address = GETPOST('fk_address');
390  $object->shipping_method_id = GETPOST('shipping_method_id', 'int');
391  $object->duree_validite = GETPOST('duree_validite');
392  $object->cond_reglement_id = GETPOST('cond_reglement_id');
393  $object->mode_reglement_id = GETPOST('mode_reglement_id');
394  $object->fk_account = GETPOST('fk_account', 'int');
395  $object->contactid = GETPOST('contactid','int');
396  $object->fk_project = GETPOST('projectid','int');
397  $object->modelpdf = GETPOST('model');
398  $object->author = $user->id; // deprecated
399  $object->note_private = GETPOST('note_private','none');
400  $object->note_public = GETPOST('note_public','none');
401  $object->fk_incoterms = GETPOST('incoterm_id', 'int');
402  $object->location_incoterms = GETPOST('location_incoterms', 'alpha');
403 
404  $object->origin = GETPOST('origin');
405  $object->origin_id = GETPOST('originid');
406 
407  // Multicurrency
408  if (!empty($conf->multicurrency->enabled))
409  {
410  $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha');
411  }
412 
413  // Fill array 'array_options' with data from add form
414  $ret = $extrafields->setOptionalsFromPost($extralabels, $object);
415  if ($ret < 0) {
416  $error ++;
417  $action = 'create';
418  }
419  }
420 
421  if (! $error)
422  {
423  if ($origin && $originid)
424  {
425  // Parse element/subelement (ex: project_task)
426  $element = $subelement = $origin;
427  if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
428  $element = $regs [1];
429  $subelement = $regs [2];
430  }
431 
432  // For compatibility
433  if ($element == 'order') {
434  $element = $subelement = 'commande';
435  }
436  if ($element == 'propal') {
437  $element = 'comm/propal';
438  $subelement = 'propal';
439  }
440  if ($element == 'contract') {
441  $element = $subelement = 'contrat';
442  }
443  if ($element == 'inter') {
444  $element = $subelement = 'ficheinter';
445  }
446  if ($element == 'shipping') {
447  $element = $subelement = 'expedition';
448  }
449 
450  $object->origin = $origin;
451  $object->origin_id = $originid;
452 
453  // Possibility to add external linked objects with hooks
454  $object->linked_objects [$object->origin] = $object->origin_id;
455  if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) {
456  $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']);
457  }
458 
459  $id = $object->create($user);
460  if ($id > 0)
461  {
462  dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
463 
464  $classname = ucfirst($subelement);
465  $srcobject = new $classname($db);
466 
467  dol_syslog("Try to find source object origin=" . $object->origin . " originid=" . $object->origin_id . " to add lines");
468  $result = $srcobject->fetch($object->origin_id);
469 
470  if ($result > 0)
471  {
472  $lines = $srcobject->lines;
473  if (empty($lines) && method_exists($srcobject, 'fetch_lines'))
474  {
475  $srcobject->fetch_lines();
476  $lines = $srcobject->lines;
477  }
478 
479  $fk_parent_line=0;
480  $num=count($lines);
481  for ($i=0;$i<$num;$i++)
482  {
483  $label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
484  $desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
485 
486  // Positive line
487  $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
488 
489  // Date start
490  $date_start = false;
491  if ($lines[$i]->date_debut_prevue)
492  $date_start = $lines[$i]->date_debut_prevue;
493  if ($lines[$i]->date_debut_reel)
494  $date_start = $lines[$i]->date_debut_reel;
495  if ($lines[$i]->date_start)
496  $date_start = $lines[$i]->date_start;
497 
498  // Date end
499  $date_end = false;
500  if ($lines[$i]->date_fin_prevue)
501  $date_end = $lines[$i]->date_fin_prevue;
502  if ($lines[$i]->date_fin_reel)
503  $date_end = $lines[$i]->date_fin_reel;
504  if ($lines[$i]->date_end)
505  $date_end = $lines[$i]->date_end;
506 
507  // Reset fk_parent_line for no child products and special product
508  if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) {
509  $fk_parent_line = 0;
510  }
511 
512  // Extrafields
513  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && method_exists($lines[$i], 'fetch_optionals')) {
514  $lines[$i]->fetch_optionals();
515  $array_options = $lines[$i]->array_options;
516  }
517 
518  $tva_tx = $lines[$i]->tva_tx;
519  if (! empty($lines[$i]->vat_src_code) && ! preg_match('/\(/', $tva_tx)) $tva_tx .= ' ('.$lines[$i]->vat_src_code.')';
520 
521  $result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->qty, $tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->fk_product, $lines[$i]->remise_percent, 'HT', 0, $lines[$i]->info_bits, $product_type, $lines[$i]->rang, $lines[$i]->special_code, $fk_parent_line, $lines[$i]->fk_fournprice, $lines[$i]->pa_ht, $label, $date_start, $date_end, $array_options, $lines[$i]->fk_unit);
522 
523  if ($result > 0) {
524  $lineid = $result;
525  } else {
526  $lineid = 0;
527  $error ++;
528  break;
529  }
530 
531  // Defined the new fk_parent_line
532  if ($result > 0 && $lines[$i]->product_type == 9) {
533  $fk_parent_line = $result;
534  }
535  }
536 
537  // Hooks
538  $parameters = array('objFrom' => $srcobject);
539  $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been
540  // modified by hook
541  if ($reshook < 0)
542  $error ++;
543  } else {
544  setEventMessages($srcobject->error, $srcobject->errors, 'errors');
545  $error ++;
546  }
547  } else {
548  setEventMessages($object->error, $object->errors, 'errors');
549  $error ++;
550  }
551  } // Standard creation
552  else
553  {
554  $id = $object->create($user);
555  }
556 
557  if ($id > 0)
558  {
559  // Insertion contact par defaut si defini
560  if (GETPOST('contactid') > 0)
561  {
562  $result = $object->add_contact(GETPOST('contactid'), 'CUSTOMER', 'external');
563  if ($result < 0)
564  {
565  $error++;
566  setEventMessages($langs->trans("ErrorFailedToAddContact"), null, 'errors');
567  }
568  }
569 
570  if (! empty($conf->global->PROPOSAL_AUTO_ADD_AUTHOR_AS_CONTACT))
571  {
572  $result = $object->add_contact($user->id, 'SALESREPFOLL', 'internal');
573  if ($result < 0)
574  {
575  $error++;
576  setEventMessages($langs->trans("ErrorFailedToAddUserAsContact"), null, 'errors');
577  }
578  }
579 
580  if (! $error)
581  {
582  $db->commit();
583 
584  // Define output language
585  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
586  {
587  $outputlangs = $langs;
588  $newlang = '';
589  if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id','aZ09')) $newlang = GETPOST('lang_id','aZ09');
590  if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
591  if (! empty($newlang)) {
592  $outputlangs = new Translate("", $conf);
593  $outputlangs->setDefaultLang($newlang);
594  }
595  $model=$object->modelpdf;
596 
597  $ret = $object->fetch($id); // Reload to get new records
598  $result=$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
599  if ($result < 0) dol_print_error($db,$result);
600  }
601 
602  header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $id);
603  exit();
604  }
605  else
606  {
607  $db->rollback();
608  $action='create';
609  }
610  }
611  else
612  {
613  setEventMessages($object->error, $object->errors, 'errors');
614  $db->rollback();
615  $action='create';
616  }
617  }
618  }
619  }
620 
621  // Classify billed
622  else if ($action == 'classifybilled' && $usercanclose)
623  {
624  $db->begin();
625 
626  $result=$object->cloture($user, 4, '');
627  if ($result < 0)
628  {
629  setEventMessages($object->error, $object->errors, 'errors');
630  $error++;
631  }
632 
633  if (! $error)
634  {
635  $db->commit();
636  }
637  else
638  {
639  $db->rollback();
640  }
641  }
642 
643  // Close proposal
644  else if ($action == 'setstatut' && $usercanclose && ! GETPOST('cancel','alpha'))
645  {
646  if (! (GETPOST('statut','int') > 0)) {
647  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CloseAs")), null, 'errors');
648  $action = 'statut';
649  } else {
650  // prevent browser refresh from closing proposal several times
651  if ($object->statut == Propal::STATUS_VALIDATED)
652  {
653  $db->begin();
654 
655  $result=$object->cloture($user, GETPOST('statut','int'), GETPOST('note_private','none'));
656  if ($result < 0)
657  {
658  setEventMessages($object->error, $object->errors, 'errors');
659  $error++;
660  }
661 
662  if (! $error)
663  {
664  $db->commit();
665  }
666  else
667  {
668  $db->rollback();
669  }
670  }
671  }
672  }
673 
674  // Reopen proposal
675  else if ($action == 'confirm_reopen' && $usercanclose && ! GETPOST('cancel','alpha'))
676  {
677  // prevent browser refresh from reopening proposal several times
678  if ($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED)
679  {
680  $db->begin();
681 
682  $result=$object->reopen($user, 1);
683  if ($result < 0)
684  {
685  setEventMessages($object->error, $object->errors, 'errors');
686  $error++;
687  }
688 
689  if (! $error)
690  {
691  $db->commit();
692  }
693  else
694  {
695  $db->rollback();
696  }
697  }
698  }
699 
700  include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
701 
702  // Actions to send emails
703  $actiontypecode='AC_OTH_AUTO';
704  $trigger_name='PROPAL_SENTBYMAIL';
705  $autocopy='MAIN_MAIL_AUTOCOPY_PROPOSAL_TO';
706  $trackid='pro'.$object->id;
707  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
708 
709 
710  // Go back to draft
711  if ($action == 'modif' && $usercancreate)
712  {
713  $object->set_draft($user);
714 
715  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
716  {
717  // Define output language
718  $outputlangs = $langs;
719  if (! empty($conf->global->MAIN_MULTILANGS)) {
720  $outputlangs = new Translate("", $conf);
721  $newlang = (GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $object->thirdparty->default_lang);
722  $outputlangs->setDefaultLang($newlang);
723  }
724  $ret = $object->fetch($id); // Reload to get new records
725  $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
726  }
727  }
728 
729  else if ($action == "setabsolutediscount" && $usercancreate) {
730  if ($_POST["remise_id"]) {
731  if ($object->id > 0) {
732  $result = $object->insert_discount($_POST["remise_id"]);
733  if ($result < 0) {
734  setEventMessages($object->error, $object->errors, 'errors');
735  }
736  }
737  }
738  }
739 
740  // Add line
741  else if ($action == 'addline' && $usercancreate) {
742 
743  // Set if we used free entry or predefined product
744  $predef='';
745  $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):'');
746  $price_ht = GETPOST('price_ht');
747  $price_ht_devise = GETPOST('multicurrency_price_ht');
748  $prod_entry_mode = GETPOST('prod_entry_mode');
749  if ($prod_entry_mode == 'free')
750  {
751  $idprod=0;
752  $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
753  }
754  else
755  {
756  $idprod=GETPOST('idprod', 'int');
757  $tva_tx = '';
758  }
759 
760  $qty = GETPOST('qty' . $predef);
761  $remise_percent = GETPOST('remise_percent' . $predef);
762 
763  // Extrafields
764  $extrafieldsline = new ExtraFields($db);
765  $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
766  $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef);
767  // Unset extrafield
768  if (is_array($extralabelsline)) {
769  // Get extra fields
770  foreach ($extralabelsline as $key => $value) {
771  unset($_POST["options_" . $key]);
772  }
773  }
774 
775  if ($prod_entry_mode == 'free' && empty($idprod) && GETPOST('type') < 0) {
776  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
777  $error ++;
778  }
779 
780  if ($prod_entry_mode == 'free' && empty($idprod) && $price_ht == '' && $price_ht_devise == '') // Unit price can be 0 but not ''. Also price can be negative for proposal.
781  {
782  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors');
783  $error ++;
784  }
785  if ($prod_entry_mode == 'free' && empty($idprod) && empty($product_desc)) {
786  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors');
787  $error ++;
788  }
789 
790  if (!$error && !empty($conf->variants->enabled) && $prod_entry_mode != 'free') {
791  if ($combinations = GETPOST('combinations', 'array')) {
792  //Check if there is a product with the given combination
793  $prodcomb = new ProductCombination($db);
794 
795  if ($res = $prodcomb->fetchByProductCombination2ValuePairs($idprod, $combinations)) {
796  $idprod = $res->fk_product_child;
797  } else {
798  setEventMessages($langs->trans('ErrorProductCombinationNotFound'), null, 'errors');
799  $error ++;
800  }
801  }
802  }
803 
804  if (! $error && ($qty >= 0) && (! empty($product_desc) || ! empty($idprod))) {
805  $pu_ht = 0;
806  $pu_ttc = 0;
807  $price_min = 0;
808  $price_base_type = (GETPOST('price_base_type', 'alpha') ? GETPOST('price_base_type', 'alpha') : 'HT');
809 
810  $db->begin();
811 
812  // $tva_tx can be 'x.x (XXX)'
813 
814  // Ecrase $pu par celui du produit
815  // Ecrase $desc par celui du produit
816  // Ecrase $tva_tx par celui du produit
817  // Replaces $fk_unit with the product unit
818  if (! empty($idprod)) {
819  $prod = new Product($db);
820  $prod->fetch($idprod);
821 
822  $label = ((GETPOST('product_label') && GETPOST('product_label') != $prod->label) ? GETPOST('product_label') : '');
823 
824  // Update if prices fields are defined
825  $tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
826  $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
827  if (empty($tva_tx)) $tva_npr=0;
828 
829  // Price unique per product
830  $pu_ht = $prod->price;
831  $pu_ttc = $prod->price_ttc;
832  $price_min = $prod->price_min;
833  $price_base_type = $prod->price_base_type;
834 
835  // If price per segment
836  if (! empty($conf->global->PRODUIT_MULTIPRICES) && $object->thirdparty->price_level)
837  {
838  $pu_ht = $prod->multiprices[$object->thirdparty->price_level];
839  $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level];
840  $price_min = $prod->multiprices_min[$object->thirdparty->price_level];
841  $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level];
842  if (! empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) // using this option is a bug. kept for backward compatibility
843  {
844  if (isset($prod->multiprices_tva_tx[$object->thirdparty->price_level])) $tva_tx=$prod->multiprices_tva_tx[$object->thirdparty->price_level];
845  if (isset($prod->multiprices_recuperableonly[$object->thirdparty->price_level])) $tva_npr=$prod->multiprices_recuperableonly[$object->thirdparty->price_level];
846  }
847  }
848  // If price per customer
849  elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
850  {
851  require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php';
852 
853  $prodcustprice = new Productcustomerprice($db);
854 
855  $filter = array('t.fk_product' => $prod->id, 't.fk_soc' => $object->thirdparty->id);
856 
857  $result = $prodcustprice->fetch_all('', '', 0, 0, $filter);
858  if ($result) {
859  // If there is some prices specific to the customer
860  if (count($prodcustprice->lines) > 0) {
861  $pu_ht = price($prodcustprice->lines[0]->price);
862  $pu_ttc = price($prodcustprice->lines[0]->price_ttc);
863  $price_base_type = $prodcustprice->lines[0]->price_base_type;
864  $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx . ' ('.$prodcustprice->lines[0]->default_vat_code.' )' : $prodcustprice->lines[0]->tva_tx);
865  if ($prodcustprice->lines[0]->default_vat_code && ! preg_match('/\(.*\)/', $tva_tx)) $tva_tx.= ' ('.$prodcustprice->lines[0]->default_vat_code.')';
866  $tva_npr = $prodcustprice->lines[0]->recuperableonly;
867  if (empty($tva_tx)) $tva_npr=0;
868  }
869  }
870  }
871  // If price per quantity
872  elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY))
873  {
874  if ($prod->prices_by_qty[0]) // yes, this product has some prices per quantity
875  {
876  // Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
877  $pqp = GETPOST('pbq','int');
878 
879  // Search price into product_price_by_qty from $prod->id
880  foreach($prod->prices_by_qty_list[0] as $priceforthequantityarray)
881  {
882  if ($priceforthequantityarray['rowid'] != $pqp) continue;
883  // We found the price
884  if ($priceforthequantityarray['price_base_type'] == 'HT')
885  {
886  $pu_ht = $priceforthequantityarray['unitprice'];
887  }
888  else
889  {
890  $pu_ttc = $priceforthequantityarray['unitprice'];
891  }
892  // Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
893  break;
894  }
895  }
896  }
897  // If price per quantity and customer
898  elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))
899  {
900  if ($prod->prices_by_qty[$object->thirdparty->price_level]) // yes, this product has some prices per quantity
901  {
902  // Search the correct price into loaded array product_price_by_qty using id of array retrieved into POST['pqp'].
903  $pqp = GETPOST('pbq','int');
904 
905  // Search price into product_price_by_qty from $prod->id
906  foreach($prod->prices_by_qty_list[$object->thirdparty->price_level] as $priceforthequantityarray)
907  {
908  if ($priceforthequantityarray['rowid'] != $pqp) continue;
909  // We found the price
910  if ($priceforthequantityarray['price_base_type'] == 'HT')
911  {
912  $pu_ht = $priceforthequantityarray['unitprice'];
913  }
914  else
915  {
916  $pu_ttc = $priceforthequantityarray['unitprice'];
917  }
918  // Note: the remise_percent or price by qty is used to set data on form, so we will use value from POST.
919  break;
920  }
921  }
922  }
923 
924  $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx));
925  $tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx));
926 
927  // if price ht is forced (ie: calculated by margin rate and cost price). TODO Why this ?
928  if (! empty($price_ht)) {
929  $pu_ht = price2num($price_ht, 'MU');
930  $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
931  }
932  // On reevalue prix selon taux tva car taux tva transaction peut etre different
933  // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur).
934  elseif ($tmpvat != $tmpprodvat) {
935  if ($price_base_type != 'HT') {
936  $pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
937  } else {
938  $pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
939  }
940  }
941 
942  $desc = '';
943 
944  // Define output language
945  if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
946  $outputlangs = $langs;
947  $newlang = '';
948  if (empty($newlang) && GETPOST('lang_id','aZ09'))
949  $newlang = GETPOST('lang_id','aZ09');
950  if (empty($newlang))
951  $newlang = $object->thirdparty->default_lang;
952  if (! empty($newlang)) {
953  $outputlangs = new Translate("", $conf);
954  $outputlangs->setDefaultLang($newlang);
955  }
956 
957  $desc = (! empty($prod->multilangs [$outputlangs->defaultlang] ["description"])) ? $prod->multilangs [$outputlangs->defaultlang] ["description"] : $prod->description;
958  } else {
959  $desc = $prod->description;
960  }
961 
962  $desc = dol_concatdesc($desc, $product_desc);
963 
964  // Add dimensions into product description
965  /*if (empty($conf->global->MAIN_PRODUCT_DISABLE_AUTOADD_DIM))
966  {
967  $text='';
968  if ($prod->weight) $text.=($text?"\n":"").$outputlangs->trans("Weight").': '.$prod->weight.' '.$prod->weight_units;
969  if ($prod->length) $text.=($text?"\n":"").$outputlangs->trans("Length").': '.$prod->length.' '.$prod->length_units;
970  if ($prod->surface) $text.=($text?"\n":"").$outputlangs->trans("Surface").': '.$prod->surface.' '.$prod->surface_units;
971  if ($prod->volume) $text.=($text?"\n":"").$outputlangs->trans("Volume").': '.$prod->volume.' '.$prod->volume_units;
972 
973  $desc = dol_concatdesc($desc, $text);
974  }*/
975 
976  // Add custom code and origin country into description
977  if (empty($conf->global->MAIN_PRODUCT_DISABLE_CUSTOMCOUNTRYCODE) && (! empty($prod->customcode) || ! empty($prod->country_code)))
978  {
979  $tmptxt = '(';
980  // Define output language
981  if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) {
982  $outputlangs = $langs;
983  $newlang = '';
984  if (empty($newlang) && GETPOST('lang_id','alpha'))
985  $newlang = GETPOST('lang_id','alpha');
986  if (empty($newlang))
987  $newlang = $object->thirdparty->default_lang;
988  if (! empty($newlang)) {
989  $outputlangs = new Translate("", $conf);
990  $outputlangs->setDefaultLang($newlang);
991  $outputlangs->load('products');
992  }
993  if (! empty($prod->customcode))
994  $tmptxt .= $outputlangs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode;
995  if (! empty($prod->customcode) && ! empty($prod->country_code))
996  $tmptxt .= ' - ';
997  if (! empty($prod->country_code))
998  $tmptxt .= $outputlangs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $outputlangs, 0);
999  } else {
1000  if (! empty($prod->customcode))
1001  $tmptxt .= $langs->transnoentitiesnoconv("CustomCode") . ': ' . $prod->customcode;
1002  if (! empty($prod->customcode) && ! empty($prod->country_code))
1003  $tmptxt .= ' - ';
1004  if (! empty($prod->country_code))
1005  $tmptxt .= $langs->transnoentitiesnoconv("CountryOrigin") . ': ' . getCountry($prod->country_code, 0, $db, $langs, 0);
1006  }
1007  $tmptxt .= ')';
1008  $desc = dol_concatdesc($desc, $tmptxt);
1009  }
1010 
1011  $type = $prod->type;
1012  $fk_unit = $prod->fk_unit;
1013  } else {
1014  $pu_ht = price2num($price_ht, 'MU');
1015  $pu_ttc = price2num(GETPOST('price_ttc'), 'MU');
1016  $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
1017  $tva_tx = str_replace('*', '', $tva_tx);
1018  $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1019  $desc = $product_desc;
1020  $type = GETPOST('type');
1021 
1022  $fk_unit = GETPOST('units', 'alpha');
1023  $pu_ht_devise = price2num($price_ht_devise, 'MU');
1024  }
1025 
1026  // Margin
1027  $fournprice = price2num(GETPOST('fournprice' . $predef) ? GETPOST('fournprice' . $predef) : '');
1028  $buyingprice = price2num(GETPOST('buying_price' . $predef) != '' ? GETPOST('buying_price' . $predef) : ''); // If buying_price is '0', we muste keep this value
1029 
1030  $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'));
1031  $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'));
1032 
1033  // Local Taxes
1034  $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $tva_npr);
1035  $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $tva_npr);
1036 
1037  $info_bits = 0;
1038  if ($tva_npr)
1039  $info_bits |= 0x01;
1040 
1041  if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) ) && (! empty($price_min) && (price2num($pu_ht) * (1 - price2num($remise_percent) / 100) < price2num($price_min)))) {
1042  $mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency));
1043  setEventMessages($mesg, null, 'errors');
1044  } else {
1045  // Insert line
1046  $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit, '', 0, $pu_ht_devise);
1047 
1048  if ($result > 0) {
1049  $db->commit();
1050 
1051  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1052  // Define output language
1053  $outputlangs = $langs;
1054  if (! empty($conf->global->MAIN_MULTILANGS)) {
1055  $outputlangs = new Translate("", $conf);
1056  $newlang = (GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $object->thirdparty->default_lang);
1057  $outputlangs->setDefaultLang($newlang);
1058  }
1059  $ret = $object->fetch($id); // Reload to get new records
1060  $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1061  }
1062 
1063  unset($_POST['prod_entry_mode']);
1064 
1065  unset($_POST['qty']);
1066  unset($_POST['type']);
1067  unset($_POST['remise_percent']);
1068  unset($_POST['price_ht']);
1069  unset($_POST['multicurrency_price_ht']);
1070  unset($_POST['price_ttc']);
1071  unset($_POST['tva_tx']);
1072  unset($_POST['product_ref']);
1073  unset($_POST['product_label']);
1074  unset($_POST['product_desc']);
1075  unset($_POST['fournprice']);
1076  unset($_POST['buying_price']);
1077  unset($_POST['np_marginRate']);
1078  unset($_POST['np_markRate']);
1079  unset($_POST['dp_desc']);
1080  unset($_POST['idprod']);
1081  unset($_POST['units']);
1082 
1083  unset($_POST['date_starthour']);
1084  unset($_POST['date_startmin']);
1085  unset($_POST['date_startsec']);
1086  unset($_POST['date_startday']);
1087  unset($_POST['date_startmonth']);
1088  unset($_POST['date_startyear']);
1089  unset($_POST['date_endhour']);
1090  unset($_POST['date_endmin']);
1091  unset($_POST['date_endsec']);
1092  unset($_POST['date_endday']);
1093  unset($_POST['date_endmonth']);
1094  unset($_POST['date_endyear']);
1095  } else {
1096  $db->rollback();
1097 
1098  setEventMessages($object->error, $object->errors, 'errors');
1099  }
1100  }
1101  }
1102  }
1103 
1104  // Update a line within proposal
1105  else if ($action == 'updateline' && $usercancreate && GETPOST('save'))
1106  {
1107  // Define info_bits
1108  $info_bits = 0;
1109  if (preg_match('/\*/', GETPOST('tva_tx')))
1110  $info_bits |= 0x01;
1111 
1112  // Clean parameters
1113  $description = dol_htmlcleanlastbr(GETPOST('product_desc','none'));
1114 
1115  // Define vat_rate
1116  $vat_rate = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
1117  $vat_rate = str_replace('*', '', $vat_rate);
1118  $localtax1_rate = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
1119  $localtax2_rate = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
1120  $pu_ht = GETPOST('price_ht');
1121 
1122  // Add buying price
1123  $fournprice = price2num(GETPOST('fournprice') ? GETPOST('fournprice') : '');
1124  $buyingprice = price2num(GETPOST('buying_price') != '' ? GETPOST('buying_price') : ''); // If buying_price is '0', we muste keep this value
1125 
1126  $pu_ht_devise = GETPOST('multicurrency_subprice');
1127 
1128  $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), GETPOST('date_startsec'), GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
1129  $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), GETPOST('date_endsec'), GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
1130 
1131  // Extrafields
1132  $extrafieldsline = new ExtraFields($db);
1133  $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line);
1134  $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline);
1135  // Unset extrafield
1136  if (is_array($extralabelsline)) {
1137  // Get extra fields
1138  foreach ($extralabelsline as $key => $value) {
1139  unset($_POST["options_" . $key]);
1140  }
1141  }
1142 
1143  // Define special_code for special lines
1144  $special_code=GETPOST('special_code');
1145  if (! GETPOST('qty')) $special_code=3;
1146 
1147  // Check minimum price
1148  $productid = GETPOST('productid', 'int');
1149  if (! empty($productid)) {
1150  $product = new Product($db);
1151  $res = $product->fetch($productid);
1152 
1153  $type = $product->type;
1154 
1155  $price_min = $product->price_min;
1156  if (! empty($conf->global->PRODUIT_MULTIPRICES) && ! empty($object->thirdparty->price_level))
1157  $price_min = $product->multiprices_min [$object->thirdparty->price_level];
1158 
1159  $label = ((GETPOST('update_label') && GETPOST('product_label')) ? GETPOST('product_label') : '');
1160  if (((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS) )&& ($price_min && (price2num($pu_ht) * (1 - price2num(GETPOST('remise_percent')) / 100) < price2num($price_min)))) {
1161  setEventMessages($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, - 1, $conf->currency)), null, 'errors');
1162  $error ++;
1163  }
1164  } else {
1165  $type = GETPOST('type');
1166  $label = (GETPOST('product_label') ? GETPOST('product_label') : '');
1167 
1168  // Check parameters
1169  if (GETPOST('type') < 0) {
1170  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
1171  $error ++;
1172  }
1173  }
1174 
1175  if (! $error) {
1176  $db->begin();
1177 
1178  if (empty($user->rights->margins->creer))
1179  {
1180  foreach ($object->lines as &$line)
1181  {
1182  if ($line->id == GETPOST('lineid'))
1183  {
1184  $fournprice = $line->fk_fournprice;
1185  $buyingprice = $line->pa_ht;
1186  break;
1187  }
1188  }
1189  }
1190  $result = $object->updateline(GETPOST('lineid'), $pu_ht, GETPOST('qty'), GETPOST('remise_percent'), $vat_rate, $localtax1_rate, $localtax2_rate, $description, 'HT', $info_bits, $special_code, GETPOST('fk_parent_line'), 0, $fournprice, $buyingprice, $label, $type, $date_start, $date_end, $array_options, $_POST["units"], $pu_ht_devise);
1191 
1192  if ($result >= 0) {
1193  $db->commit();
1194 
1195  if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
1196  // Define output language
1197  $outputlangs = $langs;
1198  if (! empty($conf->global->MAIN_MULTILANGS)) {
1199  $outputlangs = new Translate("", $conf);
1200  $newlang = (GETPOST('lang_id','aZ09') ? GETPOST('lang_id','aZ09') : $object->thirdparty->default_lang);
1201  $outputlangs->setDefaultLang($newlang);
1202  }
1203  $ret = $object->fetch($id); // Reload to get new records
1204  $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
1205  }
1206 
1207  unset($_POST['qty']);
1208  unset($_POST['type']);
1209  unset($_POST['productid']);
1210  unset($_POST['remise_percent']);
1211  unset($_POST['price_ht']);
1212  unset($_POST['multicurrency_price_ht']);
1213  unset($_POST['price_ttc']);
1214  unset($_POST['tva_tx']);
1215  unset($_POST['product_ref']);
1216  unset($_POST['product_label']);
1217  unset($_POST['product_desc']);
1218  unset($_POST['fournprice']);
1219  unset($_POST['buying_price']);
1220 
1221  unset($_POST['date_starthour']);
1222  unset($_POST['date_startmin']);
1223  unset($_POST['date_startsec']);
1224  unset($_POST['date_startday']);
1225  unset($_POST['date_startmonth']);
1226  unset($_POST['date_startyear']);
1227  unset($_POST['date_endhour']);
1228  unset($_POST['date_endmin']);
1229  unset($_POST['date_endsec']);
1230  unset($_POST['date_endday']);
1231  unset($_POST['date_endmonth']);
1232  unset($_POST['date_endyear']);
1233  } else {
1234  $db->rollback();
1235 
1236  setEventMessages($object->error, $object->errors, 'errors');
1237  }
1238  }
1239  }
1240 
1241  else if ($action == 'updateline' && $usercancreate && GETPOST('cancel','alpha'))
1242  {
1243  header('Location: ' . $_SERVER['PHP_SELF'] . '?id=' . $object->id); // Pour reaffichage de la fiche en cours d'edition
1244  exit();
1245  }
1246 
1247  // Set project
1248  else if ($action == 'classin' && $usercancreate) {
1249  $object->setProject(GETPOST('projectid','int'));
1250  }
1251 
1252  // Delai de livraison
1253  else if ($action == 'setavailability' && $usercancreate) {
1254  $result = $object->set_availability($user, GETPOST('availability_id','int'));
1255  }
1256 
1257  // Origine de la propale
1258  else if ($action == 'setdemandreason' && $usercancreate) {
1259  $result = $object->set_demand_reason($user, GETPOST('demand_reason_id','int'));
1260  }
1261 
1262  // Conditions de reglement
1263  else if ($action == 'setconditions' && $usercancreate) {
1264  $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'));
1265  }
1266 
1267  else if ($action == 'setremisepercent' && $usercancreate) {
1268  $result = $object->set_remise_percent($user, $_POST['remise_percent']);
1269  }
1270 
1271  else if ($action == 'setremiseabsolue' && $usercancreate) {
1272  $result = $object->set_remise_absolue($user, $_POST['remise_absolue']);
1273  }
1274 
1275  // Mode de reglement
1276  else if ($action == 'setmode' && $usercancreate) {
1277  $result = $object->setPaymentMethods(GETPOST('mode_reglement_id', 'int'));
1278  }
1279 
1280  // Multicurrency Code
1281  else if ($action == 'setmulticurrencycode' && $usercancreate) {
1282  $result = $object->setMulticurrencyCode(GETPOST('multicurrency_code', 'alpha'));
1283  }
1284 
1285  // Multicurrency rate
1286  else if ($action == 'setmulticurrencyrate' && $usercancreate) {
1287  $result = $object->setMulticurrencyRate(price2num(GETPOST('multicurrency_tx')));
1288  }
1289 
1290  // bank account
1291  else if ($action == 'setbankaccount' && $usercancreate) {
1292  $result=$object->setBankAccount(GETPOST('fk_account', 'int'));
1293  }
1294 
1295  // shipping method
1296  else if ($action == 'setshippingmethod' && $usercancreate) {
1297  $result=$object->setShippingMethod(GETPOST('shipping_method_id', 'int'));
1298  }
1299 
1300  else if ($action == 'update_extras') {
1301  $object->oldcopy = dol_clone($object);
1302 
1303  // Fill array 'array_options' with data from update form
1304  $extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
1305  $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute','none'));
1306  if ($ret < 0) $error++;
1307  if (! $error)
1308  {
1309  $result = $object->insertExtraFields('PROPAL_MODIFY');
1310  if ($result < 0)
1311  {
1312  setEventMessages($object->error, $object->errors, 'errors');
1313  $error++;
1314  }
1315  }
1316  if ($error) $action = 'edit_extras';
1317  }
1318 
1319  if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $usercancreate)
1320  {
1321  if ($action == 'addcontact')
1322  {
1323  if ($object->id > 0) {
1324  $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
1325  $result = $object->add_contact($contactid, $_POST["type"], $_POST["source"]);
1326  }
1327 
1328  if ($result >= 0) {
1329  header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
1330  exit();
1331  } else {
1332  if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1333  $langs->load("errors");
1334  setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
1335  } else {
1336  setEventMessages($object->error, $object->errors, 'errors');
1337  }
1338  }
1339  }
1340 
1341  // Bascule du statut d'un contact
1342  else if ($action == 'swapstatut') {
1343  if ($object->fetch($id) > 0) {
1344  $result = $object->swapContactStatus(GETPOST('ligne'));
1345  } else {
1346  dol_print_error($db);
1347  }
1348  }
1349 
1350  // Efface un contact
1351  else if ($action == 'deletecontact') {
1352  $object->fetch($id);
1353  $result = $object->delete_contact($lineid);
1354 
1355  if ($result >= 0) {
1356  header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id);
1357  exit();
1358  } else {
1359  dol_print_error($db);
1360  }
1361  }
1362  }
1363 
1364  // Actions to build doc
1365  $upload_dir = $conf->propal->multidir_output[$object->entity];
1366  $permissioncreate=$usercancreate;
1367  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1368 }
1369 
1370 
1371 /*
1372  * View
1373  */
1374 
1375 llxHeader('', $langs->trans('Proposal'), 'EN:Commercial_Proposals|FR:Proposition_commerciale|ES:Presupuestos');
1376 
1377 $form = new Form($db);
1378 $formother = new FormOther($db);
1379 $formfile = new FormFile($db);
1380 $formpropal = new FormPropal($db);
1381 $formmargin = new FormMargin($db);
1382 $companystatic = new Societe($db);
1383 if (! empty($conf->projet->enabled)) { $formproject = new FormProjets($db); }
1384 
1385 $now = dol_now();
1386 
1387 // Add new proposal
1388 if ($action == 'create')
1389 {
1390  $currency_code = $conf->currency;
1391 
1392  print load_fiche_titre($langs->trans("NewProp"));
1393 
1394  $soc = new Societe($db);
1395  if ($socid > 0)
1396  $res = $soc->fetch($socid);
1397 
1398  // Load objectsrc
1399  if (! empty($origin) && ! empty($originid))
1400  {
1401  // Parse element/subelement (ex: project_task)
1402  $element = $subelement = $origin;
1403  if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
1404  $element = $regs [1];
1405  $subelement = $regs [2];
1406  }
1407 
1408  if ($element == 'project') {
1409  $projectid = $originid;
1410  } else {
1411  // For compatibility
1412  if ($element == 'order' || $element == 'commande') {
1413  $element = $subelement = 'commande';
1414  }
1415  if ($element == 'propal') {
1416  $element = 'comm/propal';
1417  $subelement = 'propal';
1418  }
1419  if ($element == 'contract') {
1420  $element = $subelement = 'contrat';
1421  }
1422  if ($element == 'shipping') {
1423  $element = $subelement = 'expedition';
1424  }
1425 
1426  dol_include_once('/' . $element . '/class/' . $subelement . '.class.php');
1427 
1428  $classname = ucfirst($subelement);
1429  $objectsrc = new $classname($db);
1430  $objectsrc->fetch($originid);
1431  if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines'))
1432  {
1433  $objectsrc->fetch_lines();
1434  }
1435  $objectsrc->fetch_thirdparty();
1436 
1437  $projectid = (! empty($objectsrc->fk_project) ? $objectsrc->fk_project : 0);
1438  $ref_client = (! empty($objectsrc->ref_client) ? $objectsrc->ref_client : '');
1439  $ref_int = (! empty($objectsrc->ref_int) ? $objectsrc->ref_int : '');
1440 
1441  $soc = $objectsrc->thirdparty;
1442 
1443  $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
1444  $mode_reglement_id = (! empty($objectsrc->mode_reglement_id)?$objectsrc->mode_reglement_id:(! empty($soc->mode_reglement_id)?$soc->mode_reglement_id:0));
1445  $remise_percent = (! empty($objectsrc->remise_percent)?$objectsrc->remise_percent:(! empty($soc->remise_percent)?$soc->remise_percent:0));
1446  $remise_absolue = (! empty($objectsrc->remise_absolue)?$objectsrc->remise_absolue:(! empty($soc->remise_absolue)?$soc->remise_absolue:0));
1447  $dateinvoice = (empty($dateinvoice)?(empty($conf->global->MAIN_AUTOFILL_DATE)?-1:''):$dateinvoice);
1448 
1449  // Replicate extrafields
1450  $objectsrc->fetch_optionals($originid);
1451  $object->array_options = $objectsrc->array_options;
1452 
1453  if (!empty($conf->multicurrency->enabled))
1454  {
1455  if (!empty($objectsrc->multicurrency_code)) $currency_code = $objectsrc->multicurrency_code;
1456  if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($objectsrc->multicurrency_tx)) $currency_tx = $objectsrc->multicurrency_tx;
1457  }
1458  }
1459  }
1460  else
1461  {
1462  if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code;
1463  }
1464 
1465  $object = new Propal($db);
1466 
1467  print '<form name="addprop" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
1468  print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
1469  print '<input type="hidden" name="action" value="add">';
1470  if ($origin != 'project' && $originid) {
1471  print '<input type="hidden" name="origin" value="' . $origin . '">';
1472  print '<input type="hidden" name="originid" value="' . $originid . '">';
1473  } elseif ($origin == 'project' && !empty($projectid)) {
1474  print '<input type="hidden" name="projectid" value="' . $projectid . '">';
1475  }
1476 
1477  dol_fiche_head();
1478 
1479  print '<table class="border" width="100%">';
1480 
1481  // Reference
1482  print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans('Ref') . '</td><td>' . $langs->trans("Draft") . '</td></tr>';
1483 
1484  // Ref customer
1485  print '<tr><td>' . $langs->trans('RefCustomer') . '</td><td>';
1486  print '<input type="text" name="ref_client" value="'.GETPOST('ref_client').'"></td>';
1487  print '</tr>';
1488 
1489  // Third party
1490  print '<tr>';
1491  print '<td class="fieldrequired">' . $langs->trans('Customer') . '</td>';
1492  if ($socid > 0) {
1493  print '<td>';
1494  print $soc->getNomUrl(1);
1495  print '<input type="hidden" name="socid" value="' . $soc->id . '">';
1496  print '</td>';
1497  if (! empty($conf->global->SOCIETE_ASK_FOR_SHIPPING_METHOD) && ! empty($soc->shipping_method_id)) {
1498  $shipping_method_id = $soc->shipping_method_id;
1499  }
1500  } else {
1501  print '<td>';
1502  print $form->select_company('', 'socid', '(s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
1503  // reload page to retrieve customer informations
1504  if (!empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE))
1505  {
1506  print '<script type="text/javascript">
1507  $(document).ready(function() {
1508  $("#socid").change(function() {
1509  var socid = $(this).val();
1510  // reload page
1511  window.location.href = "'.$_SERVER["PHP_SELF"].'?action=create&socid="+socid+"&ref_client="+$("input[name=ref_client]").val();
1512  });
1513  });
1514  </script>';
1515  }
1516  print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&client=3&fournisseur=0&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'">'.$langs->trans("AddThirdParty").'</a>';
1517  print '</td>';
1518  }
1519  print '</tr>' . "\n";
1520 
1521  if ($socid > 0)
1522  {
1523  // Contacts (ask contact only if thirdparty already defined). TODO do this also into order and invoice.
1524  print "<tr><td>" . $langs->trans("DefaultContact") . '</td><td>';
1525  $form->select_contacts($soc->id, $contactid, 'contactid', 1, $srccontactslist);
1526  print '</td></tr>';
1527 
1528  // Ligne info remises tiers
1529  print '<tr><td>' . $langs->trans('Discounts') . '</td><td>';
1530 
1531  $absolute_discount = $soc->getAvailableDiscounts();
1532 
1533  $thirdparty = $soc;
1534  $discount_type = 0;
1535  $backtopage = urlencode($_SERVER["PHP_SELF"] . '?socid=' . $thirdparty->id . '&action=' . $action . '&origin=' . GETPOST('origin') . '&originid=' . GETPOST('originid'));
1536  include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
1537  print '</td></tr>';
1538  }
1539 
1540  // Date
1541  print '<tr><td class="fieldrequired">' . $langs->trans('Date') . '</td><td>';
1542  print $form->selectDate('', '', '', '', '', "addprop", 1, 1);
1543  print '</td></tr>';
1544 
1545  // Validaty duration
1546  print '<tr><td class="fieldrequired">' . $langs->trans("ValidityDuration") . '</td><td><input name="duree_validite" size="5" value="' . $conf->global->PROPALE_VALIDITY_DURATION . '"> ' . $langs->trans("days") . '</td></tr>';
1547 
1548  // Terms of payment
1549  print '<tr><td class="nowrap fieldrequired">' . $langs->trans('PaymentConditionsShort') . '</td><td>';
1550  $form->select_conditions_paiements($soc->cond_reglement_id, 'cond_reglement_id');
1551  print '</td></tr>';
1552 
1553  // Mode of payment
1554  print '<tr><td>' . $langs->trans('PaymentMode') . '</td><td>';
1555  $form->select_types_paiements($soc->mode_reglement_id, 'mode_reglement_id');
1556  print '</td></tr>';
1557 
1558  // Bank Account
1559  if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL) && ! empty($conf->banque->enabled)) {
1560  print '<tr><td>' . $langs->trans('BankAccount') . '</td><td>';
1561  $form->select_comptes($soc->fk_account, 'fk_account', 0, '', 1);
1562  print '</td></tr>';
1563  }
1564 
1565  // What trigger creation
1566  print '<tr><td>' . $langs->trans('Source') . '</td><td>';
1567  $form->selectInputReason('', 'demand_reason_id', "SRC_PROP", 1);
1568  print '</td></tr>';
1569 
1570  // Delivery delay
1571  print '<tr class="fielddeliverydelay"><td>' . $langs->trans('AvailabilityPeriod') . '</td><td>';
1572  $form->selectAvailabilityDelay('', 'availability_id', '', 1);
1573  print '</td></tr>';
1574 
1575  // Shipping Method
1576  if (! empty($conf->expedition->enabled)) {
1577  print '<tr><td>' . $langs->trans('SendingMethod') . '</td><td>';
1578  print $form->selectShippingMethod($shipping_method_id, 'shipping_method_id', '', 1);
1579  print '</td></tr>';
1580  }
1581 
1582  // Delivery date (or manufacturing)
1583  print '<tr><td>' . $langs->trans("DeliveryDate") . '</td>';
1584  print '<td>';
1585  if ($conf->global->DATE_LIVRAISON_WEEK_DELAY != "") {
1586  $tmpdte = time() + ((7 * $conf->global->DATE_LIVRAISON_WEEK_DELAY) * 24 * 60 * 60);
1587  $syear = date("Y", $tmpdte);
1588  $smonth = date("m", $tmpdte);
1589  $sday = date("d", $tmpdte);
1590  print $form->selectDate($syear."-".$smonth."-".$sday, 'date_livraison', '', '', '', "addprop");
1591  } else {
1592  print $form->selectDate(-1, 'date_livraison', '', '', '', "addprop", 1, 1);
1593  }
1594  print '</td></tr>';
1595 
1596  // Project
1597  if (! empty($conf->projet->enabled))
1598  {
1599  $langs->load("projects");
1600  print '<tr>';
1601  print '<td>' . $langs->trans("Project") . '</td><td>';
1602  $numprojet = $formproject->select_projects(($soc->id > 0 ? $soc->id : -1), $projectid, 'projectid', 0, 0, 1, 1);
1603  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).'">' . $langs->trans("AddProject") . '</a>';
1604  print '</td>';
1605  print '</tr>';
1606  }
1607 
1608  // Incoterms
1609  if (!empty($conf->incoterm->enabled))
1610  {
1611  print '<tr>';
1612  print '<td><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $soc->libelle_incoterms, 1).'</label></td>';
1613  print '<td class="maxwidthonsmartphone">';
1614  print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms)?$soc->location_incoterms:''));
1615  print '</td></tr>';
1616  }
1617 
1618  // Template to use by default
1619  print '<tr>';
1620  print '<td>' . $langs->trans("DefaultModel") . '</td>';
1621  print '<td>';
1622  $liste = ModelePDFPropales::liste_modeles($db);
1623  print $form->selectarray('model', $liste, ($conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT ? $conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT : $conf->global->PROPALE_ADDON_PDF));
1624  print "</td></tr>";
1625 
1626  // Multicurrency
1627  if (! empty($conf->multicurrency->enabled))
1628  {
1629  print '<tr>';
1630  print '<td>'.fieldLabel('Currency','multicurrency_code').'</td>';
1631  print '<td class="maxwidthonsmartphone">';
1632  print $form->selectMultiCurrency($currency_code, 'multicurrency_code', 0);
1633  print '</td></tr>';
1634  }
1635 
1636  // Public note
1637  print '<tr>';
1638  print '<td class="tdtop">' . $langs->trans('NotePublic') . '</td>';
1639  print '<td valign="top">';
1640  $note_public = $object->getDefaultCreateValueFor('note_public', (is_object($objectsrc)?$objectsrc->note_public:null));
1641  $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%');
1642  print $doleditor->Create(1);
1643 
1644  // Private note
1645  if (empty($user->societe_id))
1646  {
1647  print '<tr>';
1648  print '<td class="tdtop">' . $langs->trans('NotePrivate') . '</td>';
1649  print '<td valign="top">';
1650  $note_private = $object->getDefaultCreateValueFor('note_private', ((! empty($origin) && ! empty($originid) && is_object($objectsrc))?$objectsrc->note_private:null));
1651  $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%');
1652  print $doleditor->Create(1);
1653  // print '<textarea name="note_private" wrap="soft" cols="70" rows="'.ROWS_3.'">'.$note_private.'.</textarea>
1654  print '</td></tr>';
1655  }
1656 
1657  // Other attributes
1658  include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_add.tpl.php';
1659 
1660  // Lines from source
1661  if (! empty($origin) && ! empty($originid) && is_object($objectsrc))
1662  {
1663  // TODO for compatibility
1664  if ($origin == 'contrat') {
1665  // Calcul contrat->price (HT), contrat->total (TTC), contrat->tva
1666  $objectsrc->remise_absolue = $remise_absolue;
1667  $objectsrc->remise_percent = $remise_percent;
1668  $objectsrc->update_price(1, - 1, 1);
1669  }
1670 
1671  print "\n<!-- " . $classname . " info -->";
1672  print "\n";
1673  print '<input type="hidden" name="amount" value="' . $objectsrc->total_ht . '">' . "\n";
1674  print '<input type="hidden" name="total" value="' . $objectsrc->total_ttc . '">' . "\n";
1675  print '<input type="hidden" name="tva" value="' . $objectsrc->total_tva . '">' . "\n";
1676  print '<input type="hidden" name="origin" value="' . $objectsrc->element . '">';
1677  print '<input type="hidden" name="originid" value="' . $objectsrc->id . '">';
1678 
1679  $newclassname = $classname;
1680  if ($newclassname == 'Propal')
1681  $newclassname = 'CommercialProposal';
1682  elseif ($newclassname == 'Commande')
1683  $newclassname = 'Order';
1684  elseif ($newclassname == 'Expedition')
1685  $newclassname = 'Sending';
1686  elseif ($newclassname == 'Fichinter')
1687  $newclassname = 'Intervention';
1688 
1689  print '<tr><td>' . $langs->trans($newclassname) . '</td><td>' . $objectsrc->getNomUrl(1) . '</td></tr>';
1690  print '<tr><td>' . $langs->trans('TotalHT') . '</td><td>' . price($objectsrc->total_ht, 0, $langs, 1, -1, -1, $conf->currency) . '</td></tr>';
1691  print '<tr><td>' . $langs->trans('TotalVAT') . '</td><td>' . price($objectsrc->total_tva, 0, $langs, 1, -1, -1, $conf->currency) . "</td></tr>";
1692  if ($mysoc->localtax1_assuj == "1" || $objectsrc->total_localtax1 != 0 ) // Localtax1
1693  {
1694  print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td><td>' . price($objectsrc->total_localtax1, 0, $langs, 1, -1, -1, $conf->currency) . "</td></tr>";
1695  }
1696 
1697  if ($mysoc->localtax2_assuj == "1" || $objectsrc->total_localtax2 != 0) // Localtax2
1698  {
1699  print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td><td>' . price($objectsrc->total_localtax2, 0, $langs, 1, -1, -1, $conf->currency) . "</td></tr>";
1700  }
1701  print '<tr><td>' . $langs->trans('TotalTTC') . '</td><td>' . price($objectsrc->total_ttc, 0, $langs, 1, -1, -1, $conf->currency) . "</td></tr>";
1702  }
1703 
1704  print "</table>\n";
1705 
1706 
1707  /*
1708  * Combobox pour la fonction de copie
1709  */
1710 
1711  if (empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE)) print '<input type="hidden" name="createmode" value="empty">';
1712 
1713  if (! empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE))
1714  {
1715  print '<br><table>';
1716 
1717  // For backward compatibility
1718  print '<tr>';
1719  print '<td><input type="radio" name="createmode" value="copy"></td>';
1720  print '<td>' . $langs->trans("CopyPropalFrom") . ' </td>';
1721  print '<td>';
1722  $liste_propal = array();
1723  $liste_propal [0] = '';
1724 
1725  $sql = "SELECT p.rowid as id, p.ref, s.nom";
1726  $sql .= " FROM " . MAIN_DB_PREFIX . "propal p";
1727  $sql .= ", " . MAIN_DB_PREFIX . "societe s";
1728  $sql .= " WHERE s.rowid = p.fk_soc";
1729  $sql .= " AND p.entity IN (".getEntity('propal').")";
1730  $sql .= " AND p.fk_statut <> 0";
1731  $sql .= " ORDER BY Id";
1732 
1733  $resql = $db->query($sql);
1734  if ($resql) {
1735  $num = $db->num_rows($resql);
1736  $i = 0;
1737  while ($i < $num) {
1738  $row = $db->fetch_row($resql);
1739  $propalRefAndSocName = $row [1] . " - " . $row [2];
1740  $liste_propal [$row [0]] = $propalRefAndSocName;
1741  $i ++;
1742  }
1743  print $form->selectarray("copie_propal", $liste_propal, 0);
1744  } else {
1745  dol_print_error($db);
1746  }
1747  print '</td></tr>';
1748 
1749  print '<tr><td class="tdtop"><input type="radio" name="createmode" value="empty" checked></td>';
1750  print '<td valign="top" colspan="2">' . $langs->trans("CreateEmptyPropal") . '</td></tr>';
1751  }
1752 
1753  if (! empty($conf->global->PROPAL_CLONE_ON_CREATE_PAGE)) print '</table>';
1754 
1755  dol_fiche_end();
1756 
1757  $langs->load("bills");
1758  print '<div class="center">';
1759  print '<input type="submit" class="button" value="' . $langs->trans("CreateDraft") . '">';
1760  print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
1761  print '<input type="button" class="button" value="' . $langs->trans("Cancel") . '" onClick="javascript:history.go(-1)">';
1762  print '</div>';
1763 
1764  print "</form>";
1765 
1766 
1767  // Show origin lines
1768  if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) {
1769  print '<br>';
1770 
1771  $title = $langs->trans('ProductsAndServices');
1772  print load_fiche_titre($title);
1773 
1774  print '<table class="noborder" width="100%">';
1775 
1776  $objectsrc->printOriginLinesList();
1777 
1778  print '</table>';
1779  }
1780 } elseif ($object->id > 0) {
1781  /*
1782  * Show object in view mode
1783  */
1784 
1785  $soc = new Societe($db);
1786  $soc->fetch($object->socid);
1787 
1788  $head = propal_prepare_head($object);
1789  dol_fiche_head($head, 'comm', $langs->trans('Proposal'), -1, 'propal');
1790 
1791  $formconfirm = '';
1792 
1793  // Clone confirmation
1794  if ($action == 'clone') {
1795  // Create an array for form
1796  $formquestion = array(
1797  // 'text' => $langs->trans("ConfirmClone"),
1798  // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
1799  // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' =>
1800  // 1),
1801  array('type' => 'other','name' => 'socid','label' => $langs->trans("SelectThirdParty"),'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')));
1802  if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY) && !empty($object->date_livraison)) {
1803  $formquestion[] = array('type' => 'date','name' => 'date_delivery','label' => $langs->trans("DeliveryDate"),'value' => $object->date_livraison);
1804  }
1805  // Paiement incomplet. On demande si motif = escompte ou autre
1806  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ClonePropal'), $langs->trans('ConfirmClonePropal', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
1807  }
1808 
1809  if ($action == 'statut')
1810  {
1811  //Form to close proposal (signed or not)
1812  $formquestion = array(
1813  array('type' => 'select','name' => 'statut','label' => $langs->trans("CloseAs"),'values' => array(2=>$object->LibStatut(Propal::STATUS_SIGNED), 3=>$object->LibStatut(Propal::STATUS_NOTSIGNED))),
1814  array('type' => 'text', 'name' => 'note_private', 'label' => $langs->trans("Note"),'value' => '') // Field to complete private note (not replace)
1815  );
1816 
1817  if (! empty($conf->notification->enabled))
1818  {
1819  require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
1820  $notify = new Notify($db);
1821  $formquestion = array_merge($formquestion, array(
1822  array('type' => 'onecolumn', 'value' => $notify->confirmMessage('PROPAL_CLOSE_SIGNED', $object->socid, $object)),
1823  ));
1824  }
1825 
1826  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('SetAcceptedRefused'), $text, 'setstatut', $formquestion, '', 1, 250);
1827  }
1828 
1829  // Confirm delete
1830  else if ($action == 'delete') {
1831  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteProp'), $langs->trans('ConfirmDeleteProp', $object->ref), 'confirm_delete', '', 0, 1);
1832  }
1833 
1834  // Confirm reopen
1835  else if ($action == 'reopen') {
1836  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ReOpen'), $langs->trans('ConfirmReOpenProp', $object->ref), 'confirm_reopen', '', 0, 1);
1837  }
1838 
1839  // Confirmation delete product/service line
1840  else if ($action == 'ask_deleteline') {
1841  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
1842  }
1843 
1844  // Confirm validate proposal
1845  else if ($action == 'validate') {
1846  $error = 0;
1847 
1848  // We verifie whether the object is provisionally numbering
1849  $ref = substr($object->ref, 1, 4);
1850  if ($ref == 'PROV') {
1851  $numref = $object->getNextNumRef($soc);
1852  if (empty($numref)) {
1853  $error ++;
1854  setEventMessages($object->error, $object->errors, 'errors');
1855  }
1856  } else {
1857  $numref = $object->ref;
1858  }
1859 
1860  $text = $langs->trans('ConfirmValidateProp', $numref);
1861  if (! empty($conf->notification->enabled)) {
1862  require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
1863  $notify = new Notify($db);
1864  $text .= '<br>';
1865  $text .= $notify->confirmMessage('PROPAL_VALIDATE', $object->socid, $object);
1866  }
1867 
1868  if (! $error)
1869  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ValidateProp'), $text, 'confirm_validate', '', 0, 1);
1870  }
1871 
1872  // Call Hook formConfirm
1873  $parameters = array('lineid' => $lineid);
1874  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1875  if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
1876  elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
1877 
1878  // Print form confirm
1879  print $formconfirm;
1880 
1881 
1882  // Proposal card
1883 
1884  $linkback = '<a href="' . DOL_URL_ROOT . '/comm/propal/list.php?restore_lastsearch_values=1' . (! empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
1885 
1886  $morehtmlref='<div class="refidno">';
1887  // Ref customer
1888  $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string', '', 0, 1);
1889  $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string', '', null, null, '', 1);
1890  // Thirdparty
1891  $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1,'customer');
1892  if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) $morehtmlref.=' (<a href="'.DOL_URL_ROOT.'/comm/propal/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherProposals").'</a>)';
1893  // Project
1894  if (! empty($conf->projet->enabled))
1895  {
1896  $langs->load("projects");
1897  $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
1898  if ($usercancreate)
1899  {
1900  if ($action != 'classify')
1901  $morehtmlref.='<a href="' . $_SERVER['PHP_SELF'] . '?action=classify&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
1902  if ($action == 'classify') {
1903  //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
1904  $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
1905  $morehtmlref.='<input type="hidden" name="action" value="classin">';
1906  $morehtmlref.='<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1907  $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
1908  $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
1909  $morehtmlref.='</form>';
1910  } else {
1911  $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
1912  }
1913  } else {
1914  if (! empty($object->fk_project)) {
1915  $proj = new Project($db);
1916  $proj->fetch($object->fk_project);
1917  $morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
1918  $morehtmlref.=$proj->ref;
1919  $morehtmlref.='</a>';
1920  } else {
1921  $morehtmlref.='';
1922  }
1923  }
1924  }
1925  $morehtmlref.='</div>';
1926 
1927 
1928  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
1929 
1930 
1931  print '<div class="fichecenter">';
1932  print '<div class="fichehalfleft">';
1933  print '<div class="underbanner clearboth"></div>';
1934 
1935  print '<table class="border" width="100%">';
1936 
1937  // Link for thirdparty discounts
1938  if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
1939  $filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
1940  $filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
1941  } else {
1942  $filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
1943  $filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
1944  }
1945 
1946  print '<tr><td class="titlefield">' . $langs->trans('Discounts') . '</td><td>';
1947 
1948  $absolute_discount = $soc->getAvailableDiscounts('', $filterabsolutediscount);
1949  $absolute_creditnote = $soc->getAvailableDiscounts('', $filtercreditnote);
1950  $absolute_discount = price2num($absolute_discount, 'MT');
1951  $absolute_creditnote = price2num($absolute_creditnote, 'MT');
1952 
1953  $thirdparty = $soc;
1954  $discount_type = 0;
1955  $backtopage = urlencode($_SERVER["PHP_SELF"] . '?id=' . $object->id);
1956  include DOL_DOCUMENT_ROOT.'/core/tpl/object_discounts.tpl.php';
1957 
1958  print '</td></tr>';
1959 
1960  // Date of proposal
1961  print '<tr>';
1962  print '<td>';
1963  print '<table class="nobordernopadding" width="100%"><tr><td>';
1964  print $langs->trans('Date');
1965  print '</td>';
1966  if ($action != 'editdate' && ! empty($object->brouillon) && $usercancreate)
1967  print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editdate&amp;id=' . $object->id . '">' . img_edit($langs->trans('SetDate'), 1) . '</a></td>';
1968  print '</tr></table>';
1969  print '</td><td>';
1970  if (! empty($object->brouillon) && $action == 'editdate' && $usercancreate) {
1971  print '<form name="editdate" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
1972  print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
1973  print '<input type="hidden" name="action" value="setdate">';
1974  print $form->selectDate($object->date, 're', '', '', 0, "editdate");
1975  print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
1976  print '</form>';
1977  } else {
1978  if ($object->date) {
1979  print dol_print_date($object->date, 'day');
1980  } else {
1981  print '&nbsp;';
1982  }
1983  }
1984  print '</td>';
1985 
1986  // Date end proposal
1987  print '<tr>';
1988  print '<td>';
1989  print '<table class="nobordernopadding" width="100%"><tr><td>';
1990  print $langs->trans('DateEndPropal');
1991  print '</td>';
1992  if ($action != 'editecheance' && ! empty($object->brouillon) && $usercancreate)
1993  print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editecheance&amp;id=' . $object->id . '">' . img_edit($langs->trans('SetConditions'), 1) . '</a></td>';
1994  print '</tr></table>';
1995  print '</td><td>';
1996  if (! empty($object->brouillon) && $action == 'editecheance' && $usercancreate) {
1997  print '<form name="editecheance" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '" method="post">';
1998  print '<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">';
1999  print '<input type="hidden" name="action" value="setecheance">';
2000  print $form->selectDate($object->fin_validite, 'ech', '', '', '', "editecheance");
2001  print '<input type="submit" class="button" value="' . $langs->trans('Modify') . '">';
2002  print '</form>';
2003  } else {
2004  if (! empty($object->fin_validite)) {
2005  print dol_print_date($object->fin_validite, 'day');
2006  if ($object->statut == Propal::STATUS_VALIDATED && $object->fin_validite < ($now - $conf->propal->cloture->warning_delay))
2007  print img_warning($langs->trans("Late"));
2008  } else {
2009  print '&nbsp;';
2010  }
2011  }
2012  print '</td>';
2013  print '</tr>';
2014 
2015  // Payment term
2016  print '<tr><td>';
2017  print '<table class="nobordernopadding" width="100%"><tr><td>';
2018  print $langs->trans('PaymentConditionsShort');
2019  print '</td>';
2020  if ($action != 'editconditions' && ! empty($object->brouillon) && $usercancreate)
2021  print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editconditions&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetConditions'), 1) . '</a></td>';
2022  print '</tr></table>';
2023  print '</td><td>';
2024  if (! empty($object->brouillon) && $action == 'editconditions' && $usercancreate) {
2025  $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->cond_reglement_id, 'cond_reglement_id');
2026  } else {
2027  $form->form_conditions_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->cond_reglement_id, 'none');
2028  }
2029  print '</td>';
2030  print '</tr>';
2031 
2032  // Delivery date
2033  $langs->load('deliveries');
2034  print '<tr><td>';
2035  print $form->editfieldkey($langs->trans('DeliveryDate'), 'date_livraison', $object->date_livraison, $object, $usercancreate, 'datepicker');
2036  print '</td><td>';
2037  print $form->editfieldval($langs->trans('DeliveryDate'), 'date_livraison', $object->date_livraison, $object, $usercancreate, 'datepicker');
2038  print '</td>';
2039  print '</tr>';
2040 
2041  // Delivery delay
2042  print '<tr class="fielddeliverydelay"><td>';
2043  print '<table class="nobordernopadding" width="100%"><tr><td>';
2044  print $langs->trans('AvailabilityPeriod');
2045  if (! empty($conf->commande->enabled))
2046  print ' (' . $langs->trans('AfterOrder') . ')';
2047  print '</td>';
2048  if ($action != 'editavailability' && ! empty($object->brouillon) && $usercancreate)
2049  print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editavailability&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetAvailability'), 1) . '</a></td>';
2050  print '</tr></table>';
2051  print '</td><td>';
2052  if (! empty($object->brouillon) && $action == 'editavailability' && $usercancreate) {
2053  $form->form_availability($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->availability_id, 'availability_id', 1);
2054  } else {
2055  $form->form_availability($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->availability_id, 'none', 1);
2056  }
2057 
2058  print '</td>';
2059  print '</tr>';
2060 
2061  // Shipping Method
2062  if (! empty($conf->expedition->enabled)) {
2063  print '<tr><td>';
2064  print '<table width="100%" class="nobordernopadding"><tr><td>';
2065  print $langs->trans('SendingMethod');
2066  print '</td>';
2067  if ($action != 'editshippingmethod' && $usercancreate)
2068  print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editshippingmethod&amp;id='.$object->id.'">'.img_edit($langs->trans('SetShippingMode'),1).'</a></td>';
2069  print '</tr></table>';
2070  print '</td><td>';
2071  if ($action == 'editshippingmethod' && $usercancreate) {
2072  $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1);
2073  } else {
2074  $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none');
2075  }
2076  print '</td>';
2077  print '</tr>';
2078  }
2079 
2080  // Origin of demand
2081  print '<tr><td>';
2082  print '<table class="nobordernopadding" width="100%"><tr><td>';
2083  print $langs->trans('Source');
2084  print '</td>';
2085  if ($action != 'editdemandreason' && ! empty($object->brouillon) && $usercancreate)
2086  print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editdemandreason&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetDemandReason'), 1) . '</a></td>';
2087  print '</tr></table>';
2088  print '</td><td>';
2089  if (! empty($object->brouillon) && $action == 'editdemandreason' && $usercancreate) {
2090  $form->formInputReason($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->demand_reason_id, 'demand_reason_id', 1);
2091  } else {
2092  $form->formInputReason($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->demand_reason_id, 'none');
2093  }
2094  print '</td>';
2095  print '</tr>';
2096 
2097  // Payment mode
2098  print '<tr>';
2099  print '<td>';
2100  print '<table class="nobordernopadding" width="100%"><tr><td>';
2101  print $langs->trans('PaymentMode');
2102  print '</td>';
2103  if ($action != 'editmode' && ! empty($object->brouillon) && $usercancreate)
2104  print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmode&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetMode'), 1) . '</a></td>';
2105  print '</tr></table>';
2106  print '</td><td>';
2107  if (! empty($object->brouillon) && $action == 'editmode' && $usercancreate) {
2108  $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1);
2109  } else {
2110  $form->form_modes_reglement($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->mode_reglement_id, 'none');
2111  }
2112  print '</td></tr>';
2113 
2114  // Multicurrency
2115  if (! empty($conf->multicurrency->enabled))
2116  {
2117  // Multicurrency code
2118  print '<tr>';
2119  print '<td>';
2120  print '<table class="nobordernopadding" width="100%"><tr><td>';
2121  print fieldLabel('Currency','multicurrency_code');
2122  print '</td>';
2123  if ($action != 'editmulticurrencycode' && ! empty($object->brouillon) && $usercancreate)
2124  print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmulticurrencycode&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '</a></td>';
2125  print '</tr></table>';
2126  print '</td><td>';
2127  if (! empty($object->brouillon) && $action == 'editmulticurrencycode' && $usercancreate) {
2128  $form->form_multicurrency_code($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_code, 'multicurrency_code');
2129  } else {
2130  $form->form_multicurrency_code($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_code, 'none');
2131  }
2132  print '</td></tr>';
2133 
2134  // Multicurrency rate
2135  print '<tr>';
2136  print '<td>';
2137  print '<table class="nobordernopadding" width="100%"><tr><td>';
2138  print fieldLabel('CurrencyRate','multicurrency_tx');
2139  print '</td>';
2140  if ($action != 'editmulticurrencyrate' && ! empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency && $usercancreate)
2141  print '<td align="right"><a href="' . $_SERVER["PHP_SELF"] . '?action=editmulticurrencyrate&amp;id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1) . '</a></td>';
2142  print '</tr></table>';
2143  print '</td><td>';
2144  if (! empty($object->brouillon) && ($action == 'editmulticurrencyrate' || $action == 'actualizemulticurrencyrate') && $usercancreate) {
2145  if($action == 'actualizemulticurrencyrate') {
2146  list($object->fk_multicurrency, $object->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($object->db, $object->multicurrency_code);
2147  }
2148  $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'multicurrency_tx', $object->multicurrency_code);
2149  } else {
2150  $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->multicurrency_tx, 'none', $object->multicurrency_code);
2151  if ($object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) {
2152  print '<div class="inline-block"> &nbsp; &nbsp; &nbsp; &nbsp; ';
2153  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=actualizemulticurrencyrate">'.$langs->trans("ActualizeCurrency").'</a>';
2154  print '</div>';
2155  }
2156  }
2157  print '</td></tr>';
2158  }
2159 
2160  if ($soc->outstanding_limit)
2161  {
2162  // Outstanding Bill
2163  print '<tr><td>';
2164  print $langs->trans('OutstandingBill');
2165  print '</td><td align="right">';
2166  print price($soc->get_OutstandingBill()) . ' / ';
2167  print price($soc->outstanding_limit, 0, $langs, 1, - 1, - 1, $conf->currency);
2168  print '</td>';
2169  print '</tr>';
2170  }
2171 
2172  if (! empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL) && ! empty($conf->banque->enabled))
2173  {
2174  // Bank Account
2175  print '<tr><td>';
2176  print '<table width="100%" class="nobordernopadding"><tr><td>';
2177  print $langs->trans('BankAccount');
2178  print '</td>';
2179  if ($action != 'editbankaccount' && $usercancreate)
2180  print '<td align="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editbankaccount&amp;id='.$object->id.'">'.img_edit($langs->trans('SetBankAccount'),1).'</a></td>';
2181  print '</tr></table>';
2182  print '</td><td>';
2183  if ($action == 'editbankaccount') {
2184  $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'fk_account', 1);
2185  } else {
2186  $form->formSelectAccount($_SERVER['PHP_SELF'].'?id='.$object->id, $object->fk_account, 'none');
2187  }
2188  print '</td>';
2189  print '</tr>';
2190  }
2191 
2192  $tmparray=$object->getTotalWeightVolume();
2193  $totalWeight=$tmparray['weight'];
2194  $totalVolume=$tmparray['volume'];
2195  if ($totalWeight) {
2196  print '<tr><td>' . $langs->trans("CalculatedWeight") . '</td>';
2197  print '<td>';
2198  print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, isset($conf->global->MAIN_WEIGHT_DEFAULT_ROUND)?$conf->global->MAIN_WEIGHT_DEFAULT_ROUND:-1, isset($conf->global->MAIN_WEIGHT_DEFAULT_UNIT)?$conf->global->MAIN_WEIGHT_DEFAULT_UNIT:'no');
2199  print '</td></tr>';
2200  }
2201  if ($totalVolume) {
2202  print '<tr><td>' . $langs->trans("CalculatedVolume") . '</td>';
2203  print '<td>';
2204  print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, isset($conf->global->MAIN_VOLUME_DEFAULT_ROUND)?$conf->global->MAIN_VOLUME_DEFAULT_ROUND:-1, isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT)?$conf->global->MAIN_VOLUME_DEFAULT_UNIT:'no');
2205  print '</td></tr>';
2206  }
2207 
2208  // Incoterms
2209  if (!empty($conf->incoterm->enabled))
2210  {
2211  print '<tr><td>';
2212  print '<table width="100%" class="nobordernopadding"><tr><td>';
2213  print $langs->trans('IncotermLabel');
2214  print '<td><td align="right">';
2215  if ($usercancreate) print '<a href="'.DOL_URL_ROOT.'/comm/propal/card.php?id='.$object->id.'&action=editincoterm">'.img_edit().'</a>';
2216  else print '&nbsp;';
2217  print '</td></tr></table>';
2218  print '</td>';
2219  print '<td>';
2220  if ($action != 'editincoterm')
2221  {
2222  print $form->textwithpicto($object->display_incoterms(), $object->libelle_incoterms, 1);
2223  }
2224  else
2225  {
2226  print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms)?$object->location_incoterms:''), $_SERVER['PHP_SELF'].'?id='.$object->id);
2227  }
2228  print '</td></tr>';
2229  }
2230 
2231  // Other attributes
2232  include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
2233 
2234  print '</table>';
2235 
2236  print '</div>';
2237  print '<div class="fichehalfright">';
2238  print '<div class="ficheaddleft">';
2239  print '<div class="underbanner clearboth"></div>';
2240 
2241  print '<table class="border centpercent">';
2242 
2243  if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency))
2244  {
2245  // Multicurrency Amount HT
2246  print '<tr><td class="titlefieldmiddle">' . fieldLabel('MulticurrencyAmountHT','multicurrency_total_ht') . '</td>';
2247  print '<td class="nowrap">' . price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>';
2248  print '</tr>';
2249 
2250  // Multicurrency Amount VAT
2251  print '<tr><td>' . fieldLabel('MulticurrencyAmountVAT','multicurrency_total_tva') . '</td>';
2252  print '<td class="nowrap">' . price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>';
2253  print '</tr>';
2254 
2255  // Multicurrency Amount TTC
2256  print '<tr><td>' . fieldLabel('MulticurrencyAmountTTC','multicurrency_total_ttc') . '</td>';
2257  print '<td class="nowrap">' . price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)) . '</td>';
2258  print '</tr>';
2259  }
2260 
2261  // Amount HT
2262  print '<tr><td class="titlefieldmiddle">' . $langs->trans('AmountHT') . '</td>';
2263  print '<td class="nowrap">' . price($object->total_ht, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>';
2264  print '</tr>';
2265 
2266  // Amount VAT
2267  print '<tr><td>' . $langs->trans('AmountVAT') . '</td>';
2268  print '<td class="nowrap">' . price($object->total_tva, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>';
2269  print '</tr>';
2270 
2271  // Amount Local Taxes
2272  if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) // Localtax1
2273  {
2274  print '<tr><td>' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
2275  print '<td class="nowrap">' . price($object->total_localtax1, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>';
2276  print '</tr>';
2277  }
2278  if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) // Localtax2
2279  {
2280  print '<tr><td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
2281  print '<td class="nowrap">' . price($object->total_localtax2, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>';
2282  print '</tr>';
2283  }
2284 
2285  // Amount TTC
2286  print '<tr><td>' . $langs->trans('AmountTTC') . '</td>';
2287  print '<td class="nowrap">' . price($object->total_ttc, '', $langs, 0, - 1, - 1, $conf->currency) . '</td>';
2288  print '</tr>';
2289 
2290  // Statut
2291  //print '<tr><td height="10">' . $langs->trans('Status') . '</td><td align="left" colspan="2">' . $object->getLibStatut(4) . '</td></tr>';
2292 
2293  print '</table>';
2294 
2295  // Margin Infos
2296  if (! empty($conf->margin->enabled))
2297  {
2298  $formmargin->displayMarginInfos($object);
2299  }
2300 
2301  print '</div>';
2302  print '</div>';
2303  print '</div>';
2304 
2305  print '<div class="clearboth"></div><br>';
2306 
2307  if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) {
2308  $blocname = 'contacts';
2309  $title = $langs->trans('ContactsAddresses');
2310  include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php';
2311  }
2312 
2313  if (! empty($conf->global->MAIN_DISABLE_NOTES_TAB)) {
2314  $blocname = 'notes';
2315  $title = $langs->trans('Notes');
2316  include DOL_DOCUMENT_ROOT . '/core/tpl/bloc_showhide.tpl.php';
2317  }
2318 
2319  /*
2320  * Lines
2321  */
2322 
2323  // Show object lines
2324  $result = $object->getLinesArray();
2325 
2326  print ' <form name="addproduct" id="addproduct" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . (($action != 'editline') ? '#addline' : '#line_' . GETPOST('lineid')) . '" method="POST">
2327  <input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
2328  <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline') . '">
2329  <input type="hidden" name="mode" value="">
2330  <input type="hidden" name="id" value="' . $object->id . '">
2331  ';
2332 
2333  if (! empty($conf->use_javascript_ajax) && $object->statut == Propal::STATUS_DRAFT) {
2334  include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php';
2335  }
2336 
2337  print '<div class="div-table-responsive-no-min">';
2338  print '<table id="tablelines" class="noborder noshadow" width="100%">';
2339 
2340  if (! empty($object->lines))
2341  $ret = $object->printObjectLines($action, $mysoc, $soc, $lineid, 1);
2342 
2343  // Form to add new line
2344  if ($object->statut == Propal::STATUS_DRAFT && $usercancreate && $action != 'selectlines')
2345  {
2346  if ($action != 'editline')
2347  {
2348  // Add products/services form
2349  $object->formAddObjectLine(1, $mysoc, $soc);
2350 
2351  $parameters = array();
2352  $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2353  }
2354  }
2355 
2356  print '</table>';
2357  print '</div>';
2358 
2359  print "</form>\n";
2360 
2361  dol_fiche_end();
2362 
2363  /*
2364  * Boutons Actions
2365  */
2366  if ($action != 'presend') {
2367  print '<div class="tabsAction">';
2368 
2369  $parameters = array();
2370  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
2371  // modified by hook
2372  if (empty($reshook))
2373  {
2374  if ($action != 'editline')
2375  {
2376  // Validate
2377  if ($object->statut == Propal::STATUS_DRAFT && $object->total_ttc >= 0 && count($object->lines) > 0)
2378  {
2379  if ($usercanvalidate)
2380  {
2381  print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=validate">' . $langs->trans('Validate') . '</a></div>';
2382  }
2383  else
2384  print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">' . $langs->trans('Validate') . '</a></div>';
2385  }
2386  // Create event
2387  /*if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a "workflow" action so should appears somewhere else on page.
2388  {
2389  print '<div class="inline-block divButAction"><a class="butAction" href="' . DOL_URL_ROOT . '/comm/action/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '">' . $langs->trans("AddAction") . '</a></div>';
2390  }*/
2391  // Edit
2392  if ($object->statut == Propal::STATUS_VALIDATED && $usercancreate) {
2393  print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=modif">' . $langs->trans('Modify') . '</a></div>';
2394  }
2395 
2396  // ReOpen
2397  if (($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED) && $usercanclose) {
2398  print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=reopen' . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#reopen') . '"';
2399  print '>' . $langs->trans('ReOpen') . '</a></div>';
2400  }
2401 
2402  // Send
2403  if ($object->statut == Propal::STATUS_VALIDATED || $object->statut == Propal::STATUS_SIGNED) {
2404  if ($usercansend) {
2405  print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=presend&mode=init#formmailbeforetitle">' . $langs->trans('SendMail') . '</a></div>';
2406  } else
2407  print '<div class="inline-block divButAction"><a class="butActionRefused" href="#">' . $langs->trans('SendMail') . '</a></div>';
2408  }
2409 
2410  // Create an order
2411  if (! empty($conf->commande->enabled) && $object->statut == Propal::STATUS_SIGNED) {
2412  if ($usercancreateorder) {
2413  print '<div class="inline-block divButAction"><a class="butAction" href="' . DOL_URL_ROOT . '/commande/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '">' . $langs->trans("AddOrder") . '</a></div>';
2414  }
2415  }
2416 
2417  // Create an intervention
2418  if (! empty($conf->service->enabled) && ! empty($conf->ficheinter->enabled) && $object->statut == Propal::STATUS_SIGNED) {
2419  if ($usercancreateintervention) {
2420  $langs->load("interventions");
2421  print '<div class="inline-block divButAction"><a class="butAction" href="' . DOL_URL_ROOT . '/fichinter/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '">' . $langs->trans("AddIntervention") . '</a></div>';
2422  }
2423  }
2424 
2425  // Create contract
2426  if ($conf->contrat->enabled && $object->statut == Propal::STATUS_SIGNED) {
2427  $langs->load("contracts");
2428 
2429  if ($usercancreatecontract) {
2430  print '<div class="inline-block divButAction"><a class="butAction" href="' . DOL_URL_ROOT . '/contrat/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '">' . $langs->trans('AddContract') . '</a></div>';
2431  }
2432  }
2433 
2434  // Create an invoice and classify billed
2435  if ($object->statut == Propal::STATUS_SIGNED)
2436  {
2437  if (! empty($conf->facture->enabled) && $usercancreateinvoice)
2438  {
2439  print '<div class="inline-block divButAction"><a class="butAction" href="' . DOL_URL_ROOT . '/compta/facture/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '">' . $langs->trans("AddBill") . '</a></div>';
2440  }
2441 
2442  $arrayofinvoiceforpropal = $object->getInvoiceArrayList();
2443  if ((is_array($arrayofinvoiceforpropal) && count($arrayofinvoiceforpropal) > 0) || empty($conf->global->WORKFLOW_PROPAL_NEED_INVOICE_TO_BE_CLASSIFIED_BILLED))
2444  {
2445  print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=classifybilled&amp;socid=' . $object->socid . '">' . $langs->trans("ClassifyBilled") . '</a></div>';
2446  }
2447  }
2448 
2449  // Set accepted/refused
2450  if ($object->statut == Propal::STATUS_VALIDATED && $usercanclose) {
2451  print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=statut' . (empty($conf->global->MAIN_JUMP_TAG) ? '' : '#close') . '"';
2452  print '>' . $langs->trans('SetAcceptedRefused') . '</a></div>';
2453  }
2454 
2455  // Clone
2456  if ($usercancreate) {
2457  print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;socid=' . $object->socid . '&amp;action=clone&amp;object=' . $object->element . '">' . $langs->trans("ToClone") . '</a></div>';
2458  }
2459 
2460  // Delete
2461  if ($usercandelete) {
2462  print '<div class="inline-block divButAction"><a class="butActionDelete" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=delete"';
2463  print '>' . $langs->trans('Delete') . '</a></div>';
2464  }
2465  }
2466  }
2467 
2468  print '</div>';
2469  }
2470 
2471  //Select mail models is same action as presend
2472  if (GETPOST('modelselected')) $action = 'presend';
2473 
2474  if ($action != 'presend')
2475  {
2476  print '<div class="fichecenter"><div class="fichehalfleft">';
2477  print '<a name="builddoc"></a>'; // ancre
2478  /*
2479  * Documents generes
2480  */
2481  $filename = dol_sanitizeFileName($object->ref);
2482  $filedir = $conf->propal->multidir_output[$object->entity] . "/" . dol_sanitizeFileName($object->ref);
2483  $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id;
2484  $genallowed = $usercanread;
2485  $delallowed = $usercancreate;
2486 
2487  print $formfile->showdocuments('propal', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang, '', $object);
2488 
2489  // Show links to link elements
2490  $linktoelem = $form->showLinkToObjectBlock($object, null, array('propal'));
2491  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2492 
2493  // Show online signature link
2494  $useonlinesignature = $conf->global->MAIN_FEATURES_LEVEL; // Replace this with 1 when feature to make online signature is ok
2495 
2496  if ($object->statut != Propal::STATUS_DRAFT && $useonlinesignature)
2497  {
2498  print '<br><!-- Link to sign -->';
2499  require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
2500  print showOnlineSignatureUrl('proposal', $object->ref).'<br>';
2501  }
2502 
2503  // Show direct download link
2504  if ($object->statut != Propal::STATUS_DRAFT && ! empty($conf->global->PROPOSAL_ALLOW_EXTERNAL_DOWNLOAD))
2505  {
2506  print '<br><!-- Link to download main doc -->'."\n";
2507  print showDirectDownloadLink($object).'<br>';
2508  }
2509 
2510  print '</div><div class="fichehalfright"><div class="ficheaddleft">';
2511 
2512  // List of actions on element
2513  include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
2514  $formactions = new FormActions($db);
2515  $somethingshown = $formactions->showactions($object, 'propal', $socid, 1);
2516 
2517  print '</div></div></div>';
2518  }
2519 
2520  // Presend form
2521  $modelmail='propal_send';
2522  $defaulttopic='SendPropalRef';
2523  $diroutput = $conf->propal->multidir_output[$object->entity];
2524  $trackid = 'pro'.$object->id;
2525 
2526  include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2527 }
2528 
2529 // End of page
2530 llxFooter();
2531 $db->close();
print $object label
hash of file content (md5_file(dol_osencode($destfull))
Definition: edit.php:153
File of class to manage predefined price products or services by customer.
img_warning($titlealt='default', $moreatt='')
Show warning logo.
llxFooter()
Empty footer.
Definition: wrapper.php:56
load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
GETPOST($paramname, $check='none', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Class to manage notifications.
print
Draft customers invoices.
Definition: index.php:91
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) if(! empty($conf->don->enabled) && $user->rights->societe->lire) if(! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) if(! empty($conf->facture->enabled) &&! empty($conf->commande->enabled) && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1053
Class to manage building of HTML components.
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action=='set') else if($action=='specimen') else if($action=='setmodel') else if($action=='del') else if($action=='setdoc') $formactions
View.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm=false, $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
img_edit($titlealt='default', $float=0, $other='class="pictoedit"')
Show logo editer/modifier fiche.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
Class to manage products or services.
Class to manage interventions.
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_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for properties) With native = 0: P...
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
getCountry($searchkey, $withcode='', $dbtouse=0, $outputlangs='', $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
dol_concatdesc($text1, $text2, $forxml=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Fonction qui renvoie si tva doit etre tva percue recuperable.
Class to manage generation of HTML components for proposal management.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:103
get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller="", $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate, from a $thirdparty_buyer to a $thirdparty_seller Note: This function applies same rules than get_default_tva.
Class to manage standard extra fields.
showDirectDownloadLink($object)
Return string with full Url.
Class to manage generation of HTML components Only common components must be here.
const STATUS_NOTSIGNED
Not signed quote.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting a parameter.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage projects.
const STATUS_BILLED
Billed or processed quote.
if(! function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
Classe permettant la generation de composants html autre Only common components are here...
Class to manage building of HTML components.
const STATUS_SIGNED
Signed quote.
Class to manage shipments.
dol_fiche_end($notab=0)
Show tab footer of a card.
Classe permettant la generation de composants html autre Only common components are here...
llxHeader()
Empty header.
Definition: wrapper.php:44
Class to manage translations.
if(GETPOST('cancel', 'alpha')) if(! GETPOST( 'confirmmassaction', 'alpha') &&$massaction !='presend' &&$massaction !='confirm_presend')
Draft customers invoices.
Definition: list.php:156
dol_now($mode='gmt')
Return date for now.
Class ProductCombination Used to represent a product combination.
if($_POST["cancel"]==$langs->trans("Cancel") &&! $id) if($action=='add' && $_POST["cancel"]<> $langs->trans("Cancel")) if($action=='delete') if($id) $form
Actions.
Definition: card.php:153
Class to offer components to list and upload files.
propal_prepare_head($object)
Prepare array with list of tabs.
Definition: propal.lib.php:32
const STATUS_DRAFT
Draft status.
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='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
static liste_modeles($db, $maxfilenamelength=0)
Return list of active generation modules.
dol_htmlcleanlastbr($stringtodecode)
This function remove all ending and br at end.
restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0)
Check permissions of a user to show a page and an object.
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) Si ...
showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round=-1, $forceunitoutput='no')
Output a dimension with best unit.
Class to manage a WYSIWYG editor.
const STATUS_VALIDATED
Validated status.
fieldLabel($langkey, $fieldkey, $fieldrequired=0)
Show a string with the label tag dedicated to the HTML edit field.
price2num($amount, $rounding='', $alreadysqlnb=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='')
Show tab header of a card.
Class to manage proposals.
$parameters
Actions.
Definition: card.php:114
static getIdAndTxFromCode(&$db, $code, $date_document='')
Get id and rate of currency from code.