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
27 require '../main.inc.php';
28 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
37 
38 // Load translation files required by the page
39 $langsLoad=array('projects', 'companies');
40 if (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;
56 if (!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.
84 if ($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.
101 restrictedArea($user, 'projet', $object->id, 'projet&project');
102 
103 if ($id == '' && $ref == '' && ($action != "create" && $action != "add" && $action != "update" && !GETPOST("cancel"))) {
104  accessforbidden();
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
118 if ($reshook < 0) {
119  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
120 }
121 
122 if (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) {
199  $status = Project::STATUS_VALIDATED;
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 : '');
529 if (!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 
535 llxHeader("", $title, $help_url);
536 
537 $titleboth = $langs->trans("LeadsOrProjects");
538 $titlenew = $langs->trans("NewLeadOrProject"); // Leads and opportunities by default
539 if (!getDolGlobalInt('PROJECT_USE_OPPORTUNITIES')) {
540  $titleboth = $langs->trans("Projects");
541  $titlenew = $langs->trans("NewProject");
542 }
543 if (getDolGlobalInt('PROJECT_USE_OPPORTUNITIES') == 2) { // 2 = leads only
544  $titleboth = $langs->trans("Leads");
545  $titlenew = $langs->trans("NewLead");
546 }
547 
548 if ($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
1667 llxFooter();
1668 $db->close();
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:118
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:449
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.
Definition: task.class.php:40
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:48
$parameters
Actions.
Definition: card.php:83
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
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.
Definition: files.lib.php:1356
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).
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
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.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
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.
isModEnabled($module)
Is Dolibarr module enabled.
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.
Definition: project.lib.php:39
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.