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