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