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