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