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