]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/ProjectTask/ProjectTask.php
Release 6.4.0
[Github/sugarcrm.git] / modules / ProjectTask / ProjectTask.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39
40
41
42
43
44
45
46
47
48
49
50 class ProjectTask extends SugarBean {
51         // database table columns
52         var $id;
53         var $date_entered;
54         var $date_modified;
55         //var $assigned_user_id;
56         //var $modified_user_id;
57         //var $created_by;
58         var $name;
59     var $description;
60     var $project_id;
61     var $project_task_id;
62     var $date_start;
63     var $date_finish;
64     var $duration;
65     var $duration_unit;
66     var $percent_complete;
67     var $parent_task_id;
68     var $predecessors;
69     var $priority;
70
71         // related information
72         var $assigned_user_name;
73         var $parent_name;
74         var $depends_on_name;
75         var $email_id;
76
77         var $table_name = 'project_task';
78         var $object_name = 'ProjectTask';
79         var $module_dir = 'ProjectTask';
80
81         var $field_name_map;
82         var $new_schema = true;
83
84         var $relationship_fields = array(
85                 'email_id' => 'emails',
86         );
87
88         //////////////////////////////////////////////////////////////////
89         // METHODS
90         //////////////////////////////////////////////////////////////////
91
92         /*
93          *
94          */
95         function ProjectTask($init=true)
96         {
97                 parent::SugarBean();
98                 if ($init) {
99                         // default value for a clean instantiation
100                         $this->utilization = 100;
101
102                         global $current_user;
103                         if(empty($current_user))
104                         {
105                                 $this->assigned_user_id = 1;
106                                 $admin_user = new User();
107                                 $admin_user->retrieve($this->assigned_user_id);
108                                 $this->assigned_user_name = $admin_user->user_name;
109                         }
110                         else
111                         {
112                                 $this->assigned_user_id = $current_user->id;
113                                 $this->assigned_user_name = $current_user->user_name;
114                         }
115
116                 }
117         }
118
119         function save($check_notify = FALSE){
120                 $id = parent::save($check_notify);
121         $this->updateParentProjectTaskPercentage();
122         return $id;
123         }
124
125         /**
126          * overriding the base class function to do a join with users table
127          */
128
129         /*
130          *
131          */
132    function fill_in_additional_detail_fields()
133    {
134       $this->assigned_user_name = get_assigned_user_name($this->assigned_user_id);
135       $this->project_name = $this->_get_project_name($this->project_id);
136                 /*
137         $this->depends_on_name = $this->_get_depends_on_name($this->depends_on_id);
138                 if(empty($this->depends_on_name))
139                 {
140                         $this->depends_on_id = '';
141                 }
142                 $this->parent_name = $this->_get_parent_name($this->parent_id);
143                 if(empty($this->parent_name))
144                 {
145                         $this->parent_id = '';
146                 }
147         */
148    }
149
150         /*
151          *
152          */
153    function fill_in_additional_list_fields()
154    {
155       $this->assigned_user_name = get_assigned_user_name($this->assigned_user_id);
156       //$this->parent_name = $this->_get_parent_name($this->parent_id);
157       $this->project_name = $this->_get_project_name($this->project_id);
158    }
159
160         /*
161          *
162          */
163         function get_summary_text()
164         {
165                 return $this->name;
166         }
167
168         /*
169          *
170          */
171         function _get_depends_on_name($depends_on_id)
172         {
173                 $return_value = '';
174
175                 $query  = "SELECT name, assigned_user_id FROM {$this->table_name} WHERE id='{$depends_on_id}'";
176                 $result = $this->db->query($query,true," Error filling in additional detail fields: ");
177                 $row = $this->db->fetchByAssoc($result);
178                 if($row != null)
179                 {
180                         $this->depends_on_name_owner = $row['assigned_user_id'];
181                         $this->depends_on_name_mod = 'ProjectTask';
182                         $return_value = $row['name'];
183                 }
184
185                 return $return_value;
186         }
187
188     function _get_project_name($project_id)
189     {
190         $return_value = '';
191
192         $query  = "SELECT name, assigned_user_id FROM project WHERE id='{$project_id}'";
193         $result = $this->db->query($query,true," Error filling in additional detail fields: ");
194         $row = $this->db->fetchByAssoc($result);
195         if($row != null)
196         {
197             //$this->parent_name_owner = $row['assigned_user_id'];
198             //$this->parent_name_mod = 'Project';
199             $return_value = $row['name'];
200         }
201
202         return $return_value;
203     }
204         /*
205          *
206          */
207         function _get_parent_name($parent_id)
208         {
209                 $return_value = '';
210
211                 $query  = "SELECT name, assigned_user_id FROM project WHERE id='{$parent_id}'";
212                 $result = $this->db->query($query,true," Error filling in additional detail fields: ");
213                 $row = $this->db->fetchByAssoc($result);
214                 if($row != null)
215                 {
216                         $this->parent_name_owner = $row['assigned_user_id'];
217                         $this->parent_name_mod = 'Project';
218                         $return_value = $row['name'];
219                 }
220
221                 return $return_value;
222         }
223
224         /*
225          *
226          */
227         function build_generic_where_clause ($the_query_string)
228         {
229                 $where_clauses = array();
230                 $the_query_string = $GLOBALS['db']->quote($the_query_string);
231                 array_push($where_clauses, "project_task.name like '$the_query_string%'");
232
233                 $the_where = "";
234                 foreach($where_clauses as $clause)
235                 {
236                         if($the_where != "") $the_where .= " or ";
237                         $the_where .= $clause;
238                 }
239
240                 return $the_where;
241         }
242
243         function get_list_view_data(){
244                 global $action, $currentModule, $focus, $current_module_strings, $app_list_strings, $timedate, $locale;
245                 $today = $timedate->handle_offset(date($GLOBALS['timedate']->get_db_date_time_format(), time()), $timedate->dbDayFormat, true);
246                 $task_fields =$this->get_list_view_array();
247                 //$date_due = $timedate->to_db_date($task_fields['DATE_DUE'],false);
248         if (isset($this->parent_type))
249                         $task_fields['PARENT_MODULE'] = $this->parent_type;
250
251                 /*
252         if ($this->status != "Completed" && $this->status != "Deferred" ) {
253                         $task_fields['SET_COMPLETE'] = "<a href='index.php?return_module=$currentModule&return_action=$action&return_id=" . ((!empty($focus->id)) ? $focus->id : "") . "&module=ProjectTask&action=EditView&record={$this->id}&status=Completed'>".SugarThemeRegistry::current()->getImage("close_inline","alt='Close' border='0'")."</a>";
254                 }
255
256                 if( $date_due   < $today){
257                         $task_fields['DATE_DUE']= "<font class='overdueTask'>".$task_fields['DATE_DUE']."</font>";
258                 }else if( $date_due     == $today ){
259                         $task_fields['DATE_DUE'] = "<font class='todaysTask'>".$task_fields['DATE_DUE']."</font>";
260                 }else{
261                         $task_fields['DATE_DUE'] = "<font class='futureTask'>".$task_fields['DATE_DUE']."</font>";
262                 }
263         */
264
265         if ( !isset($task_fields["FIRST_NAME"]) )
266             $task_fields["FIRST_NAME"] = '';
267         if ( !isset($task_fields["LAST_NAME"]) )
268             $task_fields["LAST_NAME"] = '';
269                 $task_fields['CONTACT_NAME']= $locale->getLocaleFormattedName($task_fields["FIRST_NAME"],$task_fields["LAST_NAME"]);
270                 $task_fields['TITLE'] = '';
271                 if (!empty($task_fields['CONTACT_NAME'])) {
272                         $task_fields['TITLE'] .= $current_module_strings['LBL_LIST_CONTACT'].": ".$task_fields['CONTACT_NAME'];
273                 }
274
275                 return $task_fields;
276         }
277
278         function bean_implements($interface){
279                 switch($interface){
280                         case 'ACL':return true;
281                 }
282                 return false;
283         }
284         function listviewACLHelper(){
285                 $array_assign = parent::listviewACLHelper();
286                 $is_owner = false;
287                 if(!empty($this->parent_name)){
288
289                         if(!empty($this->parent_name_owner)){
290                                 global $current_user;
291                                 $is_owner = $current_user->id == $this->parent_name_owner;
292                         }
293                 }
294                         if(ACLController::checkAccess('Project', 'view', $is_owner)){
295                                 $array_assign['PARENT'] = 'a';
296                         }else{
297                                 $array_assign['PARENT'] = 'span';
298                         }
299                 $is_owner = false;
300                 if(!empty($this->depends_on_name)){
301
302                         if(!empty($this->depends_on_name_owner)){
303                                 global $current_user;
304                                 $is_owner = $current_user->id == $this->depends_on_name_owner;
305                         }
306                 }
307                         if( ACLController::checkAccess('ProjectTask', 'view', $is_owner)){
308                                 $array_assign['PARENT_TASK'] = 'a';
309                         }else{
310                                 $array_assign['PARENT_TASK'] = 'span';
311                         }
312
313                 return $array_assign;
314         }
315
316     function create_export_query(&$order_by, &$where, $relate_link_join='')
317     {
318         $custom_join = $this->custom_fields->getJOIN(true, true,$where);
319                 if($custom_join)
320                                 $custom_join['join'] .= $relate_link_join;
321                 $query = "SELECT
322                                 project_task.*,
323                 users.user_name as assigned_user_name ";
324         if($custom_join){
325                         $query .=  $custom_join['select'];
326                 }
327
328         $query .= " FROM project_task LEFT JOIN project ON project_task.project_id=project.id AND project.deleted=0 ";
329
330                 if($custom_join){
331                         $query .=  $custom_join['join'];
332                 }
333         $query .= " LEFT JOIN users
334                         ON project_task.assigned_user_id=users.id ";
335
336         $where_auto = " project_task.deleted=0 ";
337
338         if($where != "")
339                 $query .= "where ($where) AND ".$where_auto;
340         else
341             $query .= "where ".$where_auto;
342
343         if(!empty($order_by)){
344                 //check to see if order by variable already has table name by looking for dot "."
345                 $table_defined_already = strpos($order_by, ".");
346
347                 if($table_defined_already === false){
348                         //table not defined yet, define accounts to avoid "ambigous column" SQL error
349                         $query .= " ORDER BY $order_by";
350                 }else{
351                         //table already defined, just add it to end of query
352                     $query .= " ORDER BY $order_by";
353                 }
354         }
355         return $query;
356     }
357
358
359     /**
360     * This method recalculates the percent complete of a parent task
361     */
362     public function updateParentProjectTaskPercentage()
363         {
364
365                 if (empty($this->parent_task_id))
366                 {
367                         return;
368                 }
369
370                 if (!empty($this->project_id))
371                 {
372             //determine parent task
373             $parentProjectTask = $this->getProjectTaskParent();
374
375             //get task children
376             if ($parentProjectTask)
377             {
378                 $subProjectTasks = $parentProjectTask->getAllSubProjectTasks();
379
380                 $totalHours = 0;
381                 $cumulativeDone = 0;
382
383                 //update cumulative calculation - mimics gantt calculation
384                 foreach ($subProjectTasks as $key => $value)
385                 {
386                     if ($value->duration == "")
387                     {
388                         $value->duration = 0;
389                     }
390
391                     if ($value->percent_complete == "")
392                     {
393                         $value->percent_complete = 0;
394                     }
395
396                     if ($value->duration_unit == "Hours")
397                     {
398                         $totalHours += $value->duration;
399                         $cumulativeDone += $value->duration * ($value->percent_complete / 100);
400                     }
401                     else
402                     {
403                         $totalHours += ($value->duration * 8);
404                         $cumulativeDone += ($value->duration * 8) * ($value->percent_complete / 100);
405                     }
406                 }
407
408                 $cumulativePercentage = 0;
409                                 if ($totalHours != 0)
410                 {
411                                         $cumulativePercentage = ($cumulativeDone/$totalHours) * 100;
412                 }
413
414                 $parentProjectTask->percent_complete = round($cumulativePercentage);
415                 $parentProjectTask->save(isset($GLOBALS['check_notify']) ? $GLOBALS['check_notify'] : '');
416             }
417                 }
418         }
419
420     /**
421     * Retrieves the parent project task of a project task
422     * returns project task bean
423     */
424     function getProjectTaskParent()
425     {
426
427         $projectTaskParent=false;
428
429         if (!empty($this->parent_task_id) && !empty($this->project_id))
430         {
431             $query = "SELECT id FROM project_task WHERE project_id = '{$this->project_id}' AND project_task_id = '{$this->parent_task_id}' AND deleted = 0 ORDER BY date_modified DESC";
432             $project_task_id = $this->db->getOne($query, true, "Error retrieving parent project task");
433
434             if (!empty($project_task_id))
435             {
436                 $projectTaskParent = BeanFactory::getBean('ProjectTask', $project_task_id);
437             }
438         }
439
440         return $projectTaskParent;
441     }
442
443     /**
444     * Retrieves all the child project tasks of a project task
445     * returns project task bean array
446     */
447     function getAllSubProjectTasks()
448     {
449                 $projectTasksBeans = array();
450
451         if (!empty($this->project_task_id) && !empty($this->project_id))
452                 {
453             //select all tasks from a project
454             $query = "SELECT id, project_task_id, parent_task_id FROM project_task WHERE project_id = '{$this->project_id}' AND deleted = 0 ORDER BY project_task_id";
455
456             $result = $this->db->query($query, true, "Error retrieving child project tasks");
457
458             $projectTasks=array();
459             while($row = $this->db->fetchByAssoc($result))
460             {
461                 $projectTasks[$row['id']]['project_task_id'] = $row['project_task_id'];
462                 $projectTasks[$row['id']]['parent_task_id'] = $row['parent_task_id'];
463             }
464
465             $potentialParentTaskIds[$this->project_task_id] = $this->project_task_id;
466             $actualParentTaskIds=array();
467             $subProjectTasks=array();
468
469             $startProjectTasksCount=0;
470             $endProjectTasksCount=0;
471
472             //get all child tasks
473             $run = true;
474             while ($run)
475             {
476                 $count=0;
477
478                 foreach ($projectTasks as $id=>$values)
479                 {
480                     if (in_array($values['parent_task_id'], $potentialParentTaskIds))
481                     {
482                         $potentialParentTaskIds[$values['project_task_id']] = $values['project_task_id'];
483                         $actualParentTaskIds[$values['parent_task_id']] = $values['parent_task_id'];
484
485                         $subProjectTasks[$id]=$values;
486                         $count=$count+1;
487                     }
488                 }
489
490                 $endProjectTasksCount = count($subProjectTasks);
491
492                 if ($startProjectTasksCount == $endProjectTasksCount)
493                 {
494                     $run = false;
495                 }
496                 else
497                 {
498                     $startProjectTasksCount = $endProjectTasksCount;
499                 }
500             }
501
502             foreach($subProjectTasks as $id=>$values)
503             {
504                 //ignore tasks that are parents
505                 if(!in_array($values['project_task_id'], $actualParentTaskIds))
506                 {
507                     $projectTaskBean = BeanFactory::getBean('ProjectTask', $id);
508                     array_push($projectTasksBeans, $projectTaskBean);
509                 }
510             }
511                 }
512
513                 return $projectTasksBeans;
514         }
515 }
516
517 function getUtilizationDropdown($focus, $field, $value, $view) {
518         global $app_list_strings;
519
520         if($view == 'EditView') {
521                 global $app_list_strings;
522         $html = '<select name="'.$field.'">';
523         $html .= get_select_options_with_id($app_list_strings['project_task_utilization_options'], $value);
524         $html .= '</select>';
525         return $html;
526     }
527
528     return translate('project_task_utilization_options', '', $focus->$field);
529 }
530 ?>