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