1<?php 2/* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> 3 * Copyright (C) 2006-2015 Laurent Destailleur <eldy@users.sourceforge.net> 4 * Copyright (C) 2010-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 20/** 21 * \file htdocs/projet/tasks/contact.php 22 * \ingroup project 23 * \brief Actors of a task 24 */ 25 26require "../../main.inc.php"; 27require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; 28require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; 29require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; 30require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; 31require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; 32 33// Load translation files required by the page 34$langs->loadLangs(array('projects', 'companies')); 35 36$id = GETPOST('id', 'int'); 37$ref = GETPOST('ref', 'alpha'); 38$action = GETPOST('action', 'aZ09'); 39$confirm = GETPOST('confirm', 'alpha'); 40$withproject = GETPOST('withproject', 'int'); 41$project_ref = GETPOST('project_ref', 'alpha'); 42 43$object = new Task($db); 44$projectstatic = new Project($db); 45 46if ($id > 0 || $ref) { 47 $object->fetch($id, $ref); 48} 49 50// Security check 51$socid = 0; 52 53restrictedArea($user, 'projet', $object->fk_project, 'projet&project'); 54 55 56/* 57 * Actions 58 */ 59 60// Add new contact 61if ($action == 'addcontact' && $user->rights->projet->creer) { 62 $source = 'internal'; 63 if (GETPOST("addsourceexternal")) { 64 $source ='external'; 65 } 66 67 $result = $object->fetch($id, $ref); 68 69 if ($result > 0 && $id > 0) { 70 if ($source == 'internal') { 71 $idfortaskuser = ((GETPOST("userid") != 0 && GETPOST('userid') != -1) ? GETPOST("userid") : 0); // GETPOST('contactid') may val -1 to mean empty or -2 to means "everybody" 72 $typeid = GETPOST('type'); 73 } else { 74 $idfortaskuser = ((GETPOST("contactid") > 0) ? GETPOST("contactid", 'int') : 0); // GETPOST('contactid') may val -1 to mean empty or -2 to means "everybody" 75 $typeid = GETPOST('typecontact'); 76 } 77 if ($idfortaskuser == -2) { 78 $result = $projectstatic->fetch($object->fk_project); 79 if ($result <= 0) { 80 dol_print_error($db, $projectstatic->error, $projectstatic->errors); 81 } else { 82 $contactsofproject = $projectstatic->getListContactId('internal'); 83 foreach ($contactsofproject as $key => $val) { 84 $result = $object->add_contact($val, $typeid, $source); 85 } 86 } 87 } else { 88 $result = $object->add_contact($idfortaskuser, $typeid, $source); 89 } 90 } 91 92 if ($result >= 0) { 93 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id.($withproject ? '&withproject=1' : '')); 94 exit; 95 } else { 96 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { 97 $langs->load("errors"); 98 setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors'); 99 } else { 100 setEventMessages($object->error, $object->errors, 'errors'); 101 } 102 } 103} 104 105// bascule du statut d'un contact 106if ($action == 'swapstatut' && $user->rights->projet->creer) { 107 if ($object->fetch($id, $ref)) { 108 $result = $object->swapContactStatus(GETPOST('ligne', 'int')); 109 } else { 110 dol_print_error($db); 111 } 112} 113 114// Efface un contact 115if ($action == 'deleteline' && $user->rights->projet->creer) { 116 $object->fetch($id, $ref); 117 $result = $object->delete_contact(GETPOST("lineid", 'int')); 118 119 if ($result >= 0) { 120 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id.($withproject ? '&withproject=1' : '')); 121 exit; 122 } else { 123 dol_print_error($db); 124 } 125} 126 127// Retrieve First Task ID of Project if withprojet is on to allow project prev next to work 128if (!empty($project_ref) && !empty($withproject)) { 129 if ($projectstatic->fetch(0, $project_ref) > 0) { 130 $tasksarray = $object->getTasksArray(0, 0, $projectstatic->id, $socid, 0); 131 if (count($tasksarray) > 0) { 132 $id = $tasksarray[0]->id; 133 } else { 134 header("Location: ".DOL_URL_ROOT.'/projet/tasks.php?id='.$projectstatic->id.($withproject ? '&withproject=1' : '').(empty($mode) ? '' : '&mode='.$mode)); 135 exit; 136 } 137 } 138} 139 140/* 141 * View 142 */ 143 144llxHeader('', $langs->trans("Task")); 145 146$form = new Form($db); 147$formcompany = new FormCompany($db); 148$contactstatic = new Contact($db); 149$userstatic = new User($db); 150 151 152/* *************************************************************************** */ 153/* */ 154/* Mode vue et edition */ 155/* */ 156/* *************************************************************************** */ 157 158if ($id > 0 || !empty($ref)) { 159 if ($object->fetch($id, $ref) > 0) { 160 if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_TASK) && method_exists($object, 'fetchComments') && empty($object->comments)) { 161 $object->fetchComments(); 162 } 163 $id = $object->id; // So when doing a search from ref, id is also set correctly. 164 165 $result = $projectstatic->fetch($object->fk_project); 166 if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($projectstatic, 'fetchComments') && empty($projectstatic->comments)) { 167 $projectstatic->fetchComments(); 168 } 169 if (!empty($projectstatic->socid)) { 170 $projectstatic->fetch_thirdparty(); 171 } 172 173 $object->project = clone $projectstatic; 174 175 $userWrite = $projectstatic->restrictedProjectArea($user, 'write'); 176 177 if ($withproject) { 178 // Tabs for project 179 $tab = 'tasks'; 180 $head = project_prepare_head($projectstatic); 181 print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public ? 'projectpub' : 'project')); 182 183 $param = ($mode == 'mine' ? '&mode=mine' : ''); 184 185 // Project card 186 187 $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>'; 188 189 $morehtmlref = '<div class="refidno">'; 190 // Title 191 $morehtmlref .= $projectstatic->title; 192 // Thirdparty 193 if ($projectstatic->thirdparty->id > 0) { 194 $morehtmlref .= '<br>'.$langs->trans('ThirdParty').' : '.$projectstatic->thirdparty->getNomUrl(1, 'project'); 195 } 196 $morehtmlref .= '</div>'; 197 198 // Define a complementary filter for search of next/prev ref. 199 if (!$user->rights->projet->all->lire) { 200 $objectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 0); 201 $projectstatic->next_prev_filter = " rowid IN (".$db->sanitize(count($objectsListId) ?join(',', array_keys($objectsListId)) : '0').")"; 202 } 203 204 dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref); 205 206 print '<div class="fichecenter">'; 207 print '<div class="fichehalfleft">'; 208 print '<div class="underbanner clearboth"></div>'; 209 210 print '<table class="border tableforfield centpercent">'; 211 212 // Usage 213 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || !empty($conf->eventorganization->enabled)) { 214 print '<tr><td class="tdtop">'; 215 print $langs->trans("Usage"); 216 print '</td>'; 217 print '<td>'; 218 if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { 219 print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_opportunity ? ' checked="checked"' : '')).'"> '; 220 $htmltext = $langs->trans("ProjectFollowOpportunity"); 221 print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext); 222 print '<br>'; 223 } 224 if (empty($conf->global->PROJECT_HIDE_TASKS)) { 225 print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_task ? ' checked="checked"' : '')).'"> '; 226 $htmltext = $langs->trans("ProjectFollowTasks"); 227 print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext); 228 print '<br>'; 229 } 230 if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) { 231 print '<input type="checkbox" disabled name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_bill_time ? ' checked="checked"' : '')).'"> '; 232 $htmltext = $langs->trans("ProjectBillTimeDescription"); 233 print $form->textwithpicto($langs->trans("BillTime"), $htmltext); 234 print '<br>'; 235 } 236 if (!empty($conf->eventorganization->enabled)) { 237 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"' : '')).'"> '; 238 $htmltext = $langs->trans("EventOrganizationDescriptionLong"); 239 print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext); 240 } 241 print '</td></tr>'; 242 } 243 244 // Visibility 245 print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>'; 246 if ($projectstatic->public) { 247 print $langs->trans('SharedProject'); 248 } else { 249 print $langs->trans('PrivateProject'); 250 } 251 print '</td></tr>'; 252 253 // Date start - end 254 print '<tr><td>'.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").'</td><td>'; 255 $start = dol_print_date($projectstatic->date_start, 'day'); 256 print ($start ? $start : '?'); 257 $end = dol_print_date($projectstatic->date_end, 'day'); 258 print ' - '; 259 print ($end ? $end : '?'); 260 if ($projectstatic->hasDelay()) { 261 print img_warning("Late"); 262 } 263 print '</td></tr>'; 264 265 // Budget 266 print '<tr><td>'.$langs->trans("Budget").'</td><td>'; 267 if (strcmp($projectstatic->budget_amount, '')) { 268 print price($projectstatic->budget_amount, '', $langs, 1, 0, 0, $conf->currency); 269 } 270 print '</td></tr>'; 271 272 // Other attributes 273 $cols = 2; 274 //include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; 275 276 print '</table>'; 277 278 print '</div>'; 279 print '<div class="fichehalfright">'; 280 print '<div class="ficheaddleft">'; 281 print '<div class="underbanner clearboth"></div>'; 282 283 print '<table class="border tableforfield" width="100%">'; 284 285 // Description 286 print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>'; 287 print nl2br($projectstatic->description); 288 print '</td></tr>'; 289 290 // Categories 291 if ($conf->categorie->enabled) { 292 print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>'; 293 print $form->showCategories($projectstatic->id, 'project', 1); 294 print "</td></tr>"; 295 } 296 297 print '</table>'; 298 299 print '</div>'; 300 print '</div>'; 301 print '</div>'; 302 303 print '<div class="clearboth"></div>'; 304 305 print dol_get_fiche_end(); 306 307 print '<br>'; 308 } 309 310 311 // To verify role of users 312 //$userAccess = $projectstatic->restrictedProjectArea($user); // We allow task affected to user even if a not allowed project 313 //$arrayofuseridoftask=$object->getListContactId('internal'); 314 315 $head = task_prepare_head($object); 316 print dol_get_fiche_head($head, 'task_contact', $langs->trans("Task"), -1, 'projecttask', 0, '', 'reposition'); 317 318 319 $param = (GETPOST('withproject') ? '&withproject=1' : ''); 320 $linkback = GETPOST('withproject') ? '<a href="'.DOL_URL_ROOT.'/projet/tasks.php?id='.$projectstatic->id.'">'.$langs->trans("BackToList").'</a>' : ''; 321 322 if (!GETPOST('withproject') || empty($projectstatic->id)) { 323 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1); 324 $object->next_prev_filter = " fk_projet IN (".$db->sanitize($projectsListId).")"; 325 } else { 326 $object->next_prev_filter = " fk_projet = ".$projectstatic->id; 327 } 328 329 $morehtmlref = ''; 330 331 // Project 332 if (empty($withproject)) { 333 $result = $projectstatic->fetch($object->fk_project); 334 $morehtmlref .= '<div class="refidno">'; 335 $morehtmlref .= $langs->trans("Project").': '; 336 $morehtmlref .= $projectstatic->getNomUrl(1); 337 $morehtmlref .= '<br>'; 338 339 // Third party 340 $morehtmlref .= $langs->trans("ThirdParty").': '; 341 if ($projectstatic->socid > 0) { 342 $projectstatic->fetch_thirdparty(); 343 $morehtmlref .= $projectstatic->thirdparty->getNomUrl(1); 344 } 345 346 $morehtmlref .= '</div>'; 347 } 348 349 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param, 0, '', '', 1); 350 351 print dol_get_fiche_end(); 352 353 /* 354 * Lines of contacts 355 */ 356 /* 357 // Contacts lines (modules that overwrite templates must declare this into descriptor) 358 $dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl')); 359 foreach($dirtpls as $reldir) 360 { 361 $res=@include dol_buildpath($reldir.'/contacts.tpl.php'); 362 if ($res) break; 363 } 364 */ 365 366 /* 367 * Add a new contact line 368 */ 369 print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$id.'" method="POST">'; 370 print '<input type="hidden" name="token" value="'.newToken().'">'; 371 print '<input type="hidden" name="action" value="addcontact">'; 372 print '<input type="hidden" name="id" value="'.$id.'">'; 373 if ($withproject) { 374 print '<input type="hidden" name="withproject" value="'.$withproject.'">'; 375 } 376 377 print '<table class="noborder centpercent">'; 378 379 if ($action != 'editline' && $user->rights->projet->creer) { 380 print '<tr class="liste_titre">'; 381 print '<td>'.$langs->trans("NatureOfContact").'</td>'; 382 print '<td>'.$langs->trans("ThirdParty").'</td>'; 383 print '<td>'.$langs->trans("Users").'</td>'; 384 print '<td>'.$langs->trans("ContactType").'</td>'; 385 print '<td colspan="3"> </td>'; 386 print "</tr>\n"; 387 388 // Ligne ajout pour contact interne 389 print '<tr class="oddeven nohover">'; 390 391 print '<td class="nowrap">'; 392 print img_object('', 'user').' '.$langs->trans("Users"); 393 print '</td>'; 394 395 print '<td>'; 396 print $conf->global->MAIN_INFO_SOCIETE_NOM; 397 print '</td>'; 398 399 print '<td>'; 400 // On recupere les id des users deja selectionnes 401 if ($object->project->public) { 402 $contactsofproject = ''; // Everybody 403 } else { 404 $contactsofproject = $projectstatic->getListContactId('internal'); 405 } 406 print $form->select_dolusers((GETPOSTISSET('userid') ? GETPOST('userid', 'int') : $user->id), 'userid', 0, '', 0, '', $contactsofproject, 0, 0, 0, '', 1, $langs->trans("ResourceNotAssignedToProject")); 407 print '</td>'; 408 print '<td>'; 409 $formcompany->selectTypeContact($object, '', 'type', 'internal', 'rowid'); 410 print '</td>'; 411 print '<td class="right" colspan="3" ><input type="submit" class="button" value="'.$langs->trans("Add").'" name="addsourceinternal"></td>'; 412 print '</tr>'; 413 414 // Line to add an external contact. Only if project linked to a third party. 415 if ($projectstatic->socid) { 416 print '<tr class="oddeven">'; 417 418 print '<td class="nowrap">'; 419 print img_object('', 'contact').' '.$langs->trans("ThirdPartyContacts"); 420 print '</td>'; 421 422 print '<td>'; 423 $thirdpartyofproject = $projectstatic->getListContactId('thirdparty'); 424 $selectedCompany = isset($_GET["newcompany"]) ? $_GET["newcompany"] : $projectstatic->socid; 425 $selectedCompany = $formcompany->selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', $thirdpartyofproject, 0, '&withproject='.$withproject); 426 print '</td>'; 427 428 print '<td>'; 429 $contactofproject = $projectstatic->getListContactId('external'); 430 print $form->selectcontacts($selectedCompany, '', 'contactid', 0, '', $contactofproject, 0, '', false, 0, 0); 431 $nbofcontacts = $form->num; 432 print '</td>'; 433 print '<td>'; 434 $formcompany->selectTypeContact($object, '', 'typecontact', 'external', 'rowid'); 435 print '</td>'; 436 print '<td class="right" colspan="3" ><input type="submit" class="button" id="add-customer-contact" name="addsourceexternal" value="'.$langs->trans("Add").'"'; 437 if (!$nbofcontacts) { 438 print ' disabled'; 439 } 440 print '></td>'; 441 print '</tr>'; 442 } 443 } 444 445 // List of contact line 446 print '<tr class="liste_titre">'; 447 print '<td>'.$langs->trans("Source").'</td>'; 448 print '<td>'.$langs->trans("ThirdParty").'</td>'; 449 print '<td>'.$langs->trans("TaskContact").'</td>'; 450 print '<td>'.$langs->trans("ContactType").'</td>'; 451 print '<td class="center">'.$langs->trans("Status").'</td>'; 452 print '<td colspan="2"> </td>'; 453 print "</tr>\n"; 454 455 $companystatic = new Societe($db); 456 457 foreach (array('internal', 'external') as $source) { 458 $tab = $object->liste_contact(-1, $source); 459 460 $num = count($tab); 461 462 $i = 0; 463 while ($i < $num) { 464 print '<tr class="oddeven" valign="top">'; 465 466 // Source 467 print '<td class="left">'; 468 if ($tab[$i]['source'] == 'internal') { 469 print $langs->trans("User"); 470 } 471 if ($tab[$i]['source'] == 'external') { 472 print $langs->trans("ThirdPartyContact"); 473 } 474 print '</td>'; 475 476 // Societe 477 print '<td class="left">'; 478 if ($tab[$i]['socid'] > 0) { 479 $companystatic->fetch($tab[$i]['socid']); 480 print $companystatic->getNomUrl(1); 481 } 482 if ($tab[$i]['socid'] < 0) { 483 print $conf->global->MAIN_INFO_SOCIETE_NOM; 484 } 485 if (!$tab[$i]['socid']) { 486 print ' '; 487 } 488 print '</td>'; 489 490 // Contact 491 print '<td>'; 492 if ($tab[$i]['source'] == 'internal') { 493 $userstatic->id = $tab[$i]['id']; 494 $userstatic->lastname = $tab[$i]['lastname']; 495 $userstatic->firstname = $tab[$i]['firstname']; 496 $userstatic->photo = $tab[$i]['photo']; 497 $userstatic->login = $tab[$i]['login']; 498 $userstatic->email = $tab[$i]['email']; 499 $userstatic->statut = $tab[$i]['statuscontact']; 500 501 print $userstatic->getNomUrl(-1); 502 } 503 if ($tab[$i]['source'] == 'external') { 504 $contactstatic->id = $tab[$i]['id']; 505 $contactstatic->lastname = $tab[$i]['lastname']; 506 $contactstatic->firstname = $tab[$i]['firstname']; 507 $contactstatic->email = $tab[$i]['email']; 508 $contactstatic->statut = $tab[$i]['statuscontact']; 509 print $contactstatic->getNomUrl(1); 510 } 511 print '</td>'; 512 513 // Type de contact 514 print '<td>'.$tab[$i]['libelle'].'</td>'; 515 516 // Statut 517 print '<td class="center">'; 518 // Activation desativation du contact 519 if ($object->statut >= 0) { 520 print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=swapstatut&ligne='.$tab[$i]['rowid'].($withproject ? '&withproject=1' : '').'">'; 521 } 522 print $contactstatic->LibStatut($tab[$i]['status'], 3); 523 if ($object->statut >= 0) { 524 print '</a>'; 525 } 526 print '</td>'; 527 528 // Icon update et delete 529 print '<td class="center nowrap">'; 530 if ($user->rights->projet->creer) { 531 print ' '; 532 print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deleteline&token='.newToken().'&lineid='.$tab[$i]['rowid'].($withproject ? '&withproject=1' : '').'">'; 533 print img_picto($langs->trans('Unlink'), 'unlink'); 534 print '</a>'; 535 } 536 print '</td>'; 537 538 print "</tr>\n"; 539 540 $i++; 541 } 542 } 543 print "</table>"; 544 545 print "</form>"; 546 } else { 547 print "ErrorRecordNotFound"; 548 } 549} 550 551if (is_object($hookmanager)) { 552 $hookmanager->initHooks(array('contacttpl')); 553 $parameters = array(); 554 $reshook = $hookmanager->executeHooks('formContactTpl', $parameters, $object, $action); 555} 556 557// End of page 558llxFooter(); 559$db->close(); 560