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