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