dolibarr 20.0.2
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, 'tdclass' => 'notitlefieldcreate'), '', '', 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
1842 print $line->showOptionals($extrafields, 'edit', array('style' => 'class="oddeven"', 'colspan' => $colspan, 'tdclass' => 'notitlefieldcreate'), '', '', 1);
1843 }
1844 }
1845
1846 $db->free($result);
1847 } else {
1848 dol_print_error($db);
1849 }
1850
1851 if ($object->statut > 0) {
1852 $moreparam = '';
1853 if (getDolGlobalString('CONTRACT_HIDE_CLOSED_SERVICES_BY_DEFAULT') && $object->lines[$cursorline - 1]->statut == ContratLigne::STATUS_CLOSED && $action != 'showclosedlines') {
1854 $moreparam = 'style="display: none;"';
1855 }
1856
1857 $colspan = 6;
1858 if (getDolGlobalInt('PRODUCT_USE_UNITS')) {
1859 $colspan++;
1860 }
1861 if (isModEnabled('margin') && getDolGlobalString('MARGIN_SHOW_ON_CONTRACT')) {
1862 $colspan++;
1863 }
1864
1865 print '<tr class="oddeven" '.$moreparam.'>';
1866 print '<td class="tdhrthin" colspan="'.$colspan.'"><hr class="opacitymedium tdhrthin"></td>';
1867 print "</tr>\n";
1868 }
1869
1870 print "</table>";
1871 print '</div>';
1872
1873 print "</form>\n";
1874
1875
1876 /*
1877 * Confirmation to delete service line of contract
1878 */
1879 if ($action == 'deleteline' && !$_REQUEST["cancel"] && $user->hasRight('contrat', 'creer') && $object->lines[$cursorline - 1]->id == GETPOST('elrowid')) {
1880 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOST('elrowid'), $langs->trans("DeleteContractLine"), $langs->trans("ConfirmDeleteContractLine"), "confirm_deleteline", '', 0, 1);
1881 if ($ret == 'html') {
1882 print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1883 }
1884 }
1885
1886 /*
1887 * Confirmation to move service toward another contract
1888 */
1889 if ($action == 'move' && !$_REQUEST["cancel"] && $user->hasRight('contrat', 'creer') && $object->lines[$cursorline - 1]->id == GETPOST('elrowid')) {
1890 $arraycontractid = array();
1891 foreach ($arrayothercontracts as $contractcursor) {
1892 $arraycontractid[$contractcursor->id] = $contractcursor->ref;
1893 }
1894 //var_dump($arraycontractid);
1895 // Cree un tableau formulaire
1896 $formquestion = array(
1897 'text' => $langs->trans("ConfirmMoveToAnotherContractQuestion"),
1898 0 => array('type' => 'select', 'name' => 'newcid', 'values' => $arraycontractid));
1899
1900 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&lineid=".GETPOSTINT('elrowid'), $langs->trans("MoveToAnotherContract"), $langs->trans("ConfirmMoveToAnotherContract"), "confirm_move", $formquestion);
1901 print '<table class="notopnoleftnoright" width="100%"><tr class="oddeven" height="6"><td></td></tr></table>';
1902 }
1903
1904 // Area with status and activation info of line
1905 if ($object->statut > 0) {
1906 print '<table class="notopnoleftnoright tableforservicepart2'.($cursorline < $nbofservices ? ' boxtablenobottom' : '').' centpercent">';
1907
1908 print '<tr class="oddeven" '.$moreparam.'>';
1909 print '<td><span class="valignmiddle hideonsmartphone">'.$langs->trans("ServiceStatus").':</span> '.$object->lines[$cursorline - 1]->getLibStatut(4).'</td>';
1910 print '<td width="30" class="right">';
1911 if ($user->socid == 0) {
1912 if ($object->statut > 0 && $action != 'activateline' && $action != 'unactivateline') {
1913 $tmpaction = 'activateline';
1914 $tmpactionpicto = 'play';
1915 $tmpactiontext = $langs->trans("Activate");
1916 if ($objp->statut == 4) {
1917 $tmpaction = 'unactivateline';
1918 $tmpactionpicto = 'playstop';
1919 $tmpactiontext = $langs->trans("Disable");
1920 }
1921 if (($tmpaction == 'activateline' && $user->hasRight('contrat', 'activer')) || ($tmpaction == 'unactivateline' && $user->hasRight('contrat', 'desactiver'))) {
1922 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;ligne='.$object->lines[$cursorline - 1]->id.'&amp;action='.$tmpaction.'">';
1923 print img_picto($tmpactiontext, $tmpactionpicto);
1924 print '</a>';
1925 }
1926 }
1927 }
1928 print '</td>';
1929 print "</tr>\n";
1930
1931 print '<tr class="oddeven" '.$moreparam.'>';
1932
1933 print '<td>';
1934 // Si pas encore active
1935 if (!$objp->date_start_real) {
1936 print $langs->trans("DateStartReal").': ';
1937 if ($objp->date_start_real) {
1938 print dol_print_date($db->jdate($objp->date_start_real), 'day');
1939 } else {
1940 print $langs->trans("ContractStatusNotRunning");
1941 }
1942 }
1943 // Si active et en cours
1944 if ($objp->date_start_real && !$objp->date_end_real) {
1945 print $langs->trans("DateStartReal").': ';
1946 print dol_print_date($db->jdate($objp->date_start_real), 'day');
1947 }
1948 // Si desactive
1949 if ($objp->date_start_real && $objp->date_end_real) {
1950 print $langs->trans("DateStartReal").': ';
1951 print dol_print_date($db->jdate($objp->date_start_real), 'day');
1952 print ' &nbsp;-&nbsp; ';
1953 print $langs->trans("DateEndReal").': ';
1954 print dol_print_date($db->jdate($objp->date_end_real), 'day');
1955 }
1956 if (!empty($objp->comment)) {
1957 print " &nbsp;-&nbsp; ".$objp->comment;
1958 }
1959 print '</td>';
1960
1961 print '<td class="center">&nbsp;</td>';
1962
1963 print '</tr>';
1964 print '</table>';
1965 }
1966
1967 // Form to activate line
1968 if ($user->hasRight('contrat', 'activer') && $action == 'activateline' && $object->lines[$cursorline - 1]->id == GETPOSTINT('ligne')) {
1969 print '<form name="active" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1970 print '<input type="hidden" name="token" value="'.newToken().'">';
1971 print '<input type="hidden" name="action" value="confirm_active">';
1972 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
1973 print '<input type="hidden" name="id" value="'.$object->id.'">';
1974 print '<input type="hidden" name="ligne" value="'.GETPOSTINT('ligne').'">';
1975 print '<input type="hidden" name="confirm" value="yes">';
1976
1977 print '<table class="noborder tableforservicepart2'.($cursorline < $nbofservices ? ' boxtablenobottom' : '').' centpercent">';
1978
1979 // Definie date debut et fin par default
1980 $dateactstart = $objp->date_start;
1981 if (GETPOST('remonth')) {
1982 $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
1983 } elseif (!$dateactstart) {
1984 $dateactstart = time();
1985 }
1986
1987 $dateactend = $objp->date_end;
1988 if (GETPOST('endmonth')) {
1989 $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
1990 } elseif (!$dateactend) {
1991 if ($objp->fk_product > 0) {
1992 $product = new Product($db);
1993 $product->fetch($objp->fk_product);
1994 $dateactend = dol_time_plus_duree(time(), $product->duration_value, $product->duration_unit);
1995 }
1996 }
1997
1998 print '<tr class="oddeven">';
1999 print '<td class="nohover">'.$langs->trans("DateServiceActivate").'</td><td class="nohover">';
2000 print $form->selectDate($dateactstart, 'start', $usehm, $usehm, 0, "active", 1, 0);
2001 print '</td>';
2002 print '<td class="nohover">'.$langs->trans("DateEndPlanned").'</td><td class="nohover">';
2003 print $form->selectDate($dateactend, "end", $usehm, $usehm, 0, "active", 1, 0);
2004 print '</td>';
2005 print '<td class="center nohover">';
2006 print '</td>';
2007
2008 print '</tr>';
2009
2010 print '<tr class="oddeven">';
2011 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>';
2012 print '<td class="nohover right">';
2013 print '<input type="submit" class="button" name="activate" value="'.$langs->trans("Activate").'"> &nbsp; ';
2014 print '<input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
2015 print '</td>';
2016 print '</tr>';
2017
2018 print '</table>';
2019
2020 print '</form>';
2021 }
2022
2023 if ($user->hasRight('contrat', 'activer') && $action == 'unactivateline' && $object->lines[$cursorline - 1]->id == GETPOSTINT('ligne')) {
2027 print '<!-- Form to disabled a line -->'."\n";
2028 print '<form name="confirm_closeline" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;ligne='.$object->lines[$cursorline - 1]->id.'" method="post">';
2029 print '<input type="hidden" name="token" value="'.newToken().'">';
2030 print '<input type="hidden" name="confirm" value="yes">';
2031 print '<input type="hidden" name="action" value="confirm_closeline">';
2032 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
2033
2034 print '<table class="noborder tableforservicepart2'.($cursorline < $nbofservices ? ' boxtablenobottom' : '').' centpercent">';
2035
2036 // Definie date debut et fin par default
2037 $dateactstart = $objp->date_start_real;
2038 if (GETPOST('remonth')) {
2039 $dateactstart = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
2040 } elseif (!$dateactstart) {
2041 $dateactstart = time();
2042 }
2043
2044 $dateactend = $objp->date_end_real;
2045 if (GETPOST('endmonth')) {
2046 $dateactend = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
2047 } elseif (!$dateactend) {
2048 if ($objp->fk_product > 0) {
2049 $product = new Product($db);
2050 $product->fetch($objp->fk_product);
2051 $dateactend = dol_time_plus_duree(time(), $product->duration_value, $product->duration_unit);
2052 }
2053 }
2054 $now = dol_now();
2055 if ($dateactend > $now) {
2056 $dateactend = $now;
2057 }
2058
2059 print '<tr class="oddeven"><td colspan="2" class="nohover">';
2060 if ($objp->statut >= 4) {
2061 if ($objp->statut == 4) {
2062 print $langs->trans("DateEndReal").' ';
2063 print $form->selectDate($dateactend, "end", $usehm, $usehm, ($objp->date_end_real > 0 ? 0 : 1), "closeline", 1, 1);
2064 }
2065 }
2066 print '</td>';
2067 print '<td class="center nohover">';
2068 print '</td></tr>';
2069
2070 print '<tr class="oddeven">';
2071 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>';
2072 print '<td class="nohover right">';
2073 print '<input type="submit" class="button" name="close" value="'.$langs->trans("Disable").'"> &nbsp; ';
2074 print '<input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
2075 print '</td>';
2076 print '</tr>';
2077
2078 print '</table>';
2079
2080 print '</form>';
2081 }
2082 print '</div>';
2083 $cursorline++;
2084 }
2085 print '</div>';
2086
2087 // Form to add new line
2088 if ($user->hasRight('contrat', 'creer') && ($object->statut == 0)) {
2089 $dateSelector = 1;
2090
2091 print "\n";
2092 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
2093 <input type="hidden" name="token" value="'.newToken().'">
2094 <input type="hidden" name="action" value="'.(($action != 'editline') ? 'addline' : 'updateline').'">
2095 <input type="hidden" name="mode" value="">
2096 <input type="hidden" name="id" value="'.$object->id.'">
2097 <input type="hidden" name="page_y" value="">
2098 <input type="hidden" name="backtopage" value="'.$backtopage.'">
2099 ';
2100
2101 print '<div class="div-table-responsive-no-min">';
2102 print '<table id="tablelines" class="noborder noshadow" width="100%">'; // Array with (n*2)+1 lines
2103
2104 // Form to add new line
2105 if ($action != 'editline') {
2106 $forcetoshowtitlelines = 1;
2107 if (empty($object->multicurrency_code)) {
2108 $object->multicurrency_code = $conf->currency; // TODO Remove this when multicurrency supported on contracts
2109 }
2110
2111 // Add free products/services
2112
2113 $parameters = array();
2114 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2115 if ($reshook < 0) {
2116 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2117 }
2118 if (empty($reshook)) {
2119 $object->formAddObjectLine(1, $mysoc, $soc);
2120 }
2121 }
2122
2123 print '</table>';
2124 print '</div>';
2125 print '</form>';
2126 }
2127
2128 print dol_get_fiche_end();
2129
2130 // Select mail models is same action as presend
2131 if (GETPOST('modelselected')) {
2132 $action = 'presend';
2133 }
2134
2135 /*
2136 * Buttons
2137 */
2138 if ($user->socid == 0 && $action != 'presend' && $action != 'editline') {
2139 print '<div class="tabsAction">';
2140
2141 $parameters = array();
2142 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
2143
2144 if (empty($reshook)) {
2145 $params = array(
2146 'attr' => array(
2147 'title' => '',
2148 'class' => 'classfortooltip'
2149 )
2150 );
2151
2152 // Send
2153 if (empty($user->socid)) {
2154 if ($object->status == $object::STATUS_VALIDATED) {
2155 if ((!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') || $user->hasRight('contrat', 'creer'))) {
2156 print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle', '', true, $params);
2157 } else {
2158 print dolGetButtonAction('', $langs->trans('SendMail'), 'default', '#', '', false, $params);
2159 }
2160 }
2161 }
2162
2163 if ($object->status == $object::STATUS_DRAFT && $nbofservices) {
2164 if ($user->hasRight('contrat', 'creer')) {
2165 unset($params['attr']['title']);
2166 print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken(), '', true, $params);
2167 } else {
2168 $params['attr']['title'] = $langs->trans("NotEnoughPermissions");
2169 print dolGetButtonAction($langs->trans('Validate'), '', 'default', '#', '', false, $params);
2170 }
2171 }
2172 if ($object->status == $object::STATUS_VALIDATED) {
2173 if ($user->hasRight('contrat', 'creer')) {
2174 unset($params['attr']['title']);
2175 print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken(), '', true, $params);
2176 } else {
2177 $params['attr']['title'] = $langs->trans("NotEnoughPermissions");
2178 print dolGetButtonAction($langs->trans('Modify'), '', 'default', '#', '', false, $params);
2179 }
2180 }
2181
2182 // Create ... buttons
2183 $arrayofcreatebutton = array();
2184 if (isModEnabled('order') && $object->status > 0 && $object->nbofservicesclosed < $nbofservices) {
2185 $arrayofcreatebutton[] = array(
2186 'url' => '/commande/card.php?action=create&token='.newToken().'&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id,
2187 'label' => $langs->trans('AddOrder'),
2188 'lang' => 'orders',
2189 'perm' => $user->hasRight('commande', 'creer')
2190 );
2191 }
2192 if (isModEnabled('invoice') && $object->status > 0 && $soc->client > 0) {
2193 $arrayofcreatebutton[] = array(
2194 'url' => '/compta/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id,
2195 'label' => $langs->trans('CreateBill'),
2196 'lang' => 'bills',
2197 'perm' => $user->hasRight('facture', 'creer')
2198 );
2199 }
2200 if (isModEnabled('supplier_invoice') && $object->status > 0 && $soc->fournisseur == 1) {
2201 $langs->load("suppliers");
2202 $arrayofcreatebutton[] = array(
2203 'url' => '/fourn/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id,
2204 'label' => $langs->trans('AddSupplierInvoice'),
2205 'lang' => 'bills',
2206 'perm' => $user->hasRight('fournisseur', 'facture', 'creer')
2207 );
2208 }
2209 if (count($arrayofcreatebutton)) {
2210 unset($params['attr']['title']);
2211 print dolGetButtonAction('', $langs->trans("Create"), 'default', $arrayofcreatebutton, '', true, $params);
2212 }
2213
2214 if ($object->nbofservicesclosed > 0 || $object->nbofserviceswait > 0) {
2215 if ($user->hasRight('contrat', 'activer')) {
2216 unset($params['attr']['title']);
2217 print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=activate&token='.newToken(), '', true, $params);
2218 } else {
2219 unset($params['attr']['title']);
2220 print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', '#', '', false, $params);
2221 }
2222 }
2223 if ($object->nbofservicesclosed < $nbofservices) {
2224 if ($user->hasRight('contrat', 'desactiver')) {
2225 unset($params['attr']['title']);
2226 print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=close&token='.newToken(), '', true, $params);
2227 } else {
2228 unset($params['attr']['title']);
2229 print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', '#', '', false, $params);
2230 }
2231
2232 //if (! $numactive)
2233 //{
2234 //}
2235 //else
2236 //{
2237 // print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("CloseRefusedBecauseOneServiceActive").'">'.$langs->trans("Close").'</a></div>';
2238 //}
2239 }
2240
2241 if (getDolGlobalString('CONTRACT_HIDE_CLOSED_SERVICES_BY_DEFAULT') && $object->nbofservicesclosed > 0) {
2242 if ($action == 'showclosedlines') {
2243 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>';
2244 } else {
2245 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>';
2246 }
2247 }
2248
2249 // Clone
2250 if ($user->hasRight('contrat', 'creer')) {
2251 unset($params['attr']['title']);
2252 print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&token='.newToken(), '', true, $params);
2253 }
2254
2255 // Delete
2256 unset($params['attr']['title']);
2257 print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), '', $permissiontodelete, $params);
2258 }
2259
2260 print "</div>";
2261 }
2262
2263 if ($action != 'presend') {
2264 print '<div class="fichecenter"><div class="fichehalfleft">';
2265
2266 /*
2267 * Generated documents
2268 */
2269 $filename = dol_sanitizeFileName($object->ref);
2270 $filedir = $conf->contrat->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->ref);
2271 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
2272 $genallowed = $user->hasRight('contrat', 'lire');
2273 $delallowed = $user->hasRight('contrat', 'creer');
2274
2275
2276 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);
2277
2278
2279 // Show links to link elements
2280 $linktoelem = $form->showLinkToObjectBlock($object, null, array('contrat'));
2281 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
2282
2283 // Show online signature link
2284 if ($object->statut != Contrat::STATUS_DRAFT && getDolGlobalString('CONTRACT_ALLOW_ONLINESIGN')) {
2285 print '<br><!-- Link to sign -->';
2286 require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
2287
2288 print showOnlineSignatureUrl('contract', $object->ref).'<br>';
2289 }
2290
2291 print '</div><div class="fichehalfright">';
2292
2293 $MAXEVENT = 10;
2294
2295 $morehtmlcenter = '<div class="nowraponall">';
2296 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/contrat/messaging.php?id='.$object->id);
2297 $morehtmlcenter .= dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/contrat/agenda.php?id='.$object->id);
2298 $morehtmlcenter .= '</div>';
2299
2300
2301 // List of actions on element
2302 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
2303 $formactions = new FormActions($db);
2304 $somethingshown = $formactions->showactions($object, 'contract', $socid, 1, 'listactions', $MAXEVENT, '', $morehtmlcenter);
2305
2306 print '</div></div>';
2307 }
2308
2309 // Presend form
2310 $modelmail = 'contract';
2311 $defaulttopic = 'SendContractRef';
2312 $diroutput = $conf->contrat->multidir_output[$object->entity];
2313 $trackid = 'con'.$object->id;
2314
2315 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
2316 }
2317}
2318
2319
2320llxFooter();
2321
2322$db->close();
2323
2324
2325// TODO Why this on the page when editing margin for contracts ?
2326if (isModEnabled('margin') && $action == 'editline') {
2327 ?>
2328<script type="text/javascript">
2329$(document).ready(function() {
2330 var idprod = $("input[name='idprod']").val();
2331 var fournprice = $("input[name='fournprice']").val();
2332 var token = '<?php echo currentToken(); ?>'; // For AJAX Call we use old 'token' and not 'newtoken'
2333 if (idprod > 0) {
2334 $.post('<?php echo DOL_URL_ROOT; ?>/fourn/ajax/getSupplierPrices.php', {
2335 'idprod': idprod,
2336 'token': token
2337 }, function(data) {
2338 if (data.length > 0) {
2339 var options = '';
2340 var trouve=false;
2341 $(data).each(function() {
2342 options += '<option value="'+this.id+'" price="'+this.price+'"';
2343 if (fournprice > 0) {
2344 if (this.id == fournprice) {
2345 options += ' selected';
2346 $("#buying_price").val(this.price);
2347 trouve = true;
2348 }
2349 }
2350 options += '>'+this.label+'</option>';
2351 });
2352 options += '<option value=null'+(trouve?'':' selected')+'><?php echo $langs->trans("InputPrice"); ?></option>';
2353 $("#fournprice").html(options);
2354 if (trouve) {
2355 $("#buying_price").hide();
2356 $("#fournprice").show();
2357 }
2358 else {
2359 $("#buying_price").show();
2360 }
2361 $("#fournprice").change(function() {
2362 var selval = $(this).find('option:selected').attr("price");
2363 if (selval)
2364 $("#buying_price").val(selval).hide();
2365 else
2366 $('#buying_price').show();
2367 });
2368 }
2369 else {
2370 $("#fournprice").hide();
2371 $('#buying_price').show();
2372 }
2373 },
2374 'json');
2375 }
2376 else {
2377 $("#fournprice").hide();
2378 $('#buying_price').show();
2379 }
2380});
2381</script>
2382 <?php
2383}
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:125
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_move_dir($srcdir, $destdir, $overwriteifexists=1, $indexdatabase=1, $renamedircontent=1)
Move a directory into another name.
dol_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:137
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.