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