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