dolibarr  20.0.0-beta
card.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2019 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2014 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
6  * Copyright (C) 2010-2017 Juanjo Menent <jmenent@2byte.es>
7  * Copyright (C) 2013 Christophe Battarel <christophe.battarel@altairis.fr>
8  * Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
9  * Copyright (C) 2014-2020 Ferran Marcet <fmarcet@2byte.es>
10  * Copyright (C) 2014-2016 Marcos García <marcosgdf@gmail.com>
11  * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
12  * Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
13  * Copyright (C) 2023 Charlene Benke <charlene@patas-monkey.com>
14  * Copyright (C) 2023 Nick Fragoulis
15  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 3 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program. If not, see <https://www.gnu.org/licenses/>.
29  */
30 
37 require "../main.inc.php";
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php';
41 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
42 require_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php';
43 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
44 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
45 require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
46 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
47 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
48 if (isModEnabled("propal")) {
49  require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
50 }
51 if (isModEnabled('project')) {
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 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
56 
57 // Load translation files required by the page
58 $langs->loadLangs(array("contracts", "orders", "companies", "bills", "products", 'compta'));
59 
60 $action = GETPOST('action', 'aZ09');
61 $confirm = GETPOST('confirm', 'alpha');
62 $cancel = GETPOST('cancel', 'alpha');
63 $backtopage = GETPOST('backtopage', 'alpha');
64 
65 $socid = GETPOSTINT('socid');
66 $id = GETPOSTINT('id');
67 $ref = GETPOST('ref', 'alpha');
68 $origin = GETPOST('origin', 'alpha');
69 $originid = GETPOSTINT('originid');
70 
71 // PDF
72 $hidedetails = (GETPOSTINT('hidedetails') ? GETPOSTINT('hidedetails') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS') ? 1 : 0));
73 $hidedesc = (GETPOSTINT('hidedesc') ? GETPOSTINT('hidedesc') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_DESC') ? 1 : 0));
74 $hideref = (GETPOSTINT('hideref') ? GETPOSTINT('hideref') : (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_HIDE_REF') ? 1 : 0));
75 
76 
77 $datecontrat = '';
78 $usehm = (getDolGlobalString('MAIN_USE_HOURMIN_IN_DATE_RANGE') ? $conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE : 0);
79 
80 // Security check
81 if ($user->socid) {
82  $socid = $user->socid;
83 }
84 
85 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
86 $hookmanager->initHooks(array('contractcard', 'globalcard'));
87 
88 $object = new Contrat($db);
89 $extrafields = new ExtraFields($db);
90 
91 // Load object
92 if ($id > 0 || !empty($ref) && $action != 'add') {
93  $ret = $object->fetch($id, $ref);
94  if ($ret > 0) {
95  $ret = $object->fetch_thirdparty();
96  }
97  if ($ret < 0) {
98  dol_print_error(null, $object->error);
99  }
100 }
101 
102 // fetch optionals attributes and labels
103 $extrafields->fetch_name_optionals_label($object->table_element);
104 
105 // fetch optionals attributes lines and labels
106 $extralabelslines = $extrafields->fetch_name_optionals_label($object->table_element_line);
107 
108 $permissionnote = $user->hasRight('contrat', 'creer'); // Used by the include of actions_setnotes.inc.php
109 $permissiondellink = $user->hasRight('contrat', 'creer'); // Used by the include of actions_dellink.inc.php
110 $permissiontodelete = ($user->hasRight('contrat', 'creer') && $object->statut == $object::STATUS_DRAFT) || $user->hasRight('contrat', 'supprimer');
111 $permissiontoadd = $user->hasRight('contrat', 'creer'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
112 $permissiontoedit = $permissiontoadd;
113 $permissiontoactivate = $user->hasRight('contrat', 'activer');
114 $error = 0;
115 
116 $result = restrictedArea($user, 'contrat', $object->id);
117 
118 
119 /*
120  * Actions
121  */
122 
123 $parameters = array('socid' => $socid);
124 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
125 if ($reshook < 0) {
126  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
127 }
128 if (empty($reshook)) {
129  $backurlforlist = DOL_URL_ROOT.'/contrat/list.php';
130 
131  if (empty($backtopage) || ($cancel && empty($id))) {
132  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
133  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
134  $backtopage = $backurlforlist;
135  } else {
136  $backtopage = DOL_URL_ROOT.'/contrat/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
137  }
138  }
139  }
140 
141  if ($cancel) {
142  if (!empty($backtopageforcancel)) {
143  header("Location: ".$backtopageforcancel);
144  exit;
145  } elseif (!empty($backtopage)) {
146  header("Location: ".$backtopage);
147  exit;
148  }
149  $action = '';
150  }
151 
152  include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once
153 
154  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
155 
156  include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once
157 
158  if ($action == 'confirm_active' && $confirm == 'yes' && $permissiontoactivate) {
159  $date_start = '';
160  $date_end = '';
161  if (GETPOST('startmonth') && GETPOST('startday') && GETPOST('startyear')) {
162  $date_start = dol_mktime(GETPOST('starthour'), GETPOST('startmin'), 0, GETPOST('startmonth'), GETPOST('startday'), GETPOST('startyear'));
163  }
164  if (GETPOST('endmonth') && GETPOST('endday') && GETPOST('endyear')) {
165  $date_end = dol_mktime(GETPOST('endhour'), GETPOST('endmin'), 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
166  }
167 
168  $result = $object->active_line($user, GETPOSTINT('ligne'), $date_start, $date_end, GETPOST('comment'));
169 
170  if ($result > 0) {
171  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
172  exit;
173  } else {
174  setEventMessages($object->error, $object->errors, 'errors');
175  }
176  } elseif ($action == 'confirm_closeline' && $confirm == 'yes' && $permissiontoactivate) {
177  $date_end = '';
178  if (GETPOST('endmonth') && GETPOST('endday') && GETPOST('endyear')) {
179  $date_end = dol_mktime(GETPOST('endhour'), GETPOST('endmin'), 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
180  }
181  if (!$date_end) {
182  $error++;
183  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), null, 'errors');
184  }
185  if (!$error) {
186  $result = $object->close_line($user, GETPOSTINT('ligne'), $date_end, urldecode(GETPOST('comment')));
187  if ($result > 0) {
188  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
189  exit;
190  } else {
191  setEventMessages($object->error, $object->errors, 'errors');
192  }
193  }
194  }
195 
196  if (GETPOST('mode') == 'predefined') {
197  $date_start = '';
198  $date_end = '';
199  if (GETPOST('date_startmonth') && GETPOST('date_startday') && GETPOST('date_startyear')) {
200  $date_start = dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear'));
201  }
202  if (GETPOST('date_endmonth') && GETPOST('date_endday') && GETPOST('date_endyear')) {
203  $date_end = dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear'));
204  }
205  }
206 
207  // Param dates
208  $date_start_update = '';
209  $date_end_update = '';
210  $date_start_real_update = '';
211  $date_end_real_update = '';
212  if (GETPOST('date_start_updatemonth') && GETPOST('date_start_updateday') && GETPOST('date_start_updateyear')) {
213  $date_start_update = dol_mktime(GETPOST('date_start_updatehour'), GETPOST('date_start_updatemin'), 0, GETPOST('date_start_updatemonth'), GETPOST('date_start_updateday'), GETPOST('date_start_updateyear'));
214  }
215  if (GETPOST('date_end_updatemonth') && GETPOST('date_end_updateday') && GETPOST('date_end_updateyear')) {
216  $date_end_update = dol_mktime(GETPOST('date_end_updatehour'), GETPOST('date_end_updatemin'), 0, GETPOST('date_end_updatemonth'), GETPOST('date_end_updateday'), GETPOST('date_end_updateyear'));
217  }
218  if (GETPOST('date_start_real_updatemonth') && GETPOST('date_start_real_updateday') && GETPOST('date_start_real_updateyear')) {
219  $date_start_real_update = dol_mktime(GETPOST('date_start_real_updatehour'), GETPOST('date_start_real_updatemin'), 0, GETPOST('date_start_real_updatemonth'), GETPOST('date_start_real_updateday'), GETPOST('date_start_real_updateyear'));
220  }
221  if (GETPOST('date_end_real_updatemonth') && GETPOST('date_end_real_updateday') && GETPOST('date_end_real_updateyear')) {
222  $date_end_real_update = dol_mktime(GETPOST('date_end_real_updatehour'), GETPOST('date_end_real_updatemin'), 0, GETPOST('date_end_real_updatemonth'), GETPOST('date_end_real_updateday'), GETPOST('date_end_real_updateyear'));
223  }
224  if (GETPOST('remonth') && GETPOST('reday') && GETPOST('reyear')) {
225  $datecontrat = dol_mktime(GETPOST('rehour'), GETPOST('remin'), 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
226  }
227 
228  // Add contract
229  if ($action == 'add' && $user->hasRight('contrat', 'creer')) {
230  // Check
231  if (empty($datecontrat)) {
232  $error++;
233  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
234  $action = 'create';
235  }
236 
237  if ($socid < 1) {
238  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ThirdParty")), null, 'errors');
239  $action = 'create';
240  $error++;
241  }
242 
243  // Fill array 'array_options' with data from add form
244  $ret = $extrafields->setOptionalsFromPost(null, $object);
245  if ($ret < 0) {
246  $error++;
247  $action = 'create';
248  }
249 
250  if (!$error) {
251  $object->socid = $socid;
252  $object->date_contrat = $datecontrat;
253 
254  $object->commercial_suivi_id = GETPOSTINT('commercial_suivi_id');
255  $object->commercial_signature_id = GETPOSTINT('commercial_signature_id');
256 
257  $object->note_private = GETPOST('note_private', 'alpha');
258  $object->note_public = GETPOST('note_public', 'alpha');
259  $object->fk_project = GETPOSTINT('projectid');
260  $object->remise_percent = price2num(GETPOST('remise_percent'), '', 2);
261  $object->ref = GETPOST('ref', 'alpha');
262  $object->ref_customer = GETPOST('ref_customer', 'alpha');
263  $object->ref_supplier = GETPOST('ref_supplier', 'alpha');
264 
265  // If creation from another object of another module (Example: origin=propal, originid=1)
266  if (!empty($origin) && !empty($originid)) {
267  // Parse element/subelement (ex: project_task)
268  $element = $subelement = $origin;
269  if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) {
270  $element = $regs[1];
271  $subelement = $regs[2];
272  }
273 
274  // For compatibility
275  if ($element == 'order') {
276  $element = $subelement = 'commande';
277  }
278  if ($element == 'propal') {
279  $element = 'comm/propal';
280  $subelement = 'propal';
281  }
282  if ($element == 'invoice' || $element == 'facture') {
283  $element = 'compta/facture';
284  $subelement = 'facture';
285  }
286 
287  $object->origin = $origin;
288  $object->origin_id = $originid;
289 
290  // Possibility to add external linked objects with hooks
291  $object->linked_objects[$object->origin] = $object->origin_id;
292  if (GETPOSTISARRAY('other_linked_objects')) {
293  $object->linked_objects = array_merge($object->linked_objects, GETPOST('other_linked_objects', 'array:int'));
294  }
295 
296  $id = $object->create($user);
297  if ($id > 0) {
298  dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
299 
300  $classname = ucfirst($subelement);
301  $srcobject = new $classname($db);
302 
303  dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines");
304  $result = $srcobject->fetch($object->origin_id);
305  if ($result > 0) {
306  $srcobject->fetch_thirdparty();
307  $lines = $srcobject->lines;
308  if (empty($lines) && method_exists($srcobject, 'fetch_lines')) {
309  $srcobject->fetch_lines();
310  $lines = $srcobject->lines;
311  }
312 
313  $fk_parent_line = 0;
314  $num = count($lines);
315 
316  for ($i = 0; $i < $num; $i++) {
317  $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0);
318 
319  if ($product_type == 1 || (getDolGlobalString('CONTRACT_SUPPORT_PRODUCTS') && in_array($product_type, array(0, 1)))) { // TODO Exclude also deee
320  // service prédéfini
321  if ($lines[$i]->fk_product > 0) {
322  $product_static = new Product($db);
323 
324  // Define output language
325  if (getDolGlobalInt('MAIN_MULTILANGS') && getDolGlobalString('PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE')) {
326  $prod = new Product($db);
327  $prod->id = $lines[$i]->fk_product;
328  $prod->getMultiLangs();
329 
330  $outputlangs = $langs;
331  $newlang = '';
332  if (empty($newlang) && GETPOST('lang_id', 'aZ09')) {
333  $newlang = GETPOST('lang_id', 'aZ09');
334  }
335  if (empty($newlang)) {
336  $newlang = $srcobject->thirdparty->default_lang;
337  }
338  if (!empty($newlang)) {
339  $outputlangs = new Translate("", $conf);
340  $outputlangs->setDefaultLang($newlang);
341  }
342 
343  $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label;
344  } else {
345  $label = $lines[$i]->product_label;
346  }
347  $desc = ($lines[$i]->desc && $lines[$i]->desc != $lines[$i]->label) ? dol_htmlentitiesbr($lines[$i]->desc) : '';
348  } else {
349  $desc = dol_htmlentitiesbr($lines[$i]->desc);
350  }
351 
352  // Extrafields
353  $array_options = array();
354  // For avoid conflicts if trigger used
355  if (method_exists($lines[$i], 'fetch_optionals')) {
356  $lines[$i]->fetch_optionals();
357  $array_options = $lines[$i]->array_options;
358  }
359 
360  $txtva = $lines[$i]->vat_src_code ? $lines[$i]->tva_tx.' ('.$lines[$i]->vat_src_code.')' : $lines[$i]->tva_tx;
361 
362  // View third's localtaxes for now
363  $localtax1_tx = get_localtax($txtva, 1, $object->thirdparty);
364  $localtax2_tx = get_localtax($txtva, 2, $object->thirdparty);
365 
366  $result = $object->addline(
367  $desc,
368  $lines[$i]->subprice,
369  $lines[$i]->qty,
370  $txtva,
371  $localtax1_tx,
372  $localtax2_tx,
373  $lines[$i]->fk_product,
374  $lines[$i]->remise_percent,
375  $lines[$i]->date_start,
376  $lines[$i]->date_end,
377  'HT',
378  0,
379  $lines[$i]->info_bits,
380  $lines[$i]->fk_fournprice,
381  $lines[$i]->pa_ht,
382  $array_options,
383  $lines[$i]->fk_unit,
384  $num + 1
385  );
386 
387  if ($result < 0) {
388  $error++;
389  break;
390  }
391  }
392  }
393  } else {
394  setEventMessages($srcobject->error, $srcobject->errors, 'errors');
395  $error++;
396  }
397 
398  // Hooks
399  $parameters = array('objFrom' => $srcobject);
400  $reshook = $hookmanager->executeHooks('createFrom', $parameters, $object, $action); // Note that $action and $object may have been
401  // modified by hook
402  if ($reshook < 0) {
403  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
404  $error++;
405  }
406  } else {
407  setEventMessages($object->error, $object->errors, 'errors');
408  $error++;
409  }
410  if ($error) {
411  $action = 'create';
412  }
413  } else {
414  $result = $object->create($user);
415  if ($result > 0) {
416  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
417  exit;
418  } else {
419  setEventMessages($object->error, $object->errors, 'errors');
420  }
421  $action = 'create';
422  }
423  }
424  } elseif ($action == 'classin' && $user->hasRight('contrat', 'creer')) {
425  $object->setProject(GETPOST('projectid'));
426  } elseif ($action == 'addline' && $user->hasRight('contrat', 'creer')) {
427  // Add a new line
428  // Set if we used free entry or predefined product
429  $predef = '';
430  $product_desc = (GETPOSTISSET('dp_desc') ? GETPOST('dp_desc', 'restricthtml') : '');
431 
432  $price_ht = '';
433  $price_ht_devise = '';
434  $price_ttc = '';
435  $price_ttc_devise = '';
436 
437  $rang = count($object->lines) + 1;
438 
439  if (GETPOST('price_ht') !== '') {
440  $price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
441  }
442  if (GETPOST('multicurrency_price_ht') !== '') {
443  $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2);
444  }
445  if (GETPOST('price_ttc') !== '') {
446  $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2);
447  }
448  if (GETPOST('multicurrency_price_ttc') !== '') {
449  $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2);
450  }
451 
452  if (GETPOST('prod_entry_mode', 'alpha') == 'free') {
453  $idprod = 0;
454  } else {
455  $idprod = GETPOSTINT('idprod');
456 
457  if (getDolGlobalString('MAIN_DISABLE_FREE_LINES') && $idprod <= 0) {
458  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ProductOrService")), null, 'errors');
459  $error++;
460  }
461  }
462 
463  $tva_tx = GETPOST('tva_tx', 'alpha');
464 
465  $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS');
466  $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef), '', 2) : 0);
467  if (empty($remise_percent)) {
468  $remise_percent = 0;
469  }
470 
471  if ($qty == '') {
472  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")), null, 'errors');
473  $error++;
474  }
475  if (GETPOST('prod_entry_mode', 'alpha') == 'free' && (empty($idprod) || $idprod < 0) && empty($product_desc)) {
476  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")), null, 'errors');
477  $error++;
478  }
479 
480  $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'));
481  $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'));
482  if (!empty($date_start) && !empty($date_end) && $date_start > $date_end) {
483  setEventMessages($langs->trans("Error").': '.$langs->trans("DateStartPlanned").' > '.$langs->trans("DateEndPlanned"), null, 'errors');
484  $error++;
485  }
486 
487  // Extrafields
488  $extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
489  $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
490  // Unset extrafield
491  if (is_array($extralabelsline)) {
492  // Get extra fields
493  foreach ($extralabelsline as $key => $value) {
494  unset($_POST["options_".$key]);
495  }
496  }
497 
498  if (!$error) {
499  // Clean parameters
500  $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'));
501  $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'));
502 
503  // Ecrase $tva_tx par celui du produit. TODO Remove this once vat selection is open
504  // Get and check minimum price
505  if ($idprod > 0) {
506  $prod = new Product($db);
507  $prod->fetch($idprod);
508 
509  // Update if prices fields are defined
510  /*$tva_tx = get_default_tva($mysoc, $object->thirdparty, $prod->id);
511  $tva_npr = get_default_npr($mysoc, $object->thirdparty, $prod->id);
512  if (empty($tva_tx)) {
513  }*/
514  $tva_npr = 0;
515 
516  $price_min = $prod->price_min;
517  $price_min_ttc = $prod->price_min_ttc;
518 
519  // On defini prix unitaire
520  if (getDolGlobalString('PRODUIT_MULTIPRICES') && $object->thirdparty->price_level) {
521  $price_min = $prod->multiprices_min[$object->thirdparty->price_level];
522  $price_min_ttc = $prod->multiprices_min_ttc[$object->thirdparty->price_level];
523  } elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES')) {
524  // If price per customer
525  require_once DOL_DOCUMENT_ROOT.'/product/class/productcustomerprice.class.php';
526 
527  $prodcustprice = new ProductCustomerPrice($db);
528 
529  $filter = array('t.fk_product' => $prod->id, 't.fk_soc' => $object->thirdparty->id);
530 
531  $result = $prodcustprice->fetchAll('', '', 0, 0, $filter);
532  if ($result) {
533  if (count($prodcustprice->lines) > 0) {
534  $price_min = price($prodcustprice->lines[0]->price_min);
535  $price_min_ttc = price($prodcustprice->lines[0]->price_min_ttc);
536  /*$tva_tx = $prodcustprice->lines[0]->tva_tx;
537  if ($prodcustprice->lines[0]->default_vat_code && !preg_match('/\‍(.*\‍)/', $tva_tx)) {
538  $tva_tx .= ' ('.$prodcustprice->lines[0]->default_vat_code.')';
539  }
540  $tva_npr = $prodcustprice->lines[0]->recuperableonly;
541  if (empty($tva_tx)) {
542  $tva_npr = 0;
543  }*/
544  }
545  }
546  }
547 
548  $tmpvat = price2num(preg_replace('/\s*\‍(.*\‍)/', '', $tva_tx));
549  $tmpprodvat = price2num(preg_replace('/\s*\‍(.*\‍)/', '', (string) $prod->tva_tx));
550 
551  // Set unit price to use
552  if (!empty($price_ht) || $price_ht === '0') {
553  $pu_ht = price2num($price_ht, 'MU');
554  $pu_ttc = price2num((float) $pu_ht * (1 + ((float) $tmpvat / 100)), 'MU');
555  $price_base_type = 'HT';
556  } elseif (!empty($price_ttc) || $price_ttc === '0') {
557  $pu_ttc = price2num($price_ttc, 'MU');
558  $pu_ht = price2num((float) $pu_ttc / (1 + ((float) $tmpvat / 100)), 'MU');
559  $price_base_type = 'TTC';
560  }
561 
562  $desc = $prod->description;
563 
564  //If text set in desc is the same as product descpription (as now it's preloaded) we add it only one time
565  if ($product_desc == $desc && getDolGlobalString('PRODUIT_AUTOFILL_DESC')) {
566  $product_desc = '';
567  }
568 
569  if (!empty($product_desc) && getDolGlobalString('MAIN_NO_CONCAT_DESCRIPTION')) {
570  $desc = $product_desc;
571  } else {
572  $desc = dol_concatdesc($desc, $product_desc, '', getDolGlobalString('MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION'));
573  }
574 
575  $fk_unit = $prod->fk_unit;
576  } else {
577  $pu_ht = price2num($price_ht, 'MU');
578  $pu_ttc = price2num($price_ttc, 'MU');
579  $tva_npr = (preg_match('/\*/', $tva_tx) ? 1 : 0);
580  if (empty($tva_tx)) {
581  $tva_npr = 0;
582  }
583  $tva_tx = str_replace('*', '', $tva_tx);
584  $desc = $product_desc;
585  $fk_unit = GETPOST('units', 'alpha');
586  $pu_ht_devise = price2num($price_ht_devise, 'MU');
587  $pu_ttc_devise = price2num($price_ttc_devise, 'MU');
588 
589  $tmpvat = price2num(preg_replace('/\s*\‍(.*\‍)/', '', $tva_tx));
590 
591  // Set unit price to use
592  if (!empty($price_ht) || $price_ht === '0') {
593  $pu_ht = price2num($price_ht, 'MU');
594  $pu_ttc = price2num((float) $pu_ht * (1 + ((float) $tmpvat / 100)), 'MU');
595  $price_base_type = 'HT';
596  } elseif (!empty($price_ttc) || $price_ttc === '0') {
597  $pu_ttc = price2num($price_ttc, 'MU');
598  $pu_ht = price2num((float) $pu_ttc / (1 + ((float) $tmpvat / 100)), 'MU');
599  $price_base_type = 'TTC';
600  }
601  }
602 
603  $localtax1_tx = get_localtax($tva_tx, 1, $object->thirdparty, $mysoc, $tva_npr);
604  $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr);
605 
606  // ajout prix achat
607  $fk_fournprice = GETPOST('fournprice');
608  if (GETPOST('buying_price')) {
609  $pa_ht = GETPOST('buying_price');
610  } else {
611  $pa_ht = null;
612  }
613 
614  $info_bits = 0;
615  if ($tva_npr) {
616  $info_bits |= 0x01;
617  }
618 
619  if (((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('produit', 'ignore_price_min_advance'))
620  || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS')) && ($price_min && ((float) price2num($pu_ht) * (1 - (float) price2num($remise_percent) / 100) < (float) price2num($price_min)))) {
621  $object->error = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
622  $result = -1;
623  } else {
624  // Insert line
625  $result = $object->addline(
626  $desc,
627  $pu_ht,
628  $qty,
629  $tva_tx,
630  $localtax1_tx,
631  $localtax2_tx,
632  $idprod,
633  $remise_percent,
634  $date_start,
635  $date_end,
636  $price_base_type,
637  $pu_ttc,
638  $info_bits,
639  $fk_fournprice,
640  $pa_ht,
641  $array_options,
642  $fk_unit,
643  $rang
644  );
645  }
646 
647  if ($result > 0) {
648  // Define output language
649  if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE') && getDolGlobalString('CONTRACT_ADDON_PDF')) { // No generation if default type not defined
650  $outputlangs = $langs;
651  $newlang = '';
652  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
653  $newlang = GETPOST('lang_id', 'aZ09');
654  }
655  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
656  $newlang = $object->thirdparty->default_lang;
657  }
658  if (!empty($newlang)) {
659  $outputlangs = new Translate("", $conf);
660  $outputlangs->setDefaultLang($newlang);
661  }
662 
663  $ret = $object->fetch($id); // Reload to get new records
664 
665  $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
666  }
667 
668  unset($_POST['prod_entry_mode']);
669 
670  unset($_POST['qty']);
671  unset($_POST['type']);
672  unset($_POST['remise_percent']);
673  unset($_POST['price_ht']);
674  unset($_POST['multicurrency_price_ht']);
675  unset($_POST['price_ttc']);
676  unset($_POST['tva_tx']);
677  unset($_POST['product_ref']);
678  unset($_POST['product_label']);
679  unset($_POST['product_desc']);
680  unset($_POST['fournprice']);
681  unset($_POST['buying_price']);
682  unset($_POST['np_marginRate']);
683  unset($_POST['np_markRate']);
684  unset($_POST['dp_desc']);
685  unset($_POST['idprod']);
686 
687  unset($_POST['date_starthour']);
688  unset($_POST['date_startmin']);
689  unset($_POST['date_startsec']);
690  unset($_POST['date_startday']);
691  unset($_POST['date_startmonth']);
692  unset($_POST['date_startyear']);
693  unset($_POST['date_endhour']);
694  unset($_POST['date_endmin']);
695  unset($_POST['date_endsec']);
696  unset($_POST['date_endday']);
697  unset($_POST['date_endmonth']);
698  unset($_POST['date_endyear']);
699  } else {
700  setEventMessages($object->error, $object->errors, 'errors');
701  }
702  }
703  } elseif ($action == 'updateline' && $user->hasRight('contrat', 'creer') && !GETPOST('cancel', 'alpha')) {
704  $error = 0;
705  $predef = '';
706 
707  if (!empty($date_start_update) && !empty($date_end_update) && $date_start_update > $date_end_update) {
708  setEventMessages($langs->trans("Error").': '.$langs->trans("DateStartPlanned").' > '.$langs->trans("DateEndPlanned"), null, 'errors');
709  $action = 'editline';
710  $_GET['rowid'] = GETPOST('elrowid'); // Keep $_GET here. Used by GETPOST('rowid') later
711  $error++;
712  }
713 
714  if (!$error) {
715  $objectline = new ContratLigne($db);
716  if ($objectline->fetch(GETPOSTINT('elrowid')) < 0) {
717  setEventMessages($objectline->error, $objectline->errors, 'errors');
718  $error++;
719  }
720  $objectline->fetch_optionals();
721 
722  $objectline->oldcopy = dol_clone($objectline, 2);
723  }
724 
725  $db->begin();
726 
727  if (!$error) {
728  if ($date_start_real_update == '') {
729  $date_start_real_update = $objectline->date_start_real;
730  }
731  if ($date_end_real_update == '') {
732  $date_end_real_update = $objectline->date_end_real;
733  }
734 
735  $vat_rate = GETPOST('eltva_tx', 'alpha');
736  // Define info_bits
737  $info_bits = 0;
738  if (preg_match('/\*/', $vat_rate)) {
739  $info_bits |= 0x01;
740  }
741 
742  // Define vat_rate
743  $vat_rate = str_replace('*', '', $vat_rate);
744  $localtax1_tx = get_localtax($vat_rate, 1, $object->thirdparty, $mysoc);
745  $localtax2_tx = get_localtax($vat_rate, 2, $object->thirdparty, $mysoc);
746 
747  $txtva = $vat_rate;
748 
749  // Clean vat code
750  $reg = array();
751  $vat_src_code = '';
752  if (preg_match('/\‍((.*)\‍)/', $txtva, $reg)) {
753  $vat_src_code = $reg[1];
754  $txtva = preg_replace('/\s*\‍(.*\‍)/', '', $txtva); // Remove code into vatrate.
755  }
756 
757  // ajout prix d'achat
758  if (GETPOST('buying_price')) {
759  $pa_ht = price2num(GETPOST('buying_price'), '', 2);
760  } else {
761  $pa_ht = null;
762  }
763 
764  $fk_unit = GETPOST('unit', 'alpha');
765 
766  // update price_ht with discount
767  // TODO Use object->updateline instead objectline->update
768 
769  $price_ht = price2num(GETPOST('elprice'), 'MU');
770  $remise_percent = price2num(GETPOST('elremise_percent'), '', 2);
771  if ($remise_percent > 0) {
772  $remise = round(((float) $price_ht * (float) $remise_percent / 100), 2);
773  }
774 
775  $objectline->fk_product = GETPOSTINT('idprod');
776  $objectline->description = GETPOST('product_desc', 'restricthtml');
777  $objectline->price_ht = $price_ht;
778  $objectline->subprice = price2num(GETPOST('elprice'), 'MU');
779  $objectline->qty = price2num(GETPOST('elqty'), 'MS');
780  $objectline->remise_percent = $remise_percent;
781  $objectline->tva_tx = ($txtva ? $txtva : 0); // Field may be disabled, so we use vat rate 0
782  $objectline->vat_src_code = $vat_src_code;
783  $objectline->localtax1_tx = is_numeric($localtax1_tx) ? $localtax1_tx : 0;
784  $objectline->localtax2_tx = is_numeric($localtax2_tx) ? $localtax2_tx : 0;
785  $objectline->date_start = $date_start_update;
786  $objectline->date_start_real = $date_start_real_update;
787  $objectline->date_end = $date_end_update;
788  $objectline->date_end_real = $date_end_real_update;
789  $objectline->user_closing_id = $user->id;
790  //$objectline->fk_fournprice = $fk_fournprice;
791  $objectline->pa_ht = $pa_ht;
792  // $objectline->rang = $objectline->rang;
793 
794  if ($fk_unit > 0) {
795  $objectline->fk_unit = GETPOST('unit');
796  } else {
797  $objectline->fk_unit = null;
798  }
799 
800  // Extrafields
801  $extralabelsline = $extrafields->fetch_name_optionals_label($objectline->table_element);
802  $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
803 
804  if (is_array($array_options) && count($array_options) > 0) {
805  // We replace values in this->line->array_options only for entries defined into $array_options
806  foreach ($array_options as $key => $value) {
807  $objectline->array_options[$key] = $array_options[$key];
808  }
809  }
810 
811  // TODO verifier price_min si fk_product et multiprix
812 
813  $result = $objectline->update($user);
814  if ($result < 0) {
815  $error++;
816  setEventMessages($objectline->error, $objectline->errors, 'errors');
817  }
818  }
819 
820  if (!$error) {
821  $db->commit();
822  } else {
823  $db->rollback();
824  }
825  } elseif ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
826  $result = $object->deleteLine(GETPOSTINT('lineid'), $user);
827 
828  if ($result >= 0) {
829  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
830  exit;
831  } else {
832  setEventMessages($object->error, $object->errors, 'errors');
833  }
834  } elseif ($action == 'confirm_valid' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
835  $result = $object->validate($user);
836 
837  if ($result > 0) {
838  // Define output language
839  if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
840  $outputlangs = $langs;
841  $newlang = '';
842  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
843  $newlang = GETPOST('lang_id', 'aZ09');
844  }
845  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
846  $newlang = $object->thirdparty->default_lang;
847  }
848  if (!empty($newlang)) {
849  $outputlangs = new Translate("", $conf);
850  $outputlangs->setDefaultLang($newlang);
851  }
852  $model = $object->model_pdf;
853  $ret = $object->fetch($id); // Reload to get new records
854 
855  $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
856  }
857  } else {
858  setEventMessages($object->error, $object->errors, 'errors');
859  }
860  } elseif ($action == 'reopen' && $user->hasRight('contrat', 'creer')) {
861  $result = $object->reopen($user);
862  if ($result < 0) {
863  setEventMessages($object->error, $object->errors, 'errors');
864  }
865  } elseif ($action == 'confirm_close' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
866  // Close all lines
867  $result = $object->closeAll($user);
868  if ($result < 0) {
869  setEventMessages($object->error, $object->errors, 'errors');
870  }
871  } elseif ($action == 'confirm_activate' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
872  $date_start = dol_mktime(12, 0, 0, GETPOST('d_startmonth'), GETPOST('d_startday'), GETPOST('d_startyear'));
873  $date_end = dol_mktime(12, 0, 0, GETPOST('d_endmonth'), GETPOST('d_endday'), GETPOST('d_endyear'));
874  $comment = GETPOST('comment', 'alpha');
875  $result = $object->activateAll($user, $date_start, 0, $comment, $date_end);
876  if ($result < 0) {
877  setEventMessages($object->error, $object->errors, 'errors');
878  }
879  } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $user->hasRight('contrat', 'supprimer')) {
880  $result = $object->delete($user);
881  if ($result >= 0) {
882  header("Location: list.php?restore_lastsearch_values=1");
883  return;
884  } else {
885  setEventMessages($object->error, $object->errors, 'errors');
886  }
887  } elseif ($action == 'confirm_move' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
888  if (GETPOST('newcid') > 0) {
889  $contractline = new ContratLigne($db);
890  $result = $contractline->fetch(GETPOSTINT('lineid'));
891  $contractline->fk_contrat = GETPOSTINT('newcid');
892  $result = $contractline->update($user, 1);
893  if ($result >= 0) {
894  header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
895  return;
896  } else {
897  setEventMessages($object->error, $object->errors, 'errors');
898  }
899  } else {
900  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("RefNewContract")), null, 'errors');
901  }
902  } elseif ($action == 'update_extras' && $permissiontoadd) {
903  $object->oldcopy = dol_clone($object, 2);
904 
905  $attribute = GETPOST('attribute', 'alphanohtml');
906 
907  // Fill array 'array_options' with data from update form
908  $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute);
909  if ($ret < 0) {
910  setEventMessages($extrafields->error, $object->errors, 'errors');
911  $error++;
912  }
913 
914  if (!$error) {
915  $result = $object->updateExtraField($attribute, 'CONTRACT_MODIFY');
916  if ($result < 0) {
917  setEventMessages($object->error, $object->errors, 'errors');
918  $error++;
919  }
920  }
921 
922  if ($error) {
923  $action = 'edit_extras';
924  }
925  } elseif ($action == 'setref_supplier' && $permissiontoadd) {
926  if (!$cancel) {
927  $object->oldcopy = dol_clone($object, 2);
928 
929  $result = $object->setValueFrom('ref_supplier', GETPOST('ref_supplier', 'alpha'), '', null, 'text', '', $user, 'CONTRACT_MODIFY');
930  if ($result < 0) {
931  setEventMessages($object->error, $object->errors, 'errors');
932  $action = 'editref_supplier';
933  } else {
934  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
935  exit;
936  }
937  } else {
938  header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
939  exit;
940  }
941  } elseif ($action == 'setref_customer' && $permissiontoadd) {
942  if (!$cancel) {
943  $object->oldcopy = dol_clone($object, 2);
944 
945  $result = $object->setValueFrom('ref_customer', GETPOST('ref_customer', 'alpha'), '', null, 'text', '', $user, 'CONTRACT_MODIFY');
946  if ($result < 0) {
947  setEventMessages($object->error, $object->errors, 'errors');
948  $action = 'editref_customer';
949  } else {
950  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
951  exit;
952  }
953  } else {
954  header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
955  exit;
956  }
957  } elseif ($action == 'setref' && $permissiontoadd) {
958  if (!$cancel) {
959  $result = $object->fetch($id);
960  if ($result < 0) {
961  setEventMessages($object->error, $object->errors, 'errors');
962  }
963 
964  $old_ref = $object->ref;
965 
966  $result = $object->setValueFrom('ref', GETPOST('ref', 'alpha'), '', null, 'text', '', $user, 'CONTRACT_MODIFY');
967  if ($result < 0) {
968  setEventMessages($object->error, $object->errors, 'errors');
969  $action = 'editref';
970  } else {
971  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
972  $old_filedir = $conf->contrat->multidir_output[$object->entity].'/'.dol_sanitizeFileName($old_ref);
973  $new_filedir = $conf->contrat->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
974 
975  // Rename directory of contract with new name
976  dol_move_dir($old_filedir, $new_filedir);
977 
978  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
979  exit;
980  }
981  } else {
982  header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
983  exit;
984  }
985  } elseif ($action == 'setdate_contrat' && $permissiontoadd) {
986  if (!$cancel) {
987  $result = $object->fetch($id);
988  if ($result < 0) {
989  setEventMessages($object->error, $object->errors, 'errors');
990  }
991  $datacontrat = dol_mktime(GETPOST('date_contrathour'), GETPOST('date_contratmin'), 0, GETPOST('date_contratmonth'), GETPOST('date_contratday'), GETPOST('date_contratyear'));
992  $result = $object->setValueFrom('date_contrat', $datacontrat, '', null, 'date', '', $user, 'CONTRACT_MODIFY');
993  if ($result < 0) {
994  setEventMessages($object->error, $object->errors, 'errors');
995  $action = 'editdate_contrat';
996  } else {
997  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
998  exit;
999  }
1000  } else {
1001  header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
1002  exit;
1003  }
1004  }
1005 
1006  // Actions when printing a doc from card
1007  include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
1008 
1009  // Actions to build doc
1010  $upload_dir = $conf->contrat->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity];
1011  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1012 
1013  // Actions to send emails
1014  $triggersendname = 'CONTRACT_SENTBYMAIL';
1015  $paramname = 'id';
1016  $mode = 'emailfromcontract';
1017  $trackid = 'con'.$object->id;
1018  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1019 
1020 
1021  if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB') && $user->hasRight('contrat', 'creer')) {
1022  if ($action == 'addcontact') {
1023  $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
1024  $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
1025  $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
1026 
1027  if ($result >= 0) {
1028  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1029  exit;
1030  } else {
1031  if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1032  $langs->load("errors");
1033  setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
1034  } else {
1035  setEventMessages($object->error, $object->errors, 'errors');
1036  }
1037  }
1038  } elseif ($action == 'swapstatut') {
1039  // bascule du statut d'un contact
1040  $result = $object->swapContactStatus(GETPOSTINT('ligne'));
1041  } elseif ($action == 'deletecontact') {
1042  // Efface un contact
1043  $result = $object->delete_contact(GETPOSTINT('lineid'));
1044 
1045  if ($result >= 0) {
1046  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1047  exit;
1048  } else {
1049  setEventMessages($object->error, $object->errors, 'errors');
1050  }
1051  }
1052  }
1053 
1054  // Action clone object
1055  if ($action == 'confirm_clone' && $confirm == 'yes') {
1056  if (!GETPOSTINT('socid', 3)) {
1057  setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
1058  } else {
1059  if ($object->id > 0) {
1060  $result = $object->createFromClone($user, $socid);
1061  if ($result > 0) {
1062  header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
1063  exit();
1064  } else {
1065  if (count($object->errors) > 0) {
1066  setEventMessages($object->error, $object->errors, 'errors');
1067  }
1068  $action = '';
1069  }
1070  }
1071  }
1072  }
1073 }
1074 
1075 
1076 /*
1077  * View
1078  */
1079 
1080 $help_url = 'EN:Module_Contracts|FR:Module_Contrat';
1081 
1082 $title = $object->ref." - ".$langs->trans('Contract');
1083 if ($action == 'create') {
1084  $title = $langs->trans("NewContract");
1085 }
1086 
1087 llxHeader('', $title, $help_url);
1088 
1089 $form = new Form($db);
1090 $formfile = new FormFile($db);
1091 if (isModEnabled('project')) {
1092  $formproject = new FormProjets($db);
1093 }
1094 
1095 // Load object modContract
1096 $module = (getDolGlobalString('CONTRACT_ADDON') ? $conf->global->CONTRACT_ADDON : 'mod_contract_serpis');
1097 if (substr($module, 0, 13) == 'mod_contract_' && substr($module, -3) == 'php') {
1098  $module = substr($module, 0, dol_strlen($module) - 4);
1099 }
1100 $result = dol_include_once('/core/modules/contract/'.$module.'.php');
1101 if ($result > 0) {
1102  $modCodeContract = new $module();
1103 }
1104 
1105 // Create
1106 if ($action == 'create') {
1107  $objectsrc = null;
1108  print load_fiche_titre($langs->trans('NewContract'), '', 'contract');
1109 
1110  $soc = new Societe($db);
1111  if ($socid > 0) {
1112  $soc->fetch($socid);
1113  }
1114 
1115  if (GETPOST('origin') && GETPOSTINT('originid')) {
1116  // Parse element/subelement (ex: project_task)
1117  $regs = array();
1118  $element = $subelement = GETPOST('origin');
1119  if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'), $regs)) {
1120  $element = $regs[1];
1121  $subelement = $regs[2];
1122  }
1123 
1124  if ($element == 'project') {
1125  $projectid = GETPOSTINT('originid');
1126  } else {
1127  // For compatibility
1128  if ($element == 'order' || $element == 'commande') {
1129  $element = $subelement = 'commande';
1130  }
1131  if ($element == 'propal') {
1132  $element = 'comm/propal';
1133  $subelement = 'propal';
1134  }
1135  if ($element == 'invoice' || $element == 'facture') {
1136  $element = 'compta/facture';
1137  $subelement = 'facture';
1138  }
1139 
1140  dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1141 
1142  $classname = ucfirst($subelement);
1143  $objectsrc = new $classname($db);
1144  $objectsrc->fetch($originid);
1145  if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
1146  $objectsrc->fetch_lines();
1147  }
1148  $objectsrc->fetch_thirdparty();
1149 
1150  // Replicate extrafields
1151  $objectsrc->fetch_optionals();
1152  $object->array_options = $objectsrc->array_options;
1153 
1154  $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
1155 
1156  $soc = $objectsrc->thirdparty;
1157 
1158  $note_private = (!empty($objectsrc->note_private) ? $objectsrc->note_private : '');
1159  $note_public = (!empty($objectsrc->note_public) ? $objectsrc->note_public : '');
1160 
1161  // Object source contacts list
1162  $srccontactslist = $objectsrc->liste_contact(-1, 'external', 1);
1163  }
1164  } else {
1165  $projectid = GETPOSTINT('projectid');
1166  $note_private = GETPOST("note_private");
1167  $note_public = GETPOST("note_public");
1168  }
1169 
1170  $object->date_contrat = dol_now();
1171 
1172  print '<form name="form_contract" action="'.$_SERVER["PHP_SELF"].'" method="post">';
1173  print '<input type="hidden" name="token" value="'.newToken().'">';
1174  print '<input type="hidden" name="action" value="add">';
1175  print '<input type="hidden" name="socid" value="'.$soc->id.'">'."\n";
1176  print '<input type="hidden" name="remise_percent" value="0">';
1177  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1178 
1179  print dol_get_fiche_head();
1180 
1181  print '<table class="border centpercent">';
1182 
1183  // Ref
1184  print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Ref').'</td><td>';
1185  if (!empty($modCodeContract->code_auto)) {
1186  $tmpcode = $langs->trans("Draft");
1187  } else {
1188  $tmpcode = '<input name="ref" class="maxwidth100" maxlength="128" value="'.dol_escape_htmltag(GETPOST('ref') ? GETPOST('ref') : $tmpcode).'">';
1189  }
1190  print $tmpcode;
1191  print '</td></tr>';
1192 
1193  // Ref customer
1194  print '<tr><td>'.$langs->trans('RefCustomer').'</td>';
1195  print '<td><input type="text" class="maxwidth150" name="ref_customer" id="ref_customer" value="'.dol_escape_htmltag(GETPOST('ref_customer', 'alpha')).'"></td></tr>';
1196 
1197  // Ref supplier
1198  print '<tr><td>'.$langs->trans('RefSupplier').'</td>';
1199  print '<td><input type="text" class="maxwidth150" name="ref_supplier" id="ref_supplier" value="'.dol_escape_htmltag(GETPOST('ref_supplier', 'alpha')).'"></td></tr>';
1200 
1201  // Thirdparty
1202  print '<tr>';
1203  print '<td class="fieldrequired">'.$langs->trans('ThirdParty').'</td>';
1204  if ($socid > 0) {
1205  print '<td>';
1206  print $soc->getNomUrl(1);
1207  print '<input type="hidden" name="socid" value="'.$soc->id.'">';
1208  print '</td>';
1209  } else {
1210  print '<td>';
1211  print img_picto('', 'company', 'class="pictofixedwidth"');
1212  print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
1213  print ' <a href="'.DOL_URL_ROOT.'/societe/card.php?action=create&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create').'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddThirdParty").'"></span></a>';
1214  print '</td>';
1215  }
1216  print '</tr>'."\n";
1217 
1218  if ($socid > 0) {
1219  // Ligne info remises tiers
1220  print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
1221  if ($soc->remise_percent) {
1222  print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_percent).' ';
1223  } else {
1224  print '<span class="hideonsmartphone">'.$langs->trans("CompanyHasNoRelativeDiscount").'. </span>';
1225  }
1226  $absolute_discount = $soc->getAvailableDiscounts();
1227  if ($absolute_discount) {
1228  print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->trans("Currency".$conf->currency)).'.';
1229  } else {
1230  print '<span class="hideonsmartphone">'.$langs->trans("CompanyHasNoAbsoluteDiscount").'.</span>';
1231  }
1232  print '</td></tr>';
1233  }
1234 
1235  // Commercial suivi
1236  print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("TypeContact_contrat_internal_SALESREPFOLL").'</span></td><td>';
1237  print img_picto('', 'user', 'class="pictofixedwidth"');
1238  print $form->select_dolusers(GETPOST("commercial_suivi_id") ? GETPOST("commercial_suivi_id") : $user->id, 'commercial_suivi_id', 1, '');
1239  print '</td></tr>';
1240 
1241  // Commercial signature
1242  print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("TypeContact_contrat_internal_SALESREPSIGN").'</span></td><td>';
1243  print img_picto('', 'user', 'class="pictofixedwidth"');
1244  print $form->select_dolusers(GETPOST("commercial_signature_id") ? GETPOST("commercial_signature_id") : $user->id, 'commercial_signature_id', 1, '');
1245  print '</td></tr>';
1246 
1247  print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td>';
1248  print img_picto('', 'action', 'class="pictofixedwidth"');
1249  print $form->selectDate($datecontrat, '', 0, 0, 0, "contrat");
1250  print "</td></tr>";
1251 
1252  // Project
1253  if (isModEnabled('project')) {
1254  $langs->load('projects');
1255 
1256  $formproject = new FormProjets($db);
1257 
1258  print '<tr><td>'.$langs->trans("Project").'</td><td>';
1259  print img_picto('', 'project', 'class="pictofixedwidth"');
1260  $formproject->select_projects(($soc->id > 0 ? $soc->id : -1), $projectid, "projectid", 0, 0, 1, 1);
1261  print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$soc->id.'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
1262  print "</td></tr>";
1263  }
1264 
1265  print '<tr><td>'.$langs->trans("NotePublic").'</td><td class="tdtop">';
1266  $doleditor = new DolEditor('note_public', $note_public, '', '100', 'dolibarr_notes', 'In', 1, true, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
1267  print $doleditor->Create(1);
1268  print '</td></tr>';
1269 
1270  if (empty($user->socid)) {
1271  print '<tr><td>'.$langs->trans("NotePrivate").'</td><td class="tdtop">';
1272  $doleditor = new DolEditor('note_private', $note_private, '', '100', 'dolibarr_notes', 'In', 1, true, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
1273  print $doleditor->Create(1);
1274  print '</td></tr>';
1275  }
1276 
1277  // Other attributes
1278  $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"', 'cols' => '3');
1279  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1280  print $hookmanager->resPrint;
1281 
1282  // Other attributes
1283  if (empty($reshook)) {
1284  print $object->showOptionals($extrafields, 'create', $parameters);
1285  }
1286 
1287  print "</table>\n";
1288 
1289  print dol_get_fiche_end();
1290 
1291  print $form->buttonsSaveCancel("Create");
1292 
1293  if (is_object($objectsrc)) {
1294  print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
1295  print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
1296 
1297  if (!getDolGlobalString('CONTRACT_SUPPORT_PRODUCTS')) {
1298  print '<br>'.$langs->trans("Note").': '.$langs->trans("OnlyLinesWithTypeServiceAreUsed");
1299  }
1300  }
1301 
1302  print "</form>\n";
1303 } else {
1304  // View and edit mode
1305  $now = dol_now();
1306 
1307  if ($object->id > 0) {
1308  $object->fetch_thirdparty();
1309 
1310  $soc = $object->thirdparty; // $soc is used later
1311 
1312  $result = $object->fetch_lines(); // This also init $this->nbofserviceswait, $this->nbofservicesopened, $this->nbofservicesexpired=, $this->nbofservicesclosed
1313  if ($result < 0) {
1314  dol_print_error($db, $object->error);
1315  }
1316 
1317  $nbofservices = count($object->lines);
1318 
1319  $author = new User($db);
1320  $author->fetch($object->user_author_id);
1321 
1322  $commercial_signature = new User($db);
1323  $commercial_signature->fetch($object->commercial_signature_id);
1324 
1325  $commercial_suivi = new User($db);
1326  $commercial_suivi->fetch($object->commercial_suivi_id);
1327 
1328  $head = contract_prepare_head($object);
1329 
1330  $hselected = 0;
1331  $formconfirm = '';
1332 
1333  print dol_get_fiche_head($head, $hselected, $langs->trans("Contract"), -1, 'contract');
1334 
1335 
1336  if ($action == 'delete') {
1337  //Confirmation de la suppression du contrat
1338  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("DeleteAContract"), $langs->trans("ConfirmDeleteAContract"), "confirm_delete", '', 0, 1);
1339  } elseif ($action == 'valid') {
1340  //Confirmation de la validation
1341  $ref = substr($object->ref, 1, 4);
1342  if ($ref == 'PROV' && !empty($modCodeContract->code_auto)) {
1343  $numref = $object->getNextNumRef($object->thirdparty);
1344  } else {
1345  $numref = $object->ref;
1346  }
1347  $text = $langs->trans('ConfirmValidateContract', $numref);
1348  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ValidateAContract"), $text, "confirm_valid", '', 0, 1);
1349  } elseif ($action == 'close') {
1350  // Confirmation de la fermeture
1351  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("CloseAContract"), $langs->trans("ConfirmCloseContract"), "confirm_close", '', 0, 1);
1352  } elseif ($action == 'activate') {
1353  $formquestion = array(
1354  array('type' => 'date', 'name' => 'd_start', 'label' => $langs->trans("DateServiceActivate"), 'value' => dol_now()),
1355  array('type' => 'date', 'name' => 'd_end', 'label' => $langs->trans("DateEndPlanned"), /*'value' => $form->selectDate('', "end", $usehm, $usehm, '', "active", 1, 0),*/ 0 => '', 1 => ''),
1356  array('type' => 'text', 'name' => 'comment', 'label' => $langs->trans("Comment"), 'value' => '', 0 => '', 1 => '', 'class' => 'minwidth300', 'moreattr' => 'autofocus')
1357  );
1358  $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ActivateAllOnContract"), $langs->trans("ConfirmActivateAllOnContract"), "confirm_activate", $formquestion, 'yes', 1, 280);
1359  } elseif ($action == 'clone') {
1360  $filter = '(s.client:IN:1,2,3)';
1361  // Clone confirmation
1362  $formquestion = array(array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid'), 'socid', $filter)));
1363  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneContract', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
1364  }
1365 
1366 
1367  // Call Hook formConfirm
1368  $parameters = array(
1369  'formConfirm' => $formconfirm,
1370  'id' => $id,
1371  //'lineid' => $lineid,
1372  );
1373  // Note that $action and $object may have been modified by hook
1374  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
1375  if (empty($reshook)) {
1376  $formconfirm .= $hookmanager->resPrint;
1377  } elseif ($reshook > 0) {
1378  $formconfirm = $hookmanager->resPrint;
1379  }
1380 
1381  // Print form confirm
1382  print $formconfirm;
1383 
1384 
1385  // Contract
1386  if ($object->status == $object::STATUS_DRAFT && $user->hasRight('contrat', 'creer')) {
1387  print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST">';
1388  print '<input type="hidden" name="token" value="'.newToken().'">';
1389  print '<input type="hidden" name="action" value="setremise">';
1390  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1391  }
1392 
1393  // Contract card
1394 
1395  $linkback = '<a href="'.DOL_URL_ROOT.'/contrat/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1396 
1397 
1398  $morehtmlref = '';
1399  if (!empty($modCodeContract->code_auto)) {
1400  $morehtmlref .= $object->ref;
1401  } else {
1402  $morehtmlref .= $form->editfieldkey("", 'ref', $object->ref, $object, $user->hasRight('contrat', 'creer'), 'string', '', 0, 3);
1403  $morehtmlref .= $form->editfieldval("", 'ref', $object->ref, $object, $user->hasRight('contrat', 'creer'), 'string', '', 0, 2);
1404  }
1405 
1406  $morehtmlref .= '<div class="refidno">';
1407  // Ref customer
1408  $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_customer', $object->ref_customer, $object, $user->hasRight('contrat', 'creer'), 'string', '', 0, 1);
1409  $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_customer', $object->ref_customer, $object, $user->hasRight('contrat', 'creer'), 'string'.(isset($conf->global->THIRDPARTY_REF_INPUT_SIZE) ? ':' . getDolGlobalString('THIRDPARTY_REF_INPUT_SIZE') : ''), '', null, null, '', 1, 'getFormatedCustomerRef');
1410  // Ref supplier
1411  $morehtmlref .= '<br>';
1412  $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('contrat', 'creer'), 'string', '', 0, 1);
1413  $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('contrat', 'creer'), 'string', '', null, null, '', 1, 'getFormatedSupplierRef');
1414  // Thirdparty
1415  $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
1416  if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
1417  $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.$object->thirdparty->id.'&search_name='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherContracts").'</a>)';
1418  }
1419  // Project
1420  if (isModEnabled('project')) {
1421  $langs->load("projects");
1422  $morehtmlref .= '<br>';
1423  if ($permissiontoadd) {
1424  $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
1425  if ($action != 'classify') {
1426  $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
1427  }
1428  $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
1429  } else {
1430  if (!empty($object->fk_project)) {
1431  $proj = new Project($db);
1432  $proj->fetch($object->fk_project);
1433  $morehtmlref .= $proj->getNomUrl(1);
1434  if ($proj->title) {
1435  $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
1436  }
1437  }
1438  }
1439  }
1440  $morehtmlref .= '</div>';
1441 
1442 
1443  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'none', $morehtmlref);
1444 
1445 
1446  print '<div class="fichecenter">';
1447  print '<div class="underbanner clearboth"></div>';
1448 
1449 
1450  print '<table class="border tableforfield" width="100%">';
1451 
1452  // Line info of thirdparty discounts
1453  print '<tr><td class="titlefield">'.$langs->trans('Discount').'</td><td colspan="3">';
1454  if ($object->thirdparty->remise_percent) {
1455  print $langs->trans("CompanyHasRelativeDiscount", $object->thirdparty->remise_percent).'. ';
1456  } else {
1457  print '<span class="hideonsmartphone">'.$langs->trans("CompanyHasNoRelativeDiscount").'. </span>';
1458  }
1459  $absolute_discount = $object->thirdparty->getAvailableDiscounts();
1460  if ($absolute_discount) {
1461  print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->trans("Currency".$conf->currency)).'.';
1462  } else {
1463  print '<span class="hideonsmartphone">'.$langs->trans("CompanyHasNoAbsoluteDiscount").'.</span>';
1464  }
1465  print '</td></tr>';
1466 
1467  // Date
1468  print '<tr>';
1469  print '<td class="titlefield">';
1470  print $form->editfieldkey("Date", 'date_contrat', $object->date_contrat, $object, $user->hasRight('contrat', 'creer'));
1471  print '</td><td>';
1472  print $form->editfieldval("Date", 'date_contrat', $object->date_contrat, $object, $user->hasRight('contrat', 'creer'), 'datehourpicker');
1473  print '</td>';
1474  print '</tr>';
1475 
1476  // Other attributes
1477  $cols = 3;
1478  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1479 
1480  print "</table>";
1481 
1482  print '</div>';
1483 
1484  if ($object->status == $object::STATUS_DRAFT && $user->hasRight('contrat', 'creer')) {
1485  print '</form>';
1486  }
1487 
1488  echo '<br>';
1489 
1490  if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
1491  $blocname = 'contacts';
1492  $title = $langs->trans('ContactsAddresses');
1493  include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
1494  }
1495 
1496  if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
1497  $blocname = 'notes';
1498  $title = $langs->trans('Notes');
1499  include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
1500  }
1501 
1502 
1503  $arrayothercontracts = $object->getListOfContracts('others'); // array or -1 if technical error
1504 
1505  /*
1506  * Lines of contracts
1507  */
1508 
1509  // Add products/services form
1510  //$forceall = 1;
1511  global $inputalsopricewithtax;
1512  $inputalsopricewithtax = 1;
1513 
1514  $productstatic = new Product($db);
1515 
1516  $usemargins = 0;
1517  if (isModEnabled('margin') && !empty($object->element) && in_array($object->element, array('facture', 'propal', 'commande'))) {
1518  $usemargins = 1;
1519  }
1520 
1521  // Title line for service
1522  $cursorline = 1;
1523 
1524 
1525  print '<div id="contrat-lines-container" id="contractlines" data-contractid="'.$object->id.'" data-element="'.$object->element.'" >';
1526  while ($cursorline <= $nbofservices) {
1527  print '<div id="contrat-line-container'.$object->lines[$cursorline - 1]->id.'" data-contratlineid = "'.$object->lines[$cursorline - 1]->id.'" data-element="'.$object->lines[$cursorline - 1]->element.'" >';
1528  print '<form name="update" id="addproduct" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="post">';
1529  print '<input type="hidden" name="token" value="'.newToken().'">';
1530  print '<input type="hidden" name="action" value="updateline">';
1531  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1532  print '<input type="hidden" name="elrowid" value="'.$object->lines[$cursorline - 1]->id.'">';
1533  print '<input type="hidden" name="fournprice" value="'.(!empty($object->lines[$cursorline - 1]->fk_fournprice) ? $object->lines[$cursorline - 1]->fk_fournprice : 0).'">';
1534 
1535  // Area with common detail of line
1536  print '<div class="div-table-responsive-no-min">';
1537  print '<table class="notopnoleftnoright allwidth tableforservicepart1 centpercent">';
1538 
1539  $sql = "SELECT cd.rowid, cd.statut, cd.label as label_det, cd.fk_product, cd.product_type, cd.description, cd.price_ht, cd.qty,";
1540  $sql .= " cd.tva_tx, cd.vat_src_code, cd.remise_percent, cd.info_bits, cd.subprice, cd.multicurrency_subprice,";
1541  $sql .= " cd.date_ouverture_prevue as date_start, cd.date_ouverture as date_start_real,";
1542  $sql .= " cd.date_fin_validite as date_end, cd.date_cloture as date_end_real,";
1543  $sql .= " cd.commentaire as comment, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht,";
1544  $sql .= " cd.fk_unit,";
1545  $sql .= " p.rowid as pid, p.ref as pref, p.label as plabel, p.fk_product_type as ptype, p.entity as pentity, p.tosell, p.tobuy, p.tobatch";
1546  $sql .= " ,cd.rang";
1547  $sql .= " FROM ".MAIN_DB_PREFIX."contratdet as cd";
1548  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid";
1549  $sql .= " WHERE cd.rowid = ".((int) $object->lines[$cursorline - 1]->id);
1550 
1551  $result = $db->query($sql);
1552  if ($result) {
1553  $total = 0;
1554 
1555  $objp = $db->fetch_object($result);
1556 
1557  // Line title
1558  print '<tr class="liste_titre'.($cursorline ? ' liste_titre_add' : '').'">';
1559  print '<td>'.$langs->trans("ServiceNb", $cursorline).'</td>';
1560  print '<td width="80" class="center">'.$langs->trans("VAT").'</td>';
1561  print '<td width="80" class="right">'.$langs->trans("PriceUHT").'</td>';
1562  //if (isModEnabled("multicurrency")) {
1563  // print '<td width="80" class="right">'.$langs->trans("PriceUHTCurrency").'</td>';
1564  //}
1565  print '<td width="30" class="center">'.$langs->trans("Qty").'</td>';
1566  if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1567  print '<td width="30" class="left">'.$langs->trans("Unit").'</td>';
1568  }
1569  print '<td width="50" class="right">'.$langs->trans("ReductionShort").'</td>';
1570  if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1571  print '<td width="50" class="right">'.$langs->trans("BuyingPrice").'</td>';
1572  }
1573  //
1574 
1575  if ($nbofservices > 1 && $conf->browser->layout != 'phone' && $user->hasRight('contrat', 'creer')) {
1576  print '<td width="30" class="linecolmove tdlineupdown center">';
1577  if ($cursorline > 1) {
1578  print '<a class="lineupdown reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=up&token='.newToken().'&rowid='.$objp->rowid.'">';
1579  echo img_up('default', 0, 'imgupforline');
1580  print '</a>';
1581  }
1582  if ($cursorline < $nbofservices) {
1583  print '<a class="lineupdown reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=down&token='.newToken().'&rowid='.$objp->rowid.'">';
1584  echo img_down('default', 0, 'imgdownforline');
1585  print '</a>';
1586  }
1587  print '</td>';
1588  } else {
1589  print '<td width="30">&nbsp;</td>';
1590  }
1591 
1592  print "</tr>\n";
1593 
1594 
1595 
1596  // Line in view mode
1597  if ($action != 'editline' || GETPOST('rowid') != $objp->rowid) {
1598  $moreparam = '';
1599  if (getDolGlobalString('CONTRACT_HIDE_CLOSED_SERVICES_BY_DEFAULT') && $objp->statut == ContratLigne::STATUS_CLOSED && $action != 'showclosedlines') {
1600  $moreparam = 'style="display: none;"';
1601  }
1602 
1603  print '<tr class="tdtop oddeven" '.$moreparam.'>';
1604 
1605  // Label
1606  if ($objp->fk_product > 0) {
1607  $productstatic->id = $objp->fk_product;
1608  $productstatic->type = $objp->ptype;
1609  $productstatic->ref = $objp->pref;
1610  $productstatic->entity = $objp->pentity;
1611  $productstatic->label = $objp->plabel;
1612  $productstatic->status = $objp->tosell;
1613  $productstatic->status_buy = $objp->tobuy;
1614  $productstatic->status_batch = $objp->tobatch;
1615 
1616  print '<td>';
1617  $text = $productstatic->getNomUrl(1, '', 32);
1618  if ($objp->plabel) {
1619  $text .= ' - ';
1620  $text .= $objp->plabel;
1621  }
1622  $description = $objp->description;
1623 
1624  // Add description in form
1625  if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
1626  $text .= (!empty($objp->description) && $objp->description != $objp->plabel) ? '<br>'.dol_htmlentitiesbr($objp->description) : '';
1627  $description = ''; // Already added into main visible desc
1628  }
1629 
1630  print $form->textwithtooltip($text, $description, 3, '', '', $cursorline, 3, (!empty($line->fk_parent_line) ? img_picto('', 'rightarrow') : ''));
1631 
1632  print '</td>';
1633  } else {
1634  print '<td>'.img_object($langs->trans("ShowProductOrService"), ($objp->product_type ? 'service' : 'product')).' '.dol_htmlentitiesbr($objp->description)."</td>\n";
1635  }
1636  // VAT
1637  print '<td class="center">';
1638  print vatrate($objp->tva_tx.($objp->vat_src_code ? (' ('.$objp->vat_src_code.')') : ''), '%', $objp->info_bits);
1639  print '</td>';
1640  // Price
1641  print '<td class="right">'.($objp->subprice != '' ? price($objp->subprice) : '')."</td>\n";
1642  // Price multicurrency
1643  /*if (isModEnabled("multicurrency")) {
1644  print '<td class="linecoluht_currency nowrap right">'.price($objp->multicurrency_subprice).'</td>';
1645  }*/
1646  // Quantity
1647  print '<td class="center">'.$objp->qty.'</td>';
1648  // Unit
1649  if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1650  print '<td class="left">'.$langs->trans($object->lines[$cursorline - 1]->getLabelOfUnit()).'</td>';
1651  }
1652  // Discount
1653  if ($objp->remise_percent > 0) {
1654  print '<td class="right">'.$objp->remise_percent."%</td>\n";
1655  } else {
1656  print '<td>&nbsp;</td>';
1657  }
1658 
1659  // Margin
1660  if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1661  print '<td class="right nowraponall">'.price($objp->pa_ht).'</td>';
1662  }
1663 
1664  // Icon move, update et delete (status contract 0=draft,1=validated,2=closed)
1665  print '<td class="nowraponall right">';
1666  if ($user->hasRight('contrat', 'creer') && is_array($arrayothercontracts) && count($arrayothercontracts) && ($object->statut >= 0)) {
1667  print '<!-- link to move service line into another contract -->';
1668  print '<a class="reposition marginrightonly" style="padding-left: 5px;" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=move&token='.newToken().'&rowid='.$objp->rowid.'">';
1669  print img_picto($langs->trans("MoveToAnotherContract"), 'uparrow');
1670  print '</a>';
1671  }
1672  if ($user->hasRight('contrat', 'creer') && ($object->statut >= 0)) {
1673  print '<a class="reposition marginrightonly editfielda" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=editline&token='.newToken().'&rowid='.$objp->rowid.'">';
1674  print img_edit();
1675  print '</a>';
1676  }
1677  if ($user->hasRight('contrat', 'creer') && ($object->statut >= 0)) {
1678  print '<a class="reposition marginrightonly" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=deleteline&token='.newToken().'&rowid='.$objp->rowid.'">';
1679  print img_delete();
1680  print '</a>';
1681  }
1682  print '</td>';
1683 
1684  print "</tr>\n";
1685 
1686  $colspan = 6;
1687  if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1688  $colspan++;
1689  }
1690  if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1691  $colspan++;
1692  }
1693 
1694  // Dates of service planned and real
1695  if ($objp->subprice >= 0) {
1696  print '<tr class="oddeven" '.$moreparam.'>';
1697  print '<td colspan="'.$colspan.'">';
1698 
1699  // Date planned
1700  print $langs->trans("DateStartPlanned").': ';
1701  if ($objp->date_start) {
1702  print dol_print_date($db->jdate($objp->date_start), 'day');
1703  // Warning si date prevu passee et pas en service
1704  if ($objp->statut == 0 && $db->jdate($objp->date_start) < ($now - $conf->contrat->services->inactifs->warning_delay)) {
1705  $warning_delay = $conf->contrat->services->inactifs->warning_delay / 3600 / 24;
1706  $textlate = $langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($warning_delay) >= 0 ? '+' : '').ceil($warning_delay).' '.$langs->trans("days");
1707  print " ".img_warning($textlate);
1708  }
1709  } else {
1710  print $langs->trans("Unknown");
1711  }
1712  print ' &nbsp;-&nbsp; ';
1713  print $langs->trans("DateEndPlanned").': ';
1714  if ($objp->date_end) {
1715  print dol_print_date($db->jdate($objp->date_end), 'day');
1716  if ($objp->statut == 4 && $db->jdate($objp->date_end) < ($now - $conf->contrat->services->expires->warning_delay)) {
1717  $warning_delay = $conf->contrat->services->expires->warning_delay / 3600 / 24;
1718  $textlate = $langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($warning_delay) >= 0 ? '+' : '').ceil($warning_delay).' '.$langs->trans("days");
1719  print " ".img_warning($textlate);
1720  }
1721  } else {
1722  print $langs->trans("Unknown");
1723  }
1724 
1725  print '</td>';
1726  print '</tr>';
1727  }
1728 
1729  // Display lines extrafields
1730  if (is_array($extralabelslines) && count($extralabelslines) > 0) {
1731  $line = new ContratLigne($db);
1732  $line->id = $objp->rowid;
1733  $line->fetch_optionals();
1734  print $line->showOptionals($extrafields, 'view', array('class' => 'oddeven', 'style' => $moreparam, 'colspan' => $colspan), '', '', 1);
1735  }
1736  } else {
1737  // Line in mode update
1738  // Ligne carac
1739  print '<tr class="oddeven">';
1740  print '<td>';
1741  if ($objp->fk_product > 0) {
1742  $canchangeproduct = 1;
1743  if (empty($canchangeproduct)) {
1744  $productstatic->id = $objp->fk_product;
1745  $productstatic->type = $objp->ptype;
1746  $productstatic->ref = $objp->pref;
1747  $productstatic->entity = $objp->pentity;
1748  print $productstatic->getNomUrl(1, '', 32);
1749  print $objp->label ? ' - '.dol_trunc($objp->label, 32) : '';
1750  print '<input type="hidden" name="idprod" value="'.(!empty($object->lines[$cursorline - 1]->fk_product) ? $object->lines[$cursorline - 1]->fk_product : 0).'">';
1751  } else {
1752  $senderissupplier = 0;
1753  if (empty($senderissupplier)) {
1754  print $form->select_produits((!empty($object->lines[$cursorline - 1]->fk_product) ? $object->lines[$cursorline - 1]->fk_product : 0), 'idprod');
1755  } else {
1756  $form->select_produits_fournisseurs((!empty($object->lines[$cursorline - 1]->fk_product) ? $object->lines[$cursorline - 1]->fk_product : 0), 'idprod');
1757  }
1758  }
1759  print '<br>';
1760  } else {
1761  print $objp->label ? $objp->label.'<br>' : '';
1762  print '<input type="hidden" name="idprod" value="'.(!empty($object->lines[$cursorline - 1]->fk_product) ? $object->lines[$cursorline - 1]->fk_product : 0).'">';
1763  }
1764 
1765  // editeur wysiwyg
1766  require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1767  $nbrows = ROWS_2;
1768  if (getDolGlobalString('MAIN_INPUT_DESC_HEIGHT')) {
1769  $nbrows = getDolGlobalString('MAIN_INPUT_DESC_HEIGHT');
1770  }
1771  $enable = (isset($conf->global->FCKEDITOR_ENABLE_DETAILS) ? $conf->global->FCKEDITOR_ENABLE_DETAILS : 0);
1772  $doleditor = new DolEditor('product_desc', $objp->description, '', 92, 'dolibarr_details', '', false, true, $enable, $nbrows, '90%');
1773  $doleditor->Create();
1774 
1775  print '</td>';
1776 
1777  // VAT
1778  print '<td class="right">';
1779  print $form->load_tva("eltva_tx", $objp->tva_tx.($objp->vat_src_code ? (' ('.$objp->vat_src_code.')') : ''), $mysoc, $object->thirdparty, $objp->fk_product, $objp->info_bits, $objp->product_type, 0, 1);
1780  print '</td>';
1781 
1782  // Price
1783  print '<td class="right"><input class="width50" type="text" name="elprice" value="'.price($objp->subprice).'"></td>';
1784 
1785  // Price multicurrency
1786  /*if (isModEnabled("multicurrency")) {
1787  print '<td class="linecoluht_currency nowrap right">'.price($objp->multicurrency_subprice).'</td>';
1788  }*/
1789 
1790  // Quantity
1791  print '<td class="center"><input size="2" type="text" name="elqty" value="'.$objp->qty.'"></td>';
1792 
1793  // Unit
1794  if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1795  print '<td class="left">';
1796  print $form->selectUnits($objp->fk_unit, "unit");
1797  print '</td>';
1798  }
1799 
1800  // Discount
1801  print '<td class="nowrap right"><input size="1" type="text" name="elremise_percent" value="'.$objp->remise_percent.'">%</td>';
1802 
1803  if (!empty($usemargins)) {
1804  print '<td class="right">';
1805  if ($objp->fk_product) {
1806  print '<select id="fournprice" name="fournprice"></select>';
1807  }
1808  print '<input id="buying_price" type="text" class="width50" name="buying_price" value="'.price($objp->pa_ht, 0, '', 0).'"></td>';
1809  }
1810  print '<td class="center">';
1811  print '<input type="submit" class="button margintoponly marginbottomonly" name="save" value="'.$langs->trans("Modify").'">';
1812  print '<br><input type="submit" class="button margintoponly marginbottomonly button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
1813  print '</td>';
1814  print '</tr>';
1815 
1816  $colspan = 6;
1817  if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1818  $colspan++;
1819  }
1820  if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1821  $colspan++;
1822  }
1823 
1824  // Line dates planned
1825  print '<tr class="oddeven">';
1826  print '<td colspan="'.$colspan.'">';
1827  print $langs->trans("DateStartPlanned").' ';
1828  print $form->selectDate($db->jdate($objp->date_start), "date_start_update", $usehm, $usehm, ($db->jdate($objp->date_start) > 0 ? 0 : 1), "update");
1829  print ' &nbsp;&nbsp;'.$langs->trans("DateEndPlanned").' ';
1830  print $form->selectDate($db->jdate($objp->date_end), "date_end_update", $usehm, $usehm, ($db->jdate($objp->date_end) > 0 ? 0 : 1), "update");
1831  print '</td>';
1832  print '</tr>';
1833 
1834  if (is_array($extralabelslines) && count($extralabelslines) > 0) {
1835  $line = new ContratLigne($db);
1836  $line->id = $objp->rowid;
1837  $line->fetch_optionals();
1838  print $line->showOptionals($extrafields, 'edit', array('style' => 'class="oddeven"', 'colspan' => $colspan), '', '', 1);
1839  }
1840  }
1841 
1842  $db->free($result);
1843  } else {
1844  dol_print_error($db);
1845  }
1846 
1847  if ($object->statut > 0) {
1848  $moreparam = '';
1849  if (getDolGlobalString('CONTRACT_HIDE_CLOSED_SERVICES_BY_DEFAULT') && $object->lines[$cursorline - 1]->statut == ContratLigne::STATUS_CLOSED && $action != 'showclosedlines') {
1850  $moreparam = 'style="display: none;"';
1851  }
1852 
1853  $colspan = 6;
1854  if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1855  $colspan++;
1856  }
1857  if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1858  $colspan++;
1859  }
1860 
1861  print '<tr class="oddeven" '.$moreparam.'>';
1862  print '<td class="tdhrthin" colspan="'.$colspan.'"><hr class="opacitymedium tdhrthin"></td>';
1863  print "</tr>\n";
1864  }
1865 
1866  print "</table>";
1867  print '</div>';
1868 
1869  print "</form>\n";
1870 
1871 
1872  /*
1873  * Confirmation to delete service line of contract
1874  */
1875  if ($action == 'deleteline' && !$_REQUEST["cancel"] && $user->hasRight('contrat', 'creer') && $object->lines[$cursorline - 1]->id == GETPOST('rowid')) {
1876  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('rowid'), $langs->trans("DeleteContractLine"), $langs->trans("ConfirmDeleteContractLine"), "confirm_deleteline", '', 0, 1);
1877  if ($ret == 'html') {
1878  print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1879  }
1880  }
1881 
1882  /*
1883  * Confirmation to move service toward another contract
1884  */
1885  if ($action == 'move' && !$_REQUEST["cancel"] && $user->hasRight('contrat', 'creer') && $object->lines[$cursorline - 1]->id == GETPOST('rowid')) {
1886  $arraycontractid = array();
1887  foreach ($arrayothercontracts as $contractcursor) {
1888  $arraycontractid[$contractcursor->id] = $contractcursor->ref;
1889  }
1890  //var_dump($arraycontractid);
1891  // Cree un tableau formulaire
1892  $formquestion = array(
1893  'text' => $langs->trans("ConfirmMoveToAnotherContractQuestion"),
1894  0 => array('type' => 'select', 'name' => 'newcid', 'values' => $arraycontractid));
1895 
1896  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOSTINT('rowid'), $langs->trans("MoveToAnotherContract"), $langs->trans("ConfirmMoveToAnotherContract"), "confirm_move", $formquestion);
1897  print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1898  }
1899 
1900  // Area with status and activation info of line
1901  if ($object->statut > 0) {
1902  print '<table class="notopnoleftnoright tableforservicepart2'.($cursorline < $nbofservices ? ' boxtablenobottom' : '').' centpercent">';
1903 
1904  print '<tr class="oddeven" '.$moreparam.'>';
1905  print '<td><span class="valignmiddle hideonsmartphone">'.$langs->trans("ServiceStatus").':</span> '.$object->lines[$cursorline - 1]->getLibStatut(4).'</td>';
1906  print '<td width="30" class="right">';
1907  if ($user->socid == 0) {
1908  if ($object->statut > 0 && $action != 'activateline' && $action != 'unactivateline') {
1909  $tmpaction = 'activateline';
1910  $tmpactionpicto = 'play';
1911  $tmpactiontext = $langs->trans("Activate");
1912  if ($objp->statut == 4) {
1913  $tmpaction = 'unactivateline';
1914  $tmpactionpicto = 'playstop';
1915  $tmpactiontext = $langs->trans("Disable");
1916  }
1917  if (($tmpaction == 'activateline' && $user->hasRight('contrat', 'activer')) || ($tmpaction == 'unactivateline' && $user->hasRight('contrat', 'desactiver'))) {
1918  print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;ligne='.$object->lines[$cursorline - 1]->id.'&amp;action='.$tmpaction.'">';
1919  print img_picto($tmpactiontext, $tmpactionpicto);
1920  print '</a>';
1921  }
1922  }
1923  }
1924  print '</td>';
1925  print "</tr>\n";
1926 
1927  print '<tr class="oddeven" '.$moreparam.'>';
1928 
1929  print '<td>';
1930  // Si pas encore active
1931  if (!$objp->date_start_real) {
1932  print $langs->trans("DateStartReal").': ';
1933  if ($objp->date_start_real) {
1934  print dol_print_date($db->jdate($objp->date_start_real), 'day');
1935  } else {
1936  print $langs->trans("ContractStatusNotRunning");
1937  }
1938  }
1939  // Si active et en cours
1940  if ($objp->date_start_real && !$objp->date_end_real) {
1941  print $langs->trans("DateStartReal").': ';
1942  print dol_print_date($db->jdate($objp->date_start_real), 'day');
1943  }
1944  // Si desactive
1945  if ($objp->date_start_real && $objp->date_end_real) {
1946  print $langs->trans("DateStartReal").': ';
1947  print dol_print_date($db->jdate($objp->date_start_real), 'day');
1948  print ' &nbsp;-&nbsp; ';
1949  print $langs->trans("DateEndReal").': ';
1950  print dol_print_date($db->jdate($objp->date_end_real), 'day');
1951  }
1952  if (!empty($objp->comment)) {
1953  print " &nbsp;-&nbsp; ".$objp->comment;
1954  }
1955  print '</td>';
1956 
1957  print '<td class="center">&nbsp;</td>';
1958 
1959  print '</tr>';
1960  print '</table>';
1961  }
1962 
1963  // Form to activate line
1964  if ($user->hasRight('contrat', 'activer') && $action == 'activateline' && $object->lines[$cursorline - 1]->id == GETPOSTINT('ligne')) {
1965  print '<form name="active" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1966  print '<input type="hidden" name="token" value="'.newToken().'">';
1967  print '<input type="hidden" name="action" value="confirm_active">';
1968  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1969  print '<input type="hidden" name="id" value="'.$object->id.'">';
1970  print '<input type="hidden" name="ligne" value="'.GETPOSTINT('ligne').'">';
1971  print '<input type="hidden" name="confirm" value="yes">';
1972 
1973  print '<table class="noborder tableforservicepart2'.($cursorline < $nbofservices ? ' boxtablenobottom' : '').' centpercent">';
1974 
1975  // Definie date debut et fin par default
1976  $dateactstart = $objp->date_start;
1977  if (GETPOST('remonth')) {
1978  $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
1979  } elseif (!$dateactstart) {
1980  $dateactstart = time();
1981  }
1982 
1983  $dateactend = $objp->date_end;
1984  if (GETPOST('endmonth')) {
1985  $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
1986  } elseif (!$dateactend) {
1987  if ($objp->fk_product > 0) {
1988  $product = new Product($db);
1989  $product->fetch($objp->fk_product);
1990  $dateactend = dol_time_plus_duree(time(), $product->duration_value, $product->duration_unit);
1991  }
1992  }
1993 
1994  print '<tr class="oddeven">';
1995  print '<td class="nohover">'.$langs->trans("DateServiceActivate").'</td><td class="nohover">';
1996  print $form->selectDate($dateactstart, 'start', $usehm, $usehm, 0, "active", 1, 0);
1997  print '</td>';
1998  print '<td class="nohover">'.$langs->trans("DateEndPlanned").'</td><td class="nohover">';
1999  print $form->selectDate($dateactend, "end", $usehm, $usehm, 0, "active", 1, 0);
2000  print '</td>';
2001  print '<td class="center nohover">';
2002  print '</td>';
2003 
2004  print '</tr>';
2005 
2006  print '<tr class="oddeven">';
2007  print '<td class="nohover">'.$langs->trans("Comment").'</td><td colspan="3" class="nohover" colspan="'.(isModEnabled('margin') ? 4 : 3).'"><input type="text" class="minwidth300" name="comment" value="'.dol_escape_htmltag(GETPOST("comment", 'alphanohtml')).'"></td>';
2008  print '<td class="nohover right">';
2009  print '<input type="submit" class="button" name="activate" value="'.$langs->trans("Activate").'"> &nbsp; ';
2010  print '<input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
2011  print '</td>';
2012  print '</tr>';
2013 
2014  print '</table>';
2015 
2016  print '</form>';
2017  }
2018 
2019  if ($user->hasRight('contrat', 'activer') && $action == 'unactivateline' && $object->lines[$cursorline - 1]->id == GETPOSTINT('ligne')) {
2023  print '<!-- Form to disabled a line -->'."\n";
2024  print '<form name="confirm_closeline" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;ligne='.$object->lines[$cursorline - 1]->id.'" method="post">';
2025  print '<input type="hidden" name="token" value="'.newToken().'">';
2026  print '<input type="hidden" name="confirm" value="yes">';
2027  print '<input type="hidden" name="action" value="confirm_closeline">';
2028  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2029 
2030  print '<table class="noborder tableforservicepart2'.($cursorline < $nbofservices ? ' boxtablenobottom' : '').' centpercent">';
2031 
2032  // Definie date debut et fin par default
2033  $dateactstart = $objp->date_start_real;
2034  if (GETPOST('remonth')) {
2035  $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
2036  } elseif (!$dateactstart) {
2037  $dateactstart = time();
2038  }
2039 
2040  $dateactend = $objp->date_end_real;
2041  if (GETPOST('endmonth')) {
2042  $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
2043  } elseif (!$dateactend) {
2044  if ($objp->fk_product > 0) {
2045  $product = new Product($db);
2046  $product->fetch($objp->fk_product);
2047  $dateactend = dol_time_plus_duree(time(), $product->duration_value, $product->duration_unit);
2048  }
2049  }
2050  $now = dol_now();
2051  if ($dateactend > $now) {
2052  $dateactend = $now;
2053  }
2054 
2055  print '<tr class="oddeven"><td colspan="2" class="nohover">';
2056  if ($objp->statut >= 4) {
2057  if ($objp->statut == 4) {
2058  print $langs->trans("DateEndReal").' ';
2059  print $form->selectDate($dateactend, "end", $usehm, $usehm, ($objp->date_end_real > 0 ? 0 : 1), "closeline", 1, 1);
2060  }
2061  }
2062  print '</td>';
2063  print '<td class="center nohover">';
2064  print '</td></tr>';
2065 
2066  print '<tr class="oddeven">';
2067  print '<td class="nohover">'.$langs->trans("Comment").'</td><td class="nohover"><input class="quatrevingtpercent" type="text" class="flat" name="comment" value="'.dol_escape_htmltag(GETPOST('comment', 'alpha')).'"></td>';
2068  print '<td class="nohover right">';
2069  print '<input type="submit" class="button" name="close" value="'.$langs->trans("Disable").'"> &nbsp; ';
2070  print '<input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
2071  print '</td>';
2072  print '</tr>';
2073 
2074  print '</table>';
2075 
2076  print '</form>';
2077  }
2078  print '</div>';
2079  $cursorline++;
2080  }
2081  print '</div>';
2082 
2083  // Form to add new line
2084  if ($user->hasRight('contrat', 'creer') && ($object->statut == 0)) {
2085  $dateSelector = 1;
2086 
2087  print "\n";
2088  print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
2089  <input type="hidden" name="token" value="'.newToken().'">
2090  <input type="hidden" name="action" value="'.(($action != 'editline') ? 'addline' : 'updateline').'">
2091  <input type="hidden" name="mode" value="">
2092  <input type="hidden" name="id" value="'.$object->id.'">
2093  <input type="hidden" name="page_y" value="">
2094  <input type="hidden" name="backtopage" value="'.$backtopage.'">
2095  ';
2096 
2097  print '<div class="div-table-responsive-no-min">';
2098  print '<table id="tablelines" class="noborder noshadow" width="100%">'; // Array with (n*2)+1 lines
2099 
2100  // Form to add new line
2101  if ($action != 'editline') {
2102  $forcetoshowtitlelines = 1;
2103  if (empty($object->multicurrency_code)) {
2104  $object->multicurrency_code = $conf->currency; // TODO Remove this when multicurrency supported on contracts
2105  }
2106 
2107  // Add free products/services
2108 
2109  $parameters = array();
2110  $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2111  if ($reshook < 0) {
2112  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2113  }
2114  if (empty($reshook)) {
2115  $object->formAddObjectLine(1, $mysoc, $soc);
2116  }
2117  }
2118 
2119  print '</table>';
2120  print '</div>';
2121  print '</form>';
2122  }
2123 
2124  print dol_get_fiche_end();
2125 
2126  // Select mail models is same action as presend
2127  if (GETPOST('modelselected')) {
2128  $action = 'presend';
2129  }
2130 
2131  /*
2132  * Buttons
2133  */
2134  if ($user->socid == 0 && $action != 'presend' && $action != 'editline') {
2135  print '<div class="tabsAction">';
2136 
2137  $parameters = array();
2138  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2139 
2140  if (empty($reshook)) {
2141  $params = array(
2142  'attr' => array(
2143  'title' => '',
2144  'class' => 'classfortooltip'
2145  )
2146  );
2147 
2148  // Send
2149  if (empty($user->socid)) {
2150  if ($object->status == $object::STATUS_VALIDATED) {
2151  if ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('contrat', 'creer'))) {
2152  print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle', '', true, $params);
2153  } else {
2154  print dolGetButtonAction('', $langs->trans('SendMail'), 'default', '#', '', false, $params);
2155  }
2156  }
2157  }
2158 
2159  if ($object->status == $object::STATUS_DRAFT && $nbofservices) {
2160  if ($user->hasRight('contrat', 'creer')) {
2161  unset($params['attr']['title']);
2162  print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken(), '', true, $params);
2163  } else {
2164  $params['attr']['title'] = $langs->trans("NotEnoughPermissions");
2165  print dolGetButtonAction($langs->trans('Validate'), '', 'default', '#', '', false, $params);
2166  }
2167  }
2168  if ($object->status == $object::STATUS_VALIDATED) {
2169  if ($user->hasRight('contrat', 'creer')) {
2170  unset($params['attr']['title']);
2171  print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken(), '', true, $params);
2172  } else {
2173  $params['attr']['title'] = $langs->trans("NotEnoughPermissions");
2174  print dolGetButtonAction($langs->trans('Modify'), '', 'default', '#', '', false, $params);
2175  }
2176  }
2177 
2178  // Create ... buttons
2179  $arrayofcreatebutton = array();
2180  if (isModEnabled('order') && $object->status > 0 && $object->nbofservicesclosed < $nbofservices) {
2181  $arrayofcreatebutton[] = array(
2182  'url' => '/commande/card.php?action=create&token='.newToken().'&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id,
2183  'label' => $langs->trans('AddOrder'),
2184  'lang' => 'orders',
2185  'perm' => $user->hasRight('commande', 'creer')
2186  );
2187  }
2188  if (isModEnabled('invoice') && $object->status > 0 && $soc->client > 0) {
2189  $arrayofcreatebutton[] = array(
2190  'url' => '/compta/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id,
2191  'label' => $langs->trans('CreateBill'),
2192  'lang' => 'bills',
2193  'perm' => $user->hasRight('facture', 'creer')
2194  );
2195  }
2196  if (isModEnabled('supplier_invoice') && $object->status > 0 && $soc->fournisseur == 1) {
2197  $arrayofcreatebutton[] = array(
2198  'url' => '/fourn/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id,
2199  'label' => $langs->trans('AddSupplierInvoice'),
2200  'lang' => 'bills',
2201  'perm' => $user->hasRight('fournisseur', 'facture', 'creer')
2202  );
2203  }
2204  if (count($arrayofcreatebutton)) {
2205  unset($params['attr']['title']);
2206  print dolGetButtonAction('', $langs->trans("Create"), 'default', $arrayofcreatebutton, '', true, $params);
2207  }
2208 
2209  if ($object->nbofservicesclosed > 0 || $object->nbofserviceswait > 0) {
2210  if ($user->hasRight('contrat', 'activer')) {
2211  unset($params['attr']['title']);
2212  print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=activate&token='.newToken(), '', true, $params);
2213  } else {
2214  unset($params['attr']['title']);
2215  print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', '#', '', false, $params);
2216  }
2217  }
2218  if ($object->nbofservicesclosed < $nbofservices) {
2219  if ($user->hasRight('contrat', 'desactiver')) {
2220  unset($params['attr']['title']);
2221  print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=close&token='.newToken(), '', true, $params);
2222  } else {
2223  unset($params['attr']['title']);
2224  print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', '#', '', false, $params);
2225  }
2226 
2227  //if (! $numactive)
2228  //{
2229  //}
2230  //else
2231  //{
2232  // print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("CloseRefusedBecauseOneServiceActive").'">'.$langs->trans("Close").'</a></div>';
2233  //}
2234  }
2235 
2236  if (getDolGlobalString('CONTRACT_HIDE_CLOSED_SERVICES_BY_DEFAULT') && $object->nbofservicesclosed > 0) {
2237  if ($action == 'showclosedlines') {
2238  print '<div class="inline-block divButAction"><a class="butAction" id="btnhideclosedlines" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=hideclosedlines">'.$langs->trans("HideClosedServices").'</a></div>';
2239  } else {
2240  print '<div class="inline-block divButAction"><a class="butAction" id="btnshowclosedlines" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=showclosedlines">'.$langs->trans("ShowClosedServices").'</a></div>';
2241  }
2242  }
2243 
2244  // Clone
2245  if ($user->hasRight('contrat', 'creer')) {
2246  unset($params['attr']['title']);
2247  print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&token='.newToken(), '', true, $params);
2248  }
2249 
2250  // Delete
2251  unset($params['attr']['title']);
2252  print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), '', $permissiontodelete, $params);
2253  }
2254 
2255  print "</div>";
2256  }
2257 
2258  if ($action != 'presend') {
2259  print '<div class="fichecenter"><div class="fichehalfleft">';
2260 
2261  /*
2262  * Generated documents
2263  */
2264  $filename = dol_sanitizeFileName($object->ref);
2265  $filedir = $conf->contrat->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->ref);
2266  $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2267  $genallowed = $user->hasRight('contrat', 'lire');
2268  $delallowed = $user->hasRight('contrat', 'creer');
2269 
2270 
2271  print $formfile->showdocuments('contract', $filename, $filedir, $urlsource, $genallowed, $delallowed, ($object->model_pdf ? $object->model_pdf : getDolGlobalString('CONTRACT_ADDON_PDF')), 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang, '', $object);
2272 
2273 
2274  // Show links to link elements
2275  $linktoelem = $form->showLinkToObjectBlock($object, null, array('contrat'));
2276  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2277 
2278  // Show online signature link
2279  if ($object->statut != Contrat::STATUS_DRAFT && getDolGlobalString('CONTRACT_ALLOW_ONLINESIGN')) {
2280  print '<br><!-- Link to sign -->';
2281  require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
2282 
2283  print showOnlineSignatureUrl('contract', $object->ref).'<br>';
2284  }
2285 
2286  print '</div><div class="fichehalfright">';
2287 
2288  $MAXEVENT = 10;
2289 
2290  $morehtmlcenter = '<div class="nowraponall">';
2291  $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/contrat/messaging.php?id='.$object->id);
2292  $morehtmlcenter .= dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/contrat/agenda.php?id='.$object->id);
2293  $morehtmlcenter .= '</div>';
2294 
2295 
2296  // List of actions on element
2297  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2298  $formactions = new FormActions($db);
2299  $somethingshown = $formactions->showactions($object, 'contract', $socid, 1, 'listactions', $MAXEVENT, '', $morehtmlcenter);
2300 
2301  print '</div></div>';
2302  }
2303 
2304  // Presend form
2305  $modelmail = 'contract';
2306  $defaulttopic = 'SendContractRef';
2307  $diroutput = $conf->contrat->multidir_output[$object->entity];
2308  $trackid = 'con'.$object->id;
2309 
2310  include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2311  }
2312 }
2313 
2314 
2315 llxFooter();
2316 
2317 $db->close();
2318 ?>
2319 
2320 <?php
2321 if (isModEnabled('margin') && $action == 'editline') {
2322  // TODO Why this ? To manage margin on contracts ??>
2323 <script type="text/javascript">
2324 $(document).ready(function() {
2325  var idprod = $("input[name='idprod']").val();
2326  var fournprice = $("input[name='fournprice']").val();
2327  var token = '<?php echo currentToken(); ?>'; // For AJAX Call we use old 'token' and not 'newtoken'
2328  if (idprod > 0) {
2329  $.post('<?php echo DOL_URL_ROOT; ?>/fourn/ajax/getSupplierPrices.php', {
2330  'idprod': idprod,
2331  'token': token
2332  }, function(data) {
2333  if (data.length > 0) {
2334  var options = '';
2335  var trouve=false;
2336  $(data).each(function() {
2337  options += '<option value="'+this.id+'" price="'+this.price+'"';
2338  if (fournprice > 0) {
2339  if (this.id == fournprice) {
2340  options += ' selected';
2341  $("#buying_price").val(this.price);
2342  trouve = true;
2343  }
2344  }
2345  options += '>'+this.label+'</option>';
2346  });
2347  options += '<option value=null'+(trouve?'':' selected')+'><?php echo $langs->trans("InputPrice"); ?></option>';
2348  $("#fournprice").html(options);
2349  if (trouve) {
2350  $("#buying_price").hide();
2351  $("#fournprice").show();
2352  }
2353  else {
2354  $("#buying_price").show();
2355  }
2356  $("#fournprice").change(function() {
2357  var selval = $(this).find('option:selected').attr("price");
2358  if (selval)
2359  $("#buying_price").val(selval).hide();
2360  else
2361  $('#buying_price').show();
2362  });
2363  }
2364  else {
2365  $("#fournprice").hide();
2366  $('#buying_price').show();
2367  }
2368  },
2369  'json');
2370  }
2371  else {
2372  $("#fournprice").hide();
2373  $('#buying_price').show();
2374  }
2375 });
2376 </script>
2377  <?php
2378 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action=='set') elseif($action=='specimen') elseif($action=='setmodel') elseif($action=='del') elseif($action=='setdoc') $formactions
View.
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:55
llxFooter()
Empty footer.
Definition: wrapper.php:69
Class to manage contracts.
Class to manage lines of contracts.
Class to manage a WYSIWYG editor.
Class to manage standard extra fields.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class to manage building of HTML components.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:50
$parameters
Actions.
Definition: card.php:84
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('MAIN_USE_NEW_SUPPLIERMOD') && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:745
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
contract_prepare_head(Contrat $object)
Prepare array with list of tabs.
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:124
dol_move_dir($srcdir, $destdir, $overwriteifexists=1, $indexdatabase=1, $renamedircontent=1)
Move a directory into another name.
Definition: files.lib.php:1175
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
img_down($titlealt='default', $selected=0, $moreclass='')
Show down arrow logo.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
GETPOSTISARRAY($paramname, $method=0)
Return true if the parameter $paramname is submit from a POST OR GET as an array.
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
img_up($titlealt='default', $selected=0, $moreclass='')
Show top arrow logo.
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
$formconfirm
if ($action == 'delbookkeepingyear') {
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:123
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.