dolibarr 20.0.0
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2023 Charlene Benke <charlene@patas_monkey.com>
6 * Copyright (C) 2023 Christian Foellmann <christian@foellmann.de>
7 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30// Load Dolibarr environment
31require '../main.inc.php';
32require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
33require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
39require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
40require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
41
42// Load translation files required by the page
43$langsLoad = array('projects', 'companies');
44if (isModEnabled('eventorganization')) {
45 $langsLoad[] = 'eventorganization';
46}
47
48$langs->loadLangs($langsLoad);
49
50$id = GETPOSTINT('id');
51$ref = GETPOST('ref', 'alpha');
52$action = GETPOST('action', 'aZ09');
53$backtopage = GETPOST('backtopage', 'alpha');
54$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
55$backtopagejsfields = GETPOST('backtopagejsfields', 'alpha');
56$cancel = GETPOST('cancel', 'alpha');
57$confirm = GETPOST('confirm', 'aZ09');
58
59$dol_openinpopup = '';
60if (!empty($backtopagejsfields)) {
61 $tmpbacktopagejsfields = explode(':', $backtopagejsfields);
62 $dol_openinpopup = preg_replace('/[^a-z0-9_]/i', '', $tmpbacktopagejsfields[0]);
63}
64
65$status = GETPOSTINT('status');
66$opp_status = GETPOSTINT('opp_status');
67$opp_percent = price2num(GETPOST('opp_percent', 'alphanohtml'));
68$objcanvas = GETPOST("objcanvas", "alphanohtml");
69$comefromclone = GETPOST("comefromclone", "alphanohtml");
70$date_start = dol_mktime(0, 0, 0, GETPOSTINT('projectstartmonth'), GETPOSTINT('projectstartday'), GETPOSTINT('projectstartyear'));
71$date_end = dol_mktime(0, 0, 0, GETPOSTINT('projectendmonth'), GETPOSTINT('projectendday'), GETPOSTINT('projectendyear'));
72$date_start_event = dol_mktime(GETPOSTINT('date_start_eventhour'), GETPOSTINT('date_start_eventmin'), GETPOSTINT('date_start_eventsec'), GETPOSTINT('date_start_eventmonth'), GETPOSTINT('date_start_eventday'), GETPOSTINT('date_start_eventyear'), 'tzuserrel');
73$date_end_event = dol_mktime(GETPOSTINT('date_end_eventhour'), GETPOSTINT('date_end_eventmin'), GETPOSTINT('date_end_eventsec'), GETPOSTINT('date_end_eventmonth'), GETPOSTINT('date_end_eventday'), GETPOSTINT('date_end_eventyear'), 'tzuserrel');
74$location = GETPOST('location', 'alphanohtml');
75$fk_project = GETPOSTINT('fk_project');
76
77
78$mine = GETPOST('mode') == 'mine' ? 1 : 0;
79//if (! $user->rights->projet->all->lire) $mine=1; // Special for projects
80
81// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
82$hookmanager->initHooks(array('projectcard', 'globalcard'));
83
84$object = new Project($db);
85$extrafields = new ExtraFields($db);
86
87// Load object
88//include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Can't use generic include because when creating a project, ref is defined and we don't want error if fetch fails from ref.
89if ($id > 0 || !empty($ref)) {
90 $ret = $object->fetch($id, $ref); // If we create project, ref may be defined into POST but record does not yet exists into database
91 if ($ret > 0) {
92 $object->fetch_thirdparty();
93 if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($object, 'fetchComments') && empty($object->comments)) {
94 $object->fetchComments();
95 }
96 $id = $object->id;
97 }
98}
99
100// fetch optionals attributes and labels
101$extrafields->fetch_name_optionals_label($object->table_element);
102
103// Security check
104$socid = GETPOSTINT('socid');
105//if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignment.
106restrictedArea($user, 'projet', $object->id, 'projet&project');
107
108if ($id == '' && $ref == '' && ($action != "create" && $action != "add" && $action != "update" && !GETPOST("cancel"))) {
110}
111
112$permissiontoadd = $user->hasRight('projet', 'creer');
113$permissiontodelete = $user->hasRight('projet', 'supprimer');
114$permissiondellink = $user->hasRight('projet', 'creer'); // Used by the include of actions_dellink.inc.php
115
116
117/*
118 * Actions
119 */
120
121$parameters = array('id' => $socid, 'objcanvas' => $objcanvas);
122$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
123if ($reshook < 0) {
124 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
125}
126
127if (empty($reshook)) {
128 $backurlforlist = DOL_URL_ROOT.'/projet/list.php';
129
130 // Cancel
131 if ($cancel) {
132 if (GETPOST("comefromclone") == 1) {
133 $result = $object->delete($user);
134 if ($result > 0) {
135 header("Location: index.php");
136 exit;
137 } else {
138 dol_syslog($object->error, LOG_DEBUG);
139 setEventMessages($langs->trans("CantRemoveProject", $langs->transnoentitiesnoconv("ProjectOverview")), null, 'errors');
140 }
141 }
142 }
143
144 if (empty($backtopage) || ($cancel && empty($id))) {
145 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
146 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
147 $backtopage = $backurlforlist;
148 } else {
149 $backtopage = DOL_URL_ROOT.'/projet/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
150 }
151 }
152 }
153
154 if ($cancel) {
155 if (!empty($backtopageforcancel)) {
156 header("Location: ".$backtopageforcancel);
157 exit;
158 } elseif (!empty($backtopage)) {
159 header("Location: ".$backtopage);
160 exit;
161 }
162 $action = '';
163 }
164
165 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
166
167 // Action setdraft object
168 if ($action == 'confirm_setdraft' && $confirm == 'yes' && $permissiontoadd) {
169 $result = $object->setStatut($object::STATUS_DRAFT, null, '', 'PROJECT_MODIFY');
170 if ($result >= 0) {
171 // Nothing else done
172 } else {
173 $error++;
174 setEventMessages($object->error, $object->errors, 'errors');
175 }
176 $action = '';
177
178 // For backward compatibility
179 $object->statut = $object::STATUS_DRAFT; // this already set for $object->status by $object->setStatut()
180 }
181
182 // Action add
183 if ($action == 'add' && $permissiontoadd) {
184 $error = 0;
185 if (!GETPOST('ref')) {
186 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors');
187 $error++;
188 }
189 if (!GETPOST('title')) {
190 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("ProjectLabel")), null, 'errors');
191 $error++;
192 }
193
194 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
195 if (GETPOST('usage_opportunity') != '' && !(GETPOST('opp_status') > 0)) {
196 $error++;
197 setEventMessages($langs->trans("ErrorOppStatusRequiredIfUsage"), null, 'errors');
198 }
199 if (GETPOST('opp_amount') != '' && !(GETPOST('opp_status') > 0)) {
200 $error++;
201 setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors');
202 }
203 }
204
205 // Create with status validated immediately
206 if (getDolGlobalString('PROJECT_CREATE_NO_DRAFT') && !$error) {
208 }
209
210 if (!$error) {
211 $error = 0;
212
213 $db->begin();
214
215 $object->ref = GETPOST('ref', 'alphanohtml');
216 $object->fk_project = GETPOSTINT('fk_project');
217 $object->title = GETPOST('title', 'alphanohtml');
218 $object->socid = GETPOSTINT('socid');
219 $object->description = GETPOST('description', 'restricthtml'); // Do not use 'alpha' here, we want field as it is
220 $object->public = GETPOST('public', 'alphanohtml');
221 $object->opp_amount = GETPOSTFLOAT('opp_amount');
222 $object->budget_amount = GETPOSTFLOAT('budget_amount');
223 $object->date_c = dol_now();
224 $object->date_start = $date_start;
225 $object->date_end = $date_end;
226 $object->date_start_event = $date_start_event;
227 $object->date_end_event = $date_end_event;
228 $object->location = $location;
229 $object->statut = $status;
230 $object->opp_status = $opp_status;
231 $object->opp_percent = $opp_percent;
232 $object->usage_opportunity = (GETPOST('usage_opportunity', 'alpha') == 'on' ? 1 : 0);
233 $object->usage_task = (GETPOST('usage_task', 'alpha') == 'on' ? 1 : 0);
234 $object->usage_bill_time = (GETPOST('usage_bill_time', 'alpha') == 'on' ? 1 : 0);
235 $object->usage_organize_event = (GETPOST('usage_organize_event', 'alpha') == 'on' ? 1 : 0);
236
237 // Fill array 'array_options' with data from add form
238 $ret = $extrafields->setOptionalsFromPost(null, $object);
239 if ($ret < 0) {
240 $error++;
241 }
242
243 $result = $object->create($user);
244 if (!$error && $result > 0) {
245 // Add myself as project leader
246 $typeofcontact = 'PROJECTLEADER';
247 $result = $object->add_contact($user->id, $typeofcontact, 'internal');
248
249 // -3 means type not found (PROJECTLEADER renamed, de-activated or deleted), so don't prevent creation if it has been the case
250 if ($result == -3) {
251 setEventMessage('ErrorPROJECTLEADERRoleMissingRestoreIt', 'errors');
252 $error++;
253 } elseif ($result < 0) {
254 $langs->load("errors");
255 setEventMessages($object->error, $object->errors, 'errors');
256 $error++;
257 }
258 } else {
259 $langs->load("errors");
260 setEventMessages($object->error, $object->errors, 'errors');
261 $error++;
262 }
263 if (!$error && !empty($object->id) > 0) {
264 // Category association
265 $categories = GETPOST('categories', 'array');
266 $result = $object->setCategories($categories);
267 if ($result < 0) {
268 $langs->load("errors");
269 setEventMessages($object->error, $object->errors, 'errors');
270 $error++;
271 }
272 }
273
274 if (!$error) {
275 $db->commit();
276
277 if (!empty($backtopage)) {
278 $backtopage = preg_replace('/--IDFORBACKTOPAGE--|__ID__/', (string) $object->id, $backtopage); // New method to autoselect project after a New on another form object creation
279 $backtopage = $backtopage.'&projectid='.$object->id; // Old method
280 header("Location: ".$backtopage);
281 exit;
282 } else {
283 header("Location:card.php?id=".$object->id);
284 exit;
285 }
286 } else {
287 $db->rollback();
288 unset($_POST["ref"]);
289 $action = 'create';
290 }
291 } else {
292 $action = 'create';
293 }
294 }
295
296 if ($action == 'update' && empty(GETPOST('cancel')) && $permissiontoadd) {
297 $error = 0;
298
299 if (empty($ref)) {
300 $error++;
301 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors');
302 }
303 if (!GETPOST("title")) {
304 $error++;
305 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("ProjectLabel")), null, 'errors');
306 }
307
308 $db->begin();
309
310 if (!$error) {
311 $object->oldcopy = clone $object;
312
313 $old_start_date = $object->date_start;
314
315 $object->ref = GETPOST('ref', 'alpha');
316 $object->fk_project = GETPOSTINT('fk_project');
317 $object->title = GETPOST('title', 'alphanohtml'); // Do not use 'alpha' here, we want field as it is
318 $object->statut = GETPOSTINT('status');
319 $object->socid = GETPOSTINT('socid');
320 $object->description = GETPOST('description', 'restricthtml'); // Do not use 'alpha' here, we want field as it is
321 $object->public = GETPOST('public', 'alpha');
322 $object->date_start = (!GETPOST('projectstart')) ? '' : $date_start;
323 $object->date_end = (!GETPOST('projectend')) ? '' : $date_end;
324 $object->date_start_event = (!GETPOST('date_start_event')) ? '' : $date_start_event;
325 $object->date_end_event = (!GETPOST('date_end_event')) ? '' : $date_end_event;
326 $object->location = $location;
327 if (GETPOSTISSET('opp_amount')) {
328 $object->opp_amount = price2num(GETPOST('opp_amount', 'alpha'));
329 }
330 if (GETPOSTISSET('budget_amount')) {
331 $object->budget_amount = price2num(GETPOST('budget_amount', 'alpha'));
332 }
333 if (GETPOSTISSET('opp_status')) {
334 $object->opp_status = $opp_status;
335 }
336 if (GETPOSTISSET('opp_percent')) {
337 $object->opp_percent = $opp_percent;
338 }
339 $object->usage_opportunity = (GETPOST('usage_opportunity', 'alpha') == 'on' ? 1 : 0);
340 $object->usage_task = (GETPOST('usage_task', 'alpha') == 'on' ? 1 : 0);
341 $object->usage_bill_time = (GETPOST('usage_bill_time', 'alpha') == 'on' ? 1 : 0);
342 $object->usage_organize_event = (GETPOST('usage_organize_event', 'alpha') == 'on' ? 1 : 0);
343
344 // Fill array 'array_options' with data from add form
345 $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET');
346 if ($ret < 0) {
347 $error++;
348 }
349 }
350
351 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
352 if ($object->opp_amount && ($object->opp_status <= 0)) {
353 $error++;
354 setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors');
355 }
356 }
357
358 if (!$error) {
359 $result = $object->update($user);
360 if ($result < 0) {
361 $error++;
362 if ($result == -4) {
363 setEventMessages($langs->trans("ErrorRefAlreadyExists"), null, 'errors');
364 } else {
365 setEventMessages($object->error, $object->errors, 'errors');
366 }
367 } else {
368 // Category association
369 $categories = GETPOST('categories', 'array');
370 $result = $object->setCategories($categories);
371 if ($result < 0) {
372 $error++;
373 setEventMessages($object->error, $object->errors, 'errors');
374 }
375 }
376 }
377
378 if (!$error) {
379 if (GETPOST("reportdate") && ($object->date_start != $old_start_date)) {
380 $result = $object->shiftTaskDate($old_start_date);
381 if ($result < 0) {
382 $error++;
383 setEventMessages($langs->trans("ErrorShiftTaskDate").':'.$object->error, $object->errors, 'errors');
384 }
385 }
386 }
387
388 // Check if we must change status
389 if (GETPOST('closeproject')) {
390 $resclose = $object->setClose($user);
391 if ($resclose < 0) {
392 $error++;
393 setEventMessages($langs->trans("FailedToCloseProject").':'.$object->error, $object->errors, 'errors');
394 }
395 }
396
397
398 if ($error) {
399 $db->rollback();
400 $action = 'edit';
401 } else {
402 $db->commit();
403
404 if (GETPOSTINT('socid') > 0) {
405 $object->fetch_thirdparty(GETPOSTINT('socid'));
406 } else {
407 unset($object->thirdparty);
408 }
409 }
410 }
411
412 if ($action == 'set_opp_status' && $user->hasRight('projet', 'creer')) {
413 $error = 0;
414 if (GETPOSTISSET('opp_status')) {
415 $object->opp_status = $opp_status;
416 }
417 if (GETPOSTISSET('opp_percent')) {
418 $object->opp_percent = $opp_percent;
419 }
420
421 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
422 if ($object->opp_amount && ($object->opp_status <= 0)) {
423 $error++;
424 setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors');
425 }
426 }
427
428 if (!$error) {
429 $result = $object->update($user);
430 if ($result < 0) {
431 $error++;
432 if ($result == -4) {
433 setEventMessages($langs->trans("ErrorRefAlreadyExists"), null, 'errors');
434 } else {
435 setEventMessages($object->error, $object->errors, 'errors');
436 }
437 }
438 }
439
440 if ($error) {
441 $db->rollback();
442 $action = 'edit';
443 } else {
444 $db->commit();
445 }
446 }
447
448 // Build doc
449 if ($action == 'builddoc' && $permissiontoadd) {
450 // Save last template used to generate document
451 if (GETPOST('model')) {
452 $object->setDocModel($user, GETPOST('model', 'alpha'));
453 }
454
455 $outputlangs = $langs;
456 if (GETPOST('lang_id', 'aZ09')) {
457 $outputlangs = new Translate("", $conf);
458 $outputlangs->setDefaultLang(GETPOST('lang_id', 'aZ09'));
459 }
460 $result = $object->generateDocument($object->model_pdf, $outputlangs);
461 if ($result <= 0) {
462 setEventMessages($object->error, $object->errors, 'errors');
463 $action = '';
464 }
465 }
466
467 // Delete file in doc form
468 if ($action == 'remove_file' && $permissiontoadd) {
469 if ($object->id > 0) {
470 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
471
472 $langs->load("other");
473 $upload_dir = $conf->project->multidir_output[$object->entity];
474 $file = $upload_dir.'/'.GETPOST('file');
475 $ret = dol_delete_file($file, 0, 0, 0, $object);
476 if ($ret) {
477 setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs');
478 } else {
479 setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors');
480 }
481 $action = '';
482 }
483 }
484
485
486 if ($action == 'confirm_validate' && $confirm == 'yes' && $permissiontoadd) {
487 $result = $object->setValid($user);
488 if ($result <= 0) {
489 setEventMessages($object->error, $object->errors, 'errors');
490 }
491 }
492
493 if ($action == 'confirm_close' && $confirm == 'yes' && $permissiontoadd) {
494 $result = $object->setClose($user);
495 if ($result <= 0) {
496 setEventMessages($object->error, $object->errors, 'errors');
497 }
498 }
499
500 if ($action == 'confirm_reopen' && $confirm == 'yes' && $permissiontoadd) {
501 $result = $object->setValid($user);
502 if ($result <= 0) {
503 setEventMessages($object->error, $object->errors, 'errors');
504 }
505 }
506
507 if ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) {
508 $object->fetch($id);
509 $result = $object->delete($user);
510 if ($result > 0) {
511 setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
512
513 if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
514 $tmpurl = $_SESSION['pageforbacktolist']['project'];
515 $tmpurl = preg_replace('/__SOCID__/', (string) $object->socid, $tmpurl);
516 $urlback = $tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1';
517 } else {
518 $urlback = DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1';
519 }
520
521 header("Location: ".$urlback);
522 exit;
523 } else {
524 dol_syslog($object->error, LOG_DEBUG);
525 setEventMessages($object->error, $object->errors, 'errors');
526 }
527 }
528
529 if ($action == 'confirm_clone' && $permissiontoadd && $confirm == 'yes') {
530 $clone_contacts = GETPOST('clone_contacts') ? 1 : 0;
531 $clone_tasks = GETPOST('clone_tasks') ? 1 : 0;
532 $clone_project_files = GETPOST('clone_project_files') ? 1 : 0;
533 $clone_task_files = GETPOST('clone_task_files') ? 1 : 0;
534 $clone_notes = GETPOST('clone_notes') ? 1 : 0;
535 $move_date = GETPOST('move_date') ? 1 : 0;
536 $clone_thirdparty = GETPOSTINT('socid') ? GETPOSTINT('socid') : 0;
537
538 $result = $object->createFromClone($user, $object->id, $clone_contacts, $clone_tasks, $clone_project_files, $clone_task_files, $clone_notes, $move_date, 0, $clone_thirdparty);
539 if ($result <= 0) {
540 setEventMessages($object->error, $object->errors, 'errors');
541 } else {
542 // Load new object
543 $newobject = new Project($db);
544 $newobject->fetch($result);
545 $newobject->fetch_optionals();
546 $newobject->fetch_thirdparty(); // Load new object
547 $object = $newobject;
548 $action = 'view';
549 $comefromclone = true;
550
551 setEventMessages($langs->trans("ProjectCreatedInDolibarr", $newobject->ref), "", 'mesgs');
552 //var_dump($newobject); exit;
553 }
554 }
555
556 // Actions to send emails
557 $triggersendname = 'PROJECT_SENTBYMAIL';
558 $paramname = 'id';
559 $autocopy = 'MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add
560 $trackid = 'proj'.$object->id;
561 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
562}
563
564
565/*
566 * View
567 */
568
569$form = new Form($db);
570$formfile = new FormFile($db);
571$formproject = new FormProjets($db);
572$userstatic = new User($db);
573
574$title = $langs->trans("Project").' - '.$object->ref.(!empty($object->thirdparty->name) ? ' - '.$object->thirdparty->name : '').(!empty($object->title) ? ' - '.$object->title : '');
575if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/projectnameonly/', getDolGlobalString('MAIN_HTML_TITLE'))) {
576 $title = $object->ref.(!empty($object->thirdparty->name) ? ' - '.$object->thirdparty->name : '').(!empty($object->title) ? ' - '.$object->title : '');
577}
578
579$help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte";
580
581llxHeader("", $title, $help_url);
582
583$titleboth = $langs->trans("LeadsOrProjects");
584$titlenew = $langs->trans("NewLeadOrProject"); // Leads and opportunities by default
585if (!getDolGlobalInt('PROJECT_USE_OPPORTUNITIES')) {
586 $titleboth = $langs->trans("Projects");
587 $titlenew = $langs->trans("NewProject");
588}
589if (getDolGlobalInt('PROJECT_USE_OPPORTUNITIES') == 2) { // 2 = leads only
590 $titleboth = $langs->trans("Leads");
591 $titlenew = $langs->trans("NewLead");
592}
593
594if ($action == 'create' && $user->hasRight('projet', 'creer')) {
595 /*
596 * Create
597 */
598
599 $thirdparty = new Societe($db);
600 if ($socid > 0) {
601 $thirdparty->fetch($socid);
602 }
603
604 print load_fiche_titre($titlenew, '', 'project');
605
606 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
607 print '<input type="hidden" name="action" value="add">';
608 print '<input type="hidden" name="token" value="'.newToken().'">';
609 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
610 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
611 print '<input type="hidden" name="backtopagejsfields" value="'.$backtopagejsfields.'">';
612 print '<input type="hidden" name="dol_openinpopup" value="'.$dol_openinpopup.'">';
613
614 print dol_get_fiche_head();
615
616 print '<table class="border centpercent tableforfieldcreate">';
617
618 $defaultref = '';
619 $modele = !getDolGlobalString('PROJECT_ADDON') ? 'mod_project_simple' : $conf->global->PROJECT_ADDON;
620
621 // Search template files
622 $file = '';
623 $classname = '';
624 $filefound = 0;
625 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
626 foreach ($dirmodels as $reldir) {
627 $file = dol_buildpath($reldir."core/modules/project/".$modele.'.php', 0);
628 if (file_exists($file)) {
629 $filefound = 1;
630 $classname = $modele;
631 break;
632 }
633 }
634
635 if ($filefound) {
636 $result = dol_include_once($reldir."core/modules/project/".$modele.'.php');
637 $modProject = new $classname();
638
639 $defaultref = $modProject->getNextValue($thirdparty, $object);
640 }
641
642 if (is_numeric($defaultref) && $defaultref <= 0) {
643 $defaultref = '';
644 }
645
646 // Ref
647 $suggestedref = (GETPOST("ref") ? GETPOST("ref") : $defaultref);
648 print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Ref").'</span></td><td class><input class="maxwidth150onsmartphone" type="text" name="ref" value="'.dol_escape_htmltag($suggestedref).'">';
649 if ($suggestedref) {
650 print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref));
651 }
652 print '</td></tr>';
653
654 // Label
655 print '<tr><td><span class="fieldrequired">'.$langs->trans("Label").'</span></td><td><input class="width500 maxwidth150onsmartphone" type="text" name="title" value="'.dol_escape_htmltag(GETPOST("title", 'alphanohtml')).'" autofocus></td></tr>';
656
657 // Parent
658 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
659 print '<tr><td>'.$langs->trans("Parent").'</td><td class="maxwidthonsmartphone">';
660 print img_picto('', 'project', 'class="pictofixedwidth"');
661 $formproject->select_projects(-1, '', 'fk_project', 64, 0, 1, 1, 0, 0, 0, '', 0, 0, '', '', '');
662 print '</td></tr>';
663 }
664
665 // Usage (opp, task, bill time, ...)
666 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
667 print '<tr><td class="tdtop">';
668 print $langs->trans("Usage");
669 print '</td>';
670 print '<td>';
671 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
672 print '<input type="checkbox" id="usage_opportunity" name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') ? ' checked="checked"' : '') : ' checked="checked"').'"> ';
673 $htmltext = $langs->trans("ProjectFollowOpportunity");
674 print '<label for="usage_opportunity">'.$form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext).'</label>';
675 print '<script>';
676 print '$( document ).ready(function() {
677 jQuery("#usage_opportunity").change(function() {
678 if (jQuery("#usage_opportunity").prop("checked")) {
679 console.log("Show opportunities fields");
680 jQuery(".classuseopportunity").show();
681 } else {
682 console.log("Hide opportunities fields "+jQuery("#usage_opportunity").prop("checked"));
683 jQuery(".classuseopportunity").hide();
684 }
685 });
686 ';
687 if (GETPOSTISSET('usage_opportunity') && !GETPOST('usage_opportunity')) {
688 print 'jQuery(".classuseopportunity").hide();';
689 }
690 print '});';
691 print '</script>';
692 print '<br>';
693 }
694 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
695 print '<input type="checkbox" id="usage_task" name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') ? ' checked="checked"' : '') : ' checked="checked"').'"> ';
696 $htmltext = $langs->trans("ProjectFollowTasks");
697 print '<label for="usage_task">'.$form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext).'</label>';
698 print '<script>';
699 print '$( document ).ready(function() {
700 jQuery("#usage_task").change(function() {
701 if (jQuery("#usage_task").prop("checked")) {
702 console.log("Show task fields");
703 jQuery(".classusetask").show();
704 } else {
705 console.log("Hide tasks fields "+jQuery("#usage_task").prop("checked"));
706 jQuery(".classusetask").hide();
707 }
708 });
709 ';
710 if (GETPOSTISSET('usage_task') && !GETPOST('usage_task')) {
711 print 'jQuery(".classusetask").hide();';
712 }
713 print '});';
714 print '</script>';
715 print '<br>';
716 }
717 if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
718 print '<input type="checkbox" id="usage_bill_time" name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') ? ' checked="checked"' : '') : '').'"> ';
719 $htmltext = $langs->trans("ProjectBillTimeDescription");
720 print '<label for="usage_bill_time">'.$form->textwithpicto($langs->trans("BillTime"), $htmltext).'</label>';
721 print '<script>';
722 print '$( document ).ready(function() {
723 jQuery("#usage_bill_time").change(function() {
724 if (jQuery("#usage_bill_time").prop("checked")) {
725 console.log("Show bill time fields");
726 jQuery(".classusebilltime").show();
727 } else {
728 console.log("Hide bill time fields "+jQuery("#usage_bill_time").prop("checked"));
729 jQuery(".classusebilltime").hide();
730 }
731 });
732 ';
733 if (GETPOSTISSET('usage_bill_time') && !GETPOST('usage_bill_time')) {
734 print 'jQuery(".classusebilltime").hide();';
735 }
736 print '});';
737 print '</script>';
738 print '<br>';
739 }
740 if (isModEnabled('eventorganization')) {
741 print '<input type="checkbox" id="usage_organize_event" name="usage_organize_event"'.(GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') ? ' checked="checked"' : '') : '').'"> ';
742 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
743 print '<label for="usage_organize_event">'.$form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext).'</label>';
744 print '<script>';
745 print '$( document ).ready(function() {
746 jQuery("#usage_organize_event").change(function() {
747 if (jQuery("#usage_organize_event").prop("checked")) {
748 console.log("Show organize event fields");
749 jQuery(".classuseorganizeevent").show();
750 } else {
751 console.log("Hide organize event fields "+jQuery("#usage_organize_event").prop("checked"));
752 jQuery(".classuseorganizeevent").hide();
753 }
754 });
755 ';
756 if (!GETPOST('usage_organize_event')) {
757 print 'jQuery(".classuseorganizeevent").hide();';
758 }
759 print '});';
760 print '</script>';
761 }
762 print '</td>';
763 print '</tr>';
764 }
765
766 // Thirdparty
767 if (isModEnabled('societe')) {
768 print '<tr><td>';
769 print(!getDolGlobalString('PROJECT_THIRDPARTY_REQUIRED') ? '' : '<span class="fieldrequired">');
770 print $langs->trans("ThirdParty");
771 print(!getDolGlobalString('PROJECT_THIRDPARTY_REQUIRED') ? '' : '</span>');
772 print '</td><td class="maxwidthonsmartphone">';
773 $filter = '';
774 if (getDolGlobalString('PROJECT_FILTER_FOR_THIRDPARTY_LIST')) {
775 $filter = getDolGlobalString('PROJECT_FILTER_FOR_THIRDPARTY_LIST');
776 }
777 $text = img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(GETPOSTINT('socid'), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
778 if (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') && empty($conf->dol_use_jmobile)) {
779 $texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty");
780 print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1);
781 } else {
782 print $text;
783 }
784 if (!GETPOSTISSET('backtopage')) {
785 $url = '/societe/card.php?action=create&client=3&fournisseur=0&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create');
786 $newbutton = '<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddThirdParty").'"></span>';
787 // TODO @LDR Implement this
788 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
789 $tmpbacktopagejsfields = 'addthirdparty:socid,search_socid';
790 print dolButtonToOpenUrlInDialogPopup('addthirdparty', $langs->transnoentitiesnoconv('AddThirdParty'), $newbutton, $url, '', '', '', $tmpbacktopagejsfields);
791 } else {
792 print ' <a href="'.DOL_URL_ROOT.$url.'">'.$newbutton.'</a>';
793 }
794 }
795 print '</td></tr>';
796 }
797
798 // Status
799 if ($status != '') {
800 print '<tr><td>'.$langs->trans("Status").'</td><td>';
801 print '<input type="hidden" name="status" value="'.$status.'">';
802 print $object->LibStatut($status, 4);
803 print '</td></tr>';
804 }
805
806 // Visibility
807 print '<tr><td>'.$langs->trans("Visibility").'</td><td class="maxwidthonsmartphone">';
808 $array = array();
809 if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) {
810 $array[0] = $langs->trans("PrivateProject");
811 }
812 if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) {
813 $array[1] = $langs->trans("SharedProject");
814 }
815
816 if (count($array) > 0) {
817 print $form->selectarray('public', $array, GETPOST('public'), 0, 0, 0, '', 0, 0, 0, '', '', 1);
818 } else {
819 print '<input type="hidden" name="public" id="public" value="'.GETPOST('public').'">';
820
821 if (GETPOST('public') == 0) {
822 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
823 print $langs->trans("PrivateProject");
824 } else {
825 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
826 print $langs->trans("SharedProject");
827 }
828 }
829 print '</td></tr>';
830
831 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
832 // Opportunity status
833 print '<tr class="classuseopportunity"><td><span class="fieldrequired">'.$langs->trans("OpportunityStatus").'</span></td>';
834 print '<td class="maxwidthonsmartphone">';
835 print $formproject->selectOpportunityStatus('opp_status', GETPOSTISSET('opp_status') ? GETPOST('opp_status') : $object->opp_status, 1, 0, 0, 0, '', 0, 1);
836
837 // Opportunity probability
838 print ' <input class="width50 right" type="text" id="opp_percent" name="opp_percent" title="'.dol_escape_htmltag($langs->trans("OpportunityProbability")).'" value="'.dol_escape_htmltag(GETPOSTISSET('opp_percent') ? GETPOST('opp_percent') : '').'"><span class="hideonsmartphone"> %</span>';
839 print '<input type="hidden" name="opp_percent_not_set" id="opp_percent_not_set" value="'.dol_escape_htmltag(GETPOSTISSET('opp_percent') ? '0' : '1').'">';
840 print '</td>';
841 print '</tr>';
842
843 // Opportunity amount
844 print '<tr class="classuseopportunity"><td>'.$langs->trans("OpportunityAmount").'</td>';
845 print '<td><input class="width75 right" type="text" name="opp_amount" value="'.dol_escape_htmltag(GETPOSTISSET('opp_amount') ? GETPOST('opp_amount') : '').'">';
846 print ' '.$langs->getCurrencySymbol($conf->currency);
847 print '</td>';
848 print '</tr>';
849 }
850
851 // Budget
852 print '<tr><td>'.$langs->trans("Budget").'</td>';
853 print '<td><input class="width75 right" type="text" name="budget_amount" value="'.dol_escape_htmltag(GETPOSTISSET('budget_amount') ? GETPOST('budget_amount') : '').'">';
854 print ' '.$langs->getCurrencySymbol($conf->currency);
855 print '</td>';
856 print '</tr>';
857
858 // Date project
859 print '<tr><td>'.$langs->trans("Date").(isModEnabled('eventorganization') ? ' <span class="classuseorganizeevent">('.$langs->trans("Project").')</span>' : '').'</td><td>';
860 print $form->selectDate(($date_start ? $date_start : ''), 'projectstart', 0, 0, 0, '', 1, 0);
861 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
862 print $form->selectDate(($date_end ? $date_end : -1), 'projectend', 0, 0, 0, '', 1, 0);
863 print '</td></tr>';
864
865 if (isModEnabled('eventorganization')) {
866 // Date event
867 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Date").' ('.$langs->trans("Event").')</td><td>';
868 print $form->selectDate(($date_start_event ? $date_start_event : -1), 'date_start_event', 1, 1, 1, '', 1, 0);
869 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
870 print $form->selectDate(($date_end_event ? $date_end_event : -1), 'date_end_event', 1, 1, 1, '', 1, 0);
871 print '</td></tr>';
872
873 // Location
874 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Location").'</td>';
875 print '<td><input class="minwidth300 maxwidth500" type="text" name="location" value="'.dol_escape_htmltag($location).'"></td>';
876 print '</tr>';
877 }
878
879 // Description
880 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
881 print '<td>';
882 $doleditor = new DolEditor('description', GETPOST("description", 'restricthtml'), '', 90, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor') && getDolGlobalString('FCKEDITOR_ENABLE_SOCIETE'), ROWS_3, '90%');
883 $doleditor->Create();
884 print '</td></tr>';
885
886 if (isModEnabled('category')) {
887 // Categories
888 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
889 $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 3);
890 $arrayselected = GETPOST('categories', 'array');
891 print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
892 print "</td></tr>";
893 }
894
895 // Other options
896 $parameters = array();
897 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
898 print $hookmanager->resPrint;
899 if (empty($reshook)) {
900 print $object->showOptionals($extrafields, 'create');
901 }
902
903 print '</table>';
904
905 print dol_get_fiche_end();
906
907 print $form->buttonsSaveCancel('CreateDraft');
908
909 print '</form>';
910
911 // Change probability from status or role of project
912 // Set also dependencies between use task and bill time
913 print '<script type="text/javascript">
914 jQuery(document).ready(function() {
915 function change_percent()
916 {
917 var element = jQuery("#opp_status option:selected");
918 var defaultpercent = element.attr("defaultpercent");
919 /*if (jQuery("#opp_percent_not_set").val() == "") */
920 jQuery("#opp_percent").val(defaultpercent);
921 }
922
923 /*init_myfunc();*/
924 jQuery("#opp_status").change(function() {
925 change_percent();
926 });
927
928 jQuery("#usage_task").change(function() {
929 console.log("We click on usage task "+jQuery("#usage_task").is(":checked"));
930 if (! jQuery("#usage_task").is(":checked")) {
931 jQuery("#usage_bill_time").prop("checked", false);
932 }
933 });
934
935 jQuery("#usage_bill_time").change(function() {
936 console.log("We click on usage to bill time");
937 if (jQuery("#usage_bill_time").is(":checked")) {
938 jQuery("#usage_task").prop("checked", true);
939 }
940 });
941 });
942 </script>';
943} elseif ($object->id > 0) {
944 /*
945 * Show or edit
946 */
947
948 $res = $object->fetch_optionals();
949
950 // To verify role of users
951 $userAccess = $object->restrictedProjectArea($user, 'read');
952 $userWrite = $object->restrictedProjectArea($user, 'write');
953 $userDelete = $object->restrictedProjectArea($user, 'delete');
954 //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
955
956
957 // Confirmation validation
958 if ($action == 'validate') {
959 print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProject'), $langs->trans('ConfirmValidateProject'), 'confirm_validate', '', 0, 1);
960 }
961 // Confirmation close
962 if ($action == 'close') {
963 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("CloseAProject"), $langs->trans("ConfirmCloseAProject"), "confirm_close", '', '', 1);
964 }
965 // Confirmation reopen
966 if ($action == 'reopen') {
967 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ReOpenAProject"), $langs->trans("ConfirmReOpenAProject"), "confirm_reopen", '', '', 1);
968 }
969 // Confirmation delete
970 if ($action == 'delete') {
971 $text = $langs->trans("ConfirmDeleteAProject");
972 $task = new Task($db);
973 $taskarray = $task->getTasksArray(0, 0, $object->id, 0, 0);
974 $nboftask = count($taskarray);
975 if ($nboftask) {
976 $text .= '<br>'.img_warning().' '.$langs->trans("ThisWillAlsoRemoveTasks", $nboftask);
977 }
978 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("DeleteAProject"), $text, "confirm_delete", '', '', 1);
979 }
980
981 // Clone confirmation
982 if ($action == 'clone') {
983 $formquestion = array(
984 'text' => $langs->trans("ConfirmClone"),
985 0 => array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOSTINT('socid') > 0 ? GETPOSTINT('socid') : $object->socid, 'socid', '', "None", 0, 0, null, 0, 'minwidth200 maxwidth250')),
986 1 => array('type' => 'checkbox', 'name' => 'clone_contacts', 'label' => $langs->trans("CloneContacts"), 'value' => true),
987 2 => array('type' => 'checkbox', 'name' => 'clone_tasks', 'label' => $langs->trans("CloneTasks"), 'value' => true),
988 3 => array('type' => 'checkbox', 'name' => 'move_date', 'label' => $langs->trans("CloneMoveDate"), 'value' => true),
989 4 => array('type' => 'checkbox', 'name' => 'clone_notes', 'label' => $langs->trans("CloneNotes"), 'value' => true),
990 5 => array('type' => 'checkbox', 'name' => 'clone_project_files', 'label' => $langs->trans("CloneProjectFiles"), 'value' => false),
991 6 => array('type' => 'checkbox', 'name' => 'clone_task_files', 'label' => $langs->trans("CloneTaskFiles"), 'value' => false)
992 );
993
994 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ToClone"), $langs->trans("ConfirmCloneProject"), "confirm_clone", $formquestion, '', 1, 400, 590);
995 }
996
997
998 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
999 print '<input type="hidden" name="token" value="'.newToken().'">';
1000 print '<input type="hidden" name="action" value="update">';
1001 print '<input type="hidden" name="id" value="'.$object->id.'">';
1002 print '<input type="hidden" name="comefromclone" value="'.$comefromclone.'">';
1003
1005
1006 if ($action == 'edit' && $userWrite > 0) {
1007 print dol_get_fiche_head($head, 'project', $langs->trans("Project"), 0, ($object->public ? 'projectpub' : 'project'));
1008
1009 print '<table class="border centpercent">';
1010
1011 // Ref
1012 $suggestedref = $object->ref;
1013 print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Ref").'</td>';
1014 print '<td><input class="width200" name="ref" value="'.$suggestedref.'">';
1015 print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref));
1016 print '</td></tr>';
1017
1018 // Label
1019 print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>';
1020 print '<td><input class="quatrevingtpercent" name="title" value="'.dol_escape_htmltag($object->title).'"></td></tr>';
1021
1022 // Status
1023 print '<tr><td class="fieldrequired">'.$langs->trans("Status").'</td><td>';
1024 print '<select class="flat" name="status" id="status">';
1025 $statuses = $object->labelStatusShort;
1026 if (getDolGlobalString('MAIN_DISABLEDRAFTSTATUS') || getDolGlobalString('MAIN_DISABLEDRAFTSTATUS_PROJECT')) {
1027 unset($statuses[$object::STATUS_DRAFT]);
1028 }
1029 foreach ($statuses as $key => $val) {
1030 print '<option value="'.$key.'"'.((GETPOSTISSET('status') ? GETPOST('status') : $object->statut) == $key ? ' selected="selected"' : '').'>'.$langs->trans($val).'</option>';
1031 }
1032 print '</select>';
1033 print ajax_combobox('status');
1034 print '</td></tr>';
1035
1036 // Parent
1037 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1038 print '<tr><td>'.$langs->trans("Parent").'</td><td class="maxwidthonsmartphone">';
1039 print img_picto('', 'project', 'class="pictofixedwidth"');
1040 $formproject->select_projects(-1, $object->fk_project, 'fk_project', 64, 0, 1, 1, 0, 0, 0, '', 0, 0, '', '', '');
1041 print '</td></tr>';
1042 }
1043
1044 // Usage
1045 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
1046 print '<tr><td class="tdtop">';
1047 print $langs->trans("Usage");
1048 print '</td>';
1049 print '<td>';
1050 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1051 print '<input type="checkbox" id="usage_opportunity" name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'> ';
1052 $htmltext = $langs->trans("ProjectFollowOpportunity");
1053 print '<label for="usage_opportunity">'.$form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext).'</label>';
1054 print '<script>';
1055 print '$( document ).ready(function() {
1056 jQuery("#usage_opportunity").change(function() {
1057 set_usage_opportunity();
1058 });
1059
1060 set_usage_opportunity();
1061
1062 function set_usage_opportunity() {
1063 console.log("set_usage_opportunity");
1064 if (jQuery("#usage_opportunity").prop("checked")) {
1065 console.log("Show opportunities fields");
1066 jQuery(".classuseopportunity").show();
1067 } else {
1068 console.log("Hide opportunities fields "+jQuery("#usage_opportunity").prop("checked"));
1069 jQuery(".classuseopportunity").hide();
1070 }
1071 }
1072 });';
1073 print '</script>';
1074 print '<br>';
1075 }
1076 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
1077 print '<input type="checkbox" id="usage_task" name="usage_task"' . (GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')) . '> ';
1078 $htmltext = $langs->trans("ProjectFollowTasks");
1079 print '<label for="usage_task">'.$form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext).'</label>';
1080 print '<script>';
1081 print '$( document ).ready(function() {
1082 jQuery("#usage_task").change(function() {
1083 set_usage_task();
1084 });
1085
1086 set_usage_task();
1087
1088 function set_usage_task() {
1089 console.log("set_usage_task");
1090 if (jQuery("#usage_task").prop("checked")) {
1091 console.log("Show task fields");
1092 jQuery(".classusetask").show();
1093 } else {
1094 console.log("Hide task fields "+jQuery("#usage_task").prop("checked"));
1095 jQuery(".classusetask").hide();
1096 }
1097 }
1098 });';
1099 print '</script>';
1100 print '<br>';
1101 }
1102 if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
1103 print '<input type="checkbox" id="usage_bill_time" name="usage_bill_time"' . (GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_bill_time ? ' checked="checked"' : '')) . '> ';
1104 $htmltext = $langs->trans("ProjectBillTimeDescription");
1105 print '<label for="usage_bill_time">'.$form->textwithpicto($langs->trans("BillTime"), $htmltext).'</label>';
1106 print '<script>';
1107 print '$( document ).ready(function() {
1108 jQuery("#usage_bill_time").change(function() {
1109 set_usage_bill_time();
1110 });
1111
1112 set_usage_bill_time();
1113
1114 function set_usage_bill_time() {
1115 console.log("set_usage_bill_time");
1116 if (jQuery("#usage_bill_time").prop("checked")) {
1117 console.log("Show bill time fields");
1118 jQuery(".classusebilltime").show();
1119 } else {
1120 console.log("Hide bill time fields "+jQuery("#usage_bill_time").prop("checked"));
1121 jQuery(".classusebilltime").hide();
1122 }
1123 }
1124 });';
1125 print '</script>';
1126 print '<br>';
1127 }
1128 if (isModEnabled('eventorganization')) {
1129 print '<input type="checkbox" id="usage_organize_event" name="usage_organize_event"'. (GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_organize_event ? ' checked="checked"' : '')) . '> ';
1130 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
1131 print '<label for="usage_organize_event">'.$form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext).'</label>';
1132 print '<script>';
1133 print '$( document ).ready(function() {
1134 jQuery("#usage_organize_event").change(function() {
1135 set_usage_event();
1136 });
1137
1138 set_usage_event();
1139
1140 function set_usage_event() {
1141 console.log("set_usage_event");
1142 if (jQuery("#usage_organize_event").prop("checked")) {
1143 console.log("Show organize event fields");
1144 jQuery(".classuseorganizeevent").show();
1145 } else {
1146 console.log("Hide organize event fields "+jQuery("#usage_organize_event").prop("checked"));
1147 jQuery(".classuseorganizeevent").hide();
1148 }
1149 }
1150 });';
1151 print '</script>';
1152 }
1153 print '</td></tr>';
1154 }
1155 print '</td></tr>';
1156
1157 // Thirdparty
1158 if (isModEnabled('societe')) {
1159 print '<tr><td>';
1160 print(!getDolGlobalString('PROJECT_THIRDPARTY_REQUIRED') ? '' : '<span class="fieldrequired">');
1161 print $langs->trans("ThirdParty");
1162 print(!getDolGlobalString('PROJECT_THIRDPARTY_REQUIRED') ? '' : '</span>');
1163 print '</td><td>';
1164 $filter = '';
1165 if (getDolGlobalString('PROJECT_FILTER_FOR_THIRDPARTY_LIST')) {
1166 $filter = getDolGlobalString('PROJECT_FILTER_FOR_THIRDPARTY_LIST');
1167 }
1168 $text = img_picto('', 'company', 'class="pictofixedwidth"');
1169 $text .= $form->select_company(!empty($object->thirdparty->id) ? $object->thirdparty->id : "", 'socid', $filter, 'None', 1, 0, array(), 0, 'minwidth300');
1170 if (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') && empty($conf->dol_use_jmobile)) {
1171 $texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty");
1172 print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1, 0, '', '', 2);
1173 } else {
1174 print $text;
1175 }
1176 print '</td></tr>';
1177 }
1178
1179 // Visibility
1180 print '<tr><td>'.$langs->trans("Visibility").'</td><td>';
1181 $array = array();
1182 if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) {
1183 $array[0] = $langs->trans("PrivateProject");
1184 }
1185 if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) {
1186 $array[1] = $langs->trans("SharedProject");
1187 }
1188
1189 if (count($array) > 0) {
1190 print $form->selectarray('public', $array, $object->public, 0, 0, 0, '', 0, 0, 0, '', '', 1);
1191 } else {
1192 print '<input type="hidden" id="public" name="public" value="'.$object->public.'">';
1193
1194 if ($object->public == 0) {
1195 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1196 print $langs->trans("PrivateProject");
1197 } else {
1198 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1199 print $langs->trans("SharedProject");
1200 }
1201 }
1202 print '</td></tr>';
1203
1204 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1205 $classfortr = ($object->usage_opportunity ? '' : ' hideobject');
1206 // Opportunity status
1207 print '<tr class="classuseopportunity'.$classfortr.'"><td>'.$langs->trans("OpportunityStatus").'</td>';
1208 print '<td>';
1209 print '<div>';
1210 print $formproject->selectOpportunityStatus('opp_status', $object->opp_status, 1, 0, 0, 0, 'minwidth150 inline-block valignmiddle', 1, 1);
1211
1212 // Opportunity probability
1213 print ' <input class="width50 right" type="text" id="opp_percent" name="opp_percent" title="'.dol_escape_htmltag($langs->trans("OpportunityProbability")).'" value="'.(GETPOSTISSET('opp_percent') ? GETPOST('opp_percent') : (strcmp($object->opp_percent, '') ? vatrate($object->opp_percent) : '')).'"> %';
1214 print '<span id="oldopppercent" class="opacitymedium"></span>';
1215 print '</div>';
1216
1217 print '<div id="divtocloseproject" class="inline-block valign clearboth paddingtop" style="display: none;">';
1218 print '<input type="checkbox" id="inputcloseproject" name="closeproject" />';
1219 print '<label for="inputcloseproject">';
1220 print $form->textwithpicto($langs->trans("AlsoCloseAProject"), $langs->trans("AlsoCloseAProjectTooltip")).'</label>';
1221 print ' </div>';
1222
1223 print '</td>';
1224 print '</tr>';
1225
1226 // Opportunity amount
1227 print '<tr class="classuseopportunity'.$classfortr.'"><td>'.$langs->trans("OpportunityAmount").'</td>';
1228 print '<td><input class="width75 right" type="text" name="opp_amount" value="'.(GETPOSTISSET('opp_amount') ? GETPOST('opp_amount') : (strcmp($object->opp_amount, '') ? price2num($object->opp_amount) : '')).'">';
1229 print $langs->getCurrencySymbol($conf->currency);
1230 print '</td>';
1231 print '</tr>';
1232 }
1233
1234 // Budget
1235 print '<tr><td>'.$langs->trans("Budget").'</td>';
1236 print '<td><input class="width75 right" type="text" name="budget_amount" value="'.(GETPOSTISSET('budget_amount') ? GETPOST('budget_amount') : (strcmp($object->budget_amount, '') ? price2num($object->budget_amount) : '')).'">';
1237 print $langs->getCurrencySymbol($conf->currency);
1238 print '</td>';
1239 print '</tr>';
1240
1241 // Date project
1242 print '<tr><td>'.$langs->trans("Date").(isModEnabled('eventorganization') ? ' <span class="classuseorganizeevent">('.$langs->trans("Project").')</span>' : '').'</td><td>';
1243 print $form->selectDate($object->date_start ? $object->date_start : -1, 'projectstart', 0, 0, 0, '', 1, 0);
1244 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
1245 print $form->selectDate($object->date_end ? $object->date_end : -1, 'projectend', 0, 0, 0, '', 1, 0);
1246 $object->getLinesArray(null, 0);
1247 if (!empty($object->usage_task) && !empty($object->lines)) {
1248 print ' <span id="divreportdate" class="hidden">&nbsp; &nbsp; <input type="checkbox" class="valignmiddle" id="reportdate" name="reportdate" value="yes" ';
1249 if ($comefromclone) {
1250 print 'checked ';
1251 }
1252 print '/><label for="reportdate" class="valignmiddle opacitymedium">'.$langs->trans("ProjectReportDate").'</label></span>';
1253 }
1254 print '</td></tr>';
1255
1256 if (isModEnabled('eventorganization')) {
1257 // Date event
1258 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Date").' ('.$langs->trans("Event").')</td><td>';
1259 print $form->selectDate(($date_start_event ? $date_start_event : ($object->date_start_event ? $object->date_start_event : -1)), 'date_start_event', 1, 1, 1, '', 1, 0);
1260 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
1261 print $form->selectDate(($date_end_event ? $date_end_event : ($object->date_end_event ? $object->date_end_event : -1)), 'date_end_event', 1, 1, 1, '', 1, 0);
1262 print '</td></tr>';
1263
1264 // Location
1265 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Location").'</td>';
1266 print '<td><input class="minwidth300 maxwidth500" type="text" name="location" value="'.dol_escape_htmltag(GETPOSTISSET('location') ? GETPOST('location') : $object->location).'"></td>';
1267 print '</tr>';
1268 }
1269
1270 // Description
1271 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
1272 print '<td>';
1273 $doleditor = new DolEditor('description', $object->description, '', 90, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor') && getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_3, '90%');
1274 $doleditor->Create();
1275 print '</td></tr>';
1276
1277 // Tags-Categories
1278 if (isModEnabled('category')) {
1279 $arrayselected = array();
1280 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
1281 $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 3);
1282 $c = new Categorie($db);
1283 $cats = $c->containing($object->id, Categorie::TYPE_PROJECT);
1284 foreach ($cats as $cat) {
1285 $arrayselected[] = $cat->id;
1286 }
1287 print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, '0');
1288 print "</td></tr>";
1289 }
1290
1291 // Other options
1292 $parameters = array();
1293 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1294 print $hookmanager->resPrint;
1295 if (empty($reshook)) {
1296 print $object->showOptionals($extrafields, 'edit');
1297 }
1298
1299 print '</table>';
1300 } else {
1301 print dol_get_fiche_head($head, 'project', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
1302
1303 // Project card
1304
1305 if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
1306 $tmpurl = $_SESSION['pageforbacktolist']['project'];
1307 $tmpurl = preg_replace('/__SOCID__/', (string) $object->socid, $tmpurl);
1308 $linkback = '<a href="'.$tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1309 } else {
1310 $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1311 }
1312
1313 $morehtmlref = '<div class="refidno">';
1314 // Title
1315 $morehtmlref .= dol_escape_htmltag($object->title);
1316 $morehtmlref .= '<br>';
1317 // Thirdparty
1318 if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
1319 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project');
1320 }
1321 // Parent
1322 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1323 if (!empty($object->fk_project) && $object->fk_project) {
1324 $parent = new Project($db);
1325 $parent->fetch($object->fk_project);
1326 $morehtmlref .= $langs->trans("Child of").' '.$parent->getNomUrl(1, 'project').' '.$parent->title;
1327 }
1328 }
1329 $morehtmlref .= '</div>';
1330
1331 // Define a complementary filter for search of next/prev ref.
1332 if (!$user->hasRight('projet', 'all', 'lire')) {
1333 $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
1334 $object->next_prev_filter = "rowid IN (".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")";
1335 }
1336
1337 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
1338
1339 print '<div class="fichecenter">';
1340 print '<div class="fichehalfleft">';
1341 print '<div class="underbanner clearboth"></div>';
1342
1343 print '<table class="border tableforfield centpercent">';
1344
1345 // Usage
1346 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
1347 print '<tr><td class="tdtop">';
1348 print $langs->trans("Usage");
1349 print '</td>';
1350 print '<td>';
1351 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1352 print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'> ';
1353 $htmltext = $langs->trans("ProjectFollowOpportunity");
1354 print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
1355 print '<br>';
1356 }
1357 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
1358 print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'> ';
1359 $htmltext = $langs->trans("ProjectFollowTasks");
1360 print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
1361 print '<br>';
1362 }
1363 if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
1364 print '<input type="checkbox" disabled name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_bill_time ? ' checked="checked"' : '')).'> ';
1365 $htmltext = $langs->trans("ProjectBillTimeDescription");
1366 print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
1367 print '<br>';
1368 }
1369
1370 if (isModEnabled('eventorganization')) {
1371 print '<input type="checkbox" disabled name="usage_organize_event"'.(GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_organize_event ? ' checked="checked"' : '')).'> ';
1372 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
1373 print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
1374 }
1375 print '</td></tr>';
1376 }
1377
1378 // Visibility
1379 print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
1380 if ($object->public) {
1381 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1382 print $langs->trans('SharedProject');
1383 } else {
1384 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1385 print $langs->trans('PrivateProject');
1386 }
1387 print '</td></tr>';
1388
1389 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') && !empty($object->usage_opportunity)) {
1390 // Opportunity status
1391 print '<tr><td>'.$langs->trans("OpportunityStatus");
1392 if ($action != 'edit_opp_status' && $user->hasRight('projet', 'creer')) {
1393 print '<a class="editfielda paddingtop" href="'.$_SERVER["PHP_SELF"].'?action=edit_opp_status&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a>';
1394 }
1395 print '</td><td>';
1396 $html_name_status = ($action == 'edit_opp_status') ? 'opp_status' : 'none';
1397 $html_name_percent = ($action == 'edit_opp_status') ? 'opp_percent' : 'none';
1398 $percent_value = (GETPOSTISSET('opp_percent') ? GETPOST('opp_percent') : (strcmp($object->opp_percent, '') ? vatrate($object->opp_percent) : ''));
1399 $formproject->formOpportunityStatus($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->opp_status, $percent_value, $html_name_status, $html_name_percent);
1400 print '</td></tr>';
1401
1402 // Opportunity Amount
1403 print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>';
1404 if (strcmp($object->opp_amount, '')) {
1405 print '<span class="amount">'.price($object->opp_amount, 0, $langs, 1, 0, -1, $conf->currency).'</span>';
1406 if (strcmp($object->opp_percent, '')) {
1407 print ' &nbsp; &nbsp; &nbsp; <span title="'.dol_escape_htmltag($langs->trans('OpportunityWeightedAmount')).'"><span class="opacitymedium">'.$langs->trans("OpportunityWeightedAmountShort").'</span>: <span class="amount">'.price($object->opp_amount * $object->opp_percent / 100, 0, $langs, 1, 0, -1, $conf->currency).'</span></span>';
1408 }
1409 }
1410 print '</td></tr>';
1411 }
1412
1413 // Budget
1414 print '<tr><td>'.$langs->trans("Budget").'</td><td>';
1415 if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
1416 print '<span class="amount">'.price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
1417 }
1418 print '</td></tr>';
1419
1420 // Date start - end project
1421 print '<tr><td>'.$langs->trans("Dates").'</td><td>';
1422 $start = dol_print_date($object->date_start, 'day');
1423 print($start ? $start : '?');
1424 $end = dol_print_date($object->date_end, 'day');
1425 print ' <span class="opacitymedium">-</span> ';
1426 print($end ? $end : '?');
1427 if ($object->hasDelay()) {
1428 print img_warning("Late");
1429 }
1430 print '</td></tr>';
1431
1432 // Other attributes
1433 $cols = 2;
1434 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1435
1436 print '</table>';
1437
1438 print '</div>';
1439 print '<div class="fichehalfright">';
1440 print '<div class="underbanner clearboth"></div>';
1441
1442 print '<table class="border tableforfield centpercent">';
1443
1444 // Description
1445 print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
1446 print '<div class="longmessagecut">';
1447 print dolPrintHTML($object->description);
1448 print '</div>';
1449 print '</td></tr>';
1450
1451 // Categories
1452 if (isModEnabled('category')) {
1453 print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
1454 print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
1455 print "</td></tr>";
1456 }
1457
1458 print '</table>';
1459
1460 print '</div>';
1461 print '</div>';
1462
1463 print '<div class="clearboth"></div>';
1464 }
1465
1466 print dol_get_fiche_end();
1467
1468 if ($action == 'edit' && $userWrite > 0) {
1469 print $form->buttonsSaveCancel();
1470 }
1471
1472 print '</form>';
1473
1474 // Set also dependencies between use task and bill time
1475 print '<script type="text/javascript">
1476 jQuery(document).ready(function() {
1477 jQuery("#usage_task").change(function() {
1478 console.log("We click on usage task "+jQuery("#usage_task").is(":checked"));
1479 if (! jQuery("#usage_task").is(":checked")) {
1480 jQuery("#usage_bill_time").prop("checked", false);
1481 }
1482 });
1483
1484 jQuery("#usage_bill_time").change(function() {
1485 console.log("We click on usage to bill time");
1486 if (jQuery("#usage_bill_time").is(":checked")) {
1487 jQuery("#usage_task").prop("checked", true);
1488 }
1489 });
1490
1491 jQuery("#projectstart").change(function() {
1492 console.log("We modify the start date");
1493 jQuery("#divreportdate").show();
1494 });
1495 });
1496 </script>';
1497
1498 // Change probability from status
1499 if (!empty($conf->use_javascript_ajax) && getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1500 // Default value to close or not when we set opp to 'WON'.
1501 $defaultcheckedwhenoppclose = 1;
1502 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
1503 $defaultcheckedwhenoppclose = 0;
1504 }
1505
1506 print '<!-- Javascript to manage opportunity status change -->';
1507 print '<script type="text/javascript">
1508 jQuery(document).ready(function() {
1509 function change_percent()
1510 {
1511 var element = jQuery("#opp_status option:selected");
1512 var defaultpercent = element.attr("defaultpercent");
1513 var defaultcloseproject = '.((int) $defaultcheckedwhenoppclose).';
1514 var elemcode = element.attr("elemcode");
1515 var oldpercent = \''.dol_escape_js($object->opp_percent).'\';
1516
1517 console.log("We select "+elemcode);
1518
1519 /* Define if checkbox to close is checked or not */
1520 var closeproject = 0;
1521 if (elemcode == \'LOST\') closeproject = 1;
1522 if (elemcode == \'WON\') closeproject = defaultcloseproject;
1523 if (closeproject) jQuery("#inputcloseproject").prop("checked", true);
1524 else jQuery("#inputcloseproject").prop("checked", false);
1525
1526 /* Make the close project checkbox visible or not */
1527 console.log("closeproject="+closeproject);
1528 if (elemcode == \'WON\' || elemcode == \'LOST\')
1529 {
1530 jQuery("#divtocloseproject").show();
1531 }
1532 else
1533 {
1534 jQuery("#divtocloseproject").hide();
1535 }
1536
1537 /* Change percent with default percent (defaultpercent) if new status (defaultpercent) is higher than current (jQuery("#opp_percent").val()) */
1538 if (oldpercent != \'\' && (parseFloat(defaultpercent) < parseFloat(oldpercent)))
1539 {
1540 console.log("oldpercent="+oldpercent+" defaultpercent="+defaultpercent+" def < old");
1541 if (jQuery("#opp_percent").val() != \'\' && oldpercent != \'\') {
1542 jQuery("#oldopppercent").text(\' - '.dol_escape_js($langs->transnoentities("PreviousValue")).': \'+price2numjs(oldpercent)+\' %\');
1543 }
1544
1545 if (parseFloat(oldpercent) != 100 && elemcode != \'LOST\') { jQuery("#opp_percent").val(oldpercent); }
1546 else { jQuery("#opp_percent").val(price2numjs(defaultpercent)); }
1547 } else {
1548 console.log("oldpercent="+oldpercent+" defaultpercent="+defaultpercent);
1549 if (jQuery("#opp_percent").val() == \'\' || (parseFloat(jQuery("#opp_percent").val()) < parseFloat(defaultpercent))) {
1550 if (jQuery("#opp_percent").val() != \'\' && oldpercent != \'\') {
1551 jQuery("#oldopppercent").text(\' - '.dol_escape_js($langs->transnoentities("PreviousValue")).': \'+price2numjs(oldpercent)+\' %\');
1552 }
1553 jQuery("#opp_percent").val(price2numjs(defaultpercent));
1554 }
1555 }
1556 }
1557
1558 jQuery("#opp_status").change(function() {
1559 change_percent();
1560 });
1561 });
1562 </script>';
1563 }
1564
1565
1566 /*
1567 * Actions Buttons
1568 */
1569
1570 print '<div class="tabsAction">';
1571 $parameters = array();
1572 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1573 // modified by hook
1574 if (empty($reshook)) {
1575 if ($action != "edit" && $action != 'presend') {
1576 // Create event
1577 /*if (isModEnabled('agenda') && !empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a
1578 // "workflow" action so should appears somewhere else on
1579 // page.
1580 {
1581 print '<a class="butAction" href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&amp;origin=' . $object->element . '&amp;originid=' . $object->id . '&amp;socid=' . $object->socid . '&amp;projectid=' . $object->id . '">' . $langs->trans("AddAction") . '</a>';
1582 }*/
1583
1584 // Send
1585 if (empty($user->socid)) {
1586 if ($object->statut != Project::STATUS_CLOSED) {
1587 print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?action=presend&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', '');
1588 }
1589 }
1590
1591 // Accounting Report
1592 /*
1593 $accouting_module_activated = isModEnabled('comptabilite') || isModEnabled('accounting');
1594 if ($accouting_module_activated && $object->statut != Project::STATUS_DRAFT) {
1595 $start = dol_getdate((int) $object->date_start);
1596 $end = dol_getdate((int) $object->date_end);
1597 $url = DOL_URL_ROOT.'/compta/accounting-files.php?projectid='.$object->id;
1598 if (!empty($object->date_start)) $url .= '&amp;date_startday='.$start['mday'].'&amp;date_startmonth='.$start['mon'].'&amp;date_startyear='.$start['year'];
1599 if (!empty($object->date_end)) $url .= '&amp;date_stopday='.$end['mday'].'&amp;date_stopmonth='.$end['mon'].'&amp;date_stopyear='.$end['year'];
1600 print dolGetButtonAction('', $langs->trans('ExportAccountingReportButtonLabel'), 'default', $url, '');
1601 }
1602 */
1603
1604 // Back to draft
1605 if (!getDolGlobalString('MAIN_DISABLEDRAFTSTATUS') && !getDolGlobalString('MAIN_DISABLEDRAFTSTATUS_PROJECT')) {
1606 if ($object->statut != Project::STATUS_DRAFT && $user->hasRight('projet', 'creer')) {
1607 if ($userWrite > 0) {
1608 print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?action=confirm_setdraft&amp;confirm=yes&amp;token='.newToken().'&amp;id='.$object->id, '');
1609 } else {
1610 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('SetToDraft'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1611 }
1612 }
1613 }
1614
1615 // Modify
1616 if ($object->statut != Project::STATUS_CLOSED && $user->hasRight('projet', 'creer')) {
1617 if ($userWrite > 0) {
1618 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$object->id, '');
1619 } else {
1620 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Modify'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1621 }
1622 }
1623
1624 // Validate
1625 if ($object->statut == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer')) {
1626 if ($userWrite > 0) {
1627 print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=validate&amp;token='.newToken().'&amp;id='.$object->id, '');
1628 } else {
1629 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Validate'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1630 }
1631 }
1632
1633 // Close
1634 if ($object->statut == Project::STATUS_VALIDATED && $user->hasRight('projet', 'creer')) {
1635 if ($userWrite > 0) {
1636 print dolGetButtonAction('', $langs->trans('Close'), 'default', $_SERVER["PHP_SELF"].'?action=close&amp;token='.newToken().'&amp;id='.$object->id, '');
1637 } else {
1638 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Close'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1639 }
1640 }
1641
1642 // Reopen
1643 if ($object->statut == Project::STATUS_CLOSED && $user->hasRight('projet', 'creer')) {
1644 if ($userWrite > 0) {
1645 print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&amp;token='.newToken().'&amp;id='.$object->id, '');
1646 } else {
1647 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('ReOpen'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1648 }
1649 }
1650
1651
1652 // Buttons Create
1653 if (!getDolGlobalString('PROJECT_HIDE_CREATE_OBJECT_BUTTON')) {
1654 $arrayforbutaction = array(
1655 //1 => array('lang' => 'propal', 'enabled' => 1, 'perm' => 1, 'label' => 'XXX'),
1656 10 => array('lang' => 'propal', 'enabled' => isModEnabled("propal"), 'perm' => $user->hasRight('propal', 'creer'), 'label' => 'AddProp', 'url' => '/comm/propal/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1657 20 => array('lang' => 'orders', 'enabled' => isModEnabled("order"), 'perm' => $user->hasRight('commande', 'creer'), 'label' => 'CreateOrder', 'url' => '/commande/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1658 30 => array('lang' => 'bills', 'enabled' => isModEnabled("invoice"), 'perm' => $user->hasRight('facture', 'creer'), 'label' => 'CreateBill', 'url' => '/compta/facture/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1659 40 => array('lang' => 'supplier_proposal', 'enabled' => isModEnabled("supplier_proposal"), 'perm' => $user->hasRight('supplier_proposal', 'creer'), 'label' => 'AddSupplierProposal', 'url' => '/supplier_proposal/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1660 50 => array('lang' => 'suppliers', 'enabled' => isModEnabled("supplier_order"), 'perm' => $user->hasRight('fournisseur', 'commande', 'creer'), 'label' => 'AddSupplierOrder', 'url' => '/fourn/commande/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1661 60 => array('lang' => 'suppliers', 'enabled' => isModEnabled("supplier_invoice"), 'perm' => $user->hasRight('fournisseur', 'facture', 'creer'), 'label' => 'AddSupplierInvoice', 'url' => '/fourn/facture/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1662 70 => array('lang' => 'interventions', 'enabled' => isModEnabled("intervention"), 'perm' => $user->hasRight('fichinter', 'creer'), 'label' => 'AddIntervention', 'url' => '/fichinter/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1663 80 => array('lang' => 'contracts', 'enabled' => isModEnabled("contract"), 'perm' => $user->hasRight('contrat', 'creer'), 'label' => 'AddContract', 'url' => '/contrat/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1664 90 => array('lang' => 'trips', 'enabled' => isModEnabled("expensereport"), 'perm' => $user->hasRight('expensereport', 'creer'), 'label' => 'AddTrip', 'url' => '/expensereport/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1665 100 => array('lang' => 'donations', 'enabled' => isModEnabled("don"), 'perm' => $user->hasRight('don', 'creer'), 'label' => 'AddDonation', 'url' => '/don/card.php?action=create&amp;projectid='.$object->id.'&amp;socid='.$object->socid),
1666 );
1667
1668 $params = array('backtopage' => $_SERVER["PHP_SELF"].'?id='.$object->id);
1669 //$params = array('backtopage' => $_SERVER["PHP_SELF"].'?id='.$object->id, 'isDropDown' => true);
1670
1671 print dolGetButtonAction('', $langs->trans("Create"), 'default', $arrayforbutaction, '', 1, $params);
1672 }
1673
1674 // Clone
1675 if ($user->hasRight('projet', 'creer')) {
1676 if ($userWrite > 0) {
1677 print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER["PHP_SELF"].'?action=clone&token='.newToken().'&id='.((int) $object->id), '');
1678 } else {
1679 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('ToClone'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1680 }
1681 }
1682
1683 // Delete
1684 if ($user->hasRight('projet', 'supprimer') || ($object->statut == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer'))) {
1685 if ($userDelete > 0 || ($object->statut == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer'))) {
1686 print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, '');
1687 } else {
1688 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1689 }
1690 }
1691 }
1692 }
1693
1694 print "</div>";
1695
1696 if (GETPOST('modelselected')) {
1697 $action = 'presend';
1698 }
1699
1700 if ($action != 'presend') {
1701 print '<div class="fichecenter"><div class="fichehalfleft">';
1702 print '<a name="builddoc"></a>'; // ancre
1703
1704 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1705 /*
1706 * Sub-projects (children)
1707 */
1708 $children = $object->getChildren();
1709 if ($children) {
1710 print '<table class="centpercent notopnoleftnoright table-fiche-title">';
1711 print '<tr class="titre"><td class="nobordernopadding valignmiddle col-title">';
1712 print '<div class="titre inline-block">'.$langs->trans('Sub-projects').'</div>';
1713 print '</td></tr></table>';
1714
1715 print '<div class="div-table-responsive-no-min">';
1716 print '<table class="centpercent noborder'.($morecss ? ' '.$morecss : '').'">';
1717 print '<tr class="liste_titre">';
1718 print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1);
1719 print getTitleFieldOfList('Title', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1);
1720 print getTitleFieldOfList('Status', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1);
1721 print '</tr>';
1722 print "\n";
1723
1724 $subproject = new Project($db);
1725 foreach ($children as $child) {
1726 $subproject->fetch($child->rowid);
1727 print '<tr class="oddeven">';
1728 print '<td class="nowraponall">'.$subproject->getNomUrl(1, 'project').'</td>';
1729 print '<td class="nowraponall tdoverflowmax125">'.$child->title.'</td>';
1730 print '<td class="nowraponall">'.$subproject->getLibStatut(5).'</td>';
1731 print '</tr>';
1732 }
1733
1734 print '</table>';
1735 print '</div>';
1736 }
1737 }
1738
1739 /*
1740 * Generated documents
1741 */
1742 $filename = dol_sanitizeFileName($object->ref);
1743 $filedir = $conf->project->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->ref);
1744 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
1745 $genallowed = ($user->hasRight('projet', 'lire') && $userAccess > 0);
1746 $delallowed = ($user->hasRight('projet', 'creer') && $userWrite > 0);
1747
1748 print $formfile->showdocuments('project', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', '', '', $object);
1749
1750 print '</div><div class="fichehalfright">';
1751
1752 $MAXEVENT = 10;
1753
1754 $morehtmlcenter = '<div class="nowraponall">';
1755 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/projet/messaging.php?id='.$object->id);
1756 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/projet/agenda.php?id='.$object->id);
1757 $morehtmlcenter .= '</div>';
1758
1759 // List of actions on element
1760 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1761 $formactions = new FormActions($db);
1762 $somethingshown = $formactions->showactions($object, 'project', 0, 1, '', $MAXEVENT, '', $morehtmlcenter);
1763
1764 print '</div></div>';
1765 }
1766
1767 // Presend form
1768 $modelmail = 'project';
1769 $defaulttopic = 'SendProjectRef';
1770 $defaulttopiclang = 'projects';
1771 $diroutput = $conf->project->multidir_output[$object->entity];
1772 $autocopy = 'MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add
1773 $trackid = 'proj'.$object->id;
1774
1775 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1776
1777 // Hook to add more things on page
1778 $parameters = array();
1779 $reshook = $hookmanager->executeHooks('mainCardTabAddMore', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1780} else {
1781 print $langs->trans("RecordNotFound");
1782}
1783
1784// End of page
1785llxFooter();
1786$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:456
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
Class to manage categories.
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 projects.
const STATUS_VALIDATED
Open/Validated status.
const STATUS_CLOSED
Closed status.
const STATUS_DRAFT
Draft status.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
Class to manage translations.
Class to manage Dolibarr users.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
img_help($usehelpcursor=1, $usealttitle=1)
Show help logo with cursor "?".
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dolPrintHTML($s, $allowiframe=0)
Return a string (that can be on several lines) ready to be output on a HTML page.
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.
dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $disabled='', $morecss='classlink button bordertransp', $jsonopen='', $backtopagejsfields='', $accesskey='')
Return HTML code to output a button to open a dialog popup box.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0)
Set event message in dol_events session object.
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.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
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.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='')
Return the value of a $_GET or $_POST supervariable, converted into float.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
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...
project_prepare_head(Project $project, $moreparam='')
Prepare array with list of tabs.
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.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall TAKEPOS_SHOW_SUBPRICE right right right takeposterminal SELECT e e e e e statut
Definition invoice.php:1991