dolibarr 20.0.5
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
546 setEventMessages($langs->trans("ProjectCreatedInDolibarr", $newobject->ref), "", 'mesgs');
547
548 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$result.'&action=edit&comefromclone=1');
549 exit;
550 }
551 }
552
553 // Quick edit for extrafields
554 if ($action == 'update_extras' && $permissiontoadd) {
555 $object->oldcopy = dol_clone($object, 2);
556
557 // Fill array 'array_options' with data from update form
558 $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
559 if ($ret < 0) {
560 $error++;
561 }
562
563 if (!$error) {
564 // Actions on extra fields
565 $result = $object->insertExtraFields('PROJECT_MODIFY');
566 if ($result < 0) {
567 setEventMessages($object->error, $object->errors, 'errors');
568 $error++;
569 }
570 }
571
572 if ($error) {
573 $action = 'edit_extras';
574 }
575 }
576
577 // Actions to send emails
578 $triggersendname = 'PROJECT_SENTBYMAIL';
579 $paramname = 'id';
580 $autocopy = 'MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add
581 $trackid = 'proj'.$object->id;
582 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
583}
584
585
586/*
587 * View
588 */
589
590$form = new Form($db);
591$formfile = new FormFile($db);
592$formproject = new FormProjets($db);
593$userstatic = new User($db);
594
595$title = $langs->trans("Project").' - '.$object->ref.(!empty($object->thirdparty->name) ? ' - '.$object->thirdparty->name : '').(!empty($object->title) ? ' - '.$object->title : '');
596if (getDolGlobalString('MAIN_HTML_TITLE') && preg_match('/projectnameonly/', getDolGlobalString('MAIN_HTML_TITLE'))) {
597 $title = $object->ref.(!empty($object->thirdparty->name) ? ' - '.$object->thirdparty->name : '').(!empty($object->title) ? ' - '.$object->title : '');
598}
599
600$help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte";
601
602llxHeader("", $title, $help_url);
603
604$titleboth = $langs->trans("LeadsOrProjects");
605$titlenew = $langs->trans("NewLeadOrProject"); // Leads and opportunities by default
606if (!getDolGlobalInt('PROJECT_USE_OPPORTUNITIES')) {
607 $titleboth = $langs->trans("Projects");
608 $titlenew = $langs->trans("NewProject");
609}
610if (getDolGlobalInt('PROJECT_USE_OPPORTUNITIES') == 2) { // 2 = leads only
611 $titleboth = $langs->trans("Leads");
612 $titlenew = $langs->trans("NewLead");
613}
614
615if ($action == 'create' && $user->hasRight('projet', 'creer')) {
616 /*
617 * Create
618 */
619
620 $thirdparty = new Societe($db);
621 if ($socid > 0) {
622 $thirdparty->fetch($socid);
623 }
624
625 print load_fiche_titre($titlenew, '', 'project');
626
627 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
628 print '<input type="hidden" name="action" value="add">';
629 print '<input type="hidden" name="token" value="'.newToken().'">';
630 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
631 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
632 print '<input type="hidden" name="backtopagejsfields" value="'.$backtopagejsfields.'">';
633 print '<input type="hidden" name="dol_openinpopup" value="'.$dol_openinpopup.'">';
634
635 print dol_get_fiche_head();
636
637 print '<table class="border centpercent tableforfieldcreate">';
638
639 $defaultref = '';
640 $modele = !getDolGlobalString('PROJECT_ADDON') ? 'mod_project_simple' : $conf->global->PROJECT_ADDON;
641
642 // Search template files
643 $file = '';
644 $classname = '';
645 $filefound = 0;
646 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
647 foreach ($dirmodels as $reldir) {
648 $file = dol_buildpath($reldir."core/modules/project/".$modele.'.php', 0);
649 if (file_exists($file)) {
650 $filefound = 1;
651 $classname = $modele;
652 break;
653 }
654 }
655
656 if ($filefound) {
657 $result = dol_include_once($reldir."core/modules/project/".$modele.'.php');
658 $modProject = new $classname();
659
660 $defaultref = $modProject->getNextValue($thirdparty, $object);
661 }
662
663 if (is_numeric($defaultref) && $defaultref <= 0) {
664 $defaultref = '';
665 }
666
667 // Ref
668 $suggestedref = (GETPOST("ref") ? GETPOST("ref") : $defaultref);
669 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).'">';
670 if ($suggestedref) {
671 print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref));
672 }
673 print '</td></tr>';
674
675 // Label
676 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>';
677
678 // Parent
679 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
680 print '<tr><td>'.$langs->trans("Parent").'</td><td class="maxwidthonsmartphone">';
681 print img_picto('', 'project', 'class="pictofixedwidth"');
682 $formproject->select_projects(-1, '', 'fk_project', 64, 0, 1, 1, 0, 0, 0, '', 0, 0, '', '', '');
683 print '</td></tr>';
684 }
685
686 // Usage (opp, task, bill time, ...)
687 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
688 print '<tr><td class="tdtop">';
689 print $langs->trans("Usage");
690 print '</td>';
691 print '<td>';
692 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
693 print '<input type="checkbox" id="usage_opportunity" name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') ? ' checked="checked"' : '') : ' checked="checked"').'"> ';
694 $htmltext = $langs->trans("ProjectFollowOpportunity");
695 print '<label for="usage_opportunity">'.$form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext).'</label>';
696 print '<script>';
697 print '$( document ).ready(function() {
698 jQuery("#usage_opportunity").change(function() {
699 if (jQuery("#usage_opportunity").prop("checked")) {
700 console.log("Show opportunities fields");
701 jQuery(".classuseopportunity").show();
702 } else {
703 console.log("Hide opportunities fields "+jQuery("#usage_opportunity").prop("checked"));
704 jQuery(".classuseopportunity").hide();
705 }
706 });
707 ';
708 if (GETPOSTISSET('usage_opportunity') && !GETPOST('usage_opportunity')) {
709 print 'jQuery(".classuseopportunity").hide();';
710 }
711 print '});';
712 print '</script>';
713 print '<br>';
714 }
715 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
716 print '<input type="checkbox" id="usage_task" name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') ? ' checked="checked"' : '') : ' checked="checked"').'"> ';
717 $htmltext = $langs->trans("ProjectFollowTasks");
718 print '<label for="usage_task">'.$form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext).'</label>';
719 print '<script>';
720 print '$( document ).ready(function() {
721 jQuery("#usage_task").change(function() {
722 if (jQuery("#usage_task").prop("checked")) {
723 console.log("Show task fields");
724 jQuery(".classusetask").show();
725 } else {
726 console.log("Hide tasks fields "+jQuery("#usage_task").prop("checked"));
727 jQuery(".classusetask").hide();
728 }
729 });
730 ';
731 if (GETPOSTISSET('usage_task') && !GETPOST('usage_task')) {
732 print 'jQuery(".classusetask").hide();';
733 }
734 print '});';
735 print '</script>';
736 print '<br>';
737 }
738 if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
739 print '<input type="checkbox" id="usage_bill_time" name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') ? ' checked="checked"' : '') : '').'"> ';
740 $htmltext = $langs->trans("ProjectBillTimeDescription");
741 print '<label for="usage_bill_time">'.$form->textwithpicto($langs->trans("BillTime"), $htmltext).'</label>';
742 print '<script>';
743 print '$( document ).ready(function() {
744 jQuery("#usage_bill_time").change(function() {
745 if (jQuery("#usage_bill_time").prop("checked")) {
746 console.log("Show bill time fields");
747 jQuery(".classusebilltime").show();
748 } else {
749 console.log("Hide bill time fields "+jQuery("#usage_bill_time").prop("checked"));
750 jQuery(".classusebilltime").hide();
751 }
752 });
753 ';
754 if (GETPOSTISSET('usage_bill_time') && !GETPOST('usage_bill_time')) {
755 print 'jQuery(".classusebilltime").hide();';
756 }
757 print '});';
758 print '</script>';
759 print '<br>';
760 }
761 if (isModEnabled('eventorganization')) {
762 print '<input type="checkbox" id="usage_organize_event" name="usage_organize_event"'.(GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') ? ' checked="checked"' : '') : '').'"> ';
763 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
764 print '<label for="usage_organize_event">'.$form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext).'</label>';
765 print '<script>';
766 print '$( document ).ready(function() {
767 jQuery("#usage_organize_event").change(function() {
768 if (jQuery("#usage_organize_event").prop("checked")) {
769 console.log("Show organize event fields");
770 jQuery(".classuseorganizeevent").show();
771 } else {
772 console.log("Hide organize event fields "+jQuery("#usage_organize_event").prop("checked"));
773 jQuery(".classuseorganizeevent").hide();
774 }
775 });
776 ';
777 if (!GETPOST('usage_organize_event')) {
778 print 'jQuery(".classuseorganizeevent").hide();';
779 }
780 print '});';
781 print '</script>';
782 }
783 print '</td>';
784 print '</tr>';
785 }
786
787 // Thirdparty
788 if (isModEnabled('societe')) {
789 print '<tr><td>';
790 print(!getDolGlobalString('PROJECT_THIRDPARTY_REQUIRED') ? '' : '<span class="fieldrequired">');
791 print $langs->trans("ThirdParty");
792 print(!getDolGlobalString('PROJECT_THIRDPARTY_REQUIRED') ? '' : '</span>');
793 print '</td><td class="maxwidthonsmartphone">';
794 $filter = '';
795 if (getDolGlobalString('PROJECT_FILTER_FOR_THIRDPARTY_LIST')) {
796 $filter = getDolGlobalString('PROJECT_FILTER_FOR_THIRDPARTY_LIST');
797 }
798 $text = img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(GETPOSTINT('socid'), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
799 if (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') && empty($conf->dol_use_jmobile)) {
800 $texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty");
801 print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1);
802 } else {
803 print $text;
804 }
805 if (!GETPOSTISSET('backtopage')) {
806 $url = '/societe/card.php?action=create&client=3&fournisseur=0&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create');
807 $newbutton = '<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddThirdParty").'"></span>';
808 // TODO @LDR Implement this
809 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
810 $tmpbacktopagejsfields = 'addthirdparty:socid,search_socid';
811 print dolButtonToOpenUrlInDialogPopup('addthirdparty', $langs->transnoentitiesnoconv('AddThirdParty'), $newbutton, $url, '', '', '', $tmpbacktopagejsfields);
812 } else {
813 print ' <a href="'.DOL_URL_ROOT.$url.'">'.$newbutton.'</a>';
814 }
815 }
816 print '</td></tr>';
817 }
818
819 // Status
820 if ($status != '') {
821 print '<tr><td>'.$langs->trans("Status").'</td><td>';
822 print '<input type="hidden" name="status" value="'.$status.'">';
823 print $object->LibStatut($status, 4);
824 print '</td></tr>';
825 }
826
827 // Visibility
828 print '<tr><td>'.$langs->trans("Visibility").'</td><td class="maxwidthonsmartphone">';
829 $array = array();
830 if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) {
831 $array[0] = $langs->trans("PrivateProject");
832 }
833 if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) {
834 $array[1] = $langs->trans("SharedProject");
835 }
836
837 if (count($array) > 0) {
838 print $form->selectarray('public', $array, GETPOST('public'), 0, 0, 0, '', 0, 0, 0, '', '', 1);
839 } else {
840 print '<input type="hidden" name="public" id="public" value="'.GETPOST('public').'">';
841
842 if (GETPOST('public') == 0) {
843 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
844 print $langs->trans("PrivateProject");
845 } else {
846 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
847 print $langs->trans("SharedProject");
848 }
849 }
850 print '</td></tr>';
851
852 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
853 // Opportunity status
854 print '<tr class="classuseopportunity"><td><span class="fieldrequired">'.$langs->trans("OpportunityStatus").'</span></td>';
855 print '<td class="maxwidthonsmartphone">';
856 print $formproject->selectOpportunityStatus('opp_status', GETPOSTISSET('opp_status') ? GETPOST('opp_status') : $object->opp_status, 1, 0, 0, 0, '', 0, 1);
857
858 // Opportunity probability
859 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>';
860 print '<input type="hidden" name="opp_percent_not_set" id="opp_percent_not_set" value="'.dol_escape_htmltag(GETPOSTISSET('opp_percent') ? '0' : '1').'">';
861 print '</td>';
862 print '</tr>';
863
864 // Opportunity amount
865 print '<tr class="classuseopportunity"><td>'.$langs->trans("OpportunityAmount").'</td>';
866 print '<td><input class="width75 right" type="text" name="opp_amount" value="'.dol_escape_htmltag(GETPOSTISSET('opp_amount') ? GETPOST('opp_amount') : '').'">';
867 print ' '.$langs->getCurrencySymbol($conf->currency);
868 print '</td>';
869 print '</tr>';
870 }
871
872 // Budget
873 print '<tr><td>'.$langs->trans("Budget").'</td>';
874 print '<td><input class="width75 right" type="text" name="budget_amount" value="'.dol_escape_htmltag(GETPOSTISSET('budget_amount') ? GETPOST('budget_amount') : '').'">';
875 print ' '.$langs->getCurrencySymbol($conf->currency);
876 print '</td>';
877 print '</tr>';
878
879 // Date project
880 print '<tr><td>'.$langs->trans("Date").(isModEnabled('eventorganization') ? ' <span class="classuseorganizeevent">('.$langs->trans("Project").')</span>' : '').'</td><td>';
881 print $form->selectDate(($date_start ? $date_start : ''), 'projectstart', 0, 0, 0, '', 1, 0);
882 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
883 print $form->selectDate(($date_end ? $date_end : -1), 'projectend', 0, 0, 0, '', 1, 0);
884 print '</td></tr>';
885
886 if (isModEnabled('eventorganization')) {
887 // Date event
888 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Date").' ('.$langs->trans("Event").')</td><td>';
889 print $form->selectDate(($date_start_event ? $date_start_event : -1), 'date_start_event', 1, 1, 1, '', 1, 0);
890 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
891 print $form->selectDate(($date_end_event ? $date_end_event : -1), 'date_end_event', 1, 1, 1, '', 1, 0);
892 print '</td></tr>';
893
894 // Location
895 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Location").'</td>';
896 print '<td><input class="minwidth300 maxwidth500" type="text" name="location" value="'.dol_escape_htmltag($location).'"></td>';
897 print '</tr>';
898 }
899
900 // Description
901 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
902 print '<td>';
903 $doleditor = new DolEditor('description', GETPOST("description", 'restricthtml'), '', 90, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor') && getDolGlobalString('FCKEDITOR_ENABLE_SOCIETE'), ROWS_3, '90%');
904 $doleditor->Create();
905 print '</td></tr>';
906
907 if (isModEnabled('category')) {
908 // Categories
909 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
910 $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 3);
911 $arrayselected = GETPOST('categories', 'array');
912 print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
913 print "</td></tr>";
914 }
915
916 // Other options
917 $parameters = array();
918 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
919 print $hookmanager->resPrint;
920 if (empty($reshook)) {
921 print $object->showOptionals($extrafields, 'create');
922 }
923
924 print '</table>';
925
926 print dol_get_fiche_end();
927
928 print $form->buttonsSaveCancel('CreateDraft');
929
930 print '</form>';
931
932 // Change probability from status or role of project
933 // Set also dependencies between use task and bill time
934 print '<script type="text/javascript">
935 jQuery(document).ready(function() {
936 function change_percent()
937 {
938 var element = jQuery("#opp_status option:selected");
939 var defaultpercent = element.attr("defaultpercent");
940 /*if (jQuery("#opp_percent_not_set").val() == "") */
941 jQuery("#opp_percent").val(defaultpercent);
942 }
943
944 /*init_myfunc();*/
945 jQuery("#opp_status").change(function() {
946 change_percent();
947 });
948
949 jQuery("#usage_task").change(function() {
950 console.log("We click on usage task "+jQuery("#usage_task").is(":checked"));
951 if (! jQuery("#usage_task").is(":checked")) {
952 jQuery("#usage_bill_time").prop("checked", false);
953 }
954 });
955
956 jQuery("#usage_bill_time").change(function() {
957 console.log("We click on usage to bill time");
958 if (jQuery("#usage_bill_time").is(":checked")) {
959 jQuery("#usage_task").prop("checked", true);
960 }
961 });
962 });
963 </script>';
964} elseif ($object->id > 0) {
965 /*
966 * Show or edit
967 */
968
969 $res = $object->fetch_optionals();
970
971 // To verify role of users
972 $userAccess = $object->restrictedProjectArea($user, 'read');
973 $userWrite = $object->restrictedProjectArea($user, 'write');
974 $userDelete = $object->restrictedProjectArea($user, 'delete');
975 //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
976
977
978 // Confirmation validation
979 if ($action == 'validate') {
980 print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProject'), $langs->trans('ConfirmValidateProject'), 'confirm_validate', '', 0, 1);
981 }
982 // Confirmation close
983 if ($action == 'close') {
984 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("CloseAProject"), $langs->trans("ConfirmCloseAProject"), "confirm_close", '', '', 1);
985 }
986 // Confirmation reopen
987 if ($action == 'reopen') {
988 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ReOpenAProject"), $langs->trans("ConfirmReOpenAProject"), "confirm_reopen", '', '', 1);
989 }
990 // Confirmation delete
991 if ($action == 'delete') {
992 $text = $langs->trans("ConfirmDeleteAProject");
993 $task = new Task($db);
994 $taskarray = $task->getTasksArray(0, 0, $object->id, 0, 0);
995 $nboftask = count($taskarray);
996 if ($nboftask) {
997 $text .= '<br>'.img_warning().' '.$langs->trans("ThisWillAlsoRemoveTasks", $nboftask);
998 }
999 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("DeleteAProject"), $text, "confirm_delete", '', '', 1);
1000 }
1001
1002 // Clone confirmation
1003 if ($action == 'clone') {
1004 $formquestion = array(
1005 'text' => $langs->trans("ConfirmClone"),
1006 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')),
1007 1 => array('type' => 'checkbox', 'name' => 'clone_contacts', 'label' => $langs->trans("CloneContacts"), 'value' => true),
1008 2 => array('type' => 'checkbox', 'name' => 'clone_tasks', 'label' => $langs->trans("CloneTasks"), 'value' => true),
1009 3 => array('type' => 'checkbox', 'name' => 'move_date', 'label' => $langs->trans("CloneMoveDate"), 'value' => true),
1010 4 => array('type' => 'checkbox', 'name' => 'clone_notes', 'label' => $langs->trans("CloneNotes"), 'value' => true),
1011 5 => array('type' => 'checkbox', 'name' => 'clone_project_files', 'label' => $langs->trans("CloneProjectFiles"), 'value' => false),
1012 6 => array('type' => 'checkbox', 'name' => 'clone_task_files', 'label' => $langs->trans("CloneTaskFiles"), 'value' => false)
1013 );
1014
1015 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ToClone"), $langs->trans("ConfirmCloneProject"), "confirm_clone", $formquestion, '', 1, 400, 590);
1016 }
1017
1018
1019 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1020 print '<input type="hidden" name="token" value="'.newToken().'">';
1021 print '<input type="hidden" name="action" value="update">';
1022 print '<input type="hidden" name="id" value="'.$object->id.'">';
1023 print '<input type="hidden" name="comefromclone" value="'.$comefromclone.'">';
1024
1026
1027 if ($action == 'edit' && $userWrite > 0) {
1028 print dol_get_fiche_head($head, 'project', $langs->trans("Project"), 0, ($object->public ? 'projectpub' : 'project'));
1029
1030 print '<table class="border centpercent">';
1031
1032 // Ref
1033 $suggestedref = $object->ref;
1034 print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Ref").'</td>';
1035 print '<td><input class="width200" name="ref" value="'.$suggestedref.'">';
1036 print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref));
1037 print '</td></tr>';
1038
1039 // Label
1040 print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>';
1041 print '<td><input class="quatrevingtpercent" name="title" value="'.dol_escape_htmltag($object->title).'"></td></tr>';
1042
1043 // Status
1044 print '<tr><td class="fieldrequired">'.$langs->trans("Status").'</td><td>';
1045 print '<select class="flat" name="status" id="status">';
1046 $statuses = $object->labelStatusShort;
1047 if (getDolGlobalString('MAIN_DISABLEDRAFTSTATUS') || getDolGlobalString('MAIN_DISABLEDRAFTSTATUS_PROJECT')) {
1048 unset($statuses[$object::STATUS_DRAFT]);
1049 }
1050 foreach ($statuses as $key => $val) {
1051 print '<option value="'.$key.'"'.((GETPOSTISSET('status') ? GETPOST('status') : $object->statut) == $key ? ' selected="selected"' : '').'>'.$langs->trans($val).'</option>';
1052 }
1053 print '</select>';
1054 print ajax_combobox('status');
1055 print '</td></tr>';
1056
1057 // Parent
1058 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1059 print '<tr><td>'.$langs->trans("Parent").'</td><td class="maxwidthonsmartphone">';
1060 print img_picto('', 'project', 'class="pictofixedwidth"');
1061 $formproject->select_projects(-1, $object->fk_project, 'fk_project', 64, 0, 1, 1, 0, 0, 0, '', 0, 0, '', '', '');
1062 print '</td></tr>';
1063 }
1064
1065 // Usage
1066 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
1067 print '<tr><td class="tdtop">';
1068 print $langs->trans("Usage");
1069 print '</td>';
1070 print '<td>';
1071 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1072 print '<input type="checkbox" id="usage_opportunity" name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'> ';
1073 $htmltext = $langs->trans("ProjectFollowOpportunity");
1074 print '<label for="usage_opportunity">'.$form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext).'</label>';
1075 print '<script>';
1076 print '$( document ).ready(function() {
1077 jQuery("#usage_opportunity").change(function() {
1078 set_usage_opportunity();
1079 });
1080
1081 set_usage_opportunity();
1082
1083 function set_usage_opportunity() {
1084 console.log("set_usage_opportunity");
1085 if (jQuery("#usage_opportunity").prop("checked")) {
1086 console.log("Show opportunities fields");
1087 jQuery(".classuseopportunity").show();
1088 } else {
1089 console.log("Hide opportunities fields "+jQuery("#usage_opportunity").prop("checked"));
1090 jQuery(".classuseopportunity").hide();
1091 }
1092 }
1093 });';
1094 print '</script>';
1095 print '<br>';
1096 }
1097 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
1098 print '<input type="checkbox" id="usage_task" name="usage_task"' . (GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')) . '> ';
1099 $htmltext = $langs->trans("ProjectFollowTasks");
1100 print '<label for="usage_task">'.$form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext).'</label>';
1101 print '<script>';
1102 print '$( document ).ready(function() {
1103 jQuery("#usage_task").change(function() {
1104 set_usage_task();
1105 });
1106
1107 set_usage_task();
1108
1109 function set_usage_task() {
1110 console.log("set_usage_task");
1111 if (jQuery("#usage_task").prop("checked")) {
1112 console.log("Show task fields");
1113 jQuery(".classusetask").show();
1114 } else {
1115 console.log("Hide task fields "+jQuery("#usage_task").prop("checked"));
1116 jQuery(".classusetask").hide();
1117 }
1118 }
1119 });';
1120 print '</script>';
1121 print '<br>';
1122 }
1123 if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
1124 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"' : '')) . '> ';
1125 $htmltext = $langs->trans("ProjectBillTimeDescription");
1126 print '<label for="usage_bill_time">'.$form->textwithpicto($langs->trans("BillTime"), $htmltext).'</label>';
1127 print '<script>';
1128 print '$( document ).ready(function() {
1129 jQuery("#usage_bill_time").change(function() {
1130 set_usage_bill_time();
1131 });
1132
1133 set_usage_bill_time();
1134
1135 function set_usage_bill_time() {
1136 console.log("set_usage_bill_time");
1137 if (jQuery("#usage_bill_time").prop("checked")) {
1138 console.log("Show bill time fields");
1139 jQuery(".classusebilltime").show();
1140 } else {
1141 console.log("Hide bill time fields "+jQuery("#usage_bill_time").prop("checked"));
1142 jQuery(".classusebilltime").hide();
1143 }
1144 }
1145 });';
1146 print '</script>';
1147 print '<br>';
1148 }
1149 if (isModEnabled('eventorganization')) {
1150 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"' : '')) . '> ';
1151 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
1152 print '<label for="usage_organize_event">'.$form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext).'</label>';
1153 print '<script>';
1154 print '$( document ).ready(function() {
1155 jQuery("#usage_organize_event").change(function() {
1156 set_usage_event();
1157 });
1158
1159 set_usage_event();
1160
1161 function set_usage_event() {
1162 console.log("set_usage_event");
1163 if (jQuery("#usage_organize_event").prop("checked")) {
1164 console.log("Show organize event fields");
1165 jQuery(".classuseorganizeevent").show();
1166 } else {
1167 console.log("Hide organize event fields "+jQuery("#usage_organize_event").prop("checked"));
1168 jQuery(".classuseorganizeevent").hide();
1169 }
1170 }
1171 });';
1172 print '</script>';
1173 }
1174 print '</td></tr>';
1175 }
1176 print '</td></tr>';
1177
1178 // Thirdparty
1179 if (isModEnabled('societe')) {
1180 print '<tr><td>';
1181 print(!getDolGlobalString('PROJECT_THIRDPARTY_REQUIRED') ? '' : '<span class="fieldrequired">');
1182 print $langs->trans("ThirdParty");
1183 print(!getDolGlobalString('PROJECT_THIRDPARTY_REQUIRED') ? '' : '</span>');
1184 print '</td><td>';
1185 $filter = '';
1186 if (getDolGlobalString('PROJECT_FILTER_FOR_THIRDPARTY_LIST')) {
1187 $filter = getDolGlobalString('PROJECT_FILTER_FOR_THIRDPARTY_LIST');
1188 }
1189 $text = img_picto('', 'company', 'class="pictofixedwidth"');
1190 $text .= $form->select_company(!empty($object->thirdparty->id) ? $object->thirdparty->id : "", 'socid', $filter, 'None', 1, 0, array(), 0, 'minwidth300');
1191 if (!getDolGlobalString('PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS') && empty($conf->dol_use_jmobile)) {
1192 $texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty");
1193 print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1, 0, '', '', 2);
1194 } else {
1195 print $text;
1196 }
1197 print '</td></tr>';
1198 }
1199
1200 // Visibility
1201 print '<tr><td>'.$langs->trans("Visibility").'</td><td>';
1202 $array = array();
1203 if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) {
1204 $array[0] = $langs->trans("PrivateProject");
1205 }
1206 if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) {
1207 $array[1] = $langs->trans("SharedProject");
1208 }
1209
1210 if (count($array) > 0) {
1211 print $form->selectarray('public', $array, $object->public, 0, 0, 0, '', 0, 0, 0, '', '', 1);
1212 } else {
1213 print '<input type="hidden" id="public" name="public" value="'.$object->public.'">';
1214
1215 if ($object->public == 0) {
1216 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1217 print $langs->trans("PrivateProject");
1218 } else {
1219 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1220 print $langs->trans("SharedProject");
1221 }
1222 }
1223 print '</td></tr>';
1224
1225 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1226 $classfortr = ($object->usage_opportunity ? '' : ' hideobject');
1227 // Opportunity status
1228 print '<tr class="classuseopportunity'.$classfortr.'"><td>'.$langs->trans("OpportunityStatus").'</td>';
1229 print '<td>';
1230 print '<div>';
1231 print $formproject->selectOpportunityStatus('opp_status', $object->opp_status, 1, 0, 0, 0, 'minwidth150 inline-block valignmiddle', 1, 1);
1232
1233 // Opportunity probability
1234 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) : '')).'"> %';
1235 print '<span id="oldopppercent" class="opacitymedium"></span>';
1236 print '</div>';
1237
1238 print '<div id="divtocloseproject" class="inline-block valign clearboth paddingtop" style="display: none;">';
1239 print '<input type="checkbox" id="inputcloseproject" name="closeproject" />';
1240 print '<label for="inputcloseproject">';
1241 print $form->textwithpicto($langs->trans("AlsoCloseAProject"), $langs->trans("AlsoCloseAProjectTooltip")).'</label>';
1242 print ' </div>';
1243
1244 print '</td>';
1245 print '</tr>';
1246
1247 // Opportunity amount
1248 print '<tr class="classuseopportunity'.$classfortr.'"><td>'.$langs->trans("OpportunityAmount").'</td>';
1249 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) : '')).'">';
1250 print $langs->getCurrencySymbol($conf->currency);
1251 print '</td>';
1252 print '</tr>';
1253 }
1254
1255 // Budget
1256 print '<tr><td>'.$langs->trans("Budget").'</td>';
1257 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) : '')).'">';
1258 print $langs->getCurrencySymbol($conf->currency);
1259 print '</td>';
1260 print '</tr>';
1261
1262 // Date project
1263 print '<tr><td>'.$langs->trans("Date").(isModEnabled('eventorganization') ? ' <span class="classuseorganizeevent">('.$langs->trans("Project").')</span>' : '').'</td><td>';
1264 print $form->selectDate($object->date_start ? $object->date_start : -1, 'projectstart', 0, 0, 0, '', 1, 0);
1265 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
1266 print $form->selectDate($object->date_end ? $object->date_end : -1, 'projectend', 0, 0, 0, '', 1, 0);
1267 $object->getLinesArray(null, 0);
1268 if (!empty($object->usage_task) && !empty($object->lines)) {
1269 print ' <span id="divreportdate" class="hidden">&nbsp; &nbsp; <input type="checkbox" class="valignmiddle" id="reportdate" name="reportdate" value="yes" ';
1270 if ($comefromclone) {
1271 print 'checked ';
1272 }
1273 print '/><label for="reportdate" class="valignmiddle opacitymedium">'.$langs->trans("ProjectReportDate").'</label></span>';
1274 }
1275 print '</td></tr>';
1276
1277 if (isModEnabled('eventorganization')) {
1278 // Date event
1279 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Date").' ('.$langs->trans("Event").')</td><td>';
1280 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);
1281 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
1282 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);
1283 print '</td></tr>';
1284
1285 // Location
1286 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Location").'</td>';
1287 print '<td><input class="minwidth300 maxwidth500" type="text" name="location" value="'.dol_escape_htmltag(GETPOSTISSET('location') ? GETPOST('location') : $object->location).'"></td>';
1288 print '</tr>';
1289 }
1290
1291 // Description
1292 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
1293 print '<td>';
1294 $doleditor = new DolEditor('description', $object->description, '', 90, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor') && getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_3, '90%');
1295 $doleditor->Create();
1296 print '</td></tr>';
1297
1298 // Tags-Categories
1299 if (isModEnabled('category')) {
1300 $arrayselected = array();
1301 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
1302 $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 3);
1303 $c = new Categorie($db);
1304 $cats = $c->containing($object->id, Categorie::TYPE_PROJECT);
1305 foreach ($cats as $cat) {
1306 $arrayselected[] = $cat->id;
1307 }
1308 print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, '0');
1309 print "</td></tr>";
1310 }
1311
1312 // Other options
1313 $parameters = array();
1314 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1315 print $hookmanager->resPrint;
1316 if (empty($reshook)) {
1317 print $object->showOptionals($extrafields, 'edit');
1318 }
1319
1320 print '</table>';
1321 } else {
1322 print dol_get_fiche_head($head, 'project', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
1323
1324 // Project card
1325
1326 if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
1327 $tmpurl = $_SESSION['pageforbacktolist']['project'];
1328 $tmpurl = preg_replace('/__SOCID__/', (string) $object->socid, $tmpurl);
1329 $linkback = '<a href="'.$tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1330 } else {
1331 $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1332 }
1333
1334 $morehtmlref = '<div class="refidno">';
1335 // Title
1336 $morehtmlref .= dol_escape_htmltag($object->title);
1337 $morehtmlref .= '<br>';
1338 // Thirdparty
1339 if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
1340 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project');
1341 }
1342 // Parent
1343 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1344 if (!empty($object->fk_project) && $object->fk_project) {
1345 $parent = new Project($db);
1346 $parent->fetch($object->fk_project);
1347 $morehtmlref .= $langs->trans("Child of").' '.$parent->getNomUrl(1, 'project').' '.$parent->title;
1348 }
1349 }
1350 $morehtmlref .= '</div>';
1351
1352 // Define a complementary filter for search of next/prev ref.
1353 if (!$user->hasRight('projet', 'all', 'lire')) {
1354 $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
1355 $object->next_prev_filter = "rowid IN (".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")";
1356 }
1357
1358 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
1359
1360 print '<div class="fichecenter">';
1361 print '<div class="fichehalfleft">';
1362 print '<div class="underbanner clearboth"></div>';
1363
1364 print '<table class="border tableforfield centpercent">';
1365
1366 // Usage
1367 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
1368 print '<tr><td class="tdtop">';
1369 print $langs->trans("Usage");
1370 print '</td>';
1371 print '<td>';
1372 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1373 print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'> ';
1374 $htmltext = $langs->trans("ProjectFollowOpportunity");
1375 print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
1376 print '<br>';
1377 }
1378 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
1379 print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'> ';
1380 $htmltext = $langs->trans("ProjectFollowTasks");
1381 print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
1382 print '<br>';
1383 }
1384 if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
1385 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"' : '')).'> ';
1386 $htmltext = $langs->trans("ProjectBillTimeDescription");
1387 print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
1388 print '<br>';
1389 }
1390
1391 if (isModEnabled('eventorganization')) {
1392 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"' : '')).'> ';
1393 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
1394 print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
1395 }
1396 print '</td></tr>';
1397 }
1398
1399 // Visibility
1400 print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
1401 if ($object->public) {
1402 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1403 print $langs->trans('SharedProject');
1404 } else {
1405 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1406 print $langs->trans('PrivateProject');
1407 }
1408 print '</td></tr>';
1409
1410 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') && !empty($object->usage_opportunity)) {
1411 // Opportunity status
1412 print '<tr><td>'.$langs->trans("OpportunityStatus");
1413 if ($action != 'edit_opp_status' && $user->hasRight('projet', 'creer')) {
1414 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>';
1415 }
1416 print '</td><td>';
1417 $html_name_status = ($action == 'edit_opp_status') ? 'opp_status' : 'none';
1418 $html_name_percent = ($action == 'edit_opp_status') ? 'opp_percent' : 'none';
1419 $percent_value = (GETPOSTISSET('opp_percent') ? GETPOST('opp_percent') : (strcmp($object->opp_percent, '') ? vatrate($object->opp_percent) : ''));
1420 $formproject->formOpportunityStatus($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->opp_status, $percent_value, $html_name_status, $html_name_percent);
1421 print '</td></tr>';
1422
1423 // Opportunity Amount
1424 print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>';
1425 if (strcmp($object->opp_amount, '')) {
1426 print '<span class="amount">'.price($object->opp_amount, 0, $langs, 1, 0, -1, $conf->currency).'</span>';
1427 if (strcmp($object->opp_percent, '')) {
1428 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>';
1429 }
1430 }
1431 print '</td></tr>';
1432 }
1433
1434 // Budget
1435 print '<tr><td>'.$langs->trans("Budget").'</td><td>';
1436 if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
1437 print '<span class="amount">'.price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
1438 }
1439 print '</td></tr>';
1440
1441 // Date start - end project
1442 print '<tr><td>'.$langs->trans("Dates").'</td><td>';
1443 $start = dol_print_date($object->date_start, 'day');
1444 print($start ? $start : '?');
1445 $end = dol_print_date($object->date_end, 'day');
1446 print ' <span class="opacitymedium">-</span> ';
1447 print($end ? $end : '?');
1448 if ($object->hasDelay()) {
1449 print img_warning("Late");
1450 }
1451 print '</td></tr>';
1452
1453 // Other attributes
1454 $cols = 2;
1455 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1456
1457 print '</table>';
1458
1459 print '</div>';
1460 print '<div class="fichehalfright">';
1461 print '<div class="underbanner clearboth"></div>';
1462
1463 print '<table class="border tableforfield centpercent">';
1464
1465 // Description
1466 print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
1467 print '<div class="longmessagecut">';
1468 print dolPrintHTML($object->description);
1469 print '</div>';
1470 print '</td></tr>';
1471
1472 // Categories
1473 if (isModEnabled('category')) {
1474 print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
1475 print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
1476 print "</td></tr>";
1477 }
1478
1479 print '</table>';
1480
1481 print '</div>';
1482 print '</div>';
1483
1484 print '<div class="clearboth"></div>';
1485 }
1486
1487 print dol_get_fiche_end();
1488
1489 if ($action == 'edit' && $userWrite > 0) {
1490 print $form->buttonsSaveCancel();
1491 }
1492
1493 print '</form>';
1494
1495 // Set also dependencies between use task and bill time
1496 print '<script type="text/javascript">
1497 jQuery(document).ready(function() {
1498 jQuery("#usage_task").change(function() {
1499 console.log("We click on usage task "+jQuery("#usage_task").is(":checked"));
1500 if (! jQuery("#usage_task").is(":checked")) {
1501 jQuery("#usage_bill_time").prop("checked", false);
1502 }
1503 });
1504
1505 jQuery("#usage_bill_time").change(function() {
1506 console.log("We click on usage to bill time");
1507 if (jQuery("#usage_bill_time").is(":checked")) {
1508 jQuery("#usage_task").prop("checked", true);
1509 }
1510 });
1511
1512 jQuery("#projectstart").change(function() {
1513 console.log("We modify the start date");
1514 jQuery("#divreportdate").show();
1515 });
1516 });
1517 </script>';
1518
1519 // Change probability from status
1520 if (!empty($conf->use_javascript_ajax) && getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1521 // Default value to close or not when we set opp to 'WON'.
1522 $defaultcheckedwhenoppclose = 1;
1523 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
1524 $defaultcheckedwhenoppclose = 0;
1525 }
1526
1527 print '<!-- Javascript to manage opportunity status change -->';
1528 print '<script type="text/javascript">
1529 jQuery(document).ready(function() {
1530 function change_percent()
1531 {
1532 var element = jQuery("#opp_status option:selected");
1533 var defaultpercent = element.attr("defaultpercent");
1534 var defaultcloseproject = '.((int) $defaultcheckedwhenoppclose).';
1535 var elemcode = element.attr("elemcode");
1536 var oldpercent = \''.dol_escape_js($object->opp_percent).'\';
1537
1538 console.log("We select "+elemcode);
1539
1540 /* Define if checkbox to close is checked or not */
1541 var closeproject = 0;
1542 if (elemcode == \'LOST\') closeproject = 1;
1543 if (elemcode == \'WON\') closeproject = defaultcloseproject;
1544 if (closeproject) jQuery("#inputcloseproject").prop("checked", true);
1545 else jQuery("#inputcloseproject").prop("checked", false);
1546
1547 /* Make the close project checkbox visible or not */
1548 console.log("closeproject="+closeproject);
1549 if (elemcode == \'WON\' || elemcode == \'LOST\')
1550 {
1551 jQuery("#divtocloseproject").show();
1552 }
1553 else
1554 {
1555 jQuery("#divtocloseproject").hide();
1556 }
1557
1558 /* Change percent with default percent (defaultpercent) if new status (defaultpercent) is higher than current (jQuery("#opp_percent").val()) */
1559 if (oldpercent != \'\' && (parseFloat(defaultpercent) < parseFloat(oldpercent)))
1560 {
1561 console.log("oldpercent="+oldpercent+" defaultpercent="+defaultpercent+" def < old");
1562 if (jQuery("#opp_percent").val() != \'\' && oldpercent != \'\') {
1563 jQuery("#oldopppercent").text(\' - '.dol_escape_js($langs->transnoentities("PreviousValue")).': \'+price2numjs(oldpercent)+\' %\');
1564 }
1565
1566 if (parseFloat(oldpercent) != 100 && elemcode != \'LOST\') { jQuery("#opp_percent").val(oldpercent); }
1567 else { jQuery("#opp_percent").val(price2numjs(defaultpercent)); }
1568 } else {
1569 console.log("oldpercent="+oldpercent+" defaultpercent="+defaultpercent);
1570 if (jQuery("#opp_percent").val() == \'\' || (parseFloat(jQuery("#opp_percent").val()) < parseFloat(defaultpercent))) {
1571 if (jQuery("#opp_percent").val() != \'\' && oldpercent != \'\') {
1572 jQuery("#oldopppercent").text(\' - '.dol_escape_js($langs->transnoentities("PreviousValue")).': \'+price2numjs(oldpercent)+\' %\');
1573 }
1574 jQuery("#opp_percent").val(price2numjs(defaultpercent));
1575 }
1576 }
1577 }
1578
1579 jQuery("#opp_status").change(function() {
1580 change_percent();
1581 });
1582 });
1583 </script>';
1584 }
1585
1586
1587 /*
1588 * Actions Buttons
1589 */
1590
1591 print '<div class="tabsAction">';
1592 $parameters = array();
1593 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1594 // modified by hook
1595 if (empty($reshook)) {
1596 if ($action != "edit" && $action != 'presend') {
1597 // Create event
1598 /*if (isModEnabled('agenda') && !empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a
1599 // "workflow" action so should appears somewhere else on
1600 // page.
1601 {
1602 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>';
1603 }*/
1604
1605 // Send
1606 if (empty($user->socid)) {
1607 if ($object->statut != Project::STATUS_CLOSED) {
1608 print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?action=presend&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', '');
1609 }
1610 }
1611
1612 // Accounting Report
1613 /*
1614 $accouting_module_activated = isModEnabled('comptabilite') || isModEnabled('accounting');
1615 if ($accouting_module_activated && $object->statut != Project::STATUS_DRAFT) {
1616 $start = dol_getdate((int) $object->date_start);
1617 $end = dol_getdate((int) $object->date_end);
1618 $url = DOL_URL_ROOT.'/compta/accounting-files.php?projectid='.$object->id;
1619 if (!empty($object->date_start)) $url .= '&amp;date_startday='.$start['mday'].'&amp;date_startmonth='.$start['mon'].'&amp;date_startyear='.$start['year'];
1620 if (!empty($object->date_end)) $url .= '&amp;date_stopday='.$end['mday'].'&amp;date_stopmonth='.$end['mon'].'&amp;date_stopyear='.$end['year'];
1621 print dolGetButtonAction('', $langs->trans('ExportAccountingReportButtonLabel'), 'default', $url, '');
1622 }
1623 */
1624
1625 // Back to draft
1626 if (!getDolGlobalString('MAIN_DISABLEDRAFTSTATUS') && !getDolGlobalString('MAIN_DISABLEDRAFTSTATUS_PROJECT')) {
1627 if ($object->statut != Project::STATUS_DRAFT && $user->hasRight('projet', 'creer')) {
1628 if ($userWrite > 0) {
1629 print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?action=confirm_setdraft&amp;confirm=yes&amp;token='.newToken().'&amp;id='.$object->id, '');
1630 } else {
1631 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('SetToDraft'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1632 }
1633 }
1634 }
1635
1636 // Modify
1637 if ($object->statut != Project::STATUS_CLOSED && $user->hasRight('projet', 'creer')) {
1638 if ($userWrite > 0) {
1639 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$object->id, '');
1640 } else {
1641 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Modify'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1642 }
1643 }
1644
1645 // Validate
1646 if ($object->statut == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer')) {
1647 if ($userWrite > 0) {
1648 print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=validate&amp;token='.newToken().'&amp;id='.$object->id, '');
1649 } else {
1650 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Validate'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1651 }
1652 }
1653
1654 // Close
1655 if ($object->statut == Project::STATUS_VALIDATED && $user->hasRight('projet', 'creer')) {
1656 if ($userWrite > 0) {
1657 print dolGetButtonAction('', $langs->trans('Close'), 'default', $_SERVER["PHP_SELF"].'?action=close&amp;token='.newToken().'&amp;id='.$object->id, '');
1658 } else {
1659 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Close'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1660 }
1661 }
1662
1663 // Reopen
1664 if ($object->statut == Project::STATUS_CLOSED && $user->hasRight('projet', 'creer')) {
1665 if ($userWrite > 0) {
1666 print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&amp;token='.newToken().'&amp;id='.$object->id, '');
1667 } else {
1668 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('ReOpen'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1669 }
1670 }
1671
1672
1673 // Buttons Create
1674 if (!getDolGlobalString('PROJECT_HIDE_CREATE_OBJECT_BUTTON')) {
1675 $arrayforbutaction = array(
1676 //1 => array('lang' => 'propal', 'enabled' => 1, 'perm' => 1, 'label' => 'XXX'),
1677 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),
1678 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),
1679 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),
1680 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),
1681 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),
1682 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),
1683 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),
1684 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),
1685 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),
1686 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),
1687 );
1688
1689 $params = array('backtopage' => $_SERVER["PHP_SELF"].'?id='.$object->id);
1690 //$params = array('backtopage' => $_SERVER["PHP_SELF"].'?id='.$object->id, 'isDropDown' => true);
1691
1692 print dolGetButtonAction('', $langs->trans("Create"), 'default', $arrayforbutaction, '', 1, $params);
1693 }
1694
1695 // Clone
1696 if ($user->hasRight('projet', 'creer')) {
1697 if ($userWrite > 0) {
1698 print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER["PHP_SELF"].'?action=clone&token='.newToken().'&id='.((int) $object->id), '');
1699 } else {
1700 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('ToClone'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1701 }
1702 }
1703
1704 // Delete
1705 if ($user->hasRight('projet', 'supprimer') || ($object->statut == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer'))) {
1706 if ($userDelete > 0 || ($object->statut == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer'))) {
1707 print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, '');
1708 } else {
1709 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1710 }
1711 }
1712 }
1713 }
1714
1715 print "</div>";
1716
1717 if (GETPOST('modelselected')) {
1718 $action = 'presend';
1719 }
1720
1721 if ($action != 'presend') {
1722 print '<div class="fichecenter"><div class="fichehalfleft">';
1723 print '<a name="builddoc"></a>'; // ancre
1724
1725 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1726 /*
1727 * Sub-projects (children)
1728 */
1729 $children = $object->getChildren();
1730 if ($children) {
1731 print '<table class="centpercent notopnoleftnoright table-fiche-title">';
1732 print '<tr class="titre"><td class="nobordernopadding valignmiddle col-title">';
1733 print '<div class="titre inline-block">'.$langs->trans('Sub-projects').'</div>';
1734 print '</td></tr></table>';
1735
1736 print '<div class="div-table-responsive-no-min">';
1737 print '<table class="centpercent noborder'.($morecss ? ' '.$morecss : '').'">';
1738 print '<tr class="liste_titre">';
1739 print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1);
1740 print getTitleFieldOfList('Title', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1);
1741 print getTitleFieldOfList('Status', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1);
1742 print '</tr>';
1743 print "\n";
1744
1745 $subproject = new Project($db);
1746 foreach ($children as $child) {
1747 $subproject->fetch($child->rowid);
1748 print '<tr class="oddeven">';
1749 print '<td class="nowraponall">'.$subproject->getNomUrl(1, 'project').'</td>';
1750 print '<td class="nowraponall tdoverflowmax125">'.$child->title.'</td>';
1751 print '<td class="nowraponall">'.$subproject->getLibStatut(5).'</td>';
1752 print '</tr>';
1753 }
1754
1755 print '</table>';
1756 print '</div>';
1757 }
1758 }
1759
1760 /*
1761 * Generated documents
1762 */
1763 $filename = dol_sanitizeFileName($object->ref);
1764 $filedir = $conf->project->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->ref);
1765 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
1766 $genallowed = ($user->hasRight('projet', 'lire') && $userAccess > 0);
1767 $delallowed = ($user->hasRight('projet', 'creer') && $userWrite > 0);
1768
1769 print $formfile->showdocuments('project', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', '', '', $object);
1770
1771 print '</div><div class="fichehalfright">';
1772
1773 $MAXEVENT = 10;
1774
1775 $morehtmlcenter = '<div class="nowraponall">';
1776 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/projet/messaging.php?id='.$object->id);
1777 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/projet/agenda.php?id='.$object->id);
1778 $morehtmlcenter .= '</div>';
1779
1780 // List of actions on element
1781 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1782 $formactions = new FormActions($db);
1783 $somethingshown = $formactions->showactions($object, 'project', 0, 1, '', $MAXEVENT, '', $morehtmlcenter);
1784
1785 print '</div></div>';
1786 }
1787
1788 // Presend form
1789 $modelmail = 'project';
1790 $defaulttopic = 'SendProjectRef';
1791 $defaulttopiclang = 'projects';
1792 $diroutput = $conf->project->multidir_output[$object->entity];
1793 $autocopy = 'MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add
1794 $trackid = 'proj'.$object->id;
1795
1796 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1797
1798 // Hook to add more things on page
1799 $parameters = array();
1800 $reshook = $hookmanager->executeHooks('mainCardTabAddMore', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1801} else {
1802 print $langs->trans("RecordNotFound");
1803}
1804
1805// End of page
1806llxFooter();
1807$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'.
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
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:2015