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