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