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