]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/Tasks/Task.php
Release 6.4.0beta3
[Github/sugarcrm.git] / modules / Tasks / Task.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  * Description:  TODO: To be written.
41  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
42  * All Rights Reserved.
43  * Contributor(s): ______________________________________..
44  ********************************************************************************/
45
46
47
48
49
50
51
52 // Task is used to store customer information.
53 class Task extends SugarBean {
54         var $field_name_map;
55
56         // Stored fields
57         var $id;
58         var $date_entered;
59         var $date_modified;
60         var $assigned_user_id;
61         var $modified_user_id;
62         var $created_by;
63         var $created_by_name;
64         var $modified_by_name;
65         var $description;
66         var $name;
67         var $status;
68         var $date_due_flag;
69         var $date_due;
70         var $time_due;
71         var $date_start_flag;
72         var $date_start;
73         var $time_start;
74         var $priority;
75         var $parent_type;
76         var $parent_id;
77         var $contact_id;
78
79         var $parent_name;
80         var $contact_name;
81         var $contact_phone;
82         var $contact_email;
83         var $assigned_user_name;
84
85 //bug 28138 todo
86 //      var $default_task_name_values = array('Assemble catalogs', 'Make travel arrangements', 'Send a letter', 'Send contract', 'Send fax', 'Send a follow-up letter', 'Send literature', 'Send proposal', 'Send quote', 'Call to schedule meeting', 'Setup evaluation', 'Get demo feedback', 'Arrange introduction', 'Escalate support request', 'Close out support request', 'Ship product', 'Arrange reference call', 'Schedule training', 'Send local user group information', 'Add to mailing list');
87
88         var $table_name = "tasks";
89
90         var $object_name = "Task";
91         var $module_dir = 'Tasks';
92
93         var $importable = true;
94         // This is used to retrieve related fields from form posts.
95         var $additional_column_fields = Array('assigned_user_name', 'assigned_user_id', 'contact_name', 'contact_phone', 'contact_email', 'parent_name');
96
97
98         function Task() {
99                 parent::SugarBean();
100         }
101
102         var $new_schema = true;
103
104     function save($check_notify = FALSE)
105     {
106         if (empty($this->status) ) {
107             $this->status = $this->getDefaultStatus();
108         }
109         return parent::save($check_notify);
110     }
111
112         function get_summary_text()
113         {
114                 return "$this->name";
115         }
116
117     function create_export_query(&$order_by, &$where, $relate_link_join='')
118     {
119         $custom_join = $this->custom_fields->getJOIN(true, true,$where);
120                 if($custom_join)
121                                 $custom_join['join'] .= $relate_link_join;
122                 $contact_required = stristr($where,"contacts");
123                 if($contact_required)
124                 {
125                         $query = "SELECT tasks.*, contacts.first_name, contacts.last_name, users.user_name as assigned_user_name ";
126                         if($custom_join){
127                                                         $query .= $custom_join['select'];
128                                                 }
129                         $query .= " FROM contacts, tasks ";
130                         $where_auto = "tasks.contact_id = contacts.id AND tasks.deleted=0 AND contacts.deleted=0";
131                 }
132                 else
133                 {
134                         $query = 'SELECT tasks.*, users.user_name as assigned_user_name ';
135                         if($custom_join){
136                                                         $query .= $custom_join['select'];
137                                                 }
138                         $query .= ' FROM tasks ';
139                         $where_auto = "tasks.deleted=0";
140                 }
141
142
143                                 if($custom_join){
144                                         $query .= $custom_join['join'];
145                                 }
146                 $query .= "  LEFT JOIN users ON tasks.assigned_user_id=users.id ";
147
148                 if($where != "")
149                         $query .= "where $where AND ".$where_auto;
150                 else
151                         $query .= "where ".$where_auto;
152
153                 if($order_by != "")
154                         $query .=  " ORDER BY ". $this->process_order_by($order_by, null);
155                 else
156                         $query .= " ORDER BY tasks.name";
157                 return $query;
158
159         }
160
161
162
163         function fill_in_additional_list_fields()
164         {
165
166         }
167
168         function fill_in_additional_detail_fields()
169         {
170         parent::fill_in_additional_detail_fields();
171                 global $app_strings;
172
173                 if (isset($this->contact_id)) {
174
175                         $contact = new Contact();
176                         $contact->retrieve($this->contact_id);
177
178                         if($contact->id != "") {
179                                 $this->contact_name = $contact->full_name;
180                                 $this->contact_name_owner = $contact->assigned_user_id;
181                                 $this->contact_name_mod = 'Contacts';
182                                 $this->contact_phone = $contact->phone_work;
183                                 $this->contact_email = $contact->emailAddress->getPrimaryAddress($contact);
184                         } else {
185                                 $this->contact_name_mod = '';
186                                 $this->contact_name_owner = '';
187                                 $this->contact_name='';
188                                 $this->contact_email = '';
189                                 $this->contact_id='';
190                         }
191
192                 }
193
194                 $this->fill_in_additional_parent_fields();
195         }
196
197         function fill_in_additional_parent_fields()
198         {
199
200                 $this->parent_name = '';
201                 global $app_strings, $beanFiles, $beanList, $locale;
202                 if ( ! isset($beanList[$this->parent_type]))
203                 {
204                         $this->parent_name = '';
205                         return;
206                 }
207
208             $beanType = $beanList[$this->parent_type];
209                 require_once($beanFiles[$beanType]);
210                 $parent = new $beanType();
211
212                 if (is_subclass_of($parent, 'Person')) {
213                         $query = "SELECT first_name, last_name, assigned_user_id parent_name_owner from $parent->table_name where id = '$this->parent_id'";
214                 }
215                 else if (is_subclass_of($parent, 'File')) {
216                         $query = "SELECT document_name, assigned_user_id parent_name_owner from $parent->table_name where id = '$this->parent_id'";
217                 }
218                 else {
219
220                         $query = "SELECT name ";
221                         if(isset($parent->field_defs['assigned_user_id'])){
222                                 $query .= " , assigned_user_id parent_name_owner ";
223                         }else{
224                                 $query .= " , created_by parent_name_owner ";
225                         }
226                         $query .= " from $parent->table_name where id = '$this->parent_id'";
227                 }
228                 $result = $this->db->query($query,true," Error filling in additional detail fields: ");
229
230                 // Get the id and the name.
231                 $row = $this->db->fetchByAssoc($result);
232
233                 if ($row && !empty($row['parent_name_owner'])){
234                         $this->parent_name_owner = $row['parent_name_owner'];
235                         $this->parent_name_mod = $this->parent_type;
236                 }
237                 if (is_subclass_of($parent, 'Person') and $row != null)
238                 {
239                         $this->parent_name = $locale->getLocaleFormattedName(stripslashes($row['first_name']), stripslashes($row['last_name']));
240                 }
241                 else if (is_subclass_of($parent, 'File') && $row != null) {
242                         $this->parent_name = $row['document_name'];
243                 }
244                 elseif($row != null)
245                 {
246                         $this->parent_name = stripslashes($row['name']);
247                 }
248                 else {
249                         $this->parent_name = '';
250                 }
251         }
252
253
254     protected function formatStartAndDueDates(&$task_fields, $dbtime, $override_date_for_subpanel)
255     {
256         global $timedate;
257
258         if(empty($dbtime)) return;
259
260         $today = $timedate->nowDbDate();
261
262         $task_fields['TIME_DUE'] = $timedate->to_display_time($dbtime);
263         $task_fields['DATE_DUE'] = $timedate->to_display_date($dbtime);
264
265         $date_due = $task_fields['DATE_DUE'];
266
267         $dd = $timedate->to_db_date($date_due, false);
268         $taskClass = 'futureTask';
269                 if ($dd < $today){
270             $taskClass = 'overdueTask';
271                 }else if( $dd   == $today ){
272             $taskClass = 'todaysTask';
273                 }
274         $task_fields['DATE_DUE']= "<font class='$taskClass'>$date_due</font>";
275         if($override_date_for_subpanel){
276             $task_fields['DATE_START']= "<font class='$taskClass'>$date_due</font>";
277         }
278     }
279
280         function get_list_view_data(){
281                 global $action, $currentModule, $focus, $current_module_strings, $app_list_strings, $timedate;
282
283                 $override_date_for_subpanel = false;
284                 if(!empty($_REQUEST['module']) && $_REQUEST['module'] !='Calendar' && $_REQUEST['module'] !='Tasks' && $_REQUEST['module'] !='Home'){
285                         //this is a subpanel list view, so override the due date with start date so that collections subpanel works as expected
286                         $override_date_for_subpanel = true;
287                 }
288
289                 $today = $timedate->nowDb();
290                 $task_fields = $this->get_list_view_array();
291                 $dbtime = $timedate->to_db($task_fields['DATE_DUE']);
292                 if($override_date_for_subpanel){
293                         $dbtime = $timedate->to_db($task_fields['DATE_START']);
294                 }
295
296         $task_fields['TIME_DUE'] = $timedate->to_display_time($dbtime);
297         $task_fields['DATE_DUE'] = $timedate->to_display_date($dbtime);
298
299         $this->formatStartAndDueDates($task_fields, $dbtime, $override_date_for_subpanel);
300
301                 if (!empty($this->priority))
302                         $task_fields['PRIORITY'] = $app_list_strings['task_priority_dom'][$this->priority];
303                 if (isset($this->parent_type))
304                         $task_fields['PARENT_MODULE'] = $this->parent_type;
305                 if ($this->status != "Completed" && $this->status != "Deferred" )
306                 {
307                         $setCompleteUrl = "<a onclick='SUGAR.util.closeActivityPanel.show(\"{$this->module_dir}\",\"{$this->id}\",\"Completed\",\"listview\",\"1\");'>";
308                     $task_fields['SET_COMPLETE'] = $setCompleteUrl . SugarThemeRegistry::current()->getImage("close_inline","title=".translate('LBL_LIST_CLOSE','Tasks')." border='0'",null,null,'.gif',translate('LBL_LIST_CLOSE','Tasks'))."</a>";
309                 }
310
311
312         if(!empty($task_fields['DATE_DUE']))
313         {
314             $date_due = $task_fields['DATE_DUE'];
315             $dd = $timedate->to_db_date_time($this->date_due, $this->time_due);
316
317             if ($dd < $today){
318                 $task_fields['DATE_DUE']= "<font class='overdueTask'>".$date_due."</font>";
319                 if($override_date_for_subpanel){
320                     $task_fields['DATE_START']= "<font class='overdueTask'>".$date_due."</font>";
321                 }
322             }else if( $dd == $today ){
323                 $task_fields['DATE_DUE'] = "<font class='todaysTask'>".$date_due."</font>";
324                 if($override_date_for_subpanel){
325                     $task_fields['DATE_START'] = "<font class='todaysTask'>".$date_due."</font>";
326                 }
327             }else{
328                 $task_fields['DATE_DUE'] = "<font class='futureTask'>".$date_due."</font>";
329                 if($override_date_for_subpanel){
330                     $task_fields['DATE_START'] = "<font class='futureTask'>".$date_due."</font>";
331                 }
332             }
333         }
334
335                 //make sure we grab the localized version of the contact name, if a contact is provided
336                 if (!empty($this->contact_id)) {
337             // Bug# 46125 - make first name, last name, salutation and title of Contacts respect field level ACLs
338             $contact = new Contact();
339                         $contact->retrieve($this->contact_id);
340                         if(isset($contact->id)) {
341                             $this->contact_name = $contact->full_name;
342                 $this->contact_phone = $contact->phone_work;
343                         }
344                 }
345
346                 $task_fields['CONTACT_NAME']= $this->contact_name;
347                 $task_fields['CONTACT_PHONE']= $this->contact_phone;
348                 $task_fields['TITLE'] = '';
349                 if (!empty($task_fields['CONTACT_NAME'])) {
350                         $task_fields['TITLE'] .= $current_module_strings['LBL_LIST_CONTACT'].": ".$task_fields['CONTACT_NAME'];
351                 }
352                 if (!empty($this->parent_name)) {
353                         $task_fields['TITLE'] .= "\n".$app_list_strings['parent_type_display'][$this->parent_type].": ".$this->parent_name;
354                         $task_fields['PARENT_NAME']=$this->parent_name;
355                 }
356
357                 return $task_fields;
358         }
359
360         function set_notification_body($xtpl, $task)
361         {
362                 global $app_list_strings;
363         global $timedate;
364         $notifyUser = $task->current_notify_user;
365         $prefDate = $notifyUser->getUserDateTimePreferences();
366                 $xtpl->assign("TASK_SUBJECT", $task->name);
367                 //MFH #13507
368                 $xtpl->assign("TASK_PRIORITY", (isset($task->priority)?$app_list_strings['task_priority_dom'][$task->priority]:""));
369         $userGMT = !empty($prefDate['userGmt']) ? $prefDate['userGmt'] : '';
370                 $xtpl->assign("TASK_DUEDATE", $timedate->to_display_date_time($task->date_due . " " . $task->time_due,true,true,$notifyUser)." ".$userGMT);
371                 $xtpl->assign("TASK_STATUS", (isset($task->status)?$app_list_strings['task_status_dom'][$task->status]:""));
372                 $xtpl->assign("TASK_DESCRIPTION", $task->description);
373
374                 return $xtpl;
375         }
376
377         function bean_implements($interface){
378                 switch($interface){
379                         case 'ACL':return true;
380                 }
381                 return false;
382         }
383         function listviewACLHelper(){
384                 $array_assign = parent::listviewACLHelper();
385                 $is_owner = false;
386                 if(!empty($this->parent_name)){
387                         if(!empty($this->parent_name_owner)){
388                                 global $current_user;
389                                 $is_owner = $current_user->id == $this->parent_name_owner;
390                         }
391                 }
392
393                         if(!ACLController::moduleSupportsACL($this->parent_type) || ACLController::checkAccess($this->parent_type, 'view', $is_owner)){
394                                 $array_assign['PARENT'] = 'a';
395                         }else{
396                                 $array_assign['PARENT'] = 'span';
397                         }
398                 $is_owner = false;
399                 if(!empty($this->contact_name)){
400                         if(!empty($this->contact_name_owner)){
401                                 global $current_user;
402                                 $is_owner = $current_user->id == $this->contact_name_owner;
403                         }
404                 }
405
406                 if( ACLController::checkAccess('Contacts', 'view', $is_owner)){
407                                 $array_assign['CONTACT'] = 'a';
408                 }else{
409                                 $array_assign['CONTACT'] = 'span';
410                 }
411
412                 return $array_assign;
413         }
414
415         public function getDefaultStatus()
416     {
417          $def = $this->field_defs['status'];
418          if (isset($def['default'])) {
419              return $def['default'];
420          } else {
421             $app = return_app_list_strings_language($GLOBALS['current_language']);
422             if (isset($def['options']) && isset($app[$def['options']])) {
423                 $keys = array_keys($app[$def['options']]);
424                 return $keys[0];
425             }
426         }
427         return '';
428     }
429
430 }