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