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