dolibarr  x.y.z
contact.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2010 Regis Houssin <regis.houssin@inodbox.com>
3  * Copyright (C) 2012-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
25 // Load Dolibarr environment
26 require '../main.inc.php';
27 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
28 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
32 if (isModEnabled('categorie')) {
33  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
34 }
35 
36 // Load translation files required by the page
37 $langsLoad=array('projects', 'companies');
38 if (isModEnabled('eventorganization')) {
39  $langsLoad[]='eventorganization';
40 }
41 
42 $langs->loadLangs($langsLoad);
43 
44 $id = GETPOST('id', 'int');
45 $ref = GETPOST('ref', 'alpha');
46 $lineid = GETPOST('lineid', 'int');
47 $socid = GETPOST('socid', 'int');
48 $action = GETPOST('action', 'aZ09');
49 
50 $mine = GETPOST('mode') == 'mine' ? 1 : 0;
51 //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects
52 
53 $object = new Project($db);
54 
55 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
56 if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($object, 'fetchComments') && empty($object->comments)) {
57  $object->fetchComments();
58 }
59 
60 // Security check
61 $socid = 0;
62 //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.
63 $result = restrictedArea($user, 'projet', $id, 'projet&project');
64 
65 $hookmanager->initHooks(array('projectcontactcard', 'globalcard'));
66 
67 
68 /*
69  * Actions
70  */
71 
72 // Test if we can add contact to the tasks at the same times, if not or not required, make a redirect
73 $formconfirmtoaddtasks = '';
74 if ($action == 'addcontact') {
75  $form = new Form($db);
76 
77  $source=GETPOST("source", 'aZ09');
78 
79  $taskstatic = new Task($db);
80  $task_array = $taskstatic->getTasksArray(0, 0, $object->id, 0, 0);
81  $nbTasks = count($task_array);
82 
83  //If no task avaiblable, redirec to to add confirm
84  $type_to = (GETPOST('typecontact') ? 'typecontact='.GETPOST('typecontact') : 'type='.GETPOST('type'));
85  $personToAffect = (GETPOST('userid') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int'));
86  $affect_to = (GETPOST('userid') ? 'userid='.$personToAffect : 'contactid='.$personToAffect);
87  $url_redirect='?id='.$object->id.'&'.$affect_to.'&'.$type_to.'&source='.$source;
88 
89  if ($personToAffect > 0 && (empty($conf->global->PROJECT_HIDE_TASKS) || $nbTasks > 0)) {
90  $text = $langs->trans('AddPersonToTask');
91  $textbody = $text.' (<a href="#" class="selectall">'.$langs->trans("SelectAll").'</a>)';
92  $formquestion = array('text' => $textbody);
93 
94  $task_to_affect = array();
95  foreach ($task_array as $task) {
96  $task_already_affected=false;
97  $personsLinked = $task->liste_contact(-1, $source);
98  if (!is_array($personsLinked) && count($personsLinked) < 0) {
99  setEventMessage($object->error, 'errors');
100  } else {
101  foreach ($personsLinked as $person) {
102  if ($person['id']==$personToAffect) {
103  $task_already_affected = true;
104  break;
105  }
106  }
107  if (!$task_already_affected) {
108  $task_to_affect[$task->id] = $task->id;
109  }
110  }
111  }
112 
113  if (empty($task_to_affect)) {
114  $action = 'addcontact_confirm';
115  } else {
116  $formcompany = new FormCompany($db);
117  foreach ($task_array as $task) {
118  $key = $task->id;
119  $val = $task->ref . ' '.dol_trunc($task->label);
120  $formquestion[] = array(
121  'type' => 'other',
122  'name' => 'person_'.$key.',person_role_'.$key,
123  'label' => '<input type="checkbox" class="flat'.(in_array($key, $task_to_affect) ? ' taskcheckboxes"' : '" checked disabled').' id="person_'.$key.'" name="person_'.$key.'" value="1"> <label for="person_'.$key.'">'.$val.'<label>',
124  'value' => $formcompany->selectTypeContact($taskstatic, '', 'person_role_'.$key, $source, 'position', 0, 'minwidth100imp', 0, 1)
125  );
126  }
127  $formquestion[] = array('type'=> 'other', 'name'=>'tasksavailable', 'label'=>'', 'value' => '<input type="hidden" id="tasksavailable" name="tasksavailable" value="'.implode(',', array_keys($task_to_affect)).'">');
128  }
129 
130  $formconfirmtoaddtasks = $form->formconfirm($_SERVER['PHP_SELF'] . $url_redirect, $text, '', 'addcontact_confirm', $formquestion, '', 1, 300, 590);
131  $formconfirmtoaddtasks .='
132  <script>
133  $(document).ready(function() {
134  var saveprop = false;
135  $(".selectall").click(function(){
136  console.log("We click on select all with "+saveprop);
137  if (!saveprop) {
138  $(".taskcheckboxes").prop("checked", true);
139  saveprop = true;
140  } else {
141  $(".taskcheckboxes").prop("checked", false);
142  saveprop = false;
143  }
144  });
145  });
146  </script>';
147  } else {
148  $action = 'addcontact_confirm';
149  }
150 }
151 
152 // Add new contact
153 if ($action == 'addcontact_confirm' && $user->rights->projet->creer) {
154  $contactid = (GETPOST('userid') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int'));
155  $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
156 
157  if (! ($contactid > 0)) {
158  $error++;
159  $langs->load("errors");
160  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Contact")), null, 'errors');
161  }
162 
163  $result = 0;
164  $result = $object->fetch($id);
165 
166  if (!$error && $result > 0 && $id > 0) {
167  $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09'));
168 
169  if ($result == 0) {
170  $langs->load("errors");
171  setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
172  } elseif ($result < 0) {
173  if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
174  $langs->load("errors");
175  setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
176  } else {
177  setEventMessages($object->error, $object->errors, 'errors');
178  }
179  }
180 
181  $affecttotask=GETPOST('tasksavailable', 'intcomma');
182  if (!empty($affecttotask)) {
183  require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
184  $task_to_affect = explode(',', $affecttotask);
185  if (!empty($task_to_affect)) {
186  foreach ($task_to_affect as $task_id) {
187  if (GETPOSTISSET('person_'.$task_id) && GETPOST('person_'.$task_id, 'san_alpha')) {
188  $tasksToAffect = new Task($db);
189  $result=$tasksToAffect->fetch($task_id);
190  if ($result < 0) {
191  setEventMessages($tasksToAffect->error, null, 'errors');
192  } else {
193  $result = $tasksToAffect->add_contact($contactid, GETPOST('person_role_'.$task_id), GETPOST("source", 'aZ09'));
194  if ($result < 0) {
195  if ($tasksToAffect->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
196  $langs->load("errors");
197  setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors');
198  } else {
199  setEventMessages($tasksToAffect->error, $tasksToAffect->errors, 'errors');
200  }
201  }
202  }
203  }
204  }
205  }
206  }
207  }
208 
209  if ($result >= 0) {
210  header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id);
211  exit;
212  }
213 }
214 
215 // Change contact's status
216 if ($action == 'swapstatut' && $user->rights->projet->creer) {
217  if ($object->fetch($id)) {
218  $result = $object->swapContactStatus(GETPOST('ligne', 'int'));
219  } else {
220  dol_print_error($db);
221  }
222 }
223 
224 // Delete a contact
225 if (($action == 'deleteline' || $action == 'deletecontact') && $user->rights->projet->creer) {
226  $object->fetch($id);
227  $result = $object->delete_contact(GETPOST("lineid", 'int'));
228 
229  if ($result >= 0) {
230  header("Location: contact.php?id=".$object->id);
231  exit;
232  } else {
233  dol_print_error($db);
234  }
235 }
236 
237 
238 
239 /*
240  * View
241  */
242 
243 $title = $langs->trans('ProjectContact').' - '.$object->ref.' '.$object->name;
244 if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) {
245  $title = $object->ref.' '.$object->name.' - '.$langs->trans('ProjectContact');
246 }
247 
248 $help_url = 'EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos|DE:Modul_Projekte';
249 
250 llxHeader('', $title, $help_url);
251 
252 $form = new Form($db);
253 $contactstatic = new Contact($db);
254 $userstatic = new User($db);
255 
256 
257 /* *************************************************************************** */
258 /* */
259 /* Edition and view mode */
260 /* */
261 /* *************************************************************************** */
262 
263 if ($id > 0 || !empty($ref)) {
264  if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($object, 'fetchComments') && empty($object->comments)) {
265  $object->fetchComments();
266  }
267  // To verify role of users
268  //$userAccess = $object->restrictedProjectArea($user,'read');
269  $userWrite = $object->restrictedProjectArea($user, 'write');
270  //$userDelete = $object->restrictedProjectArea($user,'delete');
271  //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
272 
273  $head = project_prepare_head($object);
274  print dol_get_fiche_head($head, 'contact', $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
275 
276  $formconfirm = $formconfirmtoaddtasks;
277 
278  // Call Hook formConfirm
279  $parameters = array('formConfirm' => $formconfirm);
280  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
281  if (empty($reshook)) {
282  $formconfirm .= $hookmanager->resPrint;
283  } elseif ($reshook > 0) {
284  $formconfirm = $hookmanager->resPrint;
285  }
286 
287  // Print form confirm
288  print $formconfirm;
289 
290  // Project card
291 
292  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
293 
294  $morehtmlref = '<div class="refidno">';
295  // Title
296  $morehtmlref .= $object->title;
297  // Thirdparty
298  if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
299  $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'project');
300  }
301  $morehtmlref .= '</div>';
302 
303  // Define a complementary filter for search of next/prev ref.
304  if (empty($user->rights->projet->all->lire)) {
305  $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
306  $object->next_prev_filter = " rowid IN (".$db->sanitize(count($objectsListId) ?join(',', array_keys($objectsListId)) : '0').")";
307  }
308 
309  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
310 
311 
312  print '<div class="fichecenter">';
313  print '<div class="fichehalfleft">';
314  print '<div class="underbanner clearboth"></div>';
315 
316  print '<table class="border tableforfield centpercent">';
317 
318  // Usage
319  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) {
320  print '<tr><td class="tdtop">';
321  print $langs->trans("Usage");
322  print '</td>';
323  print '<td>';
324  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
325  print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'"> ';
326  $htmltext = $langs->trans("ProjectFollowOpportunity");
327  print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
328  print '<br>';
329  }
330  if (empty($conf->global->PROJECT_HIDE_TASKS)) {
331  print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'"> ';
332  $htmltext = $langs->trans("ProjectFollowTasks");
333  print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
334  print '<br>';
335  }
336  if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
337  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"' : '')).'"> ';
338  $htmltext = $langs->trans("ProjectBillTimeDescription");
339  print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
340  print '<br>';
341  }
342  if (isModEnabled('eventorganization')) {
343  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"' : '')).'"> ';
344  $htmltext = $langs->trans("EventOrganizationDescriptionLong");
345  print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
346  }
347  print '</td></tr>';
348  }
349 
350  // Visibility
351  print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
352  if ($object->public) {
353  print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
354  print $langs->trans('SharedProject');
355  } else {
356  print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
357  print $langs->trans('PrivateProject');
358  }
359  print '</td></tr>';
360 
361  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) && $object->opp_status) {
362  // Opportunity status
363  print '<tr><td>'.$langs->trans("OpportunityStatus").'</td><td>';
364  $code = dol_getIdFromCode($db, $object->opp_status, 'c_lead_status', 'rowid', 'code');
365  if ($code) {
366  print $langs->trans("OppStatus".$code);
367  }
368  print '</td></tr>';
369 
370  // Opportunity percent
371  print '<tr><td>'.$langs->trans("OpportunityProbability").'</td><td>';
372  if (strcmp($object->opp_percent, '')) {
373  print price($object->opp_percent, '', $langs, 1, 0).' %';
374  }
375  print '</td></tr>';
376 
377  // Opportunity Amount
378  print '<tr><td>'.$langs->trans("OpportunityAmount").'</td><td>';
379  if (strcmp($object->opp_amount, '')) {
380  print '<span class="amount">'.price($object->opp_amount, '', $langs, 0, 0, 0, $conf->currency).'</span>';
381  if (strcmp($object->opp_percent, '')) {
382  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>';
383  }
384  }
385  print '</td></tr>';
386  }
387 
388  // Budget
389  print '<tr><td>'.$langs->trans("Budget").'</td><td>';
390  if (strcmp($object->budget_amount, '')) {
391  print '<span class="amount">'.price($object->budget_amount, '', $langs, 0, 0, 0, $conf->currency).'</span>';
392  }
393  print '</td></tr>';
394 
395  // Date start - end project
396  print '<tr><td>'.$langs->trans("Dates").'</td><td>';
397  $start = dol_print_date($object->date_start, 'day');
398  print ($start ? $start : '?');
399  $end = dol_print_date($object->date_end, 'day');
400  print ' - ';
401  print ($end ? $end : '?');
402  if ($object->hasDelay()) {
403  print img_warning("Late");
404  }
405  print '</td></tr>';
406 
407  // Other attributes
408  $cols = 2;
409  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
410 
411  print "</table>";
412 
413  print '</div>';
414  print '<div class="fichehalfright">';
415  print '<div class="underbanner clearboth"></div>';
416 
417  print '<table class="border tableforfield centpercent">';
418 
419  // Description
420  print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
421  print nl2br($object->description);
422  print '</td></tr>';
423 
424  // Categories
425  if (isModEnabled('categorie')) {
426  print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
427  print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
428  print "</td></tr>";
429  }
430 
431  print '</table>';
432 
433  print '</div>';
434  print '</div>';
435 
436  print '<div class="clearboth"></div>';
437 
438  print dol_get_fiche_end();
439 
440  print '<br>';
441 
442  // Contacts lines (modules that overwrite templates must declare this into descriptor)
443  $dirtpls = array_merge($conf->modules_parts['tpl'], array('/core/tpl'));
444  foreach ($dirtpls as $reldir) {
445  $res = @include dol_buildpath($reldir.'/contacts.tpl.php');
446  if ($res) {
447  break;
448  }
449  }
450 }
451 
452 // End of page
453 llxFooter();
454 $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(!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 contact/addresses.
Class to build HTML component for third parties management Only common components are here.
Class to manage generation of HTML components Only common components must be here.
Class to manage projects.
Class to manage tasks.
Definition: task.class.php:38
Class to manage Dolibarr users.
Definition: user.class.php:45
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
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_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
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).
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_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='')
Return an id or code from a code or id.
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
$formconfirm
if ($action == 'delbookkeepingyear') {
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.