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