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