dolibarr 19.0.4
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
771 $objectline->fk_product = GETPOST('idprod', 'int');
772 $objectline->description = GETPOST('product_desc', 'restricthtml');
773 $objectline->price_ht = $price_ht;
774 $objectline->subprice = price2num(GETPOST('elprice'), 'MU');
775 $objectline->qty = price2num(GETPOST('elqty'), 'MS');
776 $objectline->remise_percent = $remise_percent;
777 $objectline->tva_tx = ($txtva ? $txtva : 0); // Field may be disabled, so we use vat rate 0
778 $objectline->vat_src_code = $vat_src_code;
779 $objectline->localtax1_tx = is_numeric($localtax1_tx) ? $localtax1_tx : 0;
780 $objectline->localtax2_tx = is_numeric($localtax2_tx) ? $localtax2_tx : 0;
781 $objectline->date_start = $date_start_update;
782 $objectline->date_start_real = $date_start_real_update;
783 $objectline->date_end = $date_end_update;
784 $objectline->date_end_real = $date_end_real_update;
785 $objectline->user_closing_id = $user->id;
786 //$objectline->fk_fournprice = $fk_fournprice;
787 $objectline->pa_ht = $pa_ht;
788 $objectline->rang = $objectline->rang;
789
790 if ($fk_unit > 0) {
791 $objectline->fk_unit = GETPOST('unit');
792 } else {
793 $objectline->fk_unit = null;
794 }
795
796 // Extrafields
797 $extralabelsline = $extrafields->fetch_name_optionals_label($objectline->table_element);
798 $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef);
799
800 if (is_array($array_options) && count($array_options) > 0) {
801 // We replace values in this->line->array_options only for entries defined into $array_options
802 foreach ($array_options as $key => $value) {
803 $objectline->array_options[$key] = $array_options[$key];
804 }
805 }
806
807 // TODO verifier price_min si fk_product et multiprix
808
809 $result = $objectline->update($user);
810 if ($result < 0) {
811 $error++;
812 $action = 'editline';
813 $_GET['rowid'] = GETPOST('elrowid');
814 setEventMessages($objectline->error, $objectline->errors, 'errors');
815 }
816 }
817
818 if (!$error) {
819 $db->commit();
820 } else {
821 $db->rollback();
822 }
823 } elseif ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
824 $result = $object->deleteline(GETPOST('lineid', 'int'), $user);
825
826 if ($result >= 0) {
827 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
828 exit;
829 } else {
830 setEventMessages($object->error, $object->errors, 'errors');
831 }
832 } elseif ($action == 'confirm_valid' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
833 $result = $object->validate($user);
834
835 if ($result > 0) {
836 // Define output language
837 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
838 $outputlangs = $langs;
839 $newlang = '';
840 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
841 $newlang = GETPOST('lang_id', 'aZ09');
842 }
843 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
844 $newlang = $object->thirdparty->default_lang;
845 }
846 if (!empty($newlang)) {
847 $outputlangs = new Translate("", $conf);
848 $outputlangs->setDefaultLang($newlang);
849 }
850 $model = $object->model_pdf;
851 $ret = $object->fetch($id); // Reload to get new records
852
853 $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
854 }
855 } else {
856 setEventMessages($object->error, $object->errors, 'errors');
857 }
858 } elseif ($action == 'reopen' && $user->hasRight('contrat', 'creer')) {
859 $result = $object->reopen($user);
860 if ($result < 0) {
861 setEventMessages($object->error, $object->errors, 'errors');
862 }
863 } elseif ($action == 'confirm_close' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
864 // Close all lines
865 $result = $object->closeAll($user);
866 if ($result < 0) {
867 setEventMessages($object->error, $object->errors, 'errors');
868 }
869 } elseif ($action == 'confirm_activate' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
870 $date_start = dol_mktime(12, 0, 0, GETPOST('d_startmonth'), GETPOST('d_startday'), GETPOST('d_startyear'));
871 $date_end = dol_mktime(12, 0, 0, GETPOST('d_endmonth'), GETPOST('d_endday'), GETPOST('d_endyear'));
872 $comment = GETPOST('comment', 'alpha');
873 $result = $object->activateAll($user, $date_start, 0, $comment, $date_end);
874 if ($result < 0) {
875 setEventMessages($object->error, $object->errors, 'errors');
876 }
877 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && $user->hasRight('contrat', 'supprimer')) {
878 $result = $object->delete($user);
879 if ($result >= 0) {
880 header("Location: list.php?restore_lastsearch_values=1");
881 return;
882 } else {
883 setEventMessages($object->error, $object->errors, 'errors');
884 }
885 } elseif ($action == 'confirm_move' && $confirm == 'yes' && $user->hasRight('contrat', 'creer')) {
886 if (GETPOST('newcid') > 0) {
887 $contractline = new ContratLigne($db);
888 $result = $contractline->fetch(GETPOSTINT('lineid'));
889 $contractline->fk_contrat = GETPOSTINT('newcid');
890 $result = $contractline->update($user, 1);
891 if ($result >= 0) {
892 header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
893 return;
894 } else {
895 setEventMessages($object->error, $object->errors, 'errors');
896 }
897 } else {
898 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("RefNewContract")), null, 'errors');
899 }
900 } elseif ($action == 'update_extras' && $permissiontoadd) {
901 $object->oldcopy = dol_clone($object, 2);
902
903 $attribute = GETPOST('attribute', 'alphanohtml');
904
905 // Fill array 'array_options' with data from update form
906 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute);
907 if ($ret < 0) {
908 setEventMessages($extrafields->error, $object->errors, 'errors');
909 $error++;
910 }
911
912 if (!$error) {
913 $result = $object->updateExtraField($attribute, 'CONTRACT_MODIFY');
914 if ($result < 0) {
915 setEventMessages($object->error, $object->errors, 'errors');
916 $error++;
917 }
918 }
919
920 if ($error) {
921 $action = 'edit_extras';
922 }
923 } elseif ($action == 'setref_supplier' && $permissiontoadd) {
924 if (!$cancel) {
925 $object->oldcopy = dol_clone($object, 2);
926
927 $result = $object->setValueFrom('ref_supplier', GETPOST('ref_supplier', 'alpha'), '', null, 'text', '', $user, 'CONTRACT_MODIFY');
928 if ($result < 0) {
929 setEventMessages($object->error, $object->errors, 'errors');
930 $action = 'editref_supplier';
931 } else {
932 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
933 exit;
934 }
935 } else {
936 header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
937 exit;
938 }
939 } elseif ($action == 'setref_customer' && $permissiontoadd) {
940 if (!$cancel) {
941 $object->oldcopy = dol_clone($object, 2);
942
943 $result = $object->setValueFrom('ref_customer', GETPOST('ref_customer', 'alpha'), '', null, 'text', '', $user, 'CONTRACT_MODIFY');
944 if ($result < 0) {
945 setEventMessages($object->error, $object->errors, 'errors');
946 $action = 'editref_customer';
947 } else {
948 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
949 exit;
950 }
951 } else {
952 header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
953 exit;
954 }
955 } elseif ($action == 'setref' && $permissiontoadd) {
956 if (!$cancel) {
957 $result = $object->fetch($id);
958 if ($result < 0) {
959 setEventMessages($object->error, $object->errors, 'errors');
960 }
961
962 $old_ref = $object->ref;
963
964 $result = $object->setValueFrom('ref', GETPOST('ref', 'alpha'), '', null, 'text', '', $user, 'CONTRACT_MODIFY');
965 if ($result < 0) {
966 setEventMessages($object->error, $object->errors, 'errors');
967 $action = 'editref';
968 } else {
969 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
970 $old_filedir = $conf->contrat->multidir_output[$object->entity].'/'.dol_sanitizeFileName($old_ref);
971 $new_filedir = $conf->contrat->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref);
972
973 // Rename directory of contract with new name
974 dol_move_dir($old_filedir, $new_filedir);
975
976 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
977 exit;
978 }
979 } else {
980 header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
981 exit;
982 }
983 } elseif ($action == 'setdate_contrat' && $permissiontoadd) {
984 if (!$cancel) {
985 $result = $object->fetch($id);
986 if ($result < 0) {
987 setEventMessages($object->error, $object->errors, 'errors');
988 }
989 $datacontrat = dol_mktime(GETPOST('date_contrathour'), GETPOST('date_contratmin'), 0, GETPOST('date_contratmonth'), GETPOST('date_contratday'), GETPOST('date_contratyear'));
990 $result = $object->setValueFrom('date_contrat', $datacontrat, '', null, 'date', '', $user, 'CONTRACT_MODIFY');
991 if ($result < 0) {
992 setEventMessages($object->error, $object->errors, 'errors');
993 $action = 'editdate_contrat';
994 } else {
995 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
996 exit;
997 }
998 } else {
999 header("Location: ".$_SERVER['PHP_SELF']."?id=".$id);
1000 exit;
1001 }
1002 }
1003
1004 // Actions when printing a doc from card
1005 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
1006
1007 // Actions to build doc
1008 $upload_dir = $conf->contrat->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity];
1009 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
1010
1011 // Actions to send emails
1012 $triggersendname = 'CONTRACT_SENTBYMAIL';
1013 $paramname = 'id';
1014 $mode = 'emailfromcontract';
1015 $trackid = 'con'.$object->id;
1016 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
1017
1018
1019 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB') && $user->hasRight('contrat', 'creer')) {
1020 if ($action == 'addcontact') {
1021 $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid'));
1022 $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
1023 $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
1024
1025 if ($result >= 0) {
1026 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1027 exit;
1028 } else {
1029 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1030 $langs->load("errors");
1031 setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
1032 } else {
1033 setEventMessages($object->error, $object->errors, 'errors');
1034 }
1035 }
1036 } elseif ($action == 'swapstatut') {
1037 // bascule du statut d'un contact
1038 $result = $object->swapContactStatus(GETPOST('ligne', 'int'));
1039 } elseif ($action == 'deletecontact') {
1040 // Efface un contact
1041 $result = $object->delete_contact(GETPOST('lineid', 'int'));
1042
1043 if ($result >= 0) {
1044 header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
1045 exit;
1046 } else {
1047 setEventMessages($object->error, $object->errors, 'errors');
1048 }
1049 }
1050 }
1051
1052 // Action clone object
1053 if ($action == 'confirm_clone' && $confirm == 'yes') {
1054 if (!GETPOST('socid', 3)) {
1055 setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
1056 } else {
1057 if ($object->id > 0) {
1058 $result = $object->createFromClone($user, $socid);
1059 if ($result > 0) {
1060 header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
1061 exit();
1062 } else {
1063 if (count($object->errors) > 0) {
1064 setEventMessages($object->error, $object->errors, 'errors');
1065 }
1066 $action = '';
1067 }
1068 }
1069 }
1070 }
1071}
1072
1073
1074/*
1075 * View
1076 */
1077
1078$help_url = 'EN:Module_Contracts|FR:Module_Contrat';
1079
1080$title = $object->ref." - ".$langs->trans('Contract');
1081if ($action == 'create') {
1082 $title = $langs->trans("NewContract");
1083}
1084
1085llxHeader('', $title, $help_url);
1086
1087$form = new Form($db);
1088$formfile = new FormFile($db);
1089if (isModEnabled('project')) {
1090 $formproject = new FormProjets($db);
1091}
1092
1093// Load object modContract
1094$module = (getDolGlobalString('CONTRACT_ADDON') ? $conf->global->CONTRACT_ADDON : 'mod_contract_serpis');
1095if (substr($module, 0, 13) == 'mod_contract_' && substr($module, -3) == 'php') {
1096 $module = substr($module, 0, dol_strlen($module) - 4);
1097}
1098$result = dol_include_once('/core/modules/contract/'.$module.'.php');
1099if ($result > 0) {
1100 $modCodeContract = new $module();
1101}
1102
1103// Create
1104if ($action == 'create') {
1105 $objectsrc = null;
1106 print load_fiche_titre($langs->trans('NewContract'), '', 'contract');
1107
1108 $soc = new Societe($db);
1109 if ($socid > 0) {
1110 $soc->fetch($socid);
1111 }
1112
1113 if (GETPOST('origin') && GETPOST('originid', 'int')) {
1114 // Parse element/subelement (ex: project_task)
1115 $regs = array();
1116 $element = $subelement = GETPOST('origin');
1117 if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'), $regs)) {
1118 $element = $regs[1];
1119 $subelement = $regs[2];
1120 }
1121
1122 if ($element == 'project') {
1123 $projectid = GETPOST('originid', 'int');
1124 } else {
1125 // For compatibility
1126 if ($element == 'order' || $element == 'commande') {
1127 $element = $subelement = 'commande';
1128 }
1129 if ($element == 'propal') {
1130 $element = 'comm/propal';
1131 $subelement = 'propal';
1132 }
1133 if ($element == 'invoice' || $element == 'facture') {
1134 $element = 'compta/facture';
1135 $subelement = 'facture';
1136 }
1137
1138 dol_include_once('/'.$element.'/class/'.$subelement.'.class.php');
1139
1140 $classname = ucfirst($subelement);
1141 $objectsrc = new $classname($db);
1142 $objectsrc->fetch($originid);
1143 if (empty($objectsrc->lines) && method_exists($objectsrc, 'fetch_lines')) {
1144 $objectsrc->fetch_lines();
1145 }
1146 $objectsrc->fetch_thirdparty();
1147
1148 // Replicate extrafields
1149 $objectsrc->fetch_optionals();
1150 $object->array_options = $objectsrc->array_options;
1151
1152 $projectid = (!empty($objectsrc->fk_project) ? $objectsrc->fk_project : '');
1153
1154 $soc = $objectsrc->thirdparty;
1155
1156 $note_private = (!empty($objectsrc->note_private) ? $objectsrc->note_private : '');
1157 $note_public = (!empty($objectsrc->note_public) ? $objectsrc->note_public : '');
1158
1159 // Object source contacts list
1160 $srccontactslist = $objectsrc->liste_contact(-1, 'external', 1);
1161 }
1162 } else {
1163 $projectid = GETPOST('projectid', 'int');
1164 $note_private = GETPOST("note_private");
1165 $note_public = GETPOST("note_public");
1166 }
1167
1168 $object->date_contrat = dol_now();
1169
1170 print '<form name="form_contract" action="'.$_SERVER["PHP_SELF"].'" method="post">';
1171 print '<input type="hidden" name="token" value="'.newToken().'">';
1172 print '<input type="hidden" name="action" value="add">';
1173 print '<input type="hidden" name="socid" value="'.$soc->id.'">'."\n";
1174 print '<input type="hidden" name="remise_percent" value="0">';
1175 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1176
1177 print dol_get_fiche_head();
1178
1179 print '<table class="border centpercent">';
1180
1181 // Ref
1182 print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans('Ref').'</td><td>';
1183 if (!empty($modCodeContract->code_auto)) {
1184 $tmpcode = $langs->trans("Draft");
1185 } else {
1186 $tmpcode = '<input name="ref" class="maxwidth100" maxlength="128" value="'.dol_escape_htmltag(GETPOST('ref') ? GETPOST('ref') : $tmpcode).'">';
1187 }
1188 print $tmpcode;
1189 print '</td></tr>';
1190
1191 // Ref customer
1192 print '<tr><td>'.$langs->trans('RefCustomer').'</td>';
1193 print '<td><input type="text" class="maxwidth150" name="ref_customer" id="ref_customer" value="'.dol_escape_htmltag(GETPOST('ref_customer', 'alpha')).'"></td></tr>';
1194
1195 // Ref supplier
1196 print '<tr><td>'.$langs->trans('RefSupplier').'</td>';
1197 print '<td><input type="text" class="maxwidth150" name="ref_supplier" id="ref_supplier" value="'.dol_escape_htmltag(GETPOST('ref_supplier', 'alpha')).'"></td></tr>';
1198
1199 // Thirdparty
1200 print '<tr>';
1201 print '<td class="fieldrequired">'.$langs->trans('ThirdParty').'</td>';
1202 if ($socid > 0) {
1203 print '<td>';
1204 print $soc->getNomUrl(1);
1205 print '<input type="hidden" name="socid" value="'.$soc->id.'">';
1206 print '</td>';
1207 } else {
1208 print '<td>';
1209 print img_picto('', 'company', 'class="pictofixedwidth"');
1210 print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
1211 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>';
1212 print '</td>';
1213 }
1214 print '</tr>'."\n";
1215
1216 if ($socid > 0) {
1217 // Ligne info remises tiers
1218 print '<tr><td>'.$langs->trans('Discounts').'</td><td>';
1219 if ($soc->remise_percent) {
1220 print $langs->trans("CompanyHasRelativeDiscount", $soc->remise_percent).' ';
1221 } else {
1222 print '<span class="hideonsmartphone">'.$langs->trans("CompanyHasNoRelativeDiscount").'. </span>';
1223 }
1224 $absolute_discount = $soc->getAvailableDiscounts();
1225 if ($absolute_discount) {
1226 print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->trans("Currency".$conf->currency)).'.';
1227 } else {
1228 print '<span class="hideonsmartphone">'.$langs->trans("CompanyHasNoAbsoluteDiscount").'.</span>';
1229 }
1230 print '</td></tr>';
1231 }
1232
1233 // Commercial suivi
1234 print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("TypeContact_contrat_internal_SALESREPFOLL").'</span></td><td>';
1235 print img_picto('', 'user', 'class="pictofixedwidth"');
1236 print $form->select_dolusers(GETPOST("commercial_suivi_id") ? GETPOST("commercial_suivi_id") : $user->id, 'commercial_suivi_id', 1, '');
1237 print '</td></tr>';
1238
1239 // Commercial signature
1240 print '<tr><td class="nowrap"><span class="fieldrequired">'.$langs->trans("TypeContact_contrat_internal_SALESREPSIGN").'</span></td><td>';
1241 print img_picto('', 'user', 'class="pictofixedwidth"');
1242 print $form->select_dolusers(GETPOST("commercial_signature_id") ? GETPOST("commercial_signature_id") : $user->id, 'commercial_signature_id', 1, '');
1243 print '</td></tr>';
1244
1245 print '<tr><td><span class="fieldrequired">'.$langs->trans("Date").'</span></td><td>';
1246 print img_picto('', 'action', 'class="pictofixedwidth"');
1247 print $form->selectDate($datecontrat, '', 0, 0, '', "contrat");
1248 print "</td></tr>";
1249
1250 // Project
1251 if (isModEnabled('project')) {
1252 $langs->load('projects');
1253
1254 $formproject = new FormProjets($db);
1255
1256 print '<tr><td>'.$langs->trans("Project").'</td><td>';
1257 print img_picto('', 'project', 'class="pictofixedwidth"');
1258 $formproject->select_projects(($soc->id > 0 ? $soc->id : -1), $projectid, "projectid", 0, 0, 1, 1);
1259 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>';
1260 print "</td></tr>";
1261 }
1262
1263 print '<tr><td>'.$langs->trans("NotePublic").'</td><td class="tdtop">';
1264 $doleditor = new DolEditor('note_public', $note_public, '', '100', 'dolibarr_notes', 'In', 1, true, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PUBLIC') ? 0 : 1, ROWS_3, '90%');
1265 print $doleditor->Create(1);
1266 print '</td></tr>';
1267
1268 if (empty($user->socid)) {
1269 print '<tr><td>'.$langs->trans("NotePrivate").'</td><td class="tdtop">';
1270 $doleditor = new DolEditor('note_private', $note_private, '', '100', 'dolibarr_notes', 'In', 1, true, !getDolGlobalString('FCKEDITOR_ENABLE_NOTE_PRIVATE') ? 0 : 1, ROWS_3, '90%');
1271 print $doleditor->Create(1);
1272 print '</td></tr>';
1273 }
1274
1275 // Other attributes
1276 $parameters = array('objectsrc' => $objectsrc, 'colspan' => ' colspan="3"', 'cols' => '3');
1277 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1278 print $hookmanager->resPrint;
1279
1280 // Other attributes
1281 if (empty($reshook)) {
1282 print $object->showOptionals($extrafields, 'create', $parameters);
1283 }
1284
1285 print "</table>\n";
1286
1287 print dol_get_fiche_end();
1288
1289 print $form->buttonsSaveCancel("Create");
1290
1291 if (is_object($objectsrc)) {
1292 print '<input type="hidden" name="origin" value="'.$objectsrc->element.'">';
1293 print '<input type="hidden" name="originid" value="'.$objectsrc->id.'">';
1294
1295 if (!getDolGlobalString('CONTRACT_SUPPORT_PRODUCTS')) {
1296 print '<br>'.$langs->trans("Note").': '.$langs->trans("OnlyLinesWithTypeServiceAreUsed");
1297 }
1298 }
1299
1300 print "</form>\n";
1301} else {
1302 // View and edit mode
1303 $now = dol_now();
1304
1305 if ($object->id > 0) {
1306 $object->fetch_thirdparty();
1307
1308 $soc = $object->thirdparty; // $soc is used later
1309
1310 $result = $object->fetch_lines(); // This also init $this->nbofserviceswait, $this->nbofservicesopened, $this->nbofservicesexpired=, $this->nbofservicesclosed
1311 if ($result < 0) {
1312 dol_print_error($db, $object->error);
1313 }
1314
1315 $nbofservices = count($object->lines);
1316
1317 $author = new User($db);
1318 $author->fetch($object->user_author_id);
1319
1320 $commercial_signature = new User($db);
1321 $commercial_signature->fetch($object->commercial_signature_id);
1322
1323 $commercial_suivi = new User($db);
1324 $commercial_suivi->fetch($object->commercial_suivi_id);
1325
1326 $head = contract_prepare_head($object);
1327
1328 $hselected = 0;
1329 $formconfirm = '';
1330
1331 print dol_get_fiche_head($head, $hselected, $langs->trans("Contract"), -1, 'contract');
1332
1333
1334 if ($action == 'delete') {
1335 //Confirmation de la suppression du contrat
1336 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("DeleteAContract"), $langs->trans("ConfirmDeleteAContract"), "confirm_delete", '', 0, 1);
1337 } elseif ($action == 'valid') {
1338 //Confirmation de la validation
1339 $ref = substr($object->ref, 1, 4);
1340 if ($ref == 'PROV' && !empty($modCodeContract->code_auto)) {
1341 $numref = $object->getNextNumRef($object->thirdparty);
1342 } else {
1343 $numref = $object->ref;
1344 }
1345 $text = $langs->trans('ConfirmValidateContract', $numref);
1346 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ValidateAContract"), $text, "confirm_valid", '', 0, 1);
1347 } elseif ($action == 'close') {
1348 // Confirmation de la fermeture
1349 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("CloseAContract"), $langs->trans("ConfirmCloseContract"), "confirm_close", '', 0, 1);
1350 } elseif ($action == 'activate') {
1351 $formquestion = array(
1352 array('type' => 'date', 'name' => 'd_start', 'label' => $langs->trans("DateServiceActivate"), 'value' => dol_now()),
1353 array('type' => 'date', 'name' => 'd_end', 'label' => $langs->trans("DateEndPlanned"), /*'value' => $form->selectDate('', "end", $usehm, $usehm, '', "active", 1, 0),*/ '', ''),
1354 array('type' => 'text', 'name' => 'comment', 'label' => $langs->trans("Comment"), 'value' => '', '', '', 'class' => 'minwidth300', 'moreattr'=>'autofocus')
1355 );
1356 $formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ActivateAllOnContract"), $langs->trans("ConfirmActivateAllOnContract"), "confirm_activate", $formquestion, 'yes', 1, 280);
1357 } elseif ($action == 'clone') {
1358 $filter = '(s.client:IN:1,2,3)';
1359 // Clone confirmation
1360 $formquestion = array(array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter)));
1361 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneContract', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
1362 }
1363
1364
1365 // Call Hook formConfirm
1366 $parameters = array(
1367 'formConfirm' => $formconfirm,
1368 'id' => $id,
1369 //'lineid' => $lineid,
1370 );
1371 // Note that $action and $object may have been modified by hook
1372 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
1373 if (empty($reshook)) {
1374 $formconfirm .= $hookmanager->resPrint;
1375 } elseif ($reshook > 0) {
1376 $formconfirm = $hookmanager->resPrint;
1377 }
1378
1379 // Print form confirm
1380 print $formconfirm;
1381
1382
1383 // Contract
1384 if ($object->status == $object::STATUS_DRAFT && $user->hasRight('contrat', 'creer')) {
1385 print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="POST">';
1386 print '<input type="hidden" name="token" value="'.newToken().'">';
1387 print '<input type="hidden" name="action" value="setremise">';
1388 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1389 }
1390
1391 // Contract card
1392
1393 $linkback = '<a href="'.DOL_URL_ROOT.'/contrat/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
1394
1395
1396 $morehtmlref = '';
1397 if (!empty($modCodeContract->code_auto)) {
1398 $morehtmlref .= $object->ref;
1399 } else {
1400 $morehtmlref .= $form->editfieldkey("", 'ref', $object->ref, $object, $user->hasRight('contrat', 'creer'), 'string', '', 0, 3);
1401 $morehtmlref .= $form->editfieldval("", 'ref', $object->ref, $object, $user->hasRight('contrat', 'creer'), 'string', '', 0, 2);
1402 }
1403
1404 $morehtmlref .= '<div class="refidno">';
1405 // Ref customer
1406 $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_customer', $object->ref_customer, $object, $user->hasRight('contrat', 'creer'), 'string', '', 0, 1);
1407 $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');
1408 // Ref supplier
1409 $morehtmlref .= '<br>';
1410 $morehtmlref .= $form->editfieldkey("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('contrat', 'creer'), 'string', '', 0, 1);
1411 $morehtmlref .= $form->editfieldval("RefSupplier", 'ref_supplier', $object->ref_supplier, $object, $user->hasRight('contrat', 'creer'), 'string', '', null, null, '', 1, 'getFormatedSupplierRef');
1412 // Thirdparty
1413 $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
1414 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
1415 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/contrat/list.php?socid='.$object->thirdparty->id.'&search_name='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherContracts").'</a>)';
1416 }
1417 // Project
1418 if (isModEnabled('project')) {
1419 $langs->load("projects");
1420 $morehtmlref .= '<br>';
1421 if ($permissiontoadd) {
1422 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
1423 if ($action != 'classify') {
1424 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
1425 }
1426 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
1427 } else {
1428 if (!empty($object->fk_project)) {
1429 $proj = new Project($db);
1430 $proj->fetch($object->fk_project);
1431 $morehtmlref .= $proj->getNomUrl(1);
1432 if ($proj->title) {
1433 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
1434 }
1435 }
1436 }
1437 }
1438 $morehtmlref .= '</div>';
1439
1440
1441 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'none', $morehtmlref);
1442
1443
1444 print '<div class="fichecenter">';
1445 print '<div class="underbanner clearboth"></div>';
1446
1447
1448 print '<table class="border tableforfield" width="100%">';
1449
1450 // Line info of thirdparty discounts
1451 print '<tr><td class="titlefield">'.$langs->trans('Discount').'</td><td colspan="3">';
1452 if ($object->thirdparty->remise_percent) {
1453 print $langs->trans("CompanyHasRelativeDiscount", $object->thirdparty->remise_percent).'. ';
1454 } else {
1455 print '<span class="hideonsmartphone">'.$langs->trans("CompanyHasNoRelativeDiscount").'. </span>';
1456 }
1457 $absolute_discount = $object->thirdparty->getAvailableDiscounts();
1458 if ($absolute_discount) {
1459 print $langs->trans("CompanyHasAbsoluteDiscount", price($absolute_discount), $langs->trans("Currency".$conf->currency)).'.';
1460 } else {
1461 print '<span class="hideonsmartphone">'.$langs->trans("CompanyHasNoAbsoluteDiscount").'.</span>';
1462 }
1463 print '</td></tr>';
1464
1465 // Date
1466 print '<tr>';
1467 print '<td class="titlefield">';
1468 print $form->editfieldkey("Date", 'date_contrat', $object->date_contrat, $object, $user->hasRight('contrat', 'creer'));
1469 print '</td><td>';
1470 print $form->editfieldval("Date", 'date_contrat', $object->date_contrat, $object, $user->hasRight('contrat', 'creer'), 'datehourpicker');
1471 print '</td>';
1472 print '</tr>';
1473
1474 // Other attributes
1475 $cols = 3;
1476 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1477
1478 print "</table>";
1479
1480 print '</div>';
1481
1482 if ($object->status == $object::STATUS_DRAFT && $user->hasRight('contrat', 'creer')) {
1483 print '</form>';
1484 }
1485
1486 echo '<br>';
1487
1488 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
1489 $blocname = 'contacts';
1490 $title = $langs->trans('ContactsAddresses');
1491 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
1492 }
1493
1494 if (getDolGlobalString('MAIN_DISABLE_NOTES_TAB')) {
1495 $blocname = 'notes';
1496 $title = $langs->trans('Notes');
1497 include DOL_DOCUMENT_ROOT.'/core/tpl/bloc_showhide.tpl.php';
1498 }
1499
1500
1501 $arrayothercontracts = $object->getListOfContracts('others'); // array or -1 if technical error
1502
1503 /*
1504 * Lines of contracts
1505 */
1506
1507 // Add products/services form
1508 //$forceall = 1;
1509 global $inputalsopricewithtax;
1510 $inputalsopricewithtax = 1;
1511
1512 $productstatic = new Product($db);
1513
1514 $usemargins = 0;
1515 if (isModEnabled('margin') && !empty($object->element) && in_array($object->element, array('facture', 'propal', 'commande'))) {
1516 $usemargins = 1;
1517 }
1518
1519 // Title line for service
1520 $cursorline = 1;
1521
1522
1523 print '<div id="contrat-lines-container" id="contractlines" data-contractid="'.$object->id.'" data-element="'.$object->element.'" >';
1524 while ($cursorline <= $nbofservices) {
1525 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.'" >';
1526 print '<form name="update" id="addproduct" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'" method="post">';
1527 print '<input type="hidden" name="token" value="'.newToken().'">';
1528 print '<input type="hidden" name="action" value="updateline">';
1529 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1530 print '<input type="hidden" name="elrowid" value="'.$object->lines[$cursorline - 1]->id.'">';
1531 print '<input type="hidden" name="fournprice" value="'.(!empty($object->lines[$cursorline - 1]->fk_fournprice) ? $object->lines[$cursorline - 1]->fk_fournprice : 0).'">';
1532
1533 // Area with common detail of line
1534 print '<div class="div-table-responsive-no-min">';
1535 print '<table class="notopnoleftnoright allwidth tableforservicepart1 centpercent">';
1536
1537 $sql = "SELECT cd.rowid, cd.statut, cd.label as label_det, cd.fk_product, cd.product_type, cd.description, cd.price_ht, cd.qty,";
1538 $sql .= " cd.tva_tx, cd.vat_src_code, cd.remise_percent, cd.info_bits, cd.subprice, cd.multicurrency_subprice,";
1539 $sql .= " cd.date_ouverture_prevue as date_start, cd.date_ouverture as date_start_real,";
1540 $sql .= " cd.date_fin_validite as date_end, cd.date_cloture as date_end_real,";
1541 $sql .= " cd.commentaire as comment, cd.fk_product_fournisseur_price as fk_fournprice, cd.buy_price_ht as pa_ht,";
1542 $sql .= " cd.fk_unit,";
1543 $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";
1544 $sql .= " ,cd.rang";
1545 $sql .= " FROM ".MAIN_DB_PREFIX."contratdet as cd";
1546 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid";
1547 $sql .= " WHERE cd.rowid = ".((int) $object->lines[$cursorline - 1]->id);
1548
1549 $result = $db->query($sql);
1550 if ($result) {
1551 $total = 0;
1552
1553 $objp = $db->fetch_object($result);
1554
1555 // Line title
1556 print '<tr class="liste_titre'.($cursorline ? ' liste_titre_add' : '').'">';
1557 print '<td>'.$langs->trans("ServiceNb", $cursorline).'</td>';
1558 print '<td width="80" class="center">'.$langs->trans("VAT").'</td>';
1559 print '<td width="80" class="right">'.$langs->trans("PriceUHT").'</td>';
1560 //if (isModEnabled("multicurrency")) {
1561 // print '<td width="80" class="right">'.$langs->trans("PriceUHTCurrency").'</td>';
1562 //}
1563 print '<td width="30" class="center">'.$langs->trans("Qty").'</td>';
1564 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1565 print '<td width="30" class="left">'.$langs->trans("Unit").'</td>';
1566 }
1567 print '<td width="50" class="right">'.$langs->trans("ReductionShort").'</td>';
1568 if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1569 print '<td width="50" class="right">'.$langs->trans("BuyingPrice").'</td>';
1570 }
1571 //
1572
1573 if ($nbofservices > 1 && $conf->browser->layout != 'phone' && $user->hasRight('contrat', 'creer')) {
1574 print '<td width="30" class="linecolmove tdlineupdown center">';
1575 if ($cursorline > 1) {
1576 print '<a class="lineupdown reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=up&token='.newToken().'&rowid='.$objp->rowid.'">';
1577 echo img_up('default', 0, 'imgupforline');
1578 print '</a>';
1579 }
1580 if ($cursorline < $nbofservices) {
1581 print '<a class="lineupdown reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=down&token='.newToken().'&rowid='.$objp->rowid.'">';
1582 echo img_down('default', 0, 'imgdownforline');
1583 print '</a>';
1584 }
1585 print '</td>';
1586 } else {
1587 print '<td width="30">&nbsp;</td>';
1588 }
1589
1590 print "</tr>\n";
1591
1592
1593
1594 // Line in view mode
1595 if ($action != 'editline' || GETPOST('rowid') != $objp->rowid) {
1596 $moreparam = '';
1597 if (getDolGlobalString('CONTRACT_HIDE_CLOSED_SERVICES_BY_DEFAULT') && $objp->statut == ContratLigne::STATUS_CLOSED && $action != 'showclosedlines') {
1598 $moreparam = 'style="display: none;"';
1599 }
1600
1601 print '<tr class="tdtop oddeven" '.$moreparam.'>';
1602
1603 // Label
1604 if ($objp->fk_product > 0) {
1605 $productstatic->id = $objp->fk_product;
1606 $productstatic->type = $objp->ptype;
1607 $productstatic->ref = $objp->pref;
1608 $productstatic->entity = $objp->pentity;
1609 $productstatic->label = $objp->plabel;
1610 $productstatic->status = $objp->tosell;
1611 $productstatic->status_buy = $objp->tobuy;
1612 $productstatic->status_batch = $objp->tobatch;
1613
1614 print '<td>';
1615 $text = $productstatic->getNomUrl(1, '', 32);
1616 if ($objp->plabel) {
1617 $text .= ' - ';
1618 $text .= $objp->plabel;
1619 }
1620 $description = $objp->description;
1621
1622 // Add description in form
1623 if (getDolGlobalInt('PRODUIT_DESC_IN_FORM_ACCORDING_TO_DEVICE')) {
1624 $text .= (!empty($objp->description) && $objp->description != $objp->plabel) ? '<br>'.dol_htmlentitiesbr($objp->description) : '';
1625 $description = ''; // Already added into main visible desc
1626 }
1627
1628 print $form->textwithtooltip($text, $description, 3, '', '', $cursorline, 3, (!empty($line->fk_parent_line) ? img_picto('', 'rightarrow') : ''));
1629
1630 print '</td>';
1631 } else {
1632 print '<td>'.img_object($langs->trans("ShowProductOrService"), ($objp->product_type ? 'service' : 'product')).' '.dol_htmlentitiesbr($objp->description)."</td>\n";
1633 }
1634 // VAT
1635 print '<td class="center">';
1636 print vatrate($objp->tva_tx.($objp->vat_src_code ? (' ('.$objp->vat_src_code.')') : ''), '%', $objp->info_bits);
1637 print '</td>';
1638 // Price
1639 print '<td class="right">'.($objp->subprice != '' ? price($objp->subprice) : '')."</td>\n";
1640 // Price multicurrency
1641 /*if (isModEnabled("multicurrency")) {
1642 print '<td class="linecoluht_currency nowrap right">'.price($objp->multicurrency_subprice).'</td>';
1643 }*/
1644 // Quantity
1645 print '<td class="center">'.$objp->qty.'</td>';
1646 // Unit
1647 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1648 print '<td class="left">'.$langs->trans($object->lines[$cursorline - 1]->getLabelOfUnit()).'</td>';
1649 }
1650 // Discount
1651 if ($objp->remise_percent > 0) {
1652 print '<td class="right">'.$objp->remise_percent."%</td>\n";
1653 } else {
1654 print '<td>&nbsp;</td>';
1655 }
1656
1657 // Margin
1658 if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1659 print '<td class="right nowraponall">'.price($objp->pa_ht).'</td>';
1660 }
1661
1662 // Icon move, update et delete (status contract 0=draft,1=validated,2=closed)
1663 print '<td class="nowraponall right">';
1664 if ($user->hasRight('contrat', 'creer') && is_array($arrayothercontracts) && count($arrayothercontracts) && ($object->statut >= 0)) {
1665 print '<!-- link to move service line into another contract -->';
1666 print '<a class="reposition marginrightonly" style="padding-left: 5px;" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=move&token='.newToken().'&rowid='.$objp->rowid.'">';
1667 print img_picto($langs->trans("MoveToAnotherContract"), 'uparrow');
1668 print '</a>';
1669 }
1670 if ($user->hasRight('contrat', 'creer') && ($object->statut >= 0)) {
1671 print '<a class="reposition marginrightonly editfielda" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=editline&token='.newToken().'&rowid='.$objp->rowid.'">';
1672 print img_edit();
1673 print '</a>';
1674 }
1675 if ($user->hasRight('contrat', 'creer') && ($object->statut >= 0)) {
1676 print '<a class="reposition marginrightonly" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=deleteline&token='.newToken().'&rowid='.$objp->rowid.'">';
1677 print img_delete();
1678 print '</a>';
1679 }
1680 print '</td>';
1681
1682 print "</tr>\n";
1683
1684 $colspan = 6;
1685 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1686 $colspan++;
1687 }
1688 if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1689 $colspan++;
1690 }
1691
1692 // Dates of service planed and real
1693 if ($objp->subprice >= 0) {
1694 print '<tr class="oddeven" '.$moreparam.'>';
1695 print '<td colspan="'.$colspan.'">';
1696
1697 // Date planned
1698 print $langs->trans("DateStartPlanned").': ';
1699 if ($objp->date_start) {
1700 print dol_print_date($db->jdate($objp->date_start), 'day');
1701 // Warning si date prevu passee et pas en service
1702 if ($objp->statut == 0 && $db->jdate($objp->date_start) < ($now - $conf->contrat->services->inactifs->warning_delay)) {
1703 $warning_delay = $conf->contrat->services->inactifs->warning_delay / 3600 / 24;
1704 $textlate = $langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($warning_delay) >= 0 ? '+' : '').ceil($warning_delay).' '.$langs->trans("days");
1705 print " ".img_warning($textlate);
1706 }
1707 } else {
1708 print $langs->trans("Unknown");
1709 }
1710 print ' &nbsp;-&nbsp; ';
1711 print $langs->trans("DateEndPlanned").': ';
1712 if ($objp->date_end) {
1713 print dol_print_date($db->jdate($objp->date_end), 'day');
1714 if ($objp->statut == 4 && $db->jdate($objp->date_end) < ($now - $conf->contrat->services->expires->warning_delay)) {
1715 $warning_delay = $conf->contrat->services->expires->warning_delay / 3600 / 24;
1716 $textlate = $langs->trans("Late").' = '.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($warning_delay) >= 0 ? '+' : '').ceil($warning_delay).' '.$langs->trans("days");
1717 print " ".img_warning($textlate);
1718 }
1719 } else {
1720 print $langs->trans("Unknown");
1721 }
1722
1723 print '</td>';
1724 print '</tr>';
1725 }
1726
1727 // Display lines extrafields
1728 if (is_array($extralabelslines) && count($extralabelslines) > 0) {
1729 $line = new ContratLigne($db);
1730 $line->id = $objp->rowid;
1731 $line->fetch_optionals();
1732 print $line->showOptionals($extrafields, 'view', array('class'=>'oddeven', 'style'=>$moreparam, 'colspan'=>$colspan, 'tdclass' => 'notitlefieldcreate'), '', '', 1);
1733 }
1734 } else {
1735 // Line in mode update
1736 // Ligne carac
1737 print '<tr class="oddeven">';
1738 print '<td>';
1739 if ($objp->fk_product > 0) {
1740 $canchangeproduct = 1;
1741 if (empty($canchangeproduct)) {
1742 $productstatic->id = $objp->fk_product;
1743 $productstatic->type = $objp->ptype;
1744 $productstatic->ref = $objp->pref;
1745 $productstatic->entity = $objp->pentity;
1746 print $productstatic->getNomUrl(1, '', 32);
1747 print $objp->label ? ' - '.dol_trunc($objp->label, 32) : '';
1748 print '<input type="hidden" name="idprod" value="'.(!empty($object->lines[$cursorline - 1]->fk_product) ? $object->lines[$cursorline - 1]->fk_product : 0).'">';
1749 } else {
1750 $senderissupplier = 0;
1751 if (empty($senderissupplier)) {
1752 print $form->select_produits((!empty($object->lines[$cursorline - 1]->fk_product) ? $object->lines[$cursorline - 1]->fk_product : 0), 'idprod');
1753 } else {
1754 $form->select_produits_fournisseurs((!empty($object->lines[$cursorline - 1]->fk_product) ? $object->lines[$cursorline - 1]->fk_product : 0), 'idprod');
1755 }
1756 }
1757 print '<br>';
1758 } else {
1759 print $objp->label ? $objp->label.'<br>' : '';
1760 print '<input type="hidden" name="idprod" value="'.(!empty($object->lines[$cursorline - 1]->fk_product) ? $object->lines[$cursorline - 1]->fk_product : 0).'">';
1761 }
1762
1763 // editeur wysiwyg
1764 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
1765 $nbrows = ROWS_2;
1766 if (getDolGlobalString('MAIN_INPUT_DESC_HEIGHT')) {
1767 $nbrows = $conf->global->MAIN_INPUT_DESC_HEIGHT;
1768 }
1769 $enable = (isset($conf->global->FCKEDITOR_ENABLE_DETAILS) ? $conf->global->FCKEDITOR_ENABLE_DETAILS : 0);
1770 $doleditor = new DolEditor('product_desc', $objp->description, '', 92, 'dolibarr_details', '', false, true, $enable, $nbrows, '90%');
1771 $doleditor->Create();
1772
1773 print '</td>';
1774
1775 // VAT
1776 print '<td class="right">';
1777 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);
1778 print '</td>';
1779
1780 // Price
1781 print '<td class="right"><input size="5" type="text" name="elprice" value="'.price($objp->subprice).'"></td>';
1782
1783 // Price multicurrency
1784 /*if (isModEnabled("multicurrency")) {
1785 print '<td class="linecoluht_currency nowrap right">'.price($objp->multicurrency_subprice).'</td>';
1786 }*/
1787
1788 // Quantity
1789 print '<td class="center"><input size="2" type="text" name="elqty" value="'.$objp->qty.'"></td>';
1790
1791 // Unit
1792 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1793 print '<td class="left">';
1794 print $form->selectUnits($objp->fk_unit, "unit");
1795 print '</td>';
1796 }
1797
1798 // Discount
1799 print '<td class="nowrap right"><input size="1" type="text" name="elremise_percent" value="'.$objp->remise_percent.'">%</td>';
1800
1801 if (!empty($usemargins)) {
1802 print '<td class="right">';
1803 if ($objp->fk_product) {
1804 print '<select id="fournprice" name="fournprice"></select>';
1805 }
1806 print '<input id="buying_price" type="text" size="5" name="buying_price" value="'.price($objp->pa_ht, 0, '', 0).'"></td>';
1807 }
1808 print '<td class="center">';
1809 print '<input type="submit" class="button margintoponly marginbottomonly" name="save" value="'.$langs->trans("Modify").'">';
1810 print '<br><input type="submit" class="button margintoponly marginbottomonly button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
1811 print '</td>';
1812 print '</tr>';
1813
1814 $colspan = 6;
1815 if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1816 $colspan++;
1817 }
1818 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1819 $colspan++;
1820 }
1821
1822 // Line dates planed
1823 print '<tr class="oddeven">';
1824 print '<td colspan="'.$colspan.'">';
1825 print $langs->trans("DateStartPlanned").' ';
1826 print $form->selectDate($db->jdate($objp->date_start), "date_start_update", $usehm, $usehm, ($db->jdate($objp->date_start) > 0 ? 0 : 1), "update");
1827 print ' &nbsp;&nbsp;'.$langs->trans("DateEndPlanned").' ';
1828 print $form->selectDate($db->jdate($objp->date_end), "date_end_update", $usehm, $usehm, ($db->jdate($objp->date_end) > 0 ? 0 : 1), "update");
1829 print '</td>';
1830 print '</tr>';
1831
1832 if (is_array($extralabelslines) && count($extralabelslines) > 0) {
1833 $line = new ContratLigne($db);
1834 $line->id = $objp->rowid;
1835 $line->fetch_optionals();
1836 print $line->showOptionals($extrafields, 'edit', array('style'=>'class="oddeven"', 'colspan'=>$colspan, 'tdclass' => 'notitlefieldcreate'), '', '', 1);
1837 }
1838 }
1839
1840 $db->free($result);
1841 } else {
1842 dol_print_error($db);
1843 }
1844
1845 if ($object->statut > 0) {
1846 $moreparam = '';
1847 if (getDolGlobalString('CONTRACT_HIDE_CLOSED_SERVICES_BY_DEFAULT') && $object->lines[$cursorline - 1]->statut == ContratLigne::STATUS_CLOSED && $action != 'showclosedlines') {
1848 $moreparam = 'style="display: none;"';
1849 }
1850
1851 $colspan = 6;
1852 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1853 $colspan++;
1854 }
1855 if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1856 $colspan++;
1857 }
1858
1859 print '<tr class="oddeven" '.$moreparam.'>';
1860 print '<td class="tdhrthin" colspan="'.$colspan.'"><hr class="opacitymedium tdhrthin"></td>';
1861 print "</tr>\n";
1862 }
1863
1864 print "</table>";
1865 print '</div>';
1866
1867 print "</form>\n";
1868
1869
1870 /*
1871 * Confirmation to delete service line of contract
1872 */
1873 if ($action == 'deleteline' && !$_REQUEST["cancel"] && $user->hasRight('contrat', 'creer') && $object->lines[$cursorline - 1]->id == GETPOST('rowid')) {
1874 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('rowid'), $langs->trans("DeleteContractLine"), $langs->trans("ConfirmDeleteContractLine"), "confirm_deleteline", '', 0, 1);
1875 if ($ret == 'html') {
1876 print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1877 }
1878 }
1879
1880 /*
1881 * Confirmation to move service toward another contract
1882 */
1883 if ($action == 'move' && !$_REQUEST["cancel"] && $user->hasRight('contrat', 'creer') && $object->lines[$cursorline - 1]->id == GETPOST('rowid')) {
1884 $arraycontractid = array();
1885 foreach ($arrayothercontracts as $contractcursor) {
1886 $arraycontractid[$contractcursor->id] = $contractcursor->ref;
1887 }
1888 //var_dump($arraycontractid);
1889 // Cree un tableau formulaire
1890 $formquestion = array(
1891 'text' => $langs->trans("ConfirmMoveToAnotherContractQuestion"),
1892 array('type' => 'select', 'name' => 'newcid', 'values' => $arraycontractid));
1893
1894 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('rowid', 'int'), $langs->trans("MoveToAnotherContract"), $langs->trans("ConfirmMoveToAnotherContract"), "confirm_move", $formquestion);
1895 print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1896 }
1897
1898 // Area with status and activation info of line
1899 if ($object->statut > 0) {
1900 print '<table class="notopnoleftnoright tableforservicepart2'.($cursorline < $nbofservices ? ' boxtablenobottom' : '').' centpercent">';
1901
1902 print '<tr class="oddeven" '.$moreparam.'>';
1903 print '<td><span class="valignmiddle hideonsmartphone">'.$langs->trans("ServiceStatus").':</span> '.$object->lines[$cursorline - 1]->getLibStatut(4).'</td>';
1904 print '<td width="30" class="right">';
1905 if ($user->socid == 0) {
1906 if ($object->statut > 0 && $action != 'activateline' && $action != 'unactivateline') {
1907 $tmpaction = 'activateline';
1908 $tmpactionpicto = 'play';
1909 $tmpactiontext = $langs->trans("Activate");
1910 if ($objp->statut == 4) {
1911 $tmpaction = 'unactivateline';
1912 $tmpactionpicto = 'playstop';
1913 $tmpactiontext = $langs->trans("Disable");
1914 }
1915 if (($tmpaction == 'activateline' && $user->hasRight('contrat', 'activer')) || ($tmpaction == 'unactivateline' && $user->hasRight('contrat', 'desactiver'))) {
1916 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;ligne='.$object->lines[$cursorline - 1]->id.'&amp;action='.$tmpaction.'">';
1917 print img_picto($tmpactiontext, $tmpactionpicto);
1918 print '</a>';
1919 }
1920 }
1921 }
1922 print '</td>';
1923 print "</tr>\n";
1924
1925 print '<tr class="oddeven" '.$moreparam.'>';
1926
1927 print '<td>';
1928 // Si pas encore active
1929 if (!$objp->date_start_real) {
1930 print $langs->trans("DateStartReal").': ';
1931 if ($objp->date_start_real) {
1932 print dol_print_date($db->jdate($objp->date_start_real), 'day');
1933 } else {
1934 print $langs->trans("ContractStatusNotRunning");
1935 }
1936 }
1937 // Si active et en cours
1938 if ($objp->date_start_real && !$objp->date_end_real) {
1939 print $langs->trans("DateStartReal").': ';
1940 print dol_print_date($db->jdate($objp->date_start_real), 'day');
1941 }
1942 // Si desactive
1943 if ($objp->date_start_real && $objp->date_end_real) {
1944 print $langs->trans("DateStartReal").': ';
1945 print dol_print_date($db->jdate($objp->date_start_real), 'day');
1946 print ' &nbsp;-&nbsp; ';
1947 print $langs->trans("DateEndReal").': ';
1948 print dol_print_date($db->jdate($objp->date_end_real), 'day');
1949 }
1950 if (!empty($objp->comment)) {
1951 print " &nbsp;-&nbsp; ".$objp->comment;
1952 }
1953 print '</td>';
1954
1955 print '<td class="center">&nbsp;</td>';
1956
1957 print '</tr>';
1958 print '</table>';
1959 }
1960
1961 // Form to activate line
1962 if ($user->hasRight('contrat', 'activer') && $action == 'activateline' && $object->lines[$cursorline - 1]->id == GETPOST('ligne', 'int')) {
1963 print '<form name="active" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1964 print '<input type="hidden" name="token" value="'.newToken().'">';
1965 print '<input type="hidden" name="action" value="confirm_active">';
1966 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1967 print '<input type="hidden" name="id" value="'.$object->id.'">';
1968 print '<input type="hidden" name="ligne" value="'.GETPOST('ligne', 'int').'">';
1969 print '<input type="hidden" name="confirm" value="yes">';
1970
1971 print '<table class="noborder tableforservicepart2'.($cursorline < $nbofservices ? ' boxtablenobottom' : '').' centpercent">';
1972
1973 // Definie date debut et fin par defaut
1974 $dateactstart = $objp->date_start;
1975 if (GETPOST('remonth')) {
1976 $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
1977 } elseif (!$dateactstart) {
1978 $dateactstart = time();
1979 }
1980
1981 $dateactend = $objp->date_end;
1982 if (GETPOST('endmonth')) {
1983 $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
1984 } elseif (!$dateactend) {
1985 if ($objp->fk_product > 0) {
1986 $product = new Product($db);
1987 $product->fetch($objp->fk_product);
1988 if (!empty($product->duration_value) && !empty($product->duration_unit)) {
1989 $dateactend = dol_time_plus_duree(time(), $product->duration_value, $product->duration_unit);
1990 }
1991 }
1992 }
1993
1994 print '<tr class="oddeven">';
1995 print '<td class="nohover">'.$langs->trans("DateServiceActivate").'</td><td class="nohover">';
1996 print $form->selectDate($dateactstart, 'start', $usehm, $usehm, '', "active", 1, 0);
1997 print '</td>';
1998 print '<td class="nohover">'.$langs->trans("DateEndPlanned").'</td><td class="nohover">';
1999 print $form->selectDate($dateactend, "end", $usehm, $usehm, '', "active", 1, 0);
2000 print '</td>';
2001 print '<td class="center nohover">';
2002 print '</td>';
2003
2004 print '</tr>';
2005
2006 print '<tr class="oddeven">';
2007 print '<td class="nohover">'.$langs->trans("Comment").'</td><td colspan="3" class="nohover" colspan="'.(isModEnabled('margin') ? 4 : 3).'"><input type="text" class="minwidth300" name="comment" value="'.dol_escape_htmltag(GETPOST("comment", 'alphanohtml')).'"></td>';
2008 print '<td class="nohover right">';
2009 print '<input type="submit" class="button" name="activate" value="'.$langs->trans("Activate").'"> &nbsp; ';
2010 print '<input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
2011 print '</td>';
2012 print '</tr>';
2013
2014 print '</table>';
2015
2016 print '</form>';
2017 }
2018
2019 if ($user->hasRight('contrat', 'activer') && $action == 'unactivateline' && $object->lines[$cursorline - 1]->id == GETPOST('ligne', 'int')) {
2023 print '<!-- Form to disabled a line -->'."\n";
2024 print '<form name="confirm_closeline" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;ligne='.$object->lines[$cursorline - 1]->id.'" method="post">';
2025 print '<input type="hidden" name="token" value="'.newToken().'">';
2026 print '<input type="hidden" name="confirm" value="yes">';
2027 print '<input type="hidden" name="action" value="confirm_closeline">';
2028 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2029
2030 print '<table class="noborder tableforservicepart2'.($cursorline < $nbofservices ? ' boxtablenobottom' : '').' centpercent">';
2031
2032 // Definie date debut et fin par defaut
2033 $dateactstart = $objp->date_start_real;
2034 if (GETPOST('remonth')) {
2035 $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
2036 } elseif (!$dateactstart) {
2037 $dateactstart = time();
2038 }
2039
2040 $dateactend = $objp->date_end_real;
2041 if (GETPOST('endmonth')) {
2042 $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
2043 } elseif (!$dateactend) {
2044 if ($objp->fk_product > 0) {
2045 $product = new Product($db);
2046 $product->fetch($objp->fk_product);
2047 $dateactend = dol_time_plus_duree(time(), $product->duration_value, $product->duration_unit);
2048 }
2049 }
2050 $now = dol_now();
2051 if ($dateactend > $now) {
2052 $dateactend = $now;
2053 }
2054
2055 print '<tr class="oddeven"><td colspan="2" class="nohover">';
2056 if ($objp->statut >= 4) {
2057 if ($objp->statut == 4) {
2058 print $langs->trans("DateEndReal").' ';
2059 print $form->selectDate($dateactend, "end", $usehm, $usehm, ($objp->date_end_real > 0 ? 0 : 1), "closeline", 1, 1);
2060 }
2061 }
2062 print '</td>';
2063 print '<td class="center nohover">';
2064 print '</td></tr>';
2065
2066 print '<tr class="oddeven">';
2067 print '<td class="nohover">'.$langs->trans("Comment").'</td><td class="nohover"><input class="quatrevingtpercent" type="text" class="flat" name="comment" value="'.dol_escape_htmltag(GETPOST('comment', 'alpha')).'"></td>';
2068 print '<td class="nohover right">';
2069 print '<input type="submit" class="button" name="close" value="'.$langs->trans("Disable").'"> &nbsp; ';
2070 print '<input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
2071 print '</td>';
2072 print '</tr>';
2073
2074 print '</table>';
2075
2076 print '</form>';
2077 }
2078 print '</div>';
2079 $cursorline++;
2080 }
2081 print '</div>';
2082
2083 // Form to add new line
2084 if ($user->hasRight('contrat', 'creer') && ($object->statut == 0)) {
2085 $dateSelector = 1;
2086
2087 print "\n";
2088 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOST('lineid', 'int')).'" method="POST">
2089 <input type="hidden" name="token" value="'.newToken().'">
2090 <input type="hidden" name="action" value="'.(($action != 'editline') ? 'addline' : 'updateline').'">
2091 <input type="hidden" name="mode" value="">
2092 <input type="hidden" name="id" value="'.$object->id.'">
2093 <input type="hidden" name="page_y" value="">
2094 <input type="hidden" name="backtopage" value="'.$backtopage.'">
2095 ';
2096
2097 print '<div class="div-table-responsive-no-min">';
2098 print '<table id="tablelines" class="noborder noshadow" width="100%">'; // Array with (n*2)+1 lines
2099
2100 // Form to add new line
2101 if ($action != 'editline') {
2102 $forcetoshowtitlelines = 1;
2103 if (empty($object->multicurrency_code)) {
2104 $object->multicurrency_code = $conf->currency; // TODO Remove this when multicurrency supported on contracts
2105 }
2106
2107 // Add free products/services
2108
2109 $parameters = array();
2110 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2111 if ($reshook < 0) {
2112 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2113 }
2114 if (empty($reshook)) {
2115 $object->formAddObjectLine(1, $mysoc, $soc);
2116 }
2117 }
2118
2119 print '</table>';
2120 print '</div>';
2121 print '</form>';
2122 }
2123
2124 print dol_get_fiche_end();
2125
2126 // Select mail models is same action as presend
2127 if (GETPOST('modelselected')) {
2128 $action = 'presend';
2129 }
2130
2131 /*
2132 * Buttons
2133 */
2134 if ($user->socid == 0 && $action != 'presend' && $action != 'editline') {
2135 print '<div class="tabsAction">';
2136
2137 $parameters = array();
2138 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2139
2140 if (empty($reshook)) {
2141 $params = array(
2142 'attr' => array(
2143 'title' => '',
2144 'class' => 'classfortooltip'
2145 )
2146 );
2147
2148 // Send
2149 if (empty($user->socid)) {
2150 if ($object->status == $object::STATUS_VALIDATED) {
2151 if ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('contrat', 'creer'))) {
2152 print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle', '', true, $params);
2153 } else {
2154 print dolGetButtonAction('', $langs->trans('SendMail'), 'default', '#', '', false, $params);
2155 }
2156 }
2157 }
2158
2159 if ($object->status == $object::STATUS_DRAFT && $nbofservices) {
2160 if ($user->hasRight('contrat', 'creer')) {
2161 unset($params['attr']['title']);
2162 print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken(), '', true, $params);
2163 } else {
2164 $params['attr']['title'] = $langs->trans("NotEnoughPermissions");
2165 print dolGetButtonAction($langs->trans('Validate'), '', 'default', '#', '', false, $params);
2166 }
2167 }
2168 if ($object->status == $object::STATUS_VALIDATED) {
2169 if ($user->hasRight('contrat', 'creer')) {
2170 unset($params['attr']['title']);
2171 print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken(), '', true, $params);
2172 } else {
2173 $params['attr']['title'] = $langs->trans("NotEnoughPermissions");
2174 print dolGetButtonAction($langs->trans('Modify'), '', 'default', '#', '', false, $params);
2175 }
2176 }
2177
2178 // Create ... buttons
2179 $arrayofcreatebutton = array();
2180 if (isModEnabled('commande') && $object->status > 0 && $object->nbofservicesclosed < $nbofservices) {
2181 $arrayofcreatebutton[] = array(
2182 'url' => '/commande/card.php?action=create&token='.newToken().'&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id,
2183 'label' => $langs->trans('AddOrder'),
2184 'lang' => 'orders',
2185 'perm' => $user->hasRight('commande', 'creer')
2186 );
2187 }
2188 if (isModEnabled('facture') && $object->status > 0 && $soc->client > 0) {
2189 $arrayofcreatebutton[] = array(
2190 'url' => '/compta/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id,
2191 'label' => $langs->trans('CreateBill'),
2192 'lang' => 'bills',
2193 'perm' => $user->hasRight('facture', 'creer')
2194 );
2195 }
2196 if (isModEnabled('supplier_invoice') && $object->status > 0 && $soc->fournisseur == 1) {
2197 $langs->load("suppliers");
2198 $arrayofcreatebutton[] = array(
2199 'url' => '/fourn/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id,
2200 'label' => $langs->trans('AddSupplierInvoice'),
2201 'lang' => 'bills',
2202 'perm' => $user->hasRight('fournisseur', 'facture', 'creer')
2203 );
2204 }
2205 if (count($arrayofcreatebutton)) {
2206 unset($params['attr']['title']);
2207 print dolGetButtonAction('', $langs->trans("Create"), 'default', $arrayofcreatebutton, '', true, $params);
2208 }
2209
2210 if ($object->nbofservicesclosed > 0 || $object->nbofserviceswait > 0) {
2211 if ($user->hasRight('contrat', 'activer')) {
2212 unset($params['attr']['title']);
2213 print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=activate&token='.newToken(), '', true, $params);
2214 } else {
2215 unset($params['attr']['title']);
2216 print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', '#', '', false, $params);
2217 }
2218 }
2219 if ($object->nbofservicesclosed < $nbofservices) {
2220 if ($user->hasRight('contrat', 'desactiver')) {
2221 unset($params['attr']['title']);
2222 print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=close&token='.newToken(), '', true, $params);
2223 } else {
2224 unset($params['attr']['title']);
2225 print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', '#', '', false, $params);
2226 }
2227
2228 //if (! $numactive)
2229 //{
2230 //}
2231 //else
2232 //{
2233 // print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("CloseRefusedBecauseOneServiceActive").'">'.$langs->trans("Close").'</a></div>';
2234 //}
2235 }
2236
2237 if (getDolGlobalString('CONTRACT_HIDE_CLOSED_SERVICES_BY_DEFAULT') && $object->nbofservicesclosed > 0) {
2238 if ($action == 'showclosedlines') {
2239 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>';
2240 } else {
2241 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>';
2242 }
2243 }
2244
2245 // Clone
2246 if ($user->hasRight('contrat', 'creer')) {
2247 unset($params['attr']['title']);
2248 print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&token='.newToken(), '', true, $params);
2249 }
2250
2251 // Delete
2252 unset($params['attr']['title']);
2253 print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), '', $permissiontodelete, $params);
2254 }
2255
2256 print "</div>";
2257 }
2258
2259 if ($action != 'presend') {
2260 print '<div class="fichecenter"><div class="fichehalfleft">';
2261
2262 /*
2263 * Generated documents
2264 */
2265 $filename = dol_sanitizeFileName($object->ref);
2266 $filedir = $conf->contrat->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->ref);
2267 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2268 $genallowed = $user->hasRight('contrat', 'lire');
2269 $delallowed = $user->hasRight('contrat', 'creer');
2270
2271
2272 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);
2273
2274
2275 // Show links to link elements
2276 $linktoelem = $form->showLinkToObjectBlock($object, null, array('contrat'));
2277 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2278
2279 // Show online signature link
2280 if ($object->statut != Contrat::STATUS_DRAFT && getDolGlobalString('CONTRACT_ALLOW_ONLINESIGN')) {
2281 print '<br><!-- Link to sign -->';
2282 require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
2283
2284 print showOnlineSignatureUrl('contract', $object->ref, $object).'<br>';
2285 }
2286
2287 print '</div><div class="fichehalfright">';
2288
2289 $MAXEVENT = 10;
2290
2291 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/contrat/agenda.php?id='.$object->id);
2292
2293
2294 // List of actions on element
2295 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2296 $formactions = new FormActions($db);
2297 $somethingshown = $formactions->showactions($object, 'contract', $socid, 1, 'listactions', $MAXEVENT, '', $morehtmlcenter);
2298
2299 print '</div></div>';
2300 }
2301
2302 // Presend form
2303 $modelmail = 'contract';
2304 $defaulttopic = 'SendContractRef';
2305 $diroutput = $conf->contrat->multidir_output[$object->entity];
2306 $trackid = 'con'.$object->id;
2307
2308 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2309 }
2310}
2311
2312
2313llxFooter();
2314
2315$db->close();
2316?>
2317
2318<?php
2319if (isModEnabled('margin') && $action == 'editline') {
2320 // TODO Why this ? To manage margin on contracts ??>
2321<script type="text/javascript">
2322$(document).ready(function() {
2323 var idprod = $("input[name='idprod']").val();
2324 var fournprice = $("input[name='fournprice']").val();
2325 var token = '<?php echo currentToken(); ?>'; // For AJAX Call we use old 'token' and not 'newtoken'
2326 if (idprod > 0) {
2327 $.post('<?php echo DOL_URL_ROOT; ?>/fourn/ajax/getSupplierPrices.php', {
2328 'idprod': idprod,
2329 'token': token
2330 }, function(data) {
2331 if (data.length > 0) {
2332 var options = '';
2333 var trouve=false;
2334 $(data).each(function() {
2335 options += '<option value="'+this.id+'" price="'+this.price+'"';
2336 if (fournprice > 0) {
2337 if (this.id == fournprice) {
2338 options += ' selected';
2339 $("#buying_price").val(this.price);
2340 trouve = true;
2341 }
2342 }
2343 options += '>'+this.label+'</option>';
2344 });
2345 options += '<option value=null'+(trouve?'':' selected')+'><?php echo $langs->trans("InputPrice"); ?></option>';
2346 $("#fournprice").html(options);
2347 if (trouve) {
2348 $("#buying_price").hide();
2349 $("#fournprice").show();
2350 }
2351 else {
2352 $("#buying_price").show();
2353 }
2354 $("#fournprice").change(function() {
2355 var selval = $(this).find('option:selected').attr("price");
2356 if (selval)
2357 $("#buying_price").val(selval).hide();
2358 else
2359 $('#buying_price').show();
2360 });
2361 }
2362 else {
2363 $("#fournprice").hide();
2364 $('#buying_price').show();
2365 }
2366 },
2367 'json');
2368 }
2369 else {
2370 $("#fournprice").hide();
2371 $('#buying_price').show();
2372 }
2373});
2374</script>
2375 <?php
2376}
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:125
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.