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-2013 SugarCRM Inc.
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.
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
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
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.
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.
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 ********************************************************************************/
39 // Task is used to store customer information.
40 class Task extends SugarBean {
47 var $assigned_user_id;
48 var $modified_user_id;
51 var $modified_by_name;
70 var $assigned_user_name;
73 // 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');
75 var $table_name = "tasks";
77 var $object_name = "Task";
78 var $module_dir = 'Tasks';
80 var $importable = true;
81 // This is used to retrieve related fields from form posts.
82 var $additional_column_fields = Array('assigned_user_name', 'assigned_user_id', 'contact_name', 'contact_phone', 'contact_email', 'parent_name');
89 var $new_schema = true;
91 function save($check_notify = FALSE)
93 if (empty($this->status) ) {
94 $this->status = $this->getDefaultStatus();
96 return parent::save($check_notify);
99 function get_summary_text()
101 return "$this->name";
104 function create_export_query(&$order_by, &$where, $relate_link_join='')
106 $custom_join = $this->getCustomJoin(true, true, $where);
107 $custom_join['join'] .= $relate_link_join;
108 $contact_required = stristr($where,"contacts");
109 if($contact_required)
111 $query = "SELECT tasks.*, contacts.first_name, contacts.last_name, users.user_name as assigned_user_name ";
112 $query .= $custom_join['select'];
113 $query .= " FROM contacts, tasks ";
114 $where_auto = "tasks.contact_id = contacts.id AND tasks.deleted=0 AND contacts.deleted=0";
118 $query = 'SELECT tasks.*, users.user_name as assigned_user_name ';
119 $query .= $custom_join['select'];
120 $query .= ' FROM tasks ';
121 $where_auto = "tasks.deleted=0";
125 $query .= $custom_join['join'];
126 $query .= " LEFT JOIN users ON tasks.assigned_user_id=users.id ";
129 $query .= "where $where AND ".$where_auto;
131 $query .= "where ".$where_auto;
133 $order_by = $this->process_order_by($order_by);
134 if (empty($order_by)) {
135 $order_by = 'tasks.name';
137 $query .= ' ORDER BY ' . $order_by;
145 function fill_in_additional_list_fields()
150 function fill_in_additional_detail_fields()
152 parent::fill_in_additional_detail_fields();
155 if (isset($this->contact_id)) {
157 $contact = new Contact();
158 $contact->retrieve($this->contact_id);
160 if($contact->id != "") {
161 $this->contact_name = $contact->full_name;
162 $this->contact_name_owner = $contact->assigned_user_id;
163 $this->contact_name_mod = 'Contacts';
164 $this->contact_phone = $contact->phone_work;
165 $this->contact_email = $contact->emailAddress->getPrimaryAddress($contact);
167 $this->contact_name_mod = '';
168 $this->contact_name_owner = '';
169 $this->contact_name='';
170 $this->contact_email = '';
171 $this->contact_id='';
176 $this->fill_in_additional_parent_fields();
179 function fill_in_additional_parent_fields()
182 $this->parent_name = '';
183 global $app_strings, $beanFiles, $beanList, $locale;
184 if ( ! isset($beanList[$this->parent_type]))
186 $this->parent_name = '';
190 $beanType = $beanList[$this->parent_type];
191 require_once($beanFiles[$beanType]);
192 $parent = new $beanType();
194 if (is_subclass_of($parent, 'Person')) {
195 $query = "SELECT first_name, last_name, assigned_user_id parent_name_owner from $parent->table_name where id = '$this->parent_id'";
197 else if (is_subclass_of($parent, 'File')) {
198 $query = "SELECT document_name, assigned_user_id parent_name_owner from $parent->table_name where id = '$this->parent_id'";
202 $query = "SELECT name ";
203 if(isset($parent->field_defs['assigned_user_id'])){
204 $query .= " , assigned_user_id parent_name_owner ";
206 $query .= " , created_by parent_name_owner ";
208 $query .= " from $parent->table_name where id = '$this->parent_id'";
210 $result = $this->db->query($query,true," Error filling in additional detail fields: ");
212 // Get the id and the name.
213 $row = $this->db->fetchByAssoc($result);
215 if ($row && !empty($row['parent_name_owner'])){
216 $this->parent_name_owner = $row['parent_name_owner'];
217 $this->parent_name_mod = $this->parent_type;
219 if (is_subclass_of($parent, 'Person') and $row != null)
221 $this->parent_name = $locale->getLocaleFormattedName(stripslashes($row['first_name']), stripslashes($row['last_name']));
223 else if (is_subclass_of($parent, 'File') && $row != null) {
224 $this->parent_name = $row['document_name'];
228 $this->parent_name = stripslashes($row['name']);
231 $this->parent_name = '';
236 protected function formatStartAndDueDates(&$task_fields, $dbtime, $override_date_for_subpanel)
240 if(empty($dbtime)) return;
242 $today = $timedate->nowDbDate();
244 $task_fields['TIME_DUE'] = $timedate->to_display_time($dbtime);
245 $task_fields['DATE_DUE'] = $timedate->to_display_date($dbtime);
247 $date_due = $task_fields['DATE_DUE'];
249 $dd = $timedate->to_db_date($date_due, false);
250 $taskClass = 'futureTask';
252 $taskClass = 'overdueTask';
253 }else if( $dd == $today ){
254 $taskClass = 'todaysTask';
256 $task_fields['DATE_DUE']= "<font class='$taskClass'>$date_due</font>";
257 if($override_date_for_subpanel){
258 $task_fields['DATE_START']= "<font class='$taskClass'>$date_due</font>";
262 function get_list_view_data(){
263 global $action, $currentModule, $focus, $current_module_strings, $app_list_strings, $timedate;
265 $override_date_for_subpanel = false;
266 if(!empty($_REQUEST['module']) && $_REQUEST['module'] !='Calendar' && $_REQUEST['module'] !='Tasks' && $_REQUEST['module'] !='Home'){
267 //this is a subpanel list view, so override the due date with start date so that collections subpanel works as expected
268 $override_date_for_subpanel = true;
271 $today = $timedate->nowDb();
272 $task_fields = $this->get_list_view_array();
273 $dbtime = $timedate->to_db($task_fields['DATE_DUE']);
274 if($override_date_for_subpanel){
275 $dbtime = $timedate->to_db($task_fields['DATE_START']);
280 $task_fields['TIME_DUE'] = $timedate->to_display_time($dbtime);
281 $task_fields['DATE_DUE'] = $timedate->to_display_date($dbtime);
282 $this->formatStartAndDueDates($task_fields, $dbtime, $override_date_for_subpanel);
285 if (!empty($this->priority))
286 $task_fields['PRIORITY'] = $app_list_strings['task_priority_dom'][$this->priority];
287 if (isset($this->parent_type))
288 $task_fields['PARENT_MODULE'] = $this->parent_type;
289 if ($this->status != "Completed" && $this->status != "Deferred" )
291 $setCompleteUrl = "<a id='{$this->id}' onclick='SUGAR.util.closeActivityPanel.show(\"{$this->module_dir}\",\"{$this->id}\",\"Completed\",\"listview\",\"1\");'>";
292 $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>";
295 // make sure we grab the localized version of the contact name, if a contact is provided
296 if (!empty($this->contact_id))
298 $contact_temp = BeanFactory::getBean("Contacts", $this->contact_id);
299 if (!empty($contact_temp))
301 // Make first name, last name, salutation and title of Contacts respect field level ACLs
302 $contact_temp->_create_proper_name_field();
303 $this->contact_name = $contact_temp->full_name;
304 $this->contact_phone = $contact_temp->phone_work;
308 $task_fields['CONTACT_NAME']= $this->contact_name;
309 $task_fields['CONTACT_PHONE']= $this->contact_phone;
310 $task_fields['TITLE'] = '';
311 if (!empty($task_fields['CONTACT_NAME'])) {
312 $task_fields['TITLE'] .= $current_module_strings['LBL_LIST_CONTACT'].": ".$task_fields['CONTACT_NAME'];
314 if (!empty($this->parent_name)) {
315 $task_fields['TITLE'] .= "\n".$app_list_strings['parent_type_display'][$this->parent_type].": ".$this->parent_name;
316 $task_fields['PARENT_NAME']=$this->parent_name;
322 function set_notification_body($xtpl, $task)
324 global $app_list_strings;
326 $notifyUser = $task->current_notify_user;
327 $prefDate = $notifyUser->getUserDateTimePreferences();
328 $xtpl->assign("TASK_SUBJECT", $task->name);
330 $xtpl->assign("TASK_PRIORITY", (isset($task->priority)?$app_list_strings['task_priority_dom'][$task->priority]:""));
332 if(!empty($task->date_due))
334 $duedate = $timedate->fromDb($task->date_due);
335 $xtpl->assign("TASK_DUEDATE", $timedate->asUser($duedate, $notifyUser)." ".TimeDate::userTimezoneSuffix($duedate, $notifyUser));
337 $xtpl->assign("TASK_DUEDATE", '');
340 $xtpl->assign("TASK_STATUS", (isset($task->status)?$app_list_strings['task_status_dom'][$task->status]:""));
341 $xtpl->assign("TASK_DESCRIPTION", $task->description);
346 function bean_implements($interface){
348 case 'ACL':return true;
352 function listviewACLHelper(){
353 $array_assign = parent::listviewACLHelper();
355 if(!empty($this->parent_name)){
356 if(!empty($this->parent_name_owner)){
357 global $current_user;
358 $is_owner = $current_user->id == $this->parent_name_owner;
362 if(!ACLController::moduleSupportsACL($this->parent_type) || ACLController::checkAccess($this->parent_type, 'view', $is_owner)){
363 $array_assign['PARENT'] = 'a';
365 $array_assign['PARENT'] = 'span';
368 if(!empty($this->contact_name)){
369 if(!empty($this->contact_name_owner)){
370 global $current_user;
371 $is_owner = $current_user->id == $this->contact_name_owner;
375 if( ACLController::checkAccess('Contacts', 'view', $is_owner)){
376 $array_assign['CONTACT'] = 'a';
378 $array_assign['CONTACT'] = 'span';
381 return $array_assign;
384 public function getDefaultStatus()
386 $def = $this->field_defs['status'];
387 if (isset($def['default'])) {
388 return $def['default'];
390 $app = return_app_list_strings_language($GLOBALS['current_language']);
391 if (isset($def['options']) && isset($app[$def['options']])) {
392 $keys = array_keys($app[$def['options']]);