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 $newobject->fetch_optionals();
500 $newobject->fetch_thirdparty(); // Load new object
501 $object = $newobject;
502 $action = 'view';
503 $comefromclone = true;
504
505 setEventMessages($langs->trans("ProjectCreatedInDolibarr", $newobject->ref), "", 'mesgs');
506 //var_dump($newobject); exit;
507 }
508 }
509
510 // Actions to send emails
511 $triggersendname = 'PROJECT_SENTBYMAIL';
512 $paramname = 'id';
513 $autocopy = 'MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add
514 $trackid = 'proj'.$object->id;
515 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
516}
517
518
519/*
520 * View
521 */
522
523$form = new Form($db);
524$formfile = new FormFile($db);
525$formproject = new FormProjets($db);
526$userstatic = new User($db);
527
528$title = $langs->trans("Project").' - '.$object->ref.(!empty($object->thirdparty->name) ? ' - '.$object->thirdparty->name : '').(!empty($object->title) ? ' - '.$object->title : '');
529if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE)) {
530 $title = $object->ref.(!empty($object->thirdparty->name) ? ' - '.$object->thirdparty->name : '').(!empty($object->title) ? ' - '.$object->title : '');
531}
532
533$help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte";
534
535llxHeader("", $title, $help_url);
536
537$titleboth = $langs->trans("LeadsOrProjects");
538$titlenew = $langs->trans("NewLeadOrProject"); // Leads and opportunities by default
539if (!getDolGlobalInt('PROJECT_USE_OPPORTUNITIES')) {
540 $titleboth = $langs->trans("Projects");
541 $titlenew = $langs->trans("NewProject");
542}
543if (getDolGlobalInt('PROJECT_USE_OPPORTUNITIES') == 2) { // 2 = leads only
544 $titleboth = $langs->trans("Leads");
545 $titlenew = $langs->trans("NewLead");
546}
547
548if ($action == 'create' && $user->rights->projet->creer) {
549 /*
550 * Create
551 */
552
553 $thirdparty = new Societe($db);
554 if ($socid > 0) {
555 $thirdparty->fetch($socid);
556 }
557
558 print load_fiche_titre($titlenew, '', 'project');
559
560 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
561 print '<input type="hidden" name="action" value="add">';
562 print '<input type="hidden" name="token" value="'.newToken().'">';
563 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
564 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
565 print '<input type="hidden" name="backtopagejsfields" value="'.$backtopagejsfields.'">';
566 print '<input type="hidden" name="dol_openinpopup" value="'.$dol_openinpopup.'">';
567
568 print dol_get_fiche_head();
569
570 print '<table class="border centpercent tableforfieldcreate">';
571
572 $defaultref = '';
573 $modele = empty($conf->global->PROJECT_ADDON) ? 'mod_project_simple' : $conf->global->PROJECT_ADDON;
574
575 // Search template files
576 $file = ''; $classname = ''; $filefound = 0;
577 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
578 foreach ($dirmodels as $reldir) {
579 $file = dol_buildpath($reldir."core/modules/project/".$modele.'.php', 0);
580 if (file_exists($file)) {
581 $filefound = 1;
582 $classname = $modele;
583 break;
584 }
585 }
586
587 if ($filefound) {
588 $result = dol_include_once($reldir."core/modules/project/".$modele.'.php');
589 $modProject = new $classname;
590
591 $defaultref = $modProject->getNextValue($thirdparty, $object);
592 }
593
594 if (is_numeric($defaultref) && $defaultref <= 0) {
595 $defaultref = '';
596 }
597
598 // Ref
599 $suggestedref = (GETPOST("ref") ? GETPOST("ref") : $defaultref);
600 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).'">';
601 if ($suggestedref) {
602 print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref));
603 }
604 print '</td></tr>';
605
606 // Label
607 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>';
608
609 // Usage (opp, task, bill time, ...)
610 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) {
611 print '<tr><td class="tdtop">';
612 print $langs->trans("Usage");
613 print '</td>';
614 print '<td>';
615 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
616 print '<input type="checkbox" id="usage_opportunity" name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') ? ' checked="checked"' : '') : ' checked="checked"').'"> ';
617 $htmltext = $langs->trans("ProjectFollowOpportunity");
618 print '<label for="usage_opportunity">'.$form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext).'</label>';
619 print '<script>';
620 print '$( document ).ready(function() {
621 jQuery("#usage_opportunity").change(function() {
622 if (jQuery("#usage_opportunity").prop("checked")) {
623 console.log("Show opportunities fields");
624 jQuery(".classuseopportunity").show();
625 } else {
626 console.log("Hide opportunities fields "+jQuery("#usage_opportunity").prop("checked"));
627 jQuery(".classuseopportunity").hide();
628 }
629 });
630 ';
631 if (GETPOSTISSET('usage_opportunity') && !GETPOST('usage_opportunity')) {
632 print 'jQuery(".classuseopportunity").hide();';
633 }
634 print '});';
635 print '</script>';
636 print '<br>';
637 }
638 if (empty($conf->global->PROJECT_HIDE_TASKS)) {
639 print '<input type="checkbox" id="usage_task" name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') ? ' checked="checked"' : '') : ' checked="checked"').'"> ';
640 $htmltext = $langs->trans("ProjectFollowTasks");
641 print '<label for="usage_task">'.$form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext).'</label>';
642 print '<script>';
643 print '$( document ).ready(function() {
644 jQuery("#usage_task").change(function() {
645 if (jQuery("#usage_task").prop("checked")) {
646 console.log("Show task fields");
647 jQuery(".classusetask").show();
648 } else {
649 console.log("Hide tasks fields "+jQuery("#usage_task").prop("checked"));
650 jQuery(".classusetask").hide();
651 }
652 });
653 ';
654 if (GETPOSTISSET('usage_task') && !GETPOST('usage_task')) {
655 print 'jQuery(".classusetask").hide();';
656 }
657 print '});';
658 print '</script>';
659 print '<br>';
660 }
661 if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
662 print '<input type="checkbox" id="usage_bill_time" name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') ? ' checked="checked"' : '') : '').'"> ';
663 $htmltext = $langs->trans("ProjectBillTimeDescription");
664 print '<label for="usage_bill_time">'.$form->textwithpicto($langs->trans("BillTime"), $htmltext).'</label>';
665 print '<script>';
666 print '$( document ).ready(function() {
667 jQuery("#usage_bill_time").change(function() {
668 if (jQuery("#usage_bill_time").prop("checked")) {
669 console.log("Show bill time fields");
670 jQuery(".classusebilltime").show();
671 } else {
672 console.log("Hide bill time fields "+jQuery("#usage_bill_time").prop("checked"));
673 jQuery(".classusebilltime").hide();
674 }
675 });
676 ';
677 if (GETPOSTISSET('usage_bill_time') && !GETPOST('usage_bill_time')) {
678 print 'jQuery(".classusebilltime").hide();';
679 }
680 print '});';
681 print '</script>';
682 print '<br>';
683 }
684 if (isModEnabled('eventorganization')) {
685 print '<input type="checkbox" id="usage_organize_event" name="usage_organize_event"'.(GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') ? ' checked="checked"' : '') :'').'"> ';
686 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
687 print '<label for="usage_organize_event">'.$form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext).'</label>';
688 print '<script>';
689 print '$( document ).ready(function() {
690 jQuery("#usage_organize_event").change(function() {
691 if (jQuery("#usage_organize_event").prop("checked")) {
692 console.log("Show organize event fields");
693 jQuery(".classuseorganizeevent").show();
694 } else {
695 console.log("Hide organize event fields "+jQuery("#usage_organize_event").prop("checked"));
696 jQuery(".classuseorganizeevent").hide();
697 }
698 });
699 ';
700 if (!GETPOST('usage_organize_event')) {
701 print 'jQuery(".classuseorganizeevent").hide();';
702 }
703 print '});';
704 print '</script>';
705 }
706 print '</td>';
707 print '</tr>';
708 }
709
710 // Thirdparty
711 if (isModEnabled('societe')) {
712 print '<tr><td>';
713 print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : '<span class="fieldrequired">');
714 print $langs->trans("ThirdParty");
715 print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : '</span>');
716 print '</td><td class="maxwidthonsmartphone">';
717 $filter = '';
718 if (!empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) {
719 $filter = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
720 }
721 $text = img_picto('', 'company').$form->select_company(GETPOST('socid', 'int'), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
722 if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) {
723 $texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty");
724 print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1);
725 } else {
726 print $text;
727 }
728 if (!GETPOSTISSET('backtopage')) {
729 $url = '/societe/card.php?action=create&client=3&fournisseur=0&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create');
730 $newbutton = '<span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddThirdParty").'"></span>';
731 // TODO @LDR Implement this
732 if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
733 $tmpbacktopagejsfields = 'addthirdparty:socid,search_socid';
734 print dolButtonToOpenUrlInDialogPopup('addthirdparty', $langs->transnoentitiesnoconv('AddThirdParty'), $newbutton, $url, '', '', '', $tmpbacktopagejsfields);
735 } else {
736 print ' <a href="'.DOL_URL_ROOT.$url.'">'.$newbutton.'</a>';
737 }
738 }
739 print '</td></tr>';
740 }
741
742 // Status
743 if ($status != '') {
744 print '<tr><td>'.$langs->trans("Status").'</td><td>';
745 print '<input type="hidden" name="status" value="'.$status.'">';
746 print $object->LibStatut($status, 4);
747 print '</td></tr>';
748 }
749
750 // Visibility
751 print '<tr><td>'.$langs->trans("Visibility").'</td><td class="maxwidthonsmartphone">';
752 $array = array();
753 if (empty($conf->global->PROJECT_DISABLE_PRIVATE_PROJECT)) {
754 $array[0] = $langs->trans("PrivateProject");
755 }
756 if (empty($conf->global->PROJECT_DISABLE_PUBLIC_PROJECT)) {
757 $array[1] = $langs->trans("SharedProject");
758 }
759
760 if (count($array) > 0) {
761 print $form->selectarray('public', $array, GETPOST('public'), 0, 0, 0, '', 0, 0, 0, '', '', 1);
762 } else {
763 print '<input type="hidden" name="public" id="public" value="'.GETPOST('public').'">';
764
765 if (GETPOST('public') == 0) {
766 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
767 print $langs->trans("PrivateProject");
768 } else {
769 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
770 print $langs->trans("SharedProject");
771 }
772 }
773 print '</td></tr>';
774
775 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
776 // Opportunity status
777 print '<tr class="classuseopportunity"><td><span class="fieldrequired">'.$langs->trans("OpportunityStatus").'</span></td>';
778 print '<td class="maxwidthonsmartphone">';
779 print $formproject->selectOpportunityStatus('opp_status', GETPOSTISSET('opp_status') ? GETPOST('opp_status') : $object->opp_status, 1, 0, 0, 0, '', 0, 1);
780
781 // Opportunity probability
782 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>';
783 print '<input type="hidden" name="opp_percent_not_set" id="opp_percent_not_set" value="'.dol_escape_htmltag(GETPOSTISSET('opp_percent') ? '0' : '1').'">';
784 print '</td>';
785 print '</tr>';
786
787 // Opportunity amount
788 print '<tr class="classuseopportunity"><td>'.$langs->trans("OpportunityAmount").'</td>';
789 print '<td><input class="width75 right" type="text" name="opp_amount" value="'.dol_escape_htmltag(GETPOSTISSET('opp_amount') ? GETPOST('opp_amount') : '').'">';
790 print ' '.$langs->getCurrencySymbol($conf->currency);
791 print '</td>';
792 print '</tr>';
793 }
794
795 // Budget
796 print '<tr><td>'.$langs->trans("Budget").'</td>';
797 print '<td><input class="width75 right" type="text" name="budget_amount" value="'.dol_escape_htmltag(GETPOSTISSET('budget_amount') ? GETPOST('budget_amount') : '').'">';
798 print ' '.$langs->getCurrencySymbol($conf->currency);
799 print '</td>';
800 print '</tr>';
801
802 // Date project
803 print '<tr><td>'.$langs->trans("Date").(isModEnabled('eventorganization') ? ' <span class="classuseorganizeevent">('.$langs->trans("Project").')</span>' : '').'</td><td>';
804 print $form->selectDate(($date_start ? $date_start : ''), 'projectstart', 0, 0, 0, '', 1, 0);
805 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
806 print $form->selectDate(($date_end ? $date_end : -1), 'projectend', 0, 0, 0, '', 1, 0);
807 print '</td></tr>';
808
809 if (isModEnabled('eventorganization')) {
810 // Date event
811 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Date").' ('.$langs->trans("Event").')</td><td>';
812 print $form->selectDate(($date_start_event ? $date_start_event : -1), 'date_start_event', 1, 1, 1, '', 1, 0);
813 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
814 print $form->selectDate(($date_end_event ? $date_end_event : -1), 'date_end_event', 1, 1, 1, '', 1, 0);
815 print '</td></tr>';
816
817 // Location
818 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Location").'</td>';
819 print '<td><input class="minwidth300 maxwidth500" type="text" name="location" value="'.dol_escape_htmltag($location).'"></td>';
820 print '</tr>';
821 }
822
823 // Description
824 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
825 print '<td>';
826 $doleditor = new DolEditor('description', GETPOST("description", 'restricthtml'), '', 90, 'dolibarr_notes', '', false, true, getDolGlobalString('FCKEDITOR_ENABLE_SOCIETE'), ROWS_3, '90%');
827 $doleditor->Create();
828 print '</td></tr>';
829
830 if (isModEnabled('categorie')) {
831 // Categories
832 print '<tr><td>'.$langs->trans("Categories").'</td><td colspan="3">';
833 $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 1);
834 $arrayselected = GETPOST('categories', 'array');
835 print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
836 print "</td></tr>";
837 }
838
839 // Other options
840 $parameters = array();
841 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
842 print $hookmanager->resPrint;
843 if (empty($reshook)) {
844 print $object->showOptionals($extrafields, 'create');
845 }
846
847 print '</table>';
848
849 print dol_get_fiche_end();
850
851 print $form->buttonsSaveCancel('CreateDraft');
852
853 print '</form>';
854
855 // Change probability from status or role of project
856 // Set also dependencies between use taks and bill time
857 print '<script type="text/javascript">
858 jQuery(document).ready(function() {
859 function change_percent()
860 {
861 var element = jQuery("#opp_status option:selected");
862 var defaultpercent = element.attr("defaultpercent");
863 /*if (jQuery("#opp_percent_not_set").val() == "") */
864 jQuery("#opp_percent").val(defaultpercent);
865 }
866
867 /*init_myfunc();*/
868 jQuery("#opp_status").change(function() {
869 change_percent();
870 });
871
872 jQuery("#usage_task").change(function() {
873 console.log("We click on usage task "+jQuery("#usage_task").is(":checked"));
874 if (! jQuery("#usage_task").is(":checked")) {
875 jQuery("#usage_bill_time").prop("checked", false);
876 }
877 });
878
879 jQuery("#usage_bill_time").change(function() {
880 console.log("We click on usage to bill time");
881 if (jQuery("#usage_bill_time").is(":checked")) {
882 jQuery("#usage_task").prop("checked", true);
883 }
884 });
885 });
886 </script>';
887} elseif ($object->id > 0) {
888 /*
889 * Show or edit
890 */
891
892 $res = $object->fetch_optionals();
893
894 // To verify role of users
895 $userAccess = $object->restrictedProjectArea($user, 'read');
896 $userWrite = $object->restrictedProjectArea($user, 'write');
897 $userDelete = $object->restrictedProjectArea($user, 'delete');
898 //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
899
900
901 // Confirmation validation
902 if ($action == 'validate') {
903 print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProject'), $langs->trans('ConfirmValidateProject'), 'confirm_validate', '', 0, 1);
904 }
905 // Confirmation close
906 if ($action == 'close') {
907 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("CloseAProject"), $langs->trans("ConfirmCloseAProject"), "confirm_close", '', '', 1);
908 }
909 // Confirmation reopen
910 if ($action == 'reopen') {
911 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ReOpenAProject"), $langs->trans("ConfirmReOpenAProject"), "confirm_reopen", '', '', 1);
912 }
913 // Confirmation delete
914 if ($action == 'delete') {
915 $text = $langs->trans("ConfirmDeleteAProject");
916 $task = new Task($db);
917 $taskarray = $task->getTasksArray(0, 0, $object->id, 0, 0);
918 $nboftask = count($taskarray);
919 if ($nboftask) {
920 $text .= '<br>'.img_warning().' '.$langs->trans("ThisWillAlsoRemoveTasks", $nboftask);
921 }
922 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("DeleteAProject"), $text, "confirm_delete", '', '', 1);
923 }
924
925 // Clone confirmation
926 if ($action == 'clone') {
927 $formquestion = array(
928 'text' => $langs->trans("ConfirmClone"),
929 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')),
930 array('type' => 'checkbox', 'name' => 'clone_contacts', 'label' => $langs->trans("CloneContacts"), 'value' => true),
931 array('type' => 'checkbox', 'name' => 'clone_tasks', 'label' => $langs->trans("CloneTasks"), 'value' => true),
932 array('type' => 'checkbox', 'name' => 'move_date', 'label' => $langs->trans("CloneMoveDate"), 'value' => true),
933 array('type' => 'checkbox', 'name' => 'clone_notes', 'label' => $langs->trans("CloneNotes"), 'value' => true),
934 array('type' => 'checkbox', 'name' => 'clone_project_files', 'label' => $langs->trans("CloneProjectFiles"), 'value' => false),
935 array('type' => 'checkbox', 'name' => 'clone_task_files', 'label' => $langs->trans("CloneTaskFiles"), 'value' => false)
936 );
937
938 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ToClone"), $langs->trans("ConfirmCloneProject"), "confirm_clone", $formquestion, '', 1, 400, 590);
939 }
940
941
942 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
943 print '<input type="hidden" name="token" value="'.newToken().'">';
944 print '<input type="hidden" name="action" value="update">';
945 print '<input type="hidden" name="id" value="'.$object->id.'">';
946 print '<input type="hidden" name="comefromclone" value="'.$comefromclone.'">';
947
948 $head = project_prepare_head($object);
949
950 if ($action == 'edit' && $userWrite > 0) {
951 print dol_get_fiche_head($head, 'project', $langs->trans("Project"), 0, ($object->public ? 'projectpub' : 'project'));
952
953 print '<table class="border centpercent">';
954
955 // Ref
956 $suggestedref = $object->ref;
957 print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Ref").'</td>';
958 print '<td><input size="25" name="ref" value="'.$suggestedref.'">';
959 print ' '.$form->textwithpicto('', $langs->trans("YouCanCompleteRef", $suggestedref));
960 print '</td></tr>';
961
962 // Label
963 print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>';
964 print '<td><input class="quatrevingtpercent" name="title" value="'.dol_escape_htmltag($object->title).'"></td></tr>';
965
966 // Status
967 print '<tr><td class="fieldrequired">'.$langs->trans("Status").'</td><td>';
968 print '<select class="flat" name="status" id="status">';
969 foreach ($object->statuts_short as $key => $val) {
970 print '<option value="'.$key.'"'.((GETPOSTISSET('status') ? GETPOST('status') : $object->statut) == $key ? ' selected="selected"' : '').'>'.$langs->trans($val).'</option>';
971 }
972 print '</select>';
973 print ajax_combobox('status');
974 print '</td></tr>';
975
976 // Usage
977 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) {
978 print '<tr><td class="tdtop">';
979 print $langs->trans("Usage");
980 print '</td>';
981 print '<td>';
982 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
983 print '<input type="checkbox" id="usage_opportunity" name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'> ';
984 $htmltext = $langs->trans("ProjectFollowOpportunity");
985 print '<label for="usage_opportunity">'.$form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext).'</label>';
986 print '<script>';
987 print '$( document ).ready(function() {
988 jQuery("#usage_opportunity").change(function() {
989 set_usage_opportunity();
990 });
991
992 set_usage_opportunity();
993
994 function set_usage_opportunity() {
995 console.log("set_usage_opportunity");
996 if (jQuery("#usage_opportunity").prop("checked")) {
997 console.log("Show opportunities fields");
998 jQuery(".classuseopportunity").show();
999 } else {
1000 console.log("Hide opportunities fields "+jQuery("#usage_opportunity").prop("checked"));
1001 jQuery(".classuseopportunity").hide();
1002 }
1003 }
1004 });';
1005 print '</script>';
1006 print '<br>';
1007 }
1008 if (empty($conf->global->PROJECT_HIDE_TASKS)) {
1009 print '<input type="checkbox" id="usage_task" name="usage_task"' . (GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')) . '> ';
1010 $htmltext = $langs->trans("ProjectFollowTasks");
1011 print '<label for="usage_task">'.$form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext).'</label>';
1012 print '<script>';
1013 print '$( document ).ready(function() {
1014 jQuery("#usage_task").change(function() {
1015 set_usage_task();
1016 });
1017
1018 set_usage_task();
1019
1020 function set_usage_task() {
1021 console.log("set_usage_task");
1022 if (jQuery("#usage_task").prop("checked")) {
1023 console.log("Show task fields");
1024 jQuery(".classusetask").show();
1025 } else {
1026 console.log("Hide task fields "+jQuery("#usage_task").prop("checked"));
1027 jQuery(".classusetask").hide();
1028 }
1029 }
1030 });';
1031 print '</script>';
1032 print '<br>';
1033 }
1034 if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
1035 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"' : '')) . '> ';
1036 $htmltext = $langs->trans("ProjectBillTimeDescription");
1037 print '<label for="usage_bill_time">'.$form->textwithpicto($langs->trans("BillTime"), $htmltext).'</label>';
1038 print '<script>';
1039 print '$( document ).ready(function() {
1040 jQuery("#usage_bill_time").change(function() {
1041 set_usage_bill_time();
1042 });
1043
1044 set_usage_bill_time();
1045
1046 function set_usage_bill_time() {
1047 console.log("set_usage_bill_time");
1048 if (jQuery("#usage_bill_time").prop("checked")) {
1049 console.log("Show bill time fields");
1050 jQuery(".classusebilltime").show();
1051 } else {
1052 console.log("Hide bill time fields "+jQuery("#usage_bill_time").prop("checked"));
1053 jQuery(".classusebilltime").hide();
1054 }
1055 }
1056 });';
1057 print '</script>';
1058 print '<br>';
1059 }
1060 if (isModEnabled('eventorganization')) {
1061 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"' : '')) . '> ';
1062 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
1063 print '<label for="usage_organize_event">'.$form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext).'</label>';
1064 print '<script>';
1065 print '$( document ).ready(function() {
1066 jQuery("#usage_organize_event").change(function() {
1067 set_usage_event();
1068 });
1069
1070 set_usage_event();
1071
1072 function set_usage_event() {
1073 console.log("set_usage_event");
1074 if (jQuery("#usage_organize_event").prop("checked")) {
1075 console.log("Show organize event fields");
1076 jQuery(".classuseorganizeevent").show();
1077 } else {
1078 console.log("Hide organize event fields "+jQuery("#usage_organize_event").prop("checked"));
1079 jQuery(".classuseorganizeevent").hide();
1080 }
1081 }
1082 });';
1083 print '</script>';
1084 }
1085 print '</td></tr>';
1086 }
1087 print '</td></tr>';
1088
1089 // Thirdparty
1090 if (isModEnabled('societe')) {
1091 print '<tr><td>';
1092 print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : '<span class="fieldrequired">');
1093 print $langs->trans("ThirdParty");
1094 print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : '</span>');
1095 print '</td><td>';
1096 $filter = '';
1097 if (!empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) {
1098 $filter = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
1099 }
1100 $text = img_picto('', 'company', 'class="pictofixedwidth"');
1101 $text .= $form->select_company($object->thirdparty->id, 'socid', $filter, 'None', 1, 0, array(), 0, 'minwidth300');
1102 if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) {
1103 $texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty");
1104 print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1, 0, '', '', 2);
1105 } else {
1106 print $text;
1107 }
1108 print '</td></tr>';
1109 }
1110
1111 // Visibility
1112 print '<tr><td>'.$langs->trans("Visibility").'</td><td>';
1113 $array = array();
1114 if (empty($conf->global->PROJECT_DISABLE_PRIVATE_PROJECT)) {
1115 $array[0] = $langs->trans("PrivateProject");
1116 }
1117 if (empty($conf->global->PROJECT_DISABLE_PUBLIC_PROJECT)) {
1118 $array[1] = $langs->trans("SharedProject");
1119 }
1120
1121 if (count($array) > 0) {
1122 print $form->selectarray('public', $array, $object->public, 0, 0, 0, '', 0, 0, 0, '', '', 1);
1123 } else {
1124 print '<input type="hidden" id="public" name="public" value="'.$object->public.'">';
1125
1126 if ($object->public == 0) {
1127 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1128 print $langs->trans("PrivateProject");
1129 } else {
1130 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1131 print $langs->trans("SharedProject");
1132 }
1133 }
1134 print '</td></tr>';
1135
1136 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
1137 $classfortr = ($object->usage_opportunity ? '' : ' hideobject');
1138 // Opportunity status
1139 print '<tr class="classuseopportunity'.$classfortr.'"><td>'.$langs->trans("OpportunityStatus").'</td>';
1140 print '<td>';
1141 print '<div>';
1142 print $formproject->selectOpportunityStatus('opp_status', $object->opp_status, 1, 0, 0, 0, 'minwidth150 inline-block valignmiddle', 1, 1);
1143
1144 // Opportunity probability
1145 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) : '')).'"> %';
1146 print '<span id="oldopppercent" class="opacitymedium"></span>';
1147 print '</div>';
1148
1149 print '<div id="divtocloseproject" class="inline-block valign clearboth paddingtop" style="display: none;">';
1150 print '<input type="checkbox" id="inputcloseproject" name="closeproject" />';
1151 print '<label for="inputcloseproject">';
1152 print $form->textwithpicto($langs->trans("AlsoCloseAProject"), $langs->trans("AlsoCloseAProjectTooltip")).'</label>';
1153 print ' </div>';
1154
1155 print '</td>';
1156 print '</tr>';
1157
1158 // Opportunity amount
1159 print '<tr class="classuseopportunity'.$classfortr.'"><td>'.$langs->trans("OpportunityAmount").'</td>';
1160 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) : '')).'">';
1161 print $langs->getCurrencySymbol($conf->currency);
1162 print '</td>';
1163 print '</tr>';
1164 }
1165
1166 // Budget
1167 print '<tr><td>'.$langs->trans("Budget").'</td>';
1168 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) : '')).'">';
1169 print $langs->getCurrencySymbol($conf->currency);
1170 print '</td>';
1171 print '</tr>';
1172
1173 // Date project
1174 print '<tr><td>'.$langs->trans("Date").(isModEnabled('eventorganization') ? ' <span class="classuseorganizeevent">('.$langs->trans("Project").')</span>' : '').'</td><td>';
1175 print $form->selectDate($object->date_start ? $object->date_start : -1, 'projectstart', 0, 0, 0, '', 1, 0);
1176 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
1177 print $form->selectDate($object->date_end ? $object->date_end : -1, 'projectend', 0, 0, 0, '', 1, 0);
1178 $object->getLinesArray(null, 0);
1179 if (!empty($object->usage_task) && !empty($object->lines)) {
1180 print ' <span id="divreportdate" class="hidden">&nbsp; &nbsp; <input type="checkbox" class="valignmiddle" id="reportdate" name="reportdate" value="yes" ';
1181 if ($comefromclone) {
1182 print 'checked ';
1183 }
1184 print '/><label for="reportdate" class="valignmiddle opacitymedium">'.$langs->trans("ProjectReportDate").'</label></span>';
1185 }
1186 print '</td></tr>';
1187
1188 if (isModEnabled('eventorganization')) {
1189 // Date event
1190 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Date").' ('.$langs->trans("Event").')</td><td>';
1191 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);
1192 print ' <span class="opacitymedium"> '.$langs->trans("to").' </span> ';
1193 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);
1194 print '</td></tr>';
1195
1196 // Location
1197 print '<tr class="classuseorganizeevent"><td>'.$langs->trans("Location").'</td>';
1198 print '<td><input class="minwidth300 maxwidth500" type="text" name="location" value="'.dol_escape_htmltag(GETPOSTISSET('location') ? GETPOST('location') : $object->location).'"></td>';
1199 print '</tr>';
1200 }
1201
1202 // Description
1203 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
1204 print '<td>';
1205 $doleditor = new DolEditor('description', $object->description, '', 90, 'dolibarr_notes', '', false, true, getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), ROWS_3, '90%');
1206 $doleditor->Create();
1207 print '</td></tr>';
1208
1209 // Tags-Categories
1210 if (isModEnabled('categorie')) {
1211 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
1212 $cate_arbo = $form->select_all_categories(Categorie::TYPE_PROJECT, '', 'parent', 64, 0, 1);
1213 $c = new Categorie($db);
1214 $cats = $c->containing($object->id, Categorie::TYPE_PROJECT);
1215 foreach ($cats as $cat) {
1216 $arrayselected[] = $cat->id;
1217 }
1218 print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, '0');
1219 print "</td></tr>";
1220 }
1221
1222 // Other options
1223 $parameters = array();
1224 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1225 print $hookmanager->resPrint;
1226 if (empty($reshook)) {
1227 print $object->showOptionals($extrafields, 'edit');
1228 }
1229
1230 print '</table>';
1231 } else {
1232 print dol_get_fiche_head($head, 'project', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
1233
1234 // Project card
1235
1236 if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
1237 $tmpurl = $_SESSION['pageforbacktolist']['project'];
1238 $tmpurl = preg_replace('/__SOCID__/', $object->socid, $tmpurl);
1239 $linkback = '<a href="'.$tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1240 } else {
1241 $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1242 }
1243
1244 $morehtmlref = '<div class="refidno">';
1245 // Title
1246 $morehtmlref .= dol_escape_htmltag($object->title);
1247 $morehtmlref .= '<br>';
1248 // Thirdparty
1249 if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
1250 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'project');
1251 }
1252 $morehtmlref .= '</div>';
1253
1254 // Define a complementary filter for search of next/prev ref.
1255 if (empty($user->rights->projet->all->lire)) {
1256 $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
1257 $object->next_prev_filter = "rowid IN (".$db->sanitize(count($objectsListId) ? join(',', array_keys($objectsListId)) : '0').")";
1258 }
1259
1260 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
1261
1262 print '<div class="fichecenter">';
1263 print '<div class="fichehalfleft">';
1264 print '<div class="underbanner clearboth"></div>';
1265
1266 print '<table class="border tableforfield centpercent">';
1267
1268 // Usage
1269 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) {
1270 print '<tr><td class="tdtop">';
1271 print $langs->trans("Usage");
1272 print '</td>';
1273 print '<td>';
1274 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
1275 print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'> ';
1276 $htmltext = $langs->trans("ProjectFollowOpportunity");
1277 print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
1278 print '<br>';
1279 }
1280 if (empty($conf->global->PROJECT_HIDE_TASKS)) {
1281 print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'> ';
1282 $htmltext = $langs->trans("ProjectFollowTasks");
1283 print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
1284 print '<br>';
1285 }
1286 if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
1287 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"' : '')).'> ';
1288 $htmltext = $langs->trans("ProjectBillTimeDescription");
1289 print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
1290 print '<br>';
1291 }
1292
1293 if (isModEnabled('eventorganization')) {
1294 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"' : '')).'> ';
1295 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
1296 print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
1297 }
1298 print '</td></tr>';
1299 }
1300
1301 // Visibility
1302 print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
1303 if ($object->public) {
1304 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1305 print $langs->trans('SharedProject');
1306 } else {
1307 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1308 print $langs->trans('PrivateProject');
1309 }
1310 print '</td></tr>';
1311
1312 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) && !empty($object->usage_opportunity)) {
1313 // Opportunity status
1314 print '<tr><td>'.$langs->trans("OpportunityStatus").'</td><td>';
1315 $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code');
1316 if ($code) {
1317 print $langs->trans("OppStatus".$code);
1318 }
1319
1320 // Opportunity percent
1321 print ' <span title="'.$langs->trans("OpportunityProbability").'"> / ';
1322 if (strcmp($object->opp_percent, '')) {
1323 print price($object->opp_percent, 0, $langs, 1, 0).' %';
1324 }
1325 print '</span></td></tr>';
1326
1327 // Opportunity Amount
1328 print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>';
1329 if (strcmp($object->opp_amount, '')) {
1330 print '<span class="amount">'.price($object->opp_amount, 0, $langs, 1, 0, -1, $conf->currency).'</span>';
1331 if (strcmp($object->opp_percent, '')) {
1332 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>';
1333 }
1334 }
1335 print '</td></tr>';
1336 }
1337
1338 // Budget
1339 print '<tr><td>'.$langs->trans("Budget").'</td><td>';
1340 if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
1341 print '<span class="amount">'.price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
1342 }
1343 print '</td></tr>';
1344
1345 // Date start - end project
1346 print '<tr><td>'.$langs->trans("Dates").'</td><td>';
1347 $start = dol_print_date($object->date_start, 'day');
1348 print ($start ? $start : '?');
1349 $end = dol_print_date($object->date_end, 'day');
1350 print ' <span class="opacitymedium">-</span> ';
1351 print ($end ? $end : '?');
1352 if ($object->hasDelay()) {
1353 print img_warning("Late");
1354 }
1355 print '</td></tr>';
1356
1357 // Other attributes
1358 $cols = 2;
1359 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1360
1361 print '</table>';
1362
1363 print '</div>';
1364 print '<div class="fichehalfright">';
1365 print '<div class="underbanner clearboth"></div>';
1366
1367 print '<table class="border tableforfield centpercent">';
1368
1369 // Description
1370 print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
1371 print dol_htmlentitiesbr($object->description);
1372 print '</td></tr>';
1373
1374 // Categories
1375 if (isModEnabled('categorie')) {
1376 print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
1377 print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
1378 print "</td></tr>";
1379 }
1380
1381 print '</table>';
1382
1383 print '</div>';
1384 print '</div>';
1385
1386 print '<div class="clearboth"></div>';
1387 }
1388
1389 print dol_get_fiche_end();
1390
1391 if ($action == 'edit' && $userWrite > 0) {
1392 print $form->buttonsSaveCancel();
1393 }
1394
1395 print '</form>';
1396
1397 // Set also dependencies between use taks and bill time
1398 print '<script type="text/javascript">
1399 jQuery(document).ready(function() {
1400 jQuery("#usage_task").change(function() {
1401 console.log("We click on usage task "+jQuery("#usage_task").is(":checked"));
1402 if (! jQuery("#usage_task").is(":checked")) {
1403 jQuery("#usage_bill_time").prop("checked", false);
1404 }
1405 });
1406
1407 jQuery("#usage_bill_time").change(function() {
1408 console.log("We click on usage to bill time");
1409 if (jQuery("#usage_bill_time").is(":checked")) {
1410 jQuery("#usage_task").prop("checked", true);
1411 }
1412 });
1413
1414 jQuery("#projectstart").change(function() {
1415 console.log("We modify the start date");
1416 jQuery("#divreportdate").show();
1417 });
1418 });
1419 </script>';
1420
1421 // Change probability from status
1422 if (!empty($conf->use_javascript_ajax) && !empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
1423 // Default value to close or not when we set opp to 'WON'.
1424 $defaultcheckedwhenoppclose = 1;
1425 if (empty($conf->global->PROJECT_HIDE_TASKS)) {
1426 $defaultcheckedwhenoppclose = 0;
1427 }
1428
1429 print '<!-- Javascript to manage opportunity status change -->';
1430 print '<script type="text/javascript">
1431 jQuery(document).ready(function() {
1432 function change_percent()
1433 {
1434 var element = jQuery("#opp_status option:selected");
1435 var defaultpercent = element.attr("defaultpercent");
1436 var defaultcloseproject = '.((int) $defaultcheckedwhenoppclose).';
1437 var elemcode = element.attr("elemcode");
1438 var oldpercent = \''.dol_escape_js($object->opp_percent).'\';
1439
1440 console.log("We select "+elemcode);
1441
1442 /* Define if checkbox to close is checked or not */
1443 var closeproject = 0;
1444 if (elemcode == \'LOST\') closeproject = 1;
1445 if (elemcode == \'WON\') closeproject = defaultcloseproject;
1446 if (closeproject) jQuery("#inputcloseproject").prop("checked", true);
1447 else jQuery("#inputcloseproject").prop("checked", false);
1448
1449 /* Make the close project checkbox visible or not */
1450 console.log("closeproject="+closeproject);
1451 if (elemcode == \'WON\' || elemcode == \'LOST\')
1452 {
1453 jQuery("#divtocloseproject").show();
1454 }
1455 else
1456 {
1457 jQuery("#divtocloseproject").hide();
1458 }
1459
1460 /* Change percent with default percent (defaultpercent) if new status (defaultpercent) is higher than current (jQuery("#opp_percent").val()) */
1461 if (oldpercent != \'\' && (parseFloat(defaultpercent) < parseFloat(oldpercent)))
1462 {
1463 console.log("oldpercent="+oldpercent+" defaultpercent="+defaultpercent+" def < old");
1464 if (jQuery("#opp_percent").val() != \'\' && oldpercent != \'\') {
1465 jQuery("#oldopppercent").text(\' - '.dol_escape_js($langs->transnoentities("PreviousValue")).': \'+price2numjs(oldpercent)+\' %\');
1466 }
1467
1468 if (parseFloat(oldpercent) != 100 && elemcode != \'LOST\') { jQuery("#opp_percent").val(oldpercent); }
1469 else { jQuery("#opp_percent").val(price2numjs(defaultpercent)); }
1470 } else {
1471 console.log("oldpercent="+oldpercent+" defaultpercent="+defaultpercent);
1472 if (jQuery("#opp_percent").val() == \'\' || (parseFloat(jQuery("#opp_percent").val()) < parseFloat(defaultpercent))) {
1473 if (jQuery("#opp_percent").val() != \'\' && oldpercent != \'\') {
1474 jQuery("#oldopppercent").text(\' - '.dol_escape_js($langs->transnoentities("PreviousValue")).': \'+price2numjs(oldpercent)+\' %\');
1475 }
1476 jQuery("#opp_percent").val(price2numjs(defaultpercent));
1477 }
1478 }
1479 }
1480
1481 jQuery("#opp_status").change(function() {
1482 change_percent();
1483 });
1484 });
1485 </script>';
1486 }
1487
1488
1489 /*
1490 * Actions Buttons
1491 */
1492
1493 print '<div class="tabsAction">';
1494 $parameters = array();
1495 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
1496 // modified by hook
1497 if (empty($reshook)) {
1498 if ($action != "edit" && $action != 'presend') {
1499 // Create event
1500 /*if (isModEnabled('agenda') && !empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a
1501 // "workflow" action so should appears somewhere else on
1502 // page.
1503 {
1504 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>';
1505 }*/
1506
1507 // Send
1508 if (empty($user->socid)) {
1509 if ($object->statut != Project::STATUS_CLOSED) {
1510 print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?action=presend&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', '');
1511 }
1512 }
1513
1514 // Accounting Report
1515 /*
1516 $accouting_module_activated = isModEnabled('comptabilite') || isModEnabled('accounting');
1517 if ($accouting_module_activated && $object->statut != Project::STATUS_DRAFT) {
1518 $start = dol_getdate((int) $object->date_start);
1519 $end = dol_getdate((int) $object->date_end);
1520 $url = DOL_URL_ROOT.'/compta/accounting-files.php?projectid='.$object->id;
1521 if (!empty($object->date_start)) $url .= '&amp;date_startday='.$start['mday'].'&amp;date_startmonth='.$start['mon'].'&amp;date_startyear='.$start['year'];
1522 if (!empty($object->date_end)) $url .= '&amp;date_stopday='.$end['mday'].'&amp;date_stopmonth='.$end['mon'].'&amp;date_stopyear='.$end['year'];
1523 print dolGetButtonAction('', $langs->trans('ExportAccountingReportButtonLabel'), 'default', $url, '');
1524 }
1525 */
1526
1527 // Back to draft
1528 if (!getDolGlobalString('MAIN_DISABLEDRAFTSTATUS') && !getDolGlobalString('MAIN_DISABLEDRAFTSTATUS_PROJECT')) {
1529 if ($object->statut != Project::STATUS_DRAFT && $user->hasRight('projet', 'creer')) {
1530 if ($userWrite > 0) {
1531 print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?action=confirm_setdraft&amp;confirm=yes&amp;token='.newToken().'&amp;id='.$object->id, '');
1532 } else {
1533 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('SetToDraft'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1534 }
1535 }
1536 }
1537
1538 // Modify
1539 if ($object->statut != Project::STATUS_CLOSED && $user->hasRight('projet', 'creer')) {
1540 if ($userWrite > 0) {
1541 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$object->id, '');
1542 } else {
1543 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Modify'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1544 }
1545 }
1546
1547 // Validate
1548 if ($object->statut == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer')) {
1549 if ($userWrite > 0) {
1550 print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=validate&amp;token='.newToken().'&amp;id='.$object->id, '');
1551 } else {
1552 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Validate'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1553 }
1554 }
1555
1556 // Close
1557 if ($object->statut == Project::STATUS_VALIDATED && $user->rights->projet->creer) {
1558 if ($userWrite > 0) {
1559 print dolGetButtonAction('', $langs->trans('Close'), 'default', $_SERVER["PHP_SELF"].'?action=close&amp;token='.newToken().'&amp;id='.$object->id, '');
1560 } else {
1561 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Close'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1562 }
1563 }
1564
1565 // Reopen
1566 if ($object->statut == Project::STATUS_CLOSED && $user->rights->projet->creer) {
1567 if ($userWrite > 0) {
1568 print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&amp;token='.newToken().'&amp;id='.$object->id, '');
1569 } else {
1570 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('ReOpen'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1571 }
1572 }
1573
1574 // Buttons Create
1575 if (empty($conf->global->PROJECT_HIDE_CREATE_OBJECT_BUTTON)) {
1576 $arrayforbutaction = array(
1577 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),
1578 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),
1579 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),
1580 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),
1581 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),
1582 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),
1583 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),
1584 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),
1585 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),
1586 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),
1587 );
1588
1589 $params = array('backtopage' => $_SERVER["PHP_SELF"].'?id='.$object->id);
1590
1591 print dolGetButtonAction($langs->trans("Create"), '', 'default', $arrayforbutaction, '', 1, $params);
1592 }
1593
1594 // Clone
1595 if ($user->hasRight('projet', 'creer')) {
1596 if ($userWrite > 0) {
1597 print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER["PHP_SELF"].'?action=clone&amp;token='.newToken().'&amp;id='.$object->id, '');
1598 } else {
1599 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('ToClone'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1600 }
1601 }
1602
1603 // Delete
1604 if ($user->hasRight('projet', 'supprimer') || ($object->statut == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer'))) {
1605 if ($userDelete > 0 || ($object->statut == Project::STATUS_DRAFT && $user->hasRight('projet', 'creer'))) {
1606 print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, '');
1607 } else {
1608 print dolGetButtonAction($langs->trans('NotOwnerOfProject'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1609 }
1610 }
1611 }
1612 }
1613
1614 print "</div>";
1615
1616 if (GETPOST('modelselected')) {
1617 $action = 'presend';
1618 }
1619
1620 if ($action != 'presend') {
1621 print '<div class="fichecenter"><div class="fichehalfleft">';
1622 print '<a name="builddoc"></a>'; // ancre
1623
1624 /*
1625 * Generated documents
1626 */
1627 $filename = dol_sanitizeFileName($object->ref);
1628 $filedir = $conf->project->multidir_output[$object->entity]."/".dol_sanitizeFileName($object->ref);
1629 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
1630 $genallowed = ($user->hasRight('projet', 'lire') && $userAccess > 0);
1631 $delallowed = ($user->hasRight('projet', 'creer') && $userWrite > 0);
1632
1633 print $formfile->showdocuments('project', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', '', '', $object);
1634
1635 print '</div><div class="fichehalfright">';
1636
1637 $MAXEVENT = 10;
1638
1639 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/projet/messaging.php?id='.$object->id);
1640
1641 // List of actions on element
1642 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1643 $formactions = new FormActions($db);
1644 $somethingshown = $formactions->showactions($object, 'project', 0, 1, '', $MAXEVENT, '', $morehtmlcenter);
1645
1646 print '</div></div>';
1647 }
1648
1649 // Presend form
1650 $modelmail = 'project';
1651 $defaulttopic = 'SendProjectRef';
1652 $defaulttopiclang = 'projects';
1653 $diroutput = $conf->project->multidir_output[$object->entity];
1654 $autocopy = 'MAIN_MAIL_AUTOCOPY_PROJECT_TO'; // used to know the automatic BCC to add
1655 $trackid = 'proj'.$object->id;
1656
1657 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1658
1659 // Hook to add more things on page
1660 $parameters = array();
1661 $reshook = $hookmanager->executeHooks('mainCardTabAddMore', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1662} else {
1663 print $langs->trans("RecordNotFound");
1664}
1665
1666// End of page
1667llxFooter();
1668$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...
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.
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.
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.