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