[Summary view]
[Print]
[Text view]
1 <?php
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
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
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
69
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
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
126 $msg = '';
127 $obj = new CProject();
128
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
137 $criticalTasks = ($project_id > 0) ? $obj->getCriticalTasks($project_id) : null;
138
139
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
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
156
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
189
190
191
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
202
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
234
235 } else { //no tasks in project so "fake" project data
236 $worked_hours = $total_hours = $total_project_hours = 0.00;
237 }
238
239
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
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
320
321
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 +=' <?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 +=' <img src="<?php echo