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