diff --git a/timesheet/inc/class.timesheet_bo.inc.php b/timesheet/inc/class.timesheet_bo.inc.php index 3e39419d8a..42247ba41a 100644 --- a/timesheet/inc/class.timesheet_bo.inc.php +++ b/timesheet/inc/class.timesheet_bo.inc.php @@ -19,6 +19,8 @@ if (!defined('TIMESHEET_APP')) * Business object of the TimeSheet * * Uses eTemplate's so_sql as storage object (Table: egw_timesheet). + * + * @todo Implement sorting&filtering by and searching of custom fields */ class timesheet_bo extends so_sql { @@ -100,17 +102,18 @@ class timesheet_bo extends so_sql var $customfields=array(); + /** + * Name of the timesheet table storing custom fields + */ + const EXTRA_TABLE = 'egw_timesheet_extra'; + function __construct() { parent::__construct(TIMESHEET_APP,'egw_timesheet',null,'',true); // true = use global db object! $this->config_data = config::read(TIMESHEET_APP); $this->quantity_sum = $this->config_data['quantity_sum'] == 'true'; - - if (isset($this->config_data['customfields']) && is_array($this->config_data['customfields'])) - { - $this->customfields = $this->config_data['customfields']; - } + $this->customfields = config::get_customfields(TIMESHEET_APP); $this->tz_offset_s = $GLOBALS['egw']->datetime->tz_offset; $this->now = time() + $this->tz_offset_s; // time() is server-time and we need a user-time @@ -156,14 +159,15 @@ class timesheet_bo extends so_sql */ function check_acl($required,$data=null) { - if (!$data) + //error_log(__METHOD__."($required,".array2string($data).")"); + if (is_null($data) || (int)$data == $this->data['ts_id']) { $data =& $this->data; } if (!is_array($data)) { $save_data = $this->data; - $data = $this->read($data,true); + $data = $this->read($data,true,false); // no need to read cf's $this->data = $save_data; if (!$data) return null; // entry not found @@ -173,6 +177,14 @@ class timesheet_bo extends so_sql return $data && !!($rights & $required); } + /** + * return SQL implementing filtering by date + * + * @param string $name + * @param int &$start + * @param int &$end_param + * @return string + */ function date_filter($name,&$start,&$end_param) { $end = $end_param; @@ -263,6 +275,7 @@ class timesheet_bo extends so_sql */ function &search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='',$need_full_no_count=false,$only_summary=false) { + error_log(__METHOD__."(".print_r($criteria,true).",'$only_keys','$order_by',".print_r($extra_cols,true).",'$wildcard','$empty','$op','$start',".print_r($filter,true).",'$join')"); //echo "
".__METHOD__."(".print_r($criteria,true).",'$only_keys','$order_by',".print_r($extra_cols,true).",'$wildcard','$empty','$op','$start',".print_r($filter,true).",'$join')
\n"; // postgres can't round from double precission, only from numeric ;-) $total_sql = $this->db->Type != 'pgsql' ? "round(ts_quantity*ts_unitprice,2)" : "round(cast(ts_quantity*ts_unitprice AS numeric),2)"; @@ -346,40 +359,55 @@ class timesheet_bo extends so_sql * * @param int $ts_id * @param boolean $ignore_acl=false should the acl be checked + * @param boolean $read_cfs=true also read the custom fields * @return array/boolean array with timesheet entry, null if timesheet not found or false if no rights */ - function read($ts_id,$ignore_acl=false) + function read($ts_id,$ignore_acl=false,$read_cfs=true) { - $ret = null; - if (!(int)$ts_id || !$ignore_acl && !($ret = $this->check_acl(EGW_ACL_READ,$ts_id)) || - $this->data['ts_id'] != (int)$ts_id && !parent::read((int)$ts_id)) + error_log(__METHOD__."($ts_id,$ignore_acl) ".function_backtrace()); + if (!(int)$ts_id || (int)$ts_id != $this->data['ts_id'] && !parent::read($ts_id)) { - return $ret; // no read rights, or entry not found + return null; // entry not found } - - //assign custom fields - foreach($this->customfields as $name => $value) { - $row = $this->read_extra($name); - $this->data['#'.$name] = $row['ts_extra_value']; + if (!$ignore_acl && !($ret = $this->check_acl(EGW_ACL_READ))) + { + return false; // no read rights + } + if ($read_cfs && $this->customfields && ($cfs = $this->read_cfs($ts_id))) + { + $this->data += $cfs[$ts_id]; } - return $this->data; } /** - * reads a timesheet extra entry of the current timesheet dataset + * Read the cf's of the given ts_id's and evtl names * - * @param int $name => name of the current timesheet extra entry - * @param int $value => value of the current timesheet extra entry - * @return array of resultset + * @param int|array $ts_ids + * @param array $names=null + * @return array with ts_id => array(name => value) pairs */ - function read_extra($name='',$value='') + function read_cfs($ts_ids,$names=null) { - strlen($value) > 0 ? $where = ' and ts_extra_value ='.$this->db->quote($value) : ''; - strlen($name) > 0 ? $where .= ' and ts_extra_name ='.$this->db->quote($name) : ''; - - return $this->db->select('egw_timesheet_extra', 'ts_extra_name, ts_extra_value',$query,__LINE__,__FILE__,False,'', - TIMESHEET_APP,0,'where ts_id='.$this->data['ts_id'].$where)->fetch(); + error_log(__METHOD__."(".array2string($ts_ids).",".array2string($names).")"); + if (!$this->customfields || !$ts_ids) + { + return array(); + } + $where = array('ts_id' => $ts_ids); + if ($names) + { + foreach($names as $name) + { + if ($name[0] == '#') $where['ts_extra_name'][] = substr($name,1); + } + } + $cfs = array(); + foreach($this->db->select(self::EXTRA_TABLE,'ts_id,ts_extra_name,ts_extra_value',$where,__LINE__,__FILE__,false,'',TIMESHEET_APP) as $row) + { + $cfs[$row['ts_id']]['#'.$row['ts_extra_name']] = $row['ts_extra_value']; + } + return $cfs; } /** @@ -407,53 +435,28 @@ class timesheet_bo extends so_sql } if (!($err = parent::save())) { - //saves data of custom fields in timesheet_extra - $this->save_extra(); + if ($this->customfields) //saves data of custom fields in timesheet_extra + { + $this->db->delete(self::EXTRA_TABLE,array('ts_id' => $this->data['ts_id']),__LINE__,__FILE__,TIMESHEET_APP); + foreach($this->customfields as $name => $data) + { + if (isset($this->data['#'.$name]) && !empty($this->data['#'.$name])) + { + $this->db->insert(self::EXTRA_TABLE,array( + 'ts_id' => $this->data['ts_id'], + 'ts_extra_name' => $name, + 'ts_extra_value' => $this->data['#'.$name], + ),false,__LINE__,__FILE__,TIMESHEET_APP); + } + } + } // notify the link-class about the update, as other apps may be subscribt to it egw_link::notify_update(TIMESHEET_APP,$this->data['ts_id'],$this->data); } return $err; } - /** - * saves a timesheet extra entry based one the "custom fields" settings - * - * @param boolean $updateNames => if true "change timesheet extra name", otherwise update existing datasets or insert new ones - * @param boolean $oldname => original name of the timesheet extra entry - * @param boolean $name => new name of the timesheet extra entry - * @return int true on success else false - */ - function save_extra($updateNames=False,$oldname='',$name='') - { - if($updateNames) { - $keys = array('ts_extra_name' => $oldname); - $fieldAssign = array('ts_extra_name' => $name); - $this->db->update('egw_timesheet_extra',$fieldAssign,$keys,__LINE__,__FILE__,TIMESHEET_APP); - return true; - } - else { - foreach($this->customfields as $namecf => $valuecf) - { - //if entry not exist => insert - if(!$this->read_extra($namecf)) - { - $fieldAssign = array('ts_id' => $this->data['ts_id'],'ts_extra_name' => $namecf,'ts_extra_value' => $this->data['#'.$namecf]); - $this->db->insert('egw_timesheet_extra',$fieldAssign,false,__LINE__,__FILE__,TIMESHEET_APP); - } - //otherwise update existing dataset - else - { - $keys = array('ts_extra_name' => $namecf, 'ts_id' => $this->data['ts_id']); - $fieldAssign = array('ts_extra_value' => $this->data['#'.$namecf]); - $this->db->update('egw_timesheet_extra',$fieldAssign,$keys,__LINE__,__FILE__,TIMESHEET_APP); - } - } - return true; - } - return false; - } - /** * deletes a timesheet entry identified by $keys or the loaded one, reimplemented to notify the link class (unlink) * @@ -475,35 +478,16 @@ class timesheet_bo extends so_sql } if (($ret = parent::delete($keys)) && $ts_id) { - //delete custom fields entries - $this->delete_extra($ts_id); - + if ($this->customfields) //delete custom fields entries + { + $this->db->delete(self::EXTRA_TABLE,array('ts_id' => $ts_id),__LINE__,__FILE__,TIMESHEET_APP); + } // delete all links to timesheet entry $ts_id egw_link::unlink(0,TIMESHEET_APP,$ts_id); } return $ret; } - - /** - * deletes a timesheet extra entry identified by $ts_id and/or $ts_exra_name - * - * @param int $ts_id => number of timesheet - * @param string ts_extra_name => certain custom field name - * @return int false if an error - */ - function delete_extra($ts_id='',$ts_extra_name='') - { - strlen($ts_id) > 0 ? $where['ts_id'] = $ts_id : ''; - strlen($ts_extra_name) > 0 ? $where['ts_extra_name'] = $ts_extra_name : ''; - - if(count($where) > 0) - { - return $this->db->delete('egw_timesheet_extra', $where,__LINE__,__FILE__,TIMESHEET_APP); - } - return false; - } - /** * changes the data from the db-format to your work-format * @@ -571,7 +555,7 @@ class timesheet_bo extends so_sql { if (!is_array($entry)) { - $entry = $this->read( $entry ); + $entry = $this->read( $entry,false,false ); // no need to read cfs } if (!$entry) { @@ -684,7 +668,7 @@ class timesheet_bo extends so_sql { if($pm_id && isset($GLOBALS['egw_info']['user']['apps']['projectmanager'])) { - $pm_ids = ExecMethod('projectmanager.boprojectmanager.children',$pm_id); + $pm_ids = ExecMethod('projectmanager.projectmanager_bo.children',$pm_id); $pm_ids[] = $pm_id; $links = solink::get_links('projectmanager',$pm_ids,'timesheet'); // solink::get_links not egw_links::get_links! if ($links) diff --git a/timesheet/inc/class.timesheet_ui.inc.php b/timesheet/inc/class.timesheet_ui.inc.php index 44665ea0ea..3178ac8a37 100644 --- a/timesheet/inc/class.timesheet_ui.inc.php +++ b/timesheet/inc/class.timesheet_ui.inc.php @@ -487,7 +487,7 @@ class timesheet_ui extends timesheet_bo $GLOBALS['egw_info']['flags']['app_header'] .= ' - '.$GLOBALS['egw']->common->show_date($query['enddate']+12*60*60,$df,false); } } - if ($query['filter'] == 'custom') // show the custome dates + if ($query['filter'] == 'custom') // show the custom dates { $GLOBALS['egw']->js->set_onload("set_style_by_class('table','custom_hide','visibility','visible');"); } @@ -504,10 +504,16 @@ class timesheet_ui extends timesheet_bo $rows = $ids; return $this->total; // no need to set other fields or $readonlys } - $links = egw_link::get_links_multiple(TIMESHEET_APP,$ids); + $links = egw_link::get_links_multiple(TIMESHEET_APP,$ids,true,'projectmanager'); // only check for pm links! unset($query['col_filter'][0]); + // query cf's for the displayed rows + if ($ids && $this->customfields && + in_array('customfields',$cols_to_show=explode(',',$GLOBALS['egw_info']['user']['preferences'][TIMESHEET_APP]['nextmatch-timesheet.index.rows']))) + { + $cfs = $this->read_cfs($ids,$cols_to_show); + } $readonlys = array(); $have_cats = false; foreach($rows as &$row) @@ -541,6 +547,10 @@ class timesheet_ui extends timesheet_bo $row['titleClass'] = 'titleSum'; continue; } + elseif($cfs && isset($cfs[$row['ts_id']])) + { + $row += $cfs[$row['ts_id']]; + } if (!$this->check_acl(EGW_ACL_EDIT,$row)) { $readonlys["edit[$row[ts_id]]"] = true; @@ -582,10 +592,7 @@ class timesheet_ui extends timesheet_bo $rows += $this->summary; } $rows['pm_integration'] = $this->pm_integration; - - if($this->ts_viewtype == 'short') { - $rows['ts_viewtype'] = true; - } + $rows['ts_viewtype'] = $this->ts_viewtype == 'short'; return $total; } diff --git a/timesheet/setup/etemplates.inc.php b/timesheet/setup/etemplates.inc.php index 4e001dba28..668ad29468 100644 --- a/timesheet/setup/etemplates.inc.php +++ b/timesheet/setup/etemplates.inc.php @@ -2,7 +2,7 @@ /** * eGroupWare - eTemplates for Application timesheet * http://www.egroupware.org - * generated by soetemplate::dump4setup() 2008-10-07 11:25 + * generated by soetemplate::dump4setup() 2008-10-15 18:52 * * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @package timesheet @@ -30,6 +30,8 @@ $templ_data[] = array('name' => 'timesheet.edit','template' => '','lang' => '',' $templ_data[] = array('name' => 'timesheet.edit.customfields','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:1:{s:4:"type";s:12:"customfields";}}}s:4:"rows";i:1;s:4:"cols";i:1;}}','size' => '','style' => '','modified' => '1163173930',); +$templ_data[] = array('name' => 'timesheet.edit.customfields','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:0:{}i:1;a:1:{s:1:"A";a:1:{s:4:"type";s:12:"customfields";}}}s:4:"rows";i:1;s:4:"cols";i:1;s:4:"size";s:17:"100%,150,,,,,auto";s:7:"options";a:3:{i:0;s:4:"100%";i:1;s:3:"150";i:6;s:4:"auto";}}}','size' => '','style' => '','modified' => '1163173930',); + $templ_data[] = array('name' => 'timesheet.edit.general','template' => '','lang' => '','group' => '0','version' => '1.3.002','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:7:{i:0;a:13:{s:2:"c1";s:3:"row";s:1:"A";s:2:"95";s:2:"c3";s:3:"row";s:2:"c4";s:3:"row";s:2:"c5";s:3:"row";s:1:"B";s:3:"120";s:1:"C";s:15:"80,@ts_viewtype";s:1:"D";s:13:",@ts_viewtype";s:2:"c6";s:3:"row";s:2:"h6";s:13:",@ts_viewtype";s:2:"c2";s:3:"row";s:2:"h2";s:14:",!@ts_viewtype";s:2:"h1";s:13:",@ts_viewtype";}i:1;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:11:",,,ts_title";s:5:"label";s:5:"Title";}s:1:"B";a:5:{s:4:"type";s:4:"text";s:4:"size";s:5:"65,80";s:4:"name";s:8:"ts_title";s:4:"blur";s:14:"@ts_title_blur";s:4:"span";s:3:"all";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}i:2;a:4:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"comment";}s:1:"B";a:3:{s:4:"type";s:8:"textarea";s:4:"size";s:4:"5,50";s:4:"name";s:14:"ts_description";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}i:3;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:9:",,,cat_id";s:5:"label";s:8:"Category";}s:1:"B";a:4:{s:4:"type";s:10:"select-cat";s:4:"name";s:6:"cat_id";s:4:"size";s:4:"None";s:4:"span";s:3:"all";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}i:4;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:11:",,,ts_start";s:5:"label";s:4:"Date";}s:1:"B";a:4:{s:4:"type";s:4:"date";s:4:"name";s:8:"ts_start";s:6:"needed";s:1:"1";s:4:"size";s:2:",8";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Starttime";}s:1:"D";a:2:{s:4:"type";s:13:"date-timeonly";s:4:"name";s:10:"start_time";}}i:5;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:14:",,,ts_duration";s:5:"label";s:8:"Duration";}s:1:"B";a:3:{s:4:"type";s:13:"date-duration";s:4:"name";s:11:"ts_duration";s:4:"size";s:3:",hm";}s:1:"C";a:3:{s:4:"type";s:5:"label";s:5:"label";s:10:"or endtime";s:4:"span";s:7:",noWrap";}s:1:"D";a:2:{s:4:"type";s:13:"date-timeonly";s:4:"name";s:8:"end_time";}}i:6;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:14:",,,ts_quantity";s:5:"label";s:8:"Quantity";}s:1:"B";a:6:{s:4:"type";s:5:"float";s:4:"name";s:11:"ts_quantity";s:4:"help";s:30:"empty if identical to duration";s:4:"blur";s:17:"@ts_quantity_blur";s:4:"size";s:4:",,,3";s:4:"span";s:3:"all";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:6;s:4:"cols";i:4;s:4:"size";s:8:"100%,150";s:7:"options";a:2:{i:0;s:4:"100%";i:1;s:3:"150";}}}','size' => '100%,150','style' => '','modified' => '1164289627',); $templ_data[] = array('name' => 'timesheet.edit.general','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:7:{i:0;a:13:{s:2:"c1";s:3:"row";s:1:"A";s:2:"95";s:2:"c3";s:3:"row";s:2:"c4";s:3:"row";s:2:"c5";s:3:"row";s:1:"B";s:3:"120";s:1:"C";s:15:"80,@ts_viewtype";s:1:"D";s:13:",@ts_viewtype";s:2:"c6";s:3:"row";s:2:"h6";s:13:",@ts_viewtype";s:2:"c2";s:3:"row";s:2:"h2";s:14:",!@ts_viewtype";s:2:"h1";s:13:",@ts_viewtype";}i:1;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:11:",,,ts_title";s:5:"label";s:5:"Title";}s:1:"B";a:5:{s:4:"type";s:4:"text";s:4:"size";s:5:"65,80";s:4:"name";s:8:"ts_title";s:4:"blur";s:14:"@ts_title_blur";s:4:"span";s:13:"all,fullWidth";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}i:2;a:4:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"comment";}s:1:"B";a:4:{s:4:"type";s:8:"textarea";s:4:"size";s:4:"5,50";s:4:"name";s:14:"ts_description";s:4:"span";s:13:"all,fullWidth";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}i:3;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:9:",,,cat_id";s:5:"label";s:8:"Category";}s:1:"B";a:4:{s:4:"type";s:10:"select-cat";s:4:"name";s:6:"cat_id";s:4:"size";s:4:"None";s:4:"span";s:3:"all";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}i:4;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:11:",,,ts_start";s:5:"label";s:4:"Date";}s:1:"B";a:4:{s:4:"type";s:4:"date";s:4:"name";s:8:"ts_start";s:6:"needed";s:1:"1";s:4:"size";s:2:",8";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Starttime";}s:1:"D";a:2:{s:4:"type";s:13:"date-timeonly";s:4:"name";s:10:"start_time";}}i:5;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:14:",,,ts_duration";s:5:"label";s:8:"Duration";}s:1:"B";a:3:{s:4:"type";s:13:"date-duration";s:4:"name";s:11:"ts_duration";s:4:"size";s:3:",hm";}s:1:"C";a:3:{s:4:"type";s:5:"label";s:5:"label";s:10:"or endtime";s:4:"span";s:7:",noWrap";}s:1:"D";a:2:{s:4:"type";s:13:"date-timeonly";s:4:"name";s:8:"end_time";}}i:6;a:4:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:14:",,,ts_quantity";s:5:"label";s:8:"Quantity";}s:1:"B";a:6:{s:4:"type";s:5:"float";s:4:"name";s:11:"ts_quantity";s:4:"help";s:30:"empty if identical to duration";s:4:"blur";s:17:"@ts_quantity_blur";s:4:"size";s:4:",,,3";s:4:"span";s:3:"all";}s:1:"C";a:1:{s:4:"type";s:5:"label";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:6;s:4:"cols";i:4;s:4:"size";s:8:"100%,150";s:7:"options";a:2:{i:0;s:4:"100%";i:1;s:3:"150";}}}','size' => '100%,150','style' => '','modified' => '1164289627',); @@ -52,3 +54,5 @@ $templ_data[] = array('name' => 'timesheet.index.rows','template' => '','lang' = $templ_data[] = array('name' => 'timesheet.index.rows','template' => '','lang' => '','group' => '0','version' => '1.5.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:8:{s:2:"c1";s:2:"th";s:2:"c2";s:16:"$row_cont[class]";s:1:"A";s:3:"15%";s:1:"B";s:3:"50%";s:1:"H";s:14:",@no_owner_col";s:1:"G";s:13:",@ts_viewtype";s:1:"F";s:13:",@ts_viewtype";s:1:"E";s:13:",@ts_viewtype";}i:1;a:9:{s:1:"A";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Date";s:4:"name";s:8:"ts_start";}s:1:"B";a:7:{s:4:"type";s:4:"grid";s:7:"no_lang";s:1:"1";s:4:"data";a:4:{i:0;a:2:{s:2:"h1";s:21:",@pm_integration=full";s:2:"h2";s:22:",!@pm_integration=full";}i:1;a:1:{s:1:"A";a:4:{s:4:"type";s:22:"nextmatch-filterheader";s:4:"size";s:12:"All projects";s:4:"name";s:10:"ts_project";s:7:"no_lang";s:1:"1";}}i:2;a:1:{s:1:"A";a:4:{s:4:"type";s:22:"nextmatch-customfilter";s:4:"size";s:34:"projectmanager-select,All projects";s:4:"name";s:5:"pm_id";s:8:"onchange";i:1;}}i:3;a:1:{s:1:"A";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Title";s:4:"name";s:8:"ts_title";}}}s:4:"rows";i:3;s:4:"cols";i:1;s:7:"options";a:2:{i:4;s:1:"1";i:5;s:1:"1";}s:4:"size";s:7:",,,,1,1";}s:1:"C";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Category";s:4:"name";s:6:"cat_id";}s:1:"D";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Duration";s:4:"name";s:11:"ts_duration";}i:2;a:4:{s:4:"type";s:13:"date-duration";s:4:"name";s:8:"duration";s:4:"size";s:6:",h,,,1";s:8:"readonly";s:1:"1";}}s:1:"E";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:6:"2,,0,0";i:1;a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Quantity";s:4:"name";s:11:"ts_quantity";}i:2;a:4:{s:4:"type";s:5:"float";s:4:"name";s:8:"quantity";s:8:"readonly";s:1:"1";s:4:"size";s:4:",,,3";}}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Price";s:4:"name";s:12:"ts_unitprice";}s:1:"G";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Total";s:4:"name";s:8:"ts_total";}i:2;a:4:{s:4:"type";s:5:"float";s:4:"name";s:5:"price";s:8:"readonly";s:1:"1";s:4:"size";s:4:",,,2";}}s:1:"H";a:5:{s:4:"type";s:22:"nextmatch-filterheader";s:4:"name";s:8:"ts_owner";s:4:"size";s:4:"User";s:7:"no_lang";s:1:"1";s:4:"span";s:18:",$cont[ownerClass]";}s:1:"I";a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Actions";s:4:"span";s:8:",noPrint";}}i:2;a:9:{s:1:"A";a:4:{s:4:"type";s:9:"date-time";s:4:"name";s:16:"${row}[ts_start]";s:8:"readonly";s:1:"1";s:4:"size";s:2:",8";}s:1:"B";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"3";i:1;a:3:{s:4:"type";s:4:"link";s:4:"name";s:15:"${row}[ts_link]";s:7:"no_lang";s:1:"1";}i:2;a:4:{s:4:"type";s:5:"label";s:4:"name";s:16:"${row}[ts_title]";s:7:"no_lang";s:1:"1";s:4:"span";s:22:",$row_cont[titleClass]";}i:3;a:3:{s:4:"type";s:5:"label";s:4:"name";s:22:"${row}[ts_description]";s:7:"no_lang";s:1:"1";}}s:1:"C";a:4:{s:4:"type";s:10:"select-cat";s:8:"readonly";s:1:"1";s:4:"name";s:14:"${row}[cat_id]";s:4:"span";s:7:",noWrap";}s:1:"D";a:4:{s:4:"type";s:13:"date-duration";s:4:"name";s:19:"${row}[ts_duration]";s:8:"readonly";s:1:"1";s:4:"size";s:6:",h,,,1";}s:1:"E";a:5:{s:4:"type";s:5:"float";s:4:"name";s:19:"${row}[ts_quantity]";s:7:"no_lang";s:1:"1";s:4:"size";s:4:",,,3";s:8:"readonly";s:1:"1";}s:1:"F";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:20:"${row}[ts_unitprice]";}s:1:"G";a:5:{s:4:"type";s:5:"float";s:7:"no_lang";s:1:"1";s:4:"name";s:16:"${row}[ts_total]";s:4:"size";s:4:",,,2";s:8:"readonly";s:1:"1";}s:1:"H";a:4:{s:4:"type";s:14:"select-account";s:4:"name";s:16:"${row}[ts_owner]";s:8:"readonly";s:1:"1";s:4:"span";s:18:",$cont[ownerClass]";}s:1:"I";a:6:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"3";i:1;a:6:{s:4:"type";s:6:"button";s:4:"size";s:4:"view";s:5:"label";s:4:"View";s:4:"name";s:22:"view[$row_cont[ts_id]]";s:7:"onclick";s:187:"window.open(egw::link(\'/index.php\',\'menuaction=timesheet.timesheet_ui.view&ts_id=$row_cont[ts_id]\'),\'_blank\',\'dependent=yes,width=600,height=400,scrollbars=yes,status=yes\'); return false;";s:4:"help";s:15:"View this entry";}i:2;a:6:{s:4:"type";s:6:"button";s:4:"size";s:4:"edit";s:5:"label";s:4:"Edit";s:4:"name";s:22:"edit[$row_cont[ts_id]]";s:4:"help";s:15:"Edit this entry";s:7:"onclick";s:187:"window.open(egw::link(\'/index.php\',\'menuaction=timesheet.timesheet_ui.edit&ts_id=$row_cont[ts_id]\'),\'_blank\',\'dependent=yes,width=600,height=400,scrollbars=yes,status=yes\'); return false;";}i:3;a:6:{s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"name";s:24:"delete[$row_cont[ts_id]]";s:4:"help";s:17:"Delete this entry";s:7:"onclick";s:36:"return confirm(\'Delete this entry\');";}s:4:"span";s:8:",noPrint";}}}s:4:"rows";i:2;s:4:"cols";i:9;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1164279120',); +$templ_data[] = array('name' => 'timesheet.index.rows','template' => '','lang' => '','group' => '0','version' => '1.5.002','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:8:{s:2:"c1";s:2:"th";s:2:"c2";s:16:"$row_cont[class]";s:1:"A";s:3:"15%";s:1:"B";s:3:"50%";s:1:"H";s:14:",@no_owner_col";s:1:"G";s:13:",@ts_viewtype";s:1:"F";s:13:",@ts_viewtype";s:1:"E";s:13:",@ts_viewtype";}i:1;a:10:{s:1:"A";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:4:"Date";s:4:"name";s:8:"ts_start";}s:1:"B";a:7:{s:4:"type";s:4:"grid";s:7:"no_lang";s:1:"1";s:4:"data";a:4:{i:0;a:2:{s:2:"h1";s:21:",@pm_integration=full";s:2:"h2";s:22:",!@pm_integration=full";}i:1;a:1:{s:1:"A";a:4:{s:4:"type";s:22:"nextmatch-filterheader";s:4:"size";s:12:"All projects";s:4:"name";s:10:"ts_project";s:7:"no_lang";s:1:"1";}}i:2;a:1:{s:1:"A";a:4:{s:4:"type";s:22:"nextmatch-customfilter";s:4:"size";s:34:"projectmanager-select,All projects";s:4:"name";s:5:"pm_id";s:8:"onchange";i:1;}}i:3;a:1:{s:1:"A";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Title";s:4:"name";s:8:"ts_title";}}}s:4:"rows";i:3;s:4:"cols";i:1;s:7:"options";a:2:{i:4;s:1:"1";i:5;s:1:"1";}s:4:"size";s:7:",,,,1,1";}s:1:"C";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Category";s:4:"name";s:6:"cat_id";}s:1:"D";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Duration";s:4:"name";s:11:"ts_duration";}i:2;a:4:{s:4:"type";s:13:"date-duration";s:4:"name";s:8:"duration";s:4:"size";s:6:",h,,,1";s:8:"readonly";s:1:"1";}}s:1:"E";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:6:"2,,0,0";i:1;a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Quantity";s:4:"name";s:11:"ts_quantity";}i:2;a:4:{s:4:"type";s:5:"float";s:4:"name";s:8:"quantity";s:8:"readonly";s:1:"1";s:4:"size";s:4:",,,3";}}s:1:"F";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Price";s:4:"name";s:12:"ts_unitprice";}s:1:"G";a:4:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Total";s:4:"name";s:8:"ts_total";}i:2;a:4:{s:4:"type";s:5:"float";s:4:"name";s:5:"price";s:8:"readonly";s:1:"1";s:4:"size";s:4:",,,2";}}s:1:"H";a:5:{s:4:"type";s:22:"nextmatch-filterheader";s:4:"name";s:8:"ts_owner";s:4:"size";s:4:"User";s:7:"no_lang";s:1:"1";s:4:"span";s:18:",$cont[ownerClass]";}s:1:"I";a:3:{s:4:"type";s:22:"nextmatch-customfields";s:4:"name";s:12:"customfields";s:8:"readonly";s:1:"1";}s:1:"J";a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Actions";s:4:"span";s:8:",noPrint";}}i:2;a:10:{s:1:"A";a:4:{s:4:"type";s:9:"date-time";s:4:"name";s:16:"${row}[ts_start]";s:8:"readonly";s:1:"1";s:4:"size";s:2:",8";}s:1:"B";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"3";i:1;a:3:{s:4:"type";s:4:"link";s:4:"name";s:15:"${row}[ts_link]";s:7:"no_lang";s:1:"1";}i:2;a:4:{s:4:"type";s:5:"label";s:4:"name";s:16:"${row}[ts_title]";s:7:"no_lang";s:1:"1";s:4:"span";s:22:",$row_cont[titleClass]";}i:3;a:3:{s:4:"type";s:5:"label";s:4:"name";s:22:"${row}[ts_description]";s:7:"no_lang";s:1:"1";}}s:1:"C";a:4:{s:4:"type";s:10:"select-cat";s:8:"readonly";s:1:"1";s:4:"name";s:14:"${row}[cat_id]";s:4:"span";s:7:",noWrap";}s:1:"D";a:4:{s:4:"type";s:13:"date-duration";s:4:"name";s:19:"${row}[ts_duration]";s:8:"readonly";s:1:"1";s:4:"size";s:6:",h,,,1";}s:1:"E";a:5:{s:4:"type";s:5:"float";s:4:"name";s:19:"${row}[ts_quantity]";s:7:"no_lang";s:1:"1";s:4:"size";s:4:",,,3";s:8:"readonly";s:1:"1";}s:1:"F";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:20:"${row}[ts_unitprice]";}s:1:"G";a:5:{s:4:"type";s:5:"float";s:7:"no_lang";s:1:"1";s:4:"name";s:16:"${row}[ts_total]";s:4:"size";s:4:",,,2";s:8:"readonly";s:1:"1";}s:1:"H";a:4:{s:4:"type";s:14:"select-account";s:4:"name";s:16:"${row}[ts_owner]";s:8:"readonly";s:1:"1";s:4:"span";s:18:",$cont[ownerClass]";}s:1:"I";a:3:{s:4:"type";s:17:"customfields-list";s:4:"name";s:4:"$row";s:8:"readonly";s:1:"1";}s:1:"J";a:6:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"3";i:1;a:6:{s:4:"type";s:6:"button";s:4:"size";s:4:"view";s:5:"label";s:4:"View";s:4:"name";s:22:"view[$row_cont[ts_id]]";s:7:"onclick";s:187:"window.open(egw::link(\'/index.php\',\'menuaction=timesheet.timesheet_ui.view&ts_id=$row_cont[ts_id]\'),\'_blank\',\'dependent=yes,width=600,height=400,scrollbars=yes,status=yes\'); return false;";s:4:"help";s:15:"View this entry";}i:2;a:6:{s:4:"type";s:6:"button";s:4:"size";s:4:"edit";s:5:"label";s:4:"Edit";s:4:"name";s:22:"edit[$row_cont[ts_id]]";s:4:"help";s:15:"Edit this entry";s:7:"onclick";s:187:"window.open(egw::link(\'/index.php\',\'menuaction=timesheet.timesheet_ui.edit&ts_id=$row_cont[ts_id]\'),\'_blank\',\'dependent=yes,width=600,height=400,scrollbars=yes,status=yes\'); return false;";}i:3;a:6:{s:4:"type";s:6:"button";s:4:"size";s:6:"delete";s:5:"label";s:6:"Delete";s:4:"name";s:24:"delete[$row_cont[ts_id]]";s:4:"help";s:17:"Delete this entry";s:7:"onclick";s:36:"return confirm(\'Delete this entry\');";}s:4:"span";s:8:",noPrint";}}}s:4:"rows";i:2;s:4:"cols";i:10;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1164279120',); + diff --git a/timesheet/setup/tables_update.inc.php b/timesheet/setup/tables_update.inc.php index f3e0fbfea0..81a6a25430 100644 --- a/timesheet/setup/tables_update.inc.php +++ b/timesheet/setup/tables_update.inc.php @@ -49,5 +49,8 @@ function timesheet_upgrade0_2_002() function timesheet_upgrade1_4() { + // delete empty cf's generated by 1.4 + $GLOBALS['egw_setup']->db->delete('egw_timesheet_extra',"ts_extra_value=''",__LINE__,__FILE__,'timesheet'); + return $GLOBALS['setup_info']['timesheet']['currentver'] = '1.6'; } diff --git a/timesheet/templates/default/edit.xet b/timesheet/templates/default/edit.xet index 18e5b2d89f..17d6ea500b 100644 --- a/timesheet/templates/default/edit.xet +++ b/timesheet/templates/default/edit.xet @@ -81,8 +81,8 @@ - -