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) {
369 if ((int) $object->thirdparty->client == 0 || (int) $object->thirdparty->client == 2) { // If not yet customer
370 // Get ID of the special opportunity status code 'WON'
371 $idoppstatuswon = (int) dol_getIdFromCode($db, 'WON', 'c_lead_status', 'code', 'rowid');
372
373 if ($object->opp_status == $idoppstatuswon) {
374 // Switch the thirdparty into a customer (only if thirdparty exists)
375 if (!empty($object->thirdparty) && !empty($object->thirdparty->id)) {
376 $object->thirdparty->setAsCustomer();
377 }
378 }
379 }
380 }
381 }
382
383 if (!$error) {
384 $result = $object->update($user);
385 if ($result < 0) {
386 $error++;
387 if ($result == -4) {
388 setEventMessages($langs->trans("ErrorRefAlreadyExists"), null, 'errors');
389 } else {
390 setEventMessages($object->error, $object->errors, 'errors');
391 }
392 } else {
393 // Category association
394 $categories = GETPOST('categories', 'array');
395 $result = $object->setCategories($categories);
396 if ($result < 0) {
397 $error++;
398 setEventMessages($object->error, $object->errors, 'errors');
399 }
400 }
401 }
402
403 if (!$error) {
404 if (GETPOST("reportdate") && ($object->date_start != $old_start_date)) {
405 $result = $object->shiftTaskDate((int) $old_start_date);
406 if ($result < 0) {
407 $error++;
408 setEventMessages($langs->trans("ErrorShiftTaskDate").':'.$object->error, $object->errors, 'errors');
409 }
410 }
411 }
412
413 // Check if we must change status of project
414 if (GETPOST('closeproject')) {
415 $resclose = $object->setClose($user);
416 if ($resclose < 0) {
417 $error++;
418 setEventMessages($langs->trans("FailedToCloseProject").':'.$object->error, $object->errors, 'errors');
419 }
420 }
421
422
423 if ($error) {
424 $db->rollback();
425 $action = 'edit';
426 } else {
427 $db->commit();
428
429 if (GETPOSTINT('socid') > 0) {
430 $object->fetch_thirdparty(GETPOSTINT('socid'));
431 } else {
432 unset($object->thirdparty);
433 }
434 }
435 }
436
437 // Set opportunity status
438 if ($action == 'set_opp_status' && $user->hasRight('projet', 'creer')) {
439 if (GETPOSTISSET('opp_status')) {
440 $object->opp_status = $opp_status;
441 }
442 if (GETPOSTISSET('opp_percent')) {
443 $object->opp_percent = $opp_percent;
444 }
445
446 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
447 if ($object->opp_amount && ($object->opp_status <= 0)) {
448 $error++;
449 setEventMessages($langs->trans("ErrorOppStatusRequiredIfAmount"), null, 'errors');
450 }
451 }
452
453 if (!$error) {
454 $db->begin();
455
456 $result = $object->update($user);
457 if ($result < 0) {
458 $error++;
459 if ($result == -4) {
460 setEventMessages($langs->trans("ErrorRefAlreadyExists"), null, 'errors');
461 } else {
462 setEventMessages($object->error, $object->errors, 'errors');
463 }
464 }
465
466 // If opportunities are used and the customer is not yet a customer
467 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') && $object->usage_opportunity) {
468 if ((int) $object->thirdparty->client == 0 || (int) $object->thirdparty->client == 2) { // If not yet customer
469 // Get ID of the special opportunity status code 'WON'
470 $idoppstatuswon = (int) dol_getIdFromCode($db, 'WON', 'c_lead_status', 'code', 'rowid');
471
472 if (!$error && $object->opp_status == $idoppstatuswon) {
473 // Switch the thirdparty into a customer (only if thirdparty exists)
474 if (!empty($object->thirdparty) && !empty($object->thirdparty->id)) {
475 $object->thirdparty->setAsCustomer();
476 }
477 }
478 }
479 }
480
481 if ($error) {
482 $db->rollback();
483 $action = 'edit';
484 } else {
485 $db->commit();
486 }
487 } else {
488 $action = 'edit';
489 }
490 }
491
492 // Build doc
493 if ($action == 'builddoc' && $permissiontoadd) {
494 // Save last template used to generate document
495 if (GETPOST('model')) {
496 $object->setDocModel($user, GETPOST('model', 'alpha'));
497 }
498
499 $outputlangs = $langs;
500 if (GETPOST('lang_id', 'aZ09')) {
501 $outputlangs = new Translate("", $conf);
502 $outputlangs->setDefaultLang(GETPOST('lang_id', 'aZ09'));
503 }
504 $result = $object->generateDocument($object->model_pdf, $outputlangs);
505 if ($result <= 0) {
506 setEventMessages($object->error, $object->errors, 'errors');
507 $action = '';
508 } else {
509 setEventMessages($langs->trans("FileGenerated"), null, 'mesgs');
510 }
511 }
512
513 // Delete file in doc form
514 if ($action == 'remove_file' && $permissiontoadd) {
515 if ($object->id > 0) {
516 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
517
518 $langs->load("other");
519 $upload_dir = $conf->project->multidir_output[$object->entity];
520 $file = $upload_dir.'/'.GETPOST('file');
521 $ret = dol_delete_file($file, 0, 0, 0, $object);
522 if ($ret) {
523 setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs');
524 } else {
525 setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors');
526 }
527 $action = '';
528 }
529 }
530
531
532 if ($action == 'confirm_validate' && $confirm == 'yes' && $permissiontoadd) {
533 $result = $object->setValid($user);
534 if ($result <= 0) {
535 setEventMessages($object->error, $object->errors, 'errors');
536 }
537 }
538
539 if ($action == 'confirm_close' && $confirm == 'yes' && $permissiontoadd) {
540 $result = $object->setClose($user);
541 if ($result <= 0) {
542 setEventMessages($object->error, $object->errors, 'errors');
543 }
544 }
545
546 if ($action == 'confirm_reopen' && $confirm == 'yes' && $permissiontoadd) {
547 $result = $object->setValid($user);
548 if ($result <= 0) {
549 setEventMessages($object->error, $object->errors, 'errors');
550 }
551 }
552
553 if ($action == 'confirm_delete' && $confirm == 'yes' && $permissiontodelete) {
554 $object->fetch($id);
555 $result = $object->delete($user);
556 if ($result > 0) {
557 setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
558
559 if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
560 $tmpurl = $_SESSION['pageforbacktolist']['project'];
561 $tmpurl = preg_replace('/__SOCID__/', (string) $object->socid, $tmpurl);
562 $urlback = $tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1';
563 } else {
564 $urlback = DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1';
565 }
566
567 header("Location: ".$urlback);
568 exit;
569 } else {
570 dol_syslog($object->error, LOG_DEBUG);
571 setEventMessages($object->error, $object->errors, 'errors');
572 }
573 }
574
575 if ($action == 'confirm_clone' && $permissiontoadd && $confirm == 'yes') {
576 $clone_contacts = GETPOST('clone_contacts') ? 1 : 0;
577 $clone_tasks = GETPOST('clone_tasks') ? 1 : 0;
578 $clone_project_files = GETPOST('clone_project_files') ? 1 : 0;
579 $clone_task_files = GETPOST('clone_task_files') ? 1 : 0;
580 $clone_notes = GETPOST('clone_notes') ? 1 : 0;
581 $move_date = GETPOST('move_date') ? 1 : 0;
582 $clone_thirdparty = GETPOSTINT('socid') ? GETPOSTINT('socid') : 0;
583
584 $result = $object->createFromClone($user, $object->id, $clone_contacts, $clone_tasks, $clone_project_files, $clone_task_files, $clone_notes, $move_date, 0, $clone_thirdparty);
585 if ($result <= 0) {
586 setEventMessages($object->error, $object->errors, 'errors');
587 } else {
588 // Load new object
589 $newobject = new Project($db);
590 $newobject->fetch($result);
591
592 setEventMessages($langs->trans("ProjectCreatedInDolibarr", $newobject->ref), null, 'mesgs');
593
594 header('Location: '.$_SERVER['PHP_SELF'].'?id='.$result.'&action=edit&comefromclone=1');
595 exit;
596 }
597 }
598
599 // Quick edit for extrafields
600 if ($action == 'update_extras' && $permissiontoeditextra) {
601 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
602
603 $attribute_name = GETPOST('attribute', 'aZ09');
604
605 // Fill array 'array_options' with data from update form
606 $ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
607 if ($ret < 0) {
608 $error++;
609 }
610
611 if (!$error) {
612 $result = $object->updateExtraField($attribute_name, 'PROJECT_MODIFY');
613 if ($result < 0) {
614 setEventMessages($object->error, $object->errors, 'errors');
615 $error++;
616 }
617 }
618
619 if ($error) {
620 $action = 'edit_extras';
621 }
622 }
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, '', '', 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, '', '', 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
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" 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")).'</label>';
1289 print ' </div>';
1290
1291 print '</td>';
1292 print '</tr>';
1293
1294 // Opportunity amount
1295 print '<tr class="classuseopportunity'.$classfortr.'"><td>'.$langs->trans("OpportunityAmount").'</td>';
1296 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) : '')).'">';
1297 print $langs->getCurrencySymbol($conf->currency);
1298 print '</td>';
1299 print '</tr>';
1300 }
1301
1302 // Budget
1303 print '<tr><td>'.$langs->trans("Budget").'</td>';
1304 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) : '')).'">';
1305 print $langs->getCurrencySymbol($conf->currency);
1306 print '</td>';
1307 print '</tr>';
1308
1309 // Date project
1310 print '<tr><td>'.$langs->trans("Date").(isModEnabled('eventorganization') ? ' <span class="classuseorganizeevent">('.$langs->trans("Project").')</span>' : '').'</td><td>';
1311 print $form->selectDate($object->date_start ? $object->date_start : -1, 'projectstart', 0, 0, 0, '', 1, 0);
1312 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
1313 print $form->selectDate($object->date_end ? $object->date_end : -1, 'projectend', 0, 0, 0, '', 1, 0);
1314 $object->getLinesArray(null, 0);
1315 if (!empty($object->usage_task) && !empty($object->lines)) {
1316 print ' <span id="divreportdate" class="hidden">&nbsp; &nbsp; <input type="checkbox" class="valignmiddle" id="reportdate" name="reportdate" value="yes" ';
1317 if ($comefromclone) {
1318 print 'checked ';
1319 }
1320 print '/><label for="reportdate" class="valignmiddle opacitymedium">'.$langs->trans("ProjectReportDate").'</label></span>';
1321 }
1322 print '</td></tr>';
1323
1324 if (isModEnabled('eventorganization')) {
1325 // Date event
1326 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Date").' ('.$langs->trans("Event").')</td><td>';
1327 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);
1328 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
1329 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);
1330 print '</td></tr>';
1331
1332 // Location
1333 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Location").'</td>';
1334 print '<td><input class="minwidth300 maxwidth500" type="text" name="location" value="'.dol_escape_htmltag(GETPOSTISSET('location') ? GETPOST('location') : $object->location).'"></td>';
1335 print '</tr>';
1336 }
1337
1338 // Description
1339 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
1340 print '<td>';
1341 $doleditor = new DolEditor('description', $object->description, '', 90, 'dolibarr_notes', '', false, true, isModEnabled('fckeditor') && getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_3, '90%');
1342 $doleditor->Create();
1343 print '</td></tr>';
1344
1345 // Tags-Categories
1346 if (isModEnabled('category')) {
1347 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
1348 print $form->selectCategories(Categorie::TYPE_PROJECT, 'categories', $object);
1349 print "</td></tr>";
1350 }
1351
1352 // Visibility
1353 print '<tr><td>'.$langs->trans("Visibility").'</td><td>';
1354 $array = array();
1355 if (!getDolGlobalString('PROJECT_DISABLE_PRIVATE_PROJECT')) {
1356 $array[0] = $langs->trans("PrivateProject");
1357 }
1358 if (!getDolGlobalString('PROJECT_DISABLE_PUBLIC_PROJECT')) {
1359 $array[1] = $langs->trans("SharedProject");
1360 }
1361
1362 if (count($array) > 0) {
1363 print $form->selectarray('public', $array, $object->public, 0, 0, 0, '', 0, 0, 0, '', '', 1);
1364 } else {
1365 print '<input type="hidden" id="public" name="public" value="'.$object->public.'">';
1366
1367 if ($object->public == 0) {
1368 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1369 print $langs->trans("PrivateProject");
1370 } else {
1371 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1372 print $langs->trans("SharedProject");
1373 }
1374 }
1375 print '</td></tr>';
1376
1377 // Other options
1378 $parameters = array();
1379 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1380 print $hookmanager->resPrint;
1381 if (empty($reshook)) {
1382 print $object->showOptionals($extrafields, 'edit');
1383 }
1384
1385 print '</table>';
1386 } else {
1387 print dol_get_fiche_head($head, 'project', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'), 0, '', '', 0, '', 1);
1388
1389 // Project card
1390
1391 if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
1392 $tmpurl = $_SESSION['pageforbacktolist']['project'];
1393 $tmpurl = preg_replace('/__SOCID__/', (string) $object->socid, $tmpurl);
1394 $linkback = '<a href="'.$tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1395 } else {
1396 $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1397 }
1398
1399 $morehtmlref = '<div class="refidno">';
1400 // Title
1401 $morehtmlref .= dol_escape_htmltag($object->title);
1402 $morehtmlref .= '<br>';
1403 // Thirdparty
1404 if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
1405 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project');
1406 }
1407 // Parent
1408 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1409 if (!empty($object->fk_project) && $object->fk_project) {
1410 $parent = new Project($db);
1411 $parent->fetch($object->fk_project);
1412 $morehtmlref .= $langs->trans("Child of").' '.$parent->getNomUrl(1, 'project').' '.$parent->title;
1413 }
1414 }
1415 $morehtmlref .= '</div>';
1416
1417 // Define a complementary filter for search of next/prev ref.
1418 if (!$user->hasRight('projet', 'all', 'lire')) {
1419 $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
1420 $object->next_prev_filter = "rowid:IN:".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0');
1421 }
1422
1423 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
1424
1425 print '<div class="fichecenter">';
1426 print '<div class="fichehalfleft">';
1427 print '<div class="underbanner clearboth"></div>';
1428
1429 print '<table class="border tableforfield centpercent">';
1430
1431 // Usage
1432 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
1433 print '<tr><td class="tdtop">';
1434 print $langs->trans("Usage");
1435 print '</td>';
1436 print '<td>';
1437 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1438 print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'> ';
1439 $htmltext = $langs->trans("ProjectFollowOpportunity");
1440 print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
1441 print '<br>';
1442 }
1443 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
1444 print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'> ';
1445 $htmltext = $langs->trans("ProjectFollowTasks");
1446 print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
1447 print '<br>';
1448 }
1449 if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
1450 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"' : '')).'> ';
1451 $htmltext = $langs->trans("ProjectBillTimeDescription");
1452 print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
1453 print '<br>';
1454 }
1455
1456 if (isModEnabled('eventorganization')) {
1457 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"' : '')).'> ';
1458 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
1459 print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
1460 }
1461 print '</td></tr>';
1462 }
1463
1464 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') && !empty($object->usage_opportunity)) {
1465 // Opportunity status
1466 print '<tr><td>'.$langs->trans("OpportunityStatus");
1467 if ($action != 'edit_opp_status' && $user->hasRight('projet', 'creer')) {
1468 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>';
1469 }
1470 print '</td><td>';
1471 $html_name_status = ($action == 'edit_opp_status') ? 'opp_status' : 'none';
1472 $html_name_percent = ($action == 'edit_opp_status') ? 'opp_percent' : 'none';
1473 $percent_value = (GETPOSTISSET('opp_percent') ? GETPOSTINT('opp_percent') : (strcmp($object->opp_percent, '') ? vatrate($object->opp_percent) : ''));
1474 $formproject->formOpportunityStatus($_SERVER['PHP_SELF'].'?socid='.$object->id, (string) $object->opp_status, $percent_value, $html_name_status, $html_name_percent);
1475 print '</td></tr>';
1476
1477 // Opportunity Amount
1478 print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>';
1479 if (strcmp($object->opp_amount, '')) {
1480 print '<span class="amount">'.price($object->opp_amount, 0, $langs, 1, 0, -1, $conf->currency).'</span>';
1481 if (strcmp($object->opp_percent, '')) {
1482 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>';
1483 }
1484 }
1485 print '</td></tr>';
1486 }
1487
1488 // Budget
1489 print '<tr><td>'.$langs->trans("Budget").'</td><td>';
1490 if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
1491 print '<span class="amount">'.price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
1492 }
1493 print '</td></tr>';
1494
1495 // Date start - end project
1496 print '<tr><td>'.$langs->trans("Dates").'</td><td>';
1497 $start = dol_print_date($object->date_start, 'day');
1498 print($start ? $start : '?');
1499 $end = dol_print_date($object->date_end, 'day');
1500 print ' <span class="opacitymedium">-</span> ';
1501 print($end ? $end : '?');
1502 if ($object->hasDelay()) {
1503 print img_warning("Late");
1504 }
1505 print '</td></tr>';
1506
1507 // Visibility
1508 print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
1509 if ($object->public) {
1510 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1511 print $langs->trans('SharedProject');
1512 } else {
1513 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1514 print $langs->trans('PrivateProject');
1515 }
1516 print '</td></tr>';
1517
1518 // Other attributes
1519 $cols = 2;
1520 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1521
1522 print '</table>';
1523
1524 print '</div>';
1525 print '<div class="fichehalfright">';
1526 print '<div class="underbanner clearboth"></div>';
1527
1528 print '<table class="border tableforfield centpercent">';
1529
1530 // Categories
1531 if (isModEnabled('category')) {
1532 print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
1533 print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
1534 print "</td></tr>";
1535 }
1536
1537 // Description
1538 print '<tr><td class="titlefield'.($object->description ? ' noborderbottom' : '').'" colspan="2">'.$langs->trans("Description").'</td></tr>';
1539 if ($object->description) {
1540 print '<tr><td class="nottitleforfield" colspan="2">';
1541 print '<div class="longmessagecut">';
1542 print dolPrintHTML($object->description);
1543 print '</div>';
1544 print '</td></tr>';
1545 }
1546
1547 print '</table>';
1548
1549 print '</div>';
1550 print '</div>';
1551
1552 print '<div class="clearboth"></div>';
1553 }
1554
1555 print dol_get_fiche_end();
1556
1557 if ($action == 'edit' && $userWrite > 0) {
1558 print $form->buttonsSaveCancel();
1559 }
1560
1561 print '</form>';
1562
1563 // Set also dependencies between use task and bill time
1564 print '<script type="text/javascript">
1565 jQuery(document).ready(function() {
1566 jQuery("#usage_task").change(function() {
1567 console.log("We click on usage task "+jQuery("#usage_task").is(":checked"));
1568 if (! jQuery("#usage_task").is(":checked")) {
1569 jQuery("#usage_bill_time").prop("checked", false);
1570 }
1571 });
1572
1573 jQuery("#usage_bill_time").change(function() {
1574 console.log("We click on usage to bill time");
1575 if (jQuery("#usage_bill_time").is(":checked")) {
1576 jQuery("#usage_task").prop("checked", true);
1577 }
1578 });
1579
1580 jQuery("#projectstart").change(function() {
1581 console.log("We modify the start date");
1582 jQuery("#divreportdate").show();
1583 });
1584 });
1585 </script>';
1586
1587 // Change probability from status
1588 if (!empty($conf->use_javascript_ajax) && getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
1589 // Default value to close or not when we set opp to 'WON'.
1590 $defaultcheckedwhenoppclose = 1;
1591 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
1592 $defaultcheckedwhenoppclose = 0;
1593 }
1594
1595 print '<!-- Javascript to manage opportunity status change -->';
1596 print '<script type="text/javascript">
1597 jQuery(document).ready(function() {
1598 function change_percent()
1599 {
1600 var element = jQuery("#opp_status option:selected");
1601 var defaultpercent = element.attr("defaultpercent");
1602 var defaultcloseproject = '.((int) $defaultcheckedwhenoppclose).';
1603 var elemcode = element.attr("elemcode");
1604 var oldpercent = \''.dol_escape_js($object->opp_percent).'\';
1605
1606 console.log("We select "+elemcode);
1607
1608 /* Define if checkbox to close is checked or not */
1609 var closeproject = 0;
1610 if (elemcode == \'LOST\') closeproject = 1;
1611 if (elemcode == \'WON\') closeproject = defaultcloseproject;
1612 if (closeproject) jQuery("#inputcloseproject").prop("checked", true);
1613 else jQuery("#inputcloseproject").prop("checked", false);
1614
1615 /* Make the close project checkbox visible or not */
1616 console.log("closeproject="+closeproject);
1617 if (elemcode == \'WON\' || elemcode == \'LOST\')
1618 {
1619 jQuery("#divtocloseproject").show();
1620 }
1621 else
1622 {
1623 jQuery("#divtocloseproject").hide();
1624 }
1625
1626 /* Change percent with default percent (defaultpercent) if new status (defaultpercent) is higher than current (jQuery("#opp_percent").val()) */
1627 if (oldpercent != \'\' && (parseFloat(defaultpercent) < parseFloat(oldpercent)))
1628 {
1629 console.log("oldpercent="+oldpercent+" defaultpercent="+defaultpercent+" def < old");
1630 if (jQuery("#opp_percent").val() != \'\' && oldpercent != \'\') {
1631 jQuery("#oldopppercent").text(\' - '.dol_escape_js($langs->transnoentities("PreviousValue")).': \'+price2numjs(oldpercent)+\' %\');
1632 }
1633
1634 if (parseFloat(oldpercent) != 100 && elemcode != \'LOST\') { jQuery("#opp_percent").val(oldpercent); }
1635 else { jQuery("#opp_percent").val(price2numjs(defaultpercent)); }
1636 } else {
1637 console.log("oldpercent="+oldpercent+" defaultpercent="+defaultpercent);
1638 if (jQuery("#opp_percent").val() == \'\' || (parseFloat(jQuery("#opp_percent").val()) < parseFloat(defaultpercent))) {
1639 if (jQuery("#opp_percent").val() != \'\' && oldpercent != \'\') {
1640 jQuery("#oldopppercent").text(\' - '.dol_escape_js($langs->transnoentities("PreviousValue")).': \'+price2numjs(oldpercent)+\' %\');
1641 }
1642 jQuery("#opp_percent").val(price2numjs(defaultpercent));
1643 }
1644 }
1645 }
1646
1647 jQuery("#opp_status").change(function() {
1648 change_percent();
1649 });
1650 });
1651 </script>';
1652 }
1653
1654
1655 /*
1656 * Actions Buttons
1657 */
1658
1659 print '<div class="tabsAction">';
1660 $parameters = array();
1661 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1662 // modified by hook
1663 if (empty($reshook)) {
1664 if ($action != "edit" && $action != 'presend') {
1665 // Create event
1666 /*if (isModEnabled('agenda') && !empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a
1667 // "workflow" action so should appears somewhere else on
1668 // page.
1669 {
1670 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>';
1671 }*/
1672
1673 // Send
1674 if (empty($user->socid)) {
1675 if ($object->status != Project::STATUS_CLOSED) {
1676 print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?action=presend&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', '');
1677 }
1678 }
1679
1680 // Accounting Report
1681 /*
1682 $accouting_module_activated = isModEnabled('comptabilite') || isModEnabled('accounting');
1683 if ($accouting_module_activated && $object->status != Project::STATUS_DRAFT) {
1684 $start = dol_getdate((int) $object->date_start);
1685 $end = dol_getdate((int) $object->date_end);
1686 $url = DOL_URL_ROOT.'/compta/accounting-files.php?projectid='.$object->id;
1687 if (!empty($object->date_start)) $url .= '&amp;date_startday='.$start['mday'].'&amp;date_startmonth='.$start['mon'].'&amp;date_startyear='.$start['year'];
1688 if (!empty($object->date_end)) $url .= '&amp;date_stopday='.$end['mday'].'&amp;date_stopmonth='.$end['mon'].'&amp;date_stopyear='.$end['year'];
1689 print dolGetButtonAction('', $langs->trans('ExportAccountingReportButtonLabel'), 'default', $url, '');
1690 }
1691 */
1692
1693 // Back to draft
1694 if (!getDolGlobalString('MAIN_DISABLEDRAFTSTATUS') && !getDolGlobalString('MAIN_DISABLEDRAFTSTATUS_PROJECT')) {
1695 if ($object->status != Project::STATUS_DRAFT && $user->hasRight('projet', 'creer')) {
1696 if ($userWrite > 0) {
1697 print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?action=confirm_setdraft&amp;confirm=yes&amp;token='.newToken().'&amp;id='.$object->id, '');
1698 } else {
1699 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('SetToDraft'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1700 }
1701 }
1702 }
1703
1704 // Modify
1705 if ($object->status != Project::STATUS_CLOSED && $user->hasRight('projet', 'creer')) {
1706 if ($userWrite > 0) {
1707 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$object->id, '');
1708 } else {
1709 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Modify'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1710 }
1711 }
1712
1713 // Validate
1714 if ($object->status == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer')) {
1715 if ($userWrite > 0) {
1716 //print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=validate&token='.newToken().'&id='.$object->id, '');
1717 print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=confirm_validate&confirm=yes&token='.newToken().'&id='.$object->id, '');
1718 } else {
1719 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Validate'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1720 }
1721 }
1722
1723 // Close
1724 if ($object->status == Project::STATUS_VALIDATED && $user->hasRight('projet', 'creer')) {
1725 if ($userWrite > 0) {
1726 //print dolGetButtonAction('', $langs->trans('Close'), 'default', $_SERVER["PHP_SELF"].'?action=close&amp;token='.newToken().'&amp;id='.$object->id, '');
1727 print dolGetButtonAction('', $langs->trans('Close'), 'default', $_SERVER["PHP_SELF"].'?action=confirm_close&confirm=yes&token='.newToken().'&id='.$object->id, '');
1728 } else {
1729 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Close'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1730 }
1731 }
1732
1733 // Reopen
1734 if ($object->status == Project::STATUS_CLOSED && $user->hasRight('projet', 'creer')) {
1735 if ($userWrite > 0) {
1736 print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&amp;token='.newToken().'&amp;id='.$object->id, '');
1737 } else {
1738 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('ReOpen'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1739 }
1740 }
1741
1742
1743 // Buttons Create
1744 if (!getDolGlobalString('PROJECT_HIDE_CREATE_OBJECT_BUTTON')) {
1745 // We check the type of thirdparty
1746 $is_customer_or_prospect = (!empty($object->thirdparty->prospect) || !empty($object->thirdparty->client));
1747 $is_supplier_only= (!empty($object->thirdparty->fournisseur) && !$is_customer_or_prospect);
1748
1749 $arrayforbutaction = array(
1750 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),
1751 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),
1752 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),
1753 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 : '')),
1754 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 : '')),
1755 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 : '')),
1756 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),
1757 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),
1758 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),
1759 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),
1760 );
1761
1762 $params = array('backtopage' => $_SERVER["PHP_SELF"].'?id='.$object->id);
1763 //$params = array('backtopage' => $_SERVER["PHP_SELF"].'?id='.$object->id, 'isDropDown' => true);
1764
1765 print dolGetButtonAction('', $langs->trans("Create"), 'default', $arrayforbutaction, '', 1, $params);
1766 }
1767
1768 // Clone
1769 if ($user->hasRight('projet', 'creer')) {
1770 if ($userWrite > 0) {
1771 print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER["PHP_SELF"].'?action=clone&token='.newToken().'&id='.((int) $object->id), '');
1772 } else {
1773 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('ToClone'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1774 }
1775 }
1776
1777 // Delete
1778 if ($user->hasRight('projet', 'supprimer') || ($object->status == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer'))) {
1779 if ($userDelete > 0 || ($object->status == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer'))) {
1780 print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, '');
1781 } else {
1782 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1783 }
1784 }
1785 }
1786 }
1787
1788 print "</div>";
1789
1790 if (GETPOST('modelselected')) {
1791 $action = 'presend';
1792 }
1793
1794 if ($action != 'presend') {
1795 print '<div class="fichecenter"><div class="fichehalfleft">';
1796 print '<a name="builddoc"></a>'; // ancre
1797
1798 if (getDolGlobalInt('PROJECT_ENABLE_SUB_PROJECT')) {
1799 /*
1800 * Sub-projects (children)
1801 */
1802 $children = $object->getChildren();
1803 if ($children) {
1804 print '<table class="centpercent notopnoleftnoright table-fiche-title">';
1805 print '<tr class="titre"><td class="nobordernopadding valignmiddle col-title">';
1806 print '<div class="titre inline-block">'.$langs->trans('Sub-projects').'</div>';
1807 print '</td></tr></table>';
1808
1809 print '<div class="div-table-responsive-no-min">';
1810 print '<table class="centpercent noborder'.($morecss ? ' '.$morecss : '').'">';
1811 print '<tr class="liste_titre">';
1812 print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1);
1813 print getTitleFieldOfList('Title', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1);
1814 print getTitleFieldOfList('Status', 0, $_SERVER["PHP_SELF"], '', '', '', '', '', '', '', 1);
1815 print '</tr>';
1816 print "\n";
1817
1818 $subproject = new Project($db);
1819 foreach ($children as $child) {
1820 $subproject->fetch($child->rowid);
1821 print '<tr class="oddeven">';
1822 print '<td class="nowraponall">'.$subproject->getNomUrl(1, 'project').'</td>';
1823 print '<td class="nowraponall tdoverflowmax125">'.$child->title.'</td>';
1824 print '<td class="nowraponall">'.$subproject->getLibStatut(5).'</td>';
1825 print '</tr>';
1826 }
1827
1828 print '</table>';
1829 print '</div>';
1830 }
1831 }
1832
1833 /*
1834 * Generated documents
1835 */
1836 $filename = dol_sanitizeFileName($object->ref);
1837 $filedir = $conf->project->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->ref);
1838 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
1839 $genallowed = ($user->hasRight('projet', 'lire') && $userAccess > 0);
1840 $delallowed = ($user->hasRight('projet', 'creer') && $userWrite > 0);
1841
1842 print $formfile->showdocuments('project', $filename, $filedir, $urlsource, (int) $genallowed, (int) $delallowed, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', '', '', $object);
1843
1844 print '</div><div class="fichehalfright">';
1845
1846 $MAXEVENT = 10;
1847
1848 $morehtmlcenter = '<div class="nowraponall">';
1849 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/projet/messaging.php?id='.$object->id);
1850 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/projet/agenda.php?id='.$object->id);
1851 $morehtmlcenter .= '</div>';
1852
1853 // List of actions on element
1854 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1855 $formactions = new FormActions($db);
1856 $somethingshown = $formactions->showactions($object, 'project', 0, 1, '', $MAXEVENT, '', $morehtmlcenter);
1857
1858 print '</div></div>';
1859 }
1860
1861 // Presend form
1862 $modelmail = 'project';
1863 $defaulttopic = 'SendProjectRef';
1864 $defaulttopiclang = 'projects';
1865 $diroutput = $conf->project->multidir_output[$object->entity];
1866 $autocopy = 'MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add
1867 $trackid = 'proj'.$object->id;
1868
1869 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1870
1871 // Hook to add more things on page
1872 $parameters = array();
1873 $reshook = $hookmanager->executeHooks('mainCardTabAddMore', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1874} else {
1875 recordNotFound('', 0);
1876}
1877
1878// End of page
1879llxFooter();
1880$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.