[ Index ]

Source Code Reference for V1.00

title

Body

[close]

/modules/projects/ -> view.php (source)

   1  <?php /* $Id: view.php 156 2008-04-11 15:47:40Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/modules/projects/view.php $ */
   2  if (!defined('W2P_BASE_DIR')) {
   3      die('You should not access this file directly.');
   4  }
   5  
   6  $project_id = intval(w2PgetParam($_GET, 'project_id', 0));
   7  
   8  // check permissions for this record
   9  $perms = &$AppUI->acl();
  10  $canRead = $perms->checkModuleItem($m, 'view', $project_id);
  11  $canEdit = $perms->checkModuleItem($m, 'edit', $project_id);
  12  $canEditT = $perms->checkModule('tasks', 'add');
  13  
  14  if (!$canRead) {
  15      $AppUI->redirect('m=public&a=access_denied');
  16  }
  17  
  18  // retrieve any state parameters
  19  if (isset($_GET['tab'])) {
  20      $AppUI->setState('ProjVwTab', w2PgetParam($_GET, 'tab', null));
  21  }
  22  $tab = $AppUI->getState('ProjVwTab') !== null ? $AppUI->getState('ProjVwTab') : 0;
  23  
  24  // check if this record has dependencies to prevent deletion
  25  $msg = '';
  26  $obj = new CProject();
  27  // Now check if the proect is editable/viewable.
  28  $denied = $obj->getDeniedRecords($AppUI->user_id);
  29  if (in_array($project_id, $denied)) {
  30      $AppUI->redirect('m=public&a=access_denied');
  31  }
  32  
  33  $canDelete = $obj->canDelete($msg, $project_id);
  34  
  35  // get critical tasks (criteria: task_end_date)
  36  $criticalTasks = ($project_id > 0) ? $obj->getCriticalTasks($project_id) : null;
  37  
  38  // get ProjectPriority from sysvals
  39  $projectPriority = w2PgetSysVal('ProjectPriority');
  40  $projectPriorityColor = w2PgetSysVal('ProjectPriorityColor');
  41  
  42  $working_hours = ($w2Pconfig['daily_working_hours'] ? $w2Pconfig['daily_working_hours'] : 8);
  43  
  44  $q = new DBQuery;
  45  //check that project has tasks; otherwise run seperate query
  46  $q->addTable('tasks');
  47  $q->addQuery('COUNT(distinct tasks.task_id) AS total_tasks');
  48  $q->addWhere('task_project = ' . (int)$project_id);
  49  $hasTasks = $q->loadResult();
  50  $q->clear();
  51  
  52  // load the record data
  53  // GJB: Note that we have to special case duration type 24 and this refers to the hours in a day, NOT 24 hours
  54  $obj = null;
  55  if ($hasTasks) {
  56      $q->addTable('projects');
  57      $q->addQuery('company_name, CONCAT_WS(\' \',contact_first_name,contact_last_name) user_name, projects.*, SUM(t1.task_duration * t1.task_percent_complete * IF(t1.task_duration_type = 24, ' . $working_hours . ', t1.task_duration_type)) / SUM(t1.task_duration * IF(t1.task_duration_type = 24, ' . $working_hours . ', t1.task_duration_type)) AS project_percent_complete');
  58      $q->addJoin('companies', 'com', 'company_id = project_company', 'inner');
  59      $q->leftJoin('users', 'u', 'user_id = project_owner');
  60      $q->leftJoin('contacts', 'con', 'contact_id = user_contact');
  61      $q->addJoin('tasks', 't1', 'projects.project_id = t1.task_project', 'inner');
  62      $q->addWhere('project_id = ' . (int)$project_id . ' AND t1.task_id = t1.task_parent');
  63      $q->addGroup('project_id');
  64      $q->loadObject($obj);
  65  } else {
  66      $q->addTable('projects');
  67      $q->addQuery('company_name, CONCAT_WS(\' \',contact_first_name,contact_last_name) user_name, projects.*, (0.0) AS project_percent_complete');
  68      $q->addJoin('companies', 'com', 'company_id = project_company', 'inner');
  69      $q->leftJoin('users', 'u', 'user_id = project_owner');
  70      $q->leftJoin('contacts', 'con', 'contact_id = user_contact');
  71      $q->addWhere('project_id = ' . (int)$project_id);
  72      $q->addGroup('project_id');
  73      $q->loadObject($obj);
  74  }
  75  $q->clear();
  76  
  77  if (!$obj) {
  78      $AppUI->setMsg('Project');
  79      $AppUI->setMsg('invalidID', UI_MSG_ERROR, true);
  80      $AppUI->redirect();
  81  } else {
  82      $AppUI->savePlace();
  83  }
  84  
  85  // worked hours
  86  // now milestones are summed up, too, for consistence with the tasks duration sum
  87  // the sums have to be rounded to prevent the sum form having many (unwanted) decimals because of the mysql floating point issue
  88  // more info on http://www.mysql.com/doc/en/Problems_with_float.html
  89  if ($hasTasks) {
  90      $q->addTable('task_log');
  91      $q->addTable('tasks');
  92      $q->addQuery('ROUND(SUM(task_log_hours),2)');
  93      $q->addWhere('task_log_task = task_id AND task_project = ' . (int)$project_id);
  94      $worked_hours = $q->loadResult();
  95      $q->clear();
  96      $worked_hours = rtrim($worked_hours, '.');
  97  
  98      // total hours
  99      // same milestone comment as above, also applies to dynamic tasks
 100      $q->addTable('tasks');
 101      $q->addQuery('ROUND(SUM(task_duration),2)');
 102      $q->addWhere('task_project = ' . (int)$project_id . ' AND task_duration_type = 24 AND task_dynamic <> 1');
 103      $days = $q->loadResult();
 104      $q->clear();
 105  
 106      $q->addTable('tasks');
 107      $q->addQuery('ROUND(SUM(task_duration),2)');
 108      $q->addWhere('task_project = ' . (int)$project_id . ' AND task_duration_type = 1 AND task_dynamic <> 1');
 109      $hours = $q->loadResult();
 110      $q->clear();
 111      $total_hours = $days * $w2Pconfig['daily_working_hours'] + $hours;
 112  
 113      $total_project_hours = 0;
 114  
 115      $q->addTable('tasks', 't');
 116      $q->addQuery('ROUND(SUM(t.task_duration*u.perc_assignment/100),2)');
 117      $q->addJoin('user_tasks', 'u', 't.task_id = u.task_id', 'inner');
 118      $q->addWhere('t.task_project = ' . (int)$project_id . ' AND t.task_duration_type = 24 AND t.task_dynamic <> 1');
 119      $total_project_days = $q->loadResult();
 120      $q->clear();
 121  
 122      $q->addTable('tasks', 't');
 123      $q->addQuery('ROUND(SUM(t.task_duration*u.perc_assignment/100),2)');
 124      $q->addJoin('user_tasks', 'u', 't.task_id = u.task_id', 'inner');
 125      $q->addWhere('t.task_project = ' . (int)$project_id . ' AND t.task_duration_type = 1 AND t.task_dynamic <> 1');
 126      $total_project_hours = $q->loadResult();
 127      $q->clear();
 128  
 129      $total_project_hours = $total_project_days * $w2Pconfig['daily_working_hours'] + $total_project_hours;
 130      //due to the round above, we don't want to print decimals unless they really exist
 131      //$total_project_hours = rtrim($total_project_hours, "0");
 132  } else { //no tasks in project so "fake" project data
 133      $worked_hours = $total_hours = $total_project_hours = 0.00;
 134  }
 135  // get the prefered date format
 136  $df = $AppUI->getPref('SHDATEFORMAT');
 137  
 138  // create Date objects from the datetime fields
 139  $start_date = intval($obj->project_start_date) ? new CDate($obj->project_start_date) : null;
 140  $end_date = intval($obj->project_end_date) ? new CDate($obj->project_end_date) : null;
 141  $actual_end_date = intval($criticalTasks[0]['task_end_date']) ? new CDate($criticalTasks[0]['task_end_date']) : null;
 142  $style = (($actual_end_date > $end_date) && !empty($end_date)) ? 'style="color:red; font-weight:bold"' : '';
 143  
 144  // setup the title block
 145  $titleBlock = new CTitleBlock('View Project', 'applet3-48.png', $m, $m . '.' . $a);
 146  
 147  // patch 2.12.04 text to search entry box
 148  if (isset($_POST['searchtext'])) {
 149      $AppUI->setState('searchtext', $_POST['searchtext']);
 150  }
 151  
 152  $search_text = $AppUI->getState('searchtext') ? $AppUI->getState('searchtext') : '';
 153  $titleBlock->addCell('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' . $AppUI->_('Search') . ':');
 154  $titleBlock->addCell('<input type="text" class="text" SIZE="10" name="searchtext" onChange="document.searchfilter.submit();" value=' . "'$search_text'" . 'title="' . $AppUI->_('Search in name and description fields') . '"/>
 155             <!--<input type="submit" class="button" value=">" title="' . $AppUI->_('Search in name and description fields') . '"/>-->', '', '<form action="?m=projects&a=view&project_id=' . $project_id . '" method="post" id="searchfilter">', '</form>');
 156  
 157  if ($canEditT) {
 158      $titleBlock->addCell();
 159      $titleBlock->addCell('<input type="submit" class="button" value="' . $AppUI->_('new task') . '" />', '', '<form action="?m=tasks&a=addedit&task_project=' . $project_id . '" method="post">', '</form>');
 160  }
 161  if ($canEdit) {
 162      $titleBlock->addCell();
 163      $titleBlock->addCell('<input type="submit" class="button" value="' . $AppUI->_('new event') . '" />', '', '<form action="?m=calendar&a=addedit&event_project=' . $project_id . '" method="post">', '</form>');
 164  
 165      $titleBlock->addCell();
 166      $titleBlock->addCell('<input type="submit" class="button" value="' . $AppUI->_('new file') . '" />', '', '<form action="?m=files&a=addedit&project_id=' . $project_id . '" method="post">', '</form>');
 167  }
 168  $titleBlock->addCrumb('?m=projects', 'projects list');
 169  if ($canEdit) {
 170      $titleBlock->addCrumb('?m=projects&a=addedit&project_id=' . $project_id, 'edit this project');
 171      if ($canDelete) {
 172          $titleBlock->addCrumbDelete('delete project', $canDelete, $msg);
 173      }
 174  }
 175  $titleBlock->show();
 176  ?>
 177  <script language="javascript">
 178  function expand_multiproject(id, table_name) {
 179        var trs = document.getElementsByTagName('tr');
 180  
 181        for (var i=0, i_cmp=trs.length;i < i_cmp;i++) {
 182            var tr_name = trs.item(i).id;
 183  
 184            if (tr_name.indexOf(id) >= 0) {
 185                   var tr = document.getElementById(tr_name);
 186                   tr.style.visibility = (tr.style.visibility == '' || tr.style.visibility == 'collapse') ? 'visible' : 'collapse';
 187                   var img_expand = document.getElementById(id+'_expand');
 188                   var img_collapse = document.getElementById(id+'_collapse');
 189                   img_collapse.style.display = (tr.style.visibility == 'visible') ? 'inline' : 'none';
 190                   img_expand.style.display = (tr.style.visibility == '' || tr.style.visibility == 'collapse') ? 'inline' : 'none';
 191            }
 192        }
 193  }
 194  <?php
 195  // security improvement:
 196  // some javascript functions may not appear on client side in case of user not having write permissions
 197  // else users would be able to arbitrarily run 'bad' functions
 198  if ($canEdit) {
 199  ?>
 200  function delIt() {
 201      if (confirm( '<?php echo $AppUI->_('doDelete', UI_OUTPUT_JS) . ' ' . $AppUI->_('Project', UI_OUTPUT_JS) . '?'; ?>' )) {
 202          document.frmDelete.submit();
 203      }
 204  }
 205  <?php } ?>
 206  </script>
 207  
 208  <form name="frmDelete" action="./index.php?m=projects" method="post">
 209      <input type="hidden" name="dosql" value="do_project_aed" />
 210      <input type="hidden" name="del" value="1" />
 211      <input type="hidden" name="project_id" value="<?php echo $project_id; ?>" />
 212  </form>
 213  <table id="tblProjects" border="0" cellpadding="4" cellspacing="0" width="100%" class="std">
 214  <tr>
 215      <td style="border: outset #d1d1cd 1px;background-color:#<?php echo $obj->project_color_identifier; ?>" colspan="2">
 216      <?php
 217  echo '<font color="' . bestColor($obj->project_color_identifier) . '"><strong>' . $obj->project_name . '<strong></font>';
 218  ?>
 219      </td>
 220  </tr>
 221  
 222  <tr>
 223      <td width="50%" valign="top">
 224          <strong><?php echo $AppUI->_('Details'); ?></strong>
 225          <table cellspacing="1" cellpadding="2" border="0" width="100%">
 226          <tr>
 227              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Company'); ?>:</td>
 228              <?php if ($perms->checkModuleItem('companies', 'access', $obj->project_company)) { ?>
 229                          <td class="hilite" width="100%"> <?php echo '<a href="?m=companies&a=view&company_id=' . $obj->project_company . '">' . htmlspecialchars($obj->company_name, ENT_QUOTES) . '</a>'; ?></td>
 230              <?php } else { ?>
 231                          <td class="hilite" width="100%"><?php echo htmlspecialchars($obj->company_name, ENT_QUOTES); ?></td>
 232              <?php } ?>
 233          </tr>
 234          <tr>
 235              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Project Location'); ?>:</td>
 236              <td class="hilite"><?php echo $obj->project_location; ?></td>
 237          </tr>
 238          <tr>
 239              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Short Name'); ?>:</td>
 240              <td class="hilite"><?php echo htmlspecialchars($obj->project_short_name, ENT_QUOTES); ?></td>
 241          </tr>
 242          <tr>
 243              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Start Date'); ?>:</td>
 244              <td class="hilite"><?php echo $start_date ? $start_date->format($df) : '-'; ?></td>
 245          </tr>
 246          <tr>
 247              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Target End Date'); ?>:</td>
 248              <td class="hilite"><?php echo $end_date ? $end_date->format($df) : '-'; ?></td>
 249          </tr>
 250          <tr>
 251              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Actual End Date'); ?>:</td>
 252              <td class="hilite">
 253               <?php if ($project_id > 0) { ?>
 254                      <?php echo $actual_end_date ? '<a href="?m=tasks&a=view&task_id=' . $criticalTasks[0]['task_id'] . '">' : ''; ?>
 255                      <?php echo $actual_end_date ? '<span ' . $style . '>' . $actual_end_date->format($df) . '</span>' : '-'; ?>
 256                      <?php echo $actual_end_date ? '</a>' : ''; ?>
 257               <?php } else {
 258                          echo $AppUI->_('Dynamically calculated');
 259  } ?>
 260              </td>
 261          </tr>
 262          <tr>
 263              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Target Budget'); ?>:</td>
 264              <td class="hilite"><?php echo $w2Pconfig['currency_symbol'] ?><?php echo $obj->project_target_budget; ?></td>
 265          </tr>
 266          <tr>
 267              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Project Owner'); ?>:</td>
 268              <td class="hilite"><?php echo $obj->user_name; ?></td>
 269          </tr>
 270          <tr>
 271              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('URL'); ?>:</td>
 272              <td class="hilite"><a href="<?php echo $obj->project_url; ?>" target="_new"><?php echo $obj->project_url; ?></a></td>
 273          </tr>
 274          <tr>
 275              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Staging URL'); ?>:</td>
 276              <td class="hilite"><a href="<?php echo $obj->project_demo_url; ?>" target="_new"><?php echo $obj->project_demo_url; ?></a></td>
 277          </tr>
 278          <tr>
 279              <td colspan="2">
 280              <?php
 281  require_once ($AppUI->getSystemClass('CustomFields'));
 282  $custom_fields = new CustomFields($m, $a, $obj->project_id, 'view');
 283  $custom_fields->printHTML();
 284  ?>
 285              </td>
 286          </tr>
 287          <tr>
 288              <td colspan="2">
 289              <strong><?php echo $AppUI->_('Description'); ?></strong><br />
 290              <table cellspacing="0" cellpadding="2" border="0" width="100%">
 291              <tr>
 292                  <td class="hilite">
 293                      <?php echo str_replace(chr(10), '<br>', $obj->project_description); ?>&nbsp;
 294                  </td>
 295              </tr>
 296              </table>
 297              </td>
 298          </tr>
 299          </table>
 300      </td>
 301      <td width="50%" rowspan="1" valign="top">
 302          <strong><?php echo $AppUI->_('Summary'); ?></strong><br />
 303          <table cellspacing="1" cellpadding="2" border="0" width="100%">
 304          <tr>
 305              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Status'); ?>:</td>
 306              <td class="hilite" width="100%"><?php echo $AppUI->_($pstatus[$obj->project_status]); ?></td>
 307          </tr>
 308          <tr>
 309              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Priority'); ?>:</td>
 310              <td class="hilite" width="100%" style="background-color:<?php echo $projectPriorityColor[$obj->project_priority] ?>"><?php echo $AppUI->_($projectPriority[$obj->project_priority]); ?></td>
 311          </tr>
 312          <tr>
 313              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Type'); ?>:</td>
 314              <td class="hilite" width="100%"><?php echo $AppUI->_($ptype[$obj->project_type]); ?></td>
 315          </tr>
 316          <tr>
 317              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Progress'); ?>:</td>
 318              <td class="hilite" width="100%"><?php printf('%.1f%%', $obj->project_percent_complete); ?></td>
 319          </tr>
 320          <tr>
 321              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Active'); ?>:</td>
 322              <td class="hilite" width="100%"><?php echo $obj->project_active ? $AppUI->_('Yes') : $AppUI->_('No'); ?></td>
 323          </tr>
 324          <tr>
 325              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Worked Hours'); ?>:</td>
 326              <td class="hilite" width="100%"><?php echo $worked_hours ?></td>
 327          </tr>    
 328          <tr>
 329              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Scheduled Hours'); ?>:</td>
 330              <td class="hilite" width="100%"><?php echo $total_hours ?></td>
 331          </tr>
 332          <tr>
 333              <td align="right" nowrap="nowrap"><?php echo $AppUI->_('Project Hours'); ?>:</td>
 334              <td class="hilite" width="100%"><?php echo $total_project_hours ?></td>
 335          </tr>                
 336          <?php
 337  $q = new DBQuery;
 338  $q->addTable('departments', 'a');
 339  $q->addTable('project_departments', 'b');
 340  $q->addQuery('a.dept_id, a.dept_name, a.dept_phone');
 341  $q->addWhere('a.dept_id = b.department_id and b.project_id = ' . (int)$project_id);
 342  $department = new CDepartment;
 343  $department->setAllowedSQL($AppUI->user_id, $q);
 344  $depts = $q->loadHashList('dept_id');
 345  if (count($depts) > 0) {
 346  ?>
 347              <tr>
 348                  <td><strong><?php echo $AppUI->_('Departments'); ?></strong></td>
 349              </tr>
 350              <tr>
 351                  <td colspan='3' class="hilite">
 352                      <?php
 353      foreach ($depts as $dept_id => $dept_info) {
 354          echo '<div>' . $dept_info['dept_name'];
 355          if ($dept_info['dept_phone'] != '') {
 356              echo '( ' . $dept_info['dept_phone'] . ' )';
 357          }
 358          echo '</div>';
 359      }
 360  ?>
 361                  </td>
 362              </tr>
 363               <?php
 364  }
 365  
 366  $q = new DBQuery;
 367  $q->addTable('contacts', 'a');
 368  $q->addTable('project_contacts', 'b');
 369  $q->addJoin('departments', 'c', 'a.contact_department = c.dept_id', 'left outer');
 370  $q->addQuery('a.contact_id, a.contact_first_name, a.contact_last_name, a.contact_email, a.contact_phone, c.dept_name');
 371  $q->addWhere('a.contact_id = b.contact_id and b.project_id = ' . (int)$project_id . ' AND (contact_owner = ' . (int)$AppUI->user_id . ' OR contact_private = 0)');
 372  $department->setAllowedSQL($AppUI->user_id, $q);
 373  $contacts = $q->loadHashList('contact_id');
 374  if (count($contacts) > 0) {
 375  ?>
 376                  <tr>
 377                      <td><strong><?php echo $AppUI->_('Contacts'); ?></strong></td>
 378                  </tr>
 379                  <tr>
 380                      <td colspan='3' class="hilite">
 381                          <?php
 382      echo '<table cellspacing="1" cellpadding="2" border="0" width="100%" class="tbl">';
 383      echo '<tr><th>' . $AppUI->_('Name') . '</th><th>' . $AppUI->_('Email') . '</th><th>' . $AppUI->_('Phone') . '</th><th>' . $AppUI->_('Department') . '</th></tr>';
 384      foreach ($contacts as $contact_id => $contact_data) {
 385          echo '<tr>';
 386          echo '<td class="hilite">';
 387          $canEdit = $perms->checkModuleItem('contacts', 'edit', $contact_id);
 388          if ($canEdit) {
 389              echo '<a href="index.php?m=contacts&a=view&contact_id=' . $contact_id . '">';
 390          }
 391          echo $contact_data['contact_first_name'] . ' ' . $contact_data['contact_last_name'];
 392          if ($canEdit) {
 393              echo '</a>';
 394          }
 395          echo '</td>';
 396          echo '<td class="hilite"><a href="mailto:' . $contact_data['contact_email'] . '">' . $contact_data['contact_email'] . '</a></td>';
 397          echo '<td class="hilite">' . $contact_data['contact_phone'] . '</td>';
 398          echo '<td class="hilite">' . $contact_data['dept_name'] . '</td>';
 399          echo '</tr>';
 400      }
 401      echo '</table>';
 402  ?>
 403                      </td>
 404                  </tr>
 405                  <tr>
 406                      <td>
 407           <?php
 408  } ?>
 409          </table>
 410      </td>
 411  </tr>
 412  <?php
 413  //lets add the subprojects table
 414  $q = new DBQuery();
 415  $q->addTable('projects');
 416  $q->addQuery('