[ Index ]

Source Code Reference for V1.00

title

Body

[close]

/modules/projectdesigner/ -> index.php (source)

   1  <?php /* $Id: index.php 136 2008-04-04 14:24:17Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/modules/projectdesigner/index.php $ */
   2  /*  Copyright (c) 2007 Pedro A. (web2Project Development Team Member)
   3  THIS MODULE WAS SPONSORED BY DUSTIN OF PURYEAR-IT.COM
   4  
   5  This file is part of the web2Project ProjectDesigner module.
   6  
   7  The ProjectDesigner module is free software; you can redistribute it and/or modify
   8  it under the terms of the GNU General Public License as published by
   9  the Free Software Foundation; either version 2 of the License, or
  10  (at your option) any later version, as long as you keep this copyright notice as well as
  11  the sponsor.txt file which is also part of this module.
  12  
  13  The Project Designer module is distributed in the hope that it will be useful,
  14  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16  GNU General Public License for more details.
  17  
  18  You should have received a copy of the GNU General Public License
  19  along with web2Project; if not, write to the Free Software
  20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21  */
  22  if (!defined('W2P_BASE_DIR')) {
  23      die('You should not access this file directly');
  24  }
  25  global $AppUI, $w2Pconfig, $cal_df, $cf;
  26  // check permissions for this module
  27  $perms = &$AppUI->acl();
  28  $canView = $perms->checkModule($m, 'view');
  29  $canAddProject = $perms->checkModuleItem('projects', 'view', $project_id);
  30  
  31  if (!$canView) {
  32      $AppUI->redirect('m=public&a=access_denied');
  33  }
  34  
  35  $AppUI->loadCalendarJS();
  36  
  37  $today = new CDate();
  38  
  39  //Lets load the users panel viewing options
  40  $q = new DBQuery;
  41  $q->addTable('project_designer_options', 'pdo');
  42  $q->addQuery('pdo.*');
  43  $q->addWhere('pdo.pd_option_user = ' . (int)$AppUI->user_id);
  44  $view_options = $q->loadList();
  45  
  46  $project_id = intval(w2PgetParam($_REQUEST, 'project_id', 0));
  47  $extra = array('where' => 'project_active = 1');
  48  $project = new CProject();
  49  $projects = $project->getAllowedRecords($AppUI->user_id, 'projects.project_id,project_name', 'project_name', null, $extra, 'projects');
  50  $q = new DBQuery;
  51  $q->addTable('projects');
  52  $q->addQuery('projects.project_id, company_name');
  53  $q->addJoin('companies', 'co', 'co.company_id = project_company');
  54  $idx_companies = $q->loadHashList();
  55  $q->clear();
  56  foreach ($projects as $prj_id => $prj_name) {
  57      $projects[$prj_id] = $idx_companies[$prj_id] . ': ' . $prj_name;
  58  }
  59  asort($projects);
  60  $projects = arrayMerge(array('0' => $AppUI->_('(None)', UI_OUTPUT_RAW)), $projects);
  61  
  62  $extra = array();
  63  $task = new CTask();
  64  $tasks = $task->getAllowedRecords($AppUI->user_id, 'task_id,task_name', 'task_name', null, $extra);
  65  $tasks = arrayMerge(array('0' => $AppUI->_('(None)', UI_OUTPUT_RAW)), $tasks);
  66  
  67  if (!$project_id) {
  68      //$AppUI->redirect('m=projects&pd=1');
  69      // setup the title block
  70      $ttl = 'ProjectDesigner';
  71      $titleBlock = new CTitleBlock($ttl, 'projectdesigner.png', $m, $m . '.' . $a);
  72      $titleBlock->addCrumb('?m=projects', 'projects list');
  73      $titleBlock->addCell();
  74      if ($canAddProject) {
  75          $titleBlock->addCell('<input type="submit" class="button" value="' . $AppUI->_('new project') . '">', '', '<form action="?m=projects&a=addedit" method="post">', '</form>');
  76      }
  77      $titleBlock->show();
  78  ?>
  79      <script language="javascript">
  80  	function submitIt() {
  81          var f = document.prjFrm;
  82          var msg ='';
  83          if (f.project_id.value == 0) {
  84              msg += '<?php echo $AppUI->_('You must select a project first', UI_OUTPUT_JS); ?>';
  85              f.project_id.focus();
  86          }
  87          
  88          if (msg.length < 1) {
  89              f.submit();
  90          } else {
  91              alert(msg);
  92          }
  93      }
  94      </script>
  95  <?php
  96      if (function_exists('styleRenderBoxTop')) {
  97          echo styleRenderBoxTop();
  98      }
  99  ?>
 100      <table border="1" cellpadding="4" cellspacing="0" width="100%" class="std">
 101      <form name="prjFrm" action="?m=projectdesigner" method="post">
 102      <tr>
 103          <td nowrap="nowrap" style="border: outset #eeeeee 1px;background-color:#fffff" >
 104              <font color="<?php echo bestColor('#ffffff'); ?>">
 105                  <strong><?php echo $AppUI->_('Project'); ?>: <?php echo arraySelect($projects, 'project_id', 'onchange="submitIt()" class="text" style="width:500px"', 0); ?></strong>
 106              </font>
 107          </td>
 108      </tr>            
 109      </form>
 110      </table>
 111  <?php
 112  } else {
 113      // check permissions for this record
 114      $canReadProject = $perms->checkModuleItem('projects', 'view', $project_id);
 115      $canEditProject = $perms->checkModuleItem('projects', 'edit', $project_id);
 116      $canViewTasks = $perms->checkModule('tasks', 'view');
 117      $canAddTasks = $perms->checkModule('tasks', 'add');
 118      $canEditTasks = $perms->checkModule('tasks', 'edit');
 119      $canDeleteTasks = $perms->checkModule('tasks', 'delete');
 120  
 121      if (!$canReadProject) {
 122          $AppUI->redirect('m=public&a=access_denied');
 123      }
 124  
 125      // check if this record has dependencies to prevent deletion
 126      $msg = '';
 127      $obj = new CProject();
 128      // Now check if the project is editable/viewable.
 129      $denied = $obj->getDeniedRecords($AppUI->user_id);
 130      if (in_array($project_id, $denied)) {
 131          $AppUI->redirect('m=public&a=access_denied');
 132      }
 133  
 134      $canDeleteProject = $obj->canDelete($msg, $project_id);
 135  
 136      // get critical tasks (criteria: task_end_date)
 137      $criticalTasks = ($project_id > 0) ? $obj->getCriticalTasks($project_id) : null;
 138  
 139      // get ProjectPriority from sysvals
 140      $projectPriority = w2PgetSysVal('ProjectPriority');
 141      $projectPriorityColor = w2PgetSysVal('ProjectPriorityColor');
 142      $pstatus = w2PgetSysVal('ProjectStatus');
 143      $ptype = w2PgetSysVal('ProjectType');
 144  
 145      $working_hours = ($w2Pconfig['daily_working_hours'] ? $w2Pconfig['daily_working_hours'] : 8);
 146  
 147      $q = new DBQuery;
 148      //check that project has tasks; otherwise run seperate query
 149      $q->addTable('tasks');
 150      $q->addQuery('COUNT(distinct tasks.task_id) AS total_tasks');
 151      $q->addWhere('task_project = ' . (int)$project_id);
 152      $hasTasks = $q->loadResult();
 153      $q->clear();
 154  
 155      // load the record data
 156      // GJB: Note that we have to special case duration type 24 and this refers to the hours in a day, NOT 24 hours
 157      $obj = null;
 158      if ($hasTasks) {
 159          $q->addTable('projects');
 160          $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');
 161          $q->addJoin('companies', 'com', 'company_id = project_company');
 162          $q->addJoin('users', 'u', 'user_id = project_owner');
 163          $q->addJoin('contacts', 'con', 'contact_id = user_contact');
 164          $q->addJoin('tasks', 't1', 'projects.project_id = t1.task_project');
 165          $q->addWhere('project_id = ' . (int)$project_id . ' AND t1.task_id = t1.task_parent');
 166          $q->addGroup('project_id');
 167          $q->loadObject($obj);
 168      } else {
 169          $q->addTable('projects');
 170          $q->addQuery('company_name, CONCAT_WS(\' \',contact_first_name,contact_last_name) user_name, projects.*, (0.0) AS project_percent_complete');
 171          $q->addJoin('companies', 'com', 'company_id = project_company');
 172          $q->addJoin('users', 'u', 'user_id = project_owner');
 173          $q->addJoin('contacts', 'con', 'contact_id = user_contact');
 174          $q->addWhere('project_id = ' . (int)$project_id);
 175          $q->addGroup('project_id');
 176          $q->loadObject($obj);
 177      }
 178      $q->clear();
 179  
 180      if (!$obj) {
 181          $AppUI->setMsg('Project');
 182          $AppUI->setMsg('invalidID', UI_MSG_ERROR, true);
 183          $AppUI->redirect();
 184      } else {
 185          $AppUI->savePlace();
 186      }
 187  
 188      // worked hours
 189      // now milestones are summed up, too, for consistence with the tasks duration sum
 190      // the sums have to be rounded to prevent the sum form having many (unwanted) decimals because of the mysql floating point issue
 191      // more info on http://www.mysql.com/doc/en/Problems_with_float.html
 192      if ($hasTasks) {
 193          $q->addTable('task_log');
 194          $q->addTable('tasks');
 195          $q->addQuery('ROUND(SUM(task_log_hours),2)');
 196          $q->addWhere('task_log_task = task_id AND task_project = ' . (int)$project_id);
 197          $worked_hours = $q->loadResult();
 198          $q->clear();
 199          $worked_hours = rtrim($worked_hours, '.');
 200  
 201          // total hours
 202          // same milestone comment as above, also applies to dynamic tasks
 203          $q->addTable('tasks');
 204          $q->addQuery('ROUND(SUM(task_duration),2)');
 205          $q->addWhere('task_project = ' . (int)$project_id . ' AND task_duration_type = 24 AND task_dynamic = 0');
 206          $days = $q->loadResult();
 207          $q->clear();
 208  
 209          $q->addTable('tasks');
 210          $q->addQuery('ROUND(SUM(task_duration),2)');
 211          $q->addWhere('task_project = ' . (int)$project_id . ' AND task_duration_type = 1 AND task_dynamic = 0');
 212          $hours = $q->loadResult();
 213          $q->clear();
 214          $total_hours = $days * $w2Pconfig['daily_working_hours'] + $hours;
 215  
 216          $total_project_hours = 0;
 217  
 218          $q->addTable('tasks', 't');
 219          $q->addQuery('ROUND(SUM(t.task_duration*u.perc_assignment/100),2)');
 220          $q->addJoin('user_tasks', 'u', 't.task_id = u.task_id');
 221          $q->addWhere('t.task_project = ' . (int)$project_id . ' AND t.task_duration_type = 24 AND t.task_dynamic = 0');
 222          $total_project_days_sql = $q->prepare();
 223  
 224          $q2 = new DBQuery;
 225          $q2->addTable('tasks', 't');
 226          $q2->addQuery('ROUND(SUM(t.task_duration*u.perc_assignment/100),2)');
 227          $q2->addJoin('user_tasks', 'u', 't.task_id = u.task_id');
 228          $q2->addWhere('t.task_project = ' . (int)$project_id . ' AND t.task_duration_type = 1 AND t.task_dynamic = 0');
 229  
 230          $total_project_hours = $q->loadResult() * $w2Pconfig['daily_working_hours'] + $q2->loadResult();
 231          $q->clear();
 232          $q2->clear();
 233          //due to the round above, we don't want to print decimals unless they really exist
 234          //$total_project_hours = rtrim($total_project_hours, "0");
 235      } else { //no tasks in project so "fake" project data
 236          $worked_hours = $total_hours = $total_project_hours = 0.00;
 237      }
 238  
 239      // create Date objects from the datetime fields
 240      $start_date = intval($obj->project_start_date) ? new CDate($obj->project_start_date) : null;
 241      $end_date = intval($obj->project_end_date) ? new CDate($obj->project_end_date) : null;
 242      $actual_end_date = intval($criticalTasks[0]['task_end_date']) ? new CDate($criticalTasks[0]['task_end_date']) : null;
 243      $today = new CDate();
 244      $style = (($actual_end_date > $end_date) && !empty($end_date)) ? 'style="color:red; font-weight:bold"' : '';
 245      $style = (($obj->project_percent_complete < 99.99 && $today > $end_date) && !empty($end_date)) ? 'style="color:red; font-weight:bold"' : $style;
 246  
 247      // setup the title block
 248      $ttl = 'ProjectDesigner';
 249      $titleBlock = new CTitleBlock($ttl, 'projectdesigner.png', $m, $m . '.' . $a);
 250      $titleBlock->addCrumb('?m=projects', 'projects list');
 251      $titleBlock->addCrumb('?m=' . $m, 'select another project');
 252      $titleBlock->addCrumb('?m=projects&a=view&bypass=1&project_id=' . $project_id, 'normal view project');
 253  
 254      if ($canAddProject) {
 255          $titleBlock->addCell();
 256          $titleBlock->addCell('<input type="submit" class="button" value="' . $AppUI->_('new project') . '">', '', '<form action="?m=projects&a=addedit" method="post">', '</form>');
 257      }
 258  
 259      if ($canAddTask) {
 260          $titleBlock->addCell();
 261          $titleBlock->addCell('<input type="submit" class="button" value="' . $AppUI->_('new task') . '">', '', '<form action="?m=tasks&a=addedit&task_project=' . $project_id . '" method="post">', '</form>');
 262      }
 263      if ($canEditProject) {
 264          $titleBlock->addCell();
 265          $titleBlock->addCell('<input type="submit" class="button" value="' . $AppUI->_('new event') . '">', '', '<form action="?m=calendar&a=addedit&event_project=' . $project_id . '" method="post">', '</form>');
 266  
 267          $titleBlock->addCell();
 268          $titleBlock->addCell('<input type="submit" class="button" value="' . $AppUI->_('new file') . '">', '', '<form action="?m=files&a=addedit&project_id=' . $project_id . '" method="post">', '</form>');
 269          $titleBlock->addCrumb('?m=projects&a=addedit&project_id=' . $project_id, 'edit this project');
 270          if ($canDeleteProject) {
 271              $titleBlock->addCrumbDelete('delete project', $canDelete, $msg);
 272          }
 273      }
 274      $titleBlock->addCell();
 275      $titleBlock->addCell(w2PtoolTip($m, 'print project') . '<a href="javascript: void(0);" onclick ="window.open(\'index.php?m=projectdesigner&a=printproject&dialog=1&suppressHeaders=1&project_id=' . $project_id . '\', \'printproject\',\'width=1200, height=600, menubar=1, scrollbars=1\')">
 276                <img src="' . w2PfindImage('printer.png') . '" border="0" width="22" heigth"22" />
 277                </a>
 278                ' . w2PendTip());
 279      $titleBlock->addCell(w2PtoolTip($m, 'expand all panels') . '<a href="javascript: void(0);" onclick ="expandAll()">
 280                <img src="' . w2PfindImage('down.png', $m) . '" border="0" width="22" heigth="22" />
 281                </a>
 282                ' . w2PendTip());
 283      $titleBlock->addCell(w2PtoolTip($m, 'collapse all panels') . '<a href="javascript: void(0);" onclick ="collapseAll()">
 284                <img src="' . w2PfindImage('up.png', $m) . '" border="0" width="22" heigth="22" />
 285                </a>
 286                ' . w2PendTip());
 287      $titleBlock->addCell(w2PtoolTip($m, 'save your workspace') . '<a href="javascript: void(0);" onclick ="document.frmWorkspace.submit()">
 288                <img src="' . w2PfindImage('filesave.png', $m) . '" border="0" width="22" heigth="22" />
 289                </a>
 290                ' . w2PendTip());
 291      $titleBlock->addCell();
 292      $titleBlock->show();
 293  ?>
 294  <form name="frmWorkspace" action="?m=<?php echo $m; ?>" method="post">
 295      <input type="hidden" name="dosql" value="do_projectdesigner_aed" />
 296      <input type="hidden" name="project_id" value="<?php echo $project_id; ?>" />
 297      <input type="hidden" name="opt_view_project" value="<?php echo (isset($view_options[0]['pd_option_view_project']) ? $view_options[0]['pd_option_view_project'] : 1); ?>" />
 298      <input type="hidden" name="opt_view_gantt" value="<?php echo (isset($view_options[0]['pd_option_view_gantt']) ? $view_options[0]['pd_option_view_gantt'] : 1); ?>" />
 299      <input type="hidden" name="opt_view_tasks" value="<?php echo (isset($view_options[0]['pd_option_view_tasks']) ? $view_options[0]['pd_option_view_tasks'] : 1); ?>" />
 300      <input type="hidden" name="opt_view_actions" value="<?php echo (isset($view_options[0]['pd_option_view_actions']) ? $view_options[0]['pd_option_view_actions'] : 1); ?>" />
 301      <input type="hidden" name="opt_view_addtsks" value="<?php echo (isset($view_options[0]['pd_option_view_addtasks']) ? $view_options[0]['pd_option_view_addtasks'] : 1); ?>" />
 302      <input type="hidden" name="opt_view_files" value="<?php echo (isset($view_options[0]['pd_option_view_files']) ? $view_options[0]['pd_option_view_files'] : 1); ?>" />
 303  </form>
 304  
 305  <?php
 306      $priorities = w2Pgetsysval('TaskPriority');
 307      $types = w2Pgetsysval('TaskType');
 308      $durntype = w2PgetSysVal('TaskDurationType');
 309      include_once ($AppUI->getModuleClass('tasks'));
 310      global $task_access;
 311      $extra = array(0 => '(none)', 1 => 'Milestone', 2 => 'Dynamic Task', 3 => 'Inactive Task');
 312      $sel_priorities = arraySelect($priorities, 'add_task_priority0', 'style="width:80px" class="text"', '0');
 313      $sel_types = arraySelect($types, 'add_task_type0', 'style="width:80px" class="text"', '');
 314      $sel_access = arraySelect($task_access, 'add_task_access0', 'style="width:80px" class="text"', '');
 315      $sel_extra = arraySelect($extra, 'add_task_extra0', 'style="width:80px" class="text"', '');
 316      $sel_durntype = arraySelect($durntype, 'add_task_durntype0', 'style="width:80px" class="text"', '', true);
 317  ?>
 318  <script language="javascript">
 319  // security improvement:
 320  // some javascript functions may not appear on client side in case of user not having write permissions
 321  // else users would be able to arbitrarily run 'bad' functions
 322  <?php
 323      if ($canEdit) {
 324  ?>
 325  function delIt() {
 326      if (confirm( '<?php echo $AppUI->_('doDelete', UI_OUTPUT_JS) . ' ' . $AppUI->_('Project', UI_OUTPUT_JS) . '?'; ?>' )) {
 327          document.frmDelete.submit();
 328      }
 329  }
 330  <?php } ?>
 331  
 332  var sel_priorities = '<?php echo str_replace(chr(10), '', $sel_priorities); ?>';
 333  var sel_types = '<?php echo str_replace(chr(10), '', $sel_types); ?>';
 334  var sel_access = '<?php echo str_replace(chr(10), '', $sel_access); ?>';
 335  var sel_extra = '<?php echo str_replace(chr(10), '', $sel_extra); ?>';
 336  var sel_durntype = '<?php echo str_replace(chr(10), '', $sel_durntype); ?>';
 337  
 338  function addComponent() {
 339      var form = document.editFrm;
 340      var li = parseInt(form.nrcomponents.value);
 341      var line_nr = li+1;
 342      
 343      var ni = document.getElementById('tcomponents');
 344      var li = li+1;
 345      
 346      priorities = sel_priorities.replace('priority0','priority_'+line_nr);
 347      priorities = priorities.replace('priority0','priority_'+line_nr);
 348      types = sel_types.replace('type0','type_'+line_nr);
 349      types = types.replace('type0','type_'+line_nr);
 350      access = sel_access.replace('access0','access_'+line_nr);
 351      access = access.replace('access0','access_'+line_nr);
 352      extra = sel_extra.replace('extra0','extra_'+line_nr);
 353      extra = extra.replace('extra0','extra_'+line_nr);
 354      durntype = sel_durntype.replace('durntype0', 'durntype_'+line_nr);
 355      durntype = durntype.replace('durntype0', 'durntype_'+line_nr);
 356      
 357      eval('oldType_'+line_nr+'=""');
 358      
 359      var trIdName = 'component'+li+'_';
 360      var newtr = document.createElement('tr');
 361      var htmltxt = '';
 362      newtr.setAttribute('id',trIdName);
 363      oCell = document.createElement('td');
 364      oCell.setAttribute ('align','left');
 365      oCell.setAttribute ('width','5');
 366      htmltxt = '';
 367      htmltxt +='<a href="javascript: void(0);" onclick="removeComponent(\'component'+line_nr+'_\')"><img src="<?php echo w2PfindImage('remove.png', $m); ?>" width="16" height="16" border="0" /></a>';
 368      oCell.innerHTML =htmltxt;
 369      newtr.appendChild(oCell);
 370      oCell = document.createElement('td');
 371      htmltxt = '';
 372      htmltxt +='<input type="hidden" id="add_task_line_'+line_nr+'" name="add_task_line_'+line_nr+'" value="'+line_nr+'" />';
 373      htmltxt +='<input type="text" class="text" style="width:200px;" name="add_task_name_'+line_nr+'" value="" />';
 374      htmltxt +='&nbsp;<?php echo w2PtoolTip('add tasks panel', 'click here to add a description to this task and/or edit other available options.<br />click again to collapse it.'); ?><a href="javascript: void(0);" onclick="expand_collapse(\'component'+li+'_desc\', \'tblProjects\')"><img id="component'+li+'_desc_expand" src="<?php echo w2PfindImage('icons/expand.gif', $m); ?>" width="12" height="12" border="0"><img id="component'+li+'_desc_collapse" src="<?php echo w2PfindImage('icons/collapse.gif', $m); ?>" width="12" height="12" border="0" style="display:none"></a><?php echo w2PendTip(); ?>';
 375      oCell.innerHTML =htmltxt;
 376      newtr.appendChild(oCell);
 377      oCell = document.createElement('td');
 378      htmltxt = '';
 379      htmltxt +='<input type="hidden" id="add_task_start_date_'+line_nr+'" name="add_task_start_date_'+line_nr+'" value="<?php echo $today->format(FMT_TIMESTAMP); ?>" />';
 380      htmltxt +='<input type="text" onchange="setDate(\'editFrm\', \'start_date_'+line_nr+'\');" class="text" style="width:130px;" id="start_date_'+line_nr+'" name="start_date_'+line_nr+'" value="<?php echo $today->format($cf); ?>" />';
 381      htmltxt +='<a href="javascript: void(0);" onclick="return showCalendar(\'start_date_'+line_nr+'\', \'<?php echo $cf ?>\', \'editFrm\', \'<?php echo (strpos($cf, '%p') !== false ? '12' : '24') ?>\', true)" >';
 382      htmltxt +='&nbsp;<img src="<?php echo