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