forked from extern/egroupware
Initial revision
This commit is contained in:
parent
809768937d
commit
9f638e4f08
447
timesheet/inc/class.botimesheet.inc.php
Normal file
447
timesheet/inc/class.botimesheet.inc.php
Normal file
@ -0,0 +1,447 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - TimeSheet: business object *
|
||||
* http://www.eGroupWare.org *
|
||||
* Written and (c) 2005 by Ralf Becker <RalfBecker@outdoor-training.de> *
|
||||
* ------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
require_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php');
|
||||
|
||||
if (!defined('TIMESHEET_APP'))
|
||||
{
|
||||
define('TIMESHEET_APP','timesheet');
|
||||
}
|
||||
|
||||
/**
|
||||
* Business object of the TimeSheet
|
||||
*
|
||||
* Uses eTemplate's so_sql as storage object (Table: egw_timesheet).
|
||||
*
|
||||
* @package timesheet
|
||||
* @author RalfBecker-AT-outdoor-training.de
|
||||
* @copyright (c) 2005 by RalfBecker-AT-outdoor-training.de
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
class botimesheet extends so_sql
|
||||
{
|
||||
/**
|
||||
* @var array $config timesheets config data
|
||||
*/
|
||||
var $config = array();
|
||||
/**
|
||||
* @var array $timestamps timestaps that need to be adjusted to user-time on reading or saving
|
||||
*/
|
||||
var $timestamps = array(
|
||||
'ts_start','ts_modified'
|
||||
);
|
||||
/**
|
||||
* @var int $tz_offset_s offset in secconds between user and server-time,
|
||||
* it need to be add to a server-time to get the user-time or substracted from a user-time to get the server-time
|
||||
*/
|
||||
var $tz_offset_s;
|
||||
/**
|
||||
* @var int $now actual user-time as timestamp
|
||||
*/
|
||||
var $now;
|
||||
/**
|
||||
* @var int $today start of today in user-time
|
||||
*/
|
||||
var $today;
|
||||
/**
|
||||
* @var array $date_filters filter for search limiting the date-range
|
||||
*/
|
||||
var $date_filters = array( // Start: year,month,day,week, End: year,month,day,week
|
||||
'Today' => array(0,0,0,0, 0,0,1,0),
|
||||
'Yesterday' => array(0,0,-1,0, 0,0,0,0),
|
||||
'This week' => array(0,0,0,0, 0,0,0,1),
|
||||
'Last week' => array(0,0,0,-1, 0,0,0,0),
|
||||
'This month' => array(0,0,0,0, 0,1,0,0),
|
||||
'Last month' => array(0,-1,0,0, 0,0,0,0),
|
||||
'2 month ago' => array(0,-2,0,0, 0,-1,0,0),
|
||||
'This year' => array(0,0,0,0, 1,0,0,0),
|
||||
'Last year' => array(-1,0,0,0, 0,0,0,0),
|
||||
'2 years ago' => array(-2,0,0,0, -1,0,0,0),
|
||||
'3 years ago' => array(-3,0,0,0, -2,0,0,0),
|
||||
);
|
||||
|
||||
function botimesheet()
|
||||
{
|
||||
$this->so_sql(TIMESHEET_APP,'egw_timesheet');
|
||||
|
||||
$config =& CreateObject('phpgwapi.config',TIMESHEET_APP);
|
||||
$config->read_repository();
|
||||
$this->config =& $config->config_data;
|
||||
unset($config);
|
||||
|
||||
if (!is_object($GLOBALS['egw']->datetime))
|
||||
{
|
||||
$GLOBALS['egw']->datetime =& CreateObject('phpgwapi.datetime');
|
||||
}
|
||||
$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
|
||||
$this->today = mktime(0,0,0,date('m',$this->now),date('d',$this->now),date('Y',$this->now));
|
||||
|
||||
// save us in $GLOBALS['botimesheet'] for ExecMethod used in hooks
|
||||
if (!is_object($GLOBALS['botimesheet']))
|
||||
{
|
||||
$GLOBALS['botimesheet'] =& $this;
|
||||
}
|
||||
// instanciation of link-class has to be after making us globaly availible, as it calls us to get the search_link
|
||||
if (!is_object($GLOBALS['egw']->link))
|
||||
{
|
||||
$GLOBALS['egw']->link =& CreateObject('phpgwapi.bolink');
|
||||
}
|
||||
$this->link =& $GLOBALS['egw']->link;
|
||||
|
||||
$this->grants = $GLOBALS['egw']->acl->get_grants(TIMESHEET_APP);
|
||||
}
|
||||
|
||||
/**
|
||||
* get list of specified grants as uid => Username pairs
|
||||
*
|
||||
* @param int $required=EGW_ACL_READ
|
||||
* @return array with uid => Username pairs
|
||||
*/
|
||||
function grant_list($required=EGW_ACL_READ)
|
||||
{
|
||||
$result = array();
|
||||
foreach($this->grants as $uid => $grant)
|
||||
{
|
||||
if ($grant & $required)
|
||||
{
|
||||
$result[$uid] = $GLOBALS['egw']->common->grab_owner_name($uid);
|
||||
}
|
||||
}
|
||||
natcasesort($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the user has enough rights for a certain operation
|
||||
*
|
||||
* Rights are given via owner grants or role based acl
|
||||
*
|
||||
* @param int $required EGW_ACL_READ, EGW_ACL_WRITE, EGW_ACL_ADD, EGW_ACL_DELETE, EGW_ACL_BUDGET, EGW_ACL_EDIT_BUDGET
|
||||
* @param array/int $data=null project or project-id to use, default the project in $this->data
|
||||
* @return boolean true if the rights are ok, false if not
|
||||
*/
|
||||
function check_acl($required,$data=null)
|
||||
{
|
||||
if (!$data)
|
||||
{
|
||||
$data =& $this->data;
|
||||
}
|
||||
if (!is_array($data))
|
||||
{
|
||||
$save_data = $this->data;
|
||||
$data = $this->read($data,true);
|
||||
$this->data = $save_data;
|
||||
}
|
||||
$rights = $this->grants[$data['ts_owner']];
|
||||
|
||||
return $data && !!($rights & $required);
|
||||
}
|
||||
|
||||
function date_filter($name)
|
||||
{
|
||||
if (!isset($this->date_filters[$name]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$year = (int) date('Y',$this->today);
|
||||
$month = (int) date('m',$this->today);
|
||||
$day = (int) date('d',$this->today);
|
||||
|
||||
list($syear,$smonth,$sday,$sweek,$eyear,$emonth,$eday,$eweek) = $this->date_filters[$name];
|
||||
|
||||
if ($syear || $eyear)
|
||||
{
|
||||
$start = mktime(0,0,0,1,1,$syear+$year);
|
||||
$end = mktime(0,0,0,1,1,$eyear+$year);
|
||||
}
|
||||
elseif ($smonth || $emonth)
|
||||
{
|
||||
$start = mktime(0,0,0,$smonth+$month,1,$year);
|
||||
$end = mktime(0,0,0,$emonth+$month,1,$year);
|
||||
}
|
||||
elseif ($sday || $eday)
|
||||
{
|
||||
$start = mktime(0,0,0,$month,$sday+$day,$year);
|
||||
$end = mktime(0,0,0,$month,$eday+$day,$year);
|
||||
}
|
||||
elseif ($sweek || $eweek)
|
||||
{
|
||||
$wday = (int) date('w',$this->today); // 0=sun, ..., 6=sat
|
||||
switch($GLOBALS['egw_info']['user']['preferences']['calendar']['weekdaystarts'])
|
||||
{
|
||||
case 'Sunday':
|
||||
$weekstart = $this->today - $wday * 24*60*60;
|
||||
break;
|
||||
case 'Saturday':
|
||||
$weekstart = $this->today - (6-$wday) * 24*60*60;
|
||||
break;
|
||||
case 'Moday':
|
||||
default:
|
||||
$weekstart = $this->today - ($wday ? $wday-1 : 6) * 24*60*60;
|
||||
break;
|
||||
}
|
||||
$start = $weekstart + $sweek*7*24*60*60;
|
||||
$end = $weekstart + $eweek*7*24*60*60;
|
||||
// todo
|
||||
}
|
||||
//echo "<p align='right'>date_filter($name) today=".date('l, Y-m-d H:i',$this->today)." ==> ".date('l, Y-m-d H:i:s',$start)." <= date < ".date('l, Y-m-d H:i:s',$end)."</p>\n";
|
||||
// convert start + end from user to servertime
|
||||
$start -= $this->tz_offset_s;
|
||||
$end -= $this->tz_offset_s;
|
||||
|
||||
return "($start <= ts_start AND ts_start < $end)";
|
||||
}
|
||||
|
||||
/**
|
||||
* search the timesheet
|
||||
*
|
||||
* reimplemented to limit result to users we have grants from
|
||||
*
|
||||
* @param array/string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!)
|
||||
* @param boolean/string $only_keys=true True returns only keys, False returns all cols. comma seperated list of keys to return
|
||||
* @param string $order_by='' fieldnames + {ASC|DESC} separated by colons ',', can also contain a GROUP BY (if it contains ORDER BY)
|
||||
* @param string/array $extra_cols='' string or array of strings to be added to the SELECT, eg. "count(*) as num"
|
||||
* @param string $wildcard='' appended befor and after each criteria
|
||||
* @param boolean $empty=false False=empty criteria are ignored in query, True=empty have to be empty in row
|
||||
* @param string $op='AND' defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together
|
||||
* @param mixed $start=false if != false, return only maxmatch rows begining with start, or array($start,$num)
|
||||
* @param array $filter=null if set (!=null) col-data pairs, to be and-ed (!) into the query without wildcards
|
||||
* @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or
|
||||
* "LEFT JOIN table2 ON (x=y)", Note: there's no quoting done on $join!
|
||||
* @param boolean $need_full_no_count=false If true an unlimited query is run to determine the total number of rows, default false
|
||||
* @return array of matching rows (the row is an array of the cols) or False
|
||||
*/
|
||||
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)
|
||||
{
|
||||
if (!$extra_cols) $extra_cols = 'ts_quantity*ts_unitprice AS ts_total';
|
||||
|
||||
if (!isset($filter['ts_owner']) || !count($filter['ts_owner']))
|
||||
{
|
||||
$filter['ts_owner'] = array_keys($this->grants);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!is_array($filter['ts_owner'])) $filter['ts_owner'] = array($filter['ts_owner']);
|
||||
|
||||
foreach($filter['ts_owner'] as $key => $owner)
|
||||
{
|
||||
if (!isset($this->grants[$owner]))
|
||||
{
|
||||
unset($filter['ts_owner'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!count($filter['ts_owner']))
|
||||
{
|
||||
$this->total = 0;
|
||||
return array();
|
||||
}
|
||||
$this->summary = parent::search($criteria,'SUM(ts_duration) AS duration,SUM(ts_quantity*ts_unitprice) AS price',
|
||||
'','',$wildcard,$empty,$op,false,$filter,$join);
|
||||
$this->summary = $this->summary[0];
|
||||
|
||||
return parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join,$need_full_no_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* read a timesheet entry
|
||||
*
|
||||
* @param int $ts_id
|
||||
* @param boolean $ignore_acl=false should the acl be checked
|
||||
* @return array/boolean array with timesheet entry or false if no rights
|
||||
*/
|
||||
function read($ts_id,$ignore_acl=false)
|
||||
{
|
||||
if (!(int)$ts_id || !$ignore_acl && !$this->check_acl(EGW_ACL_READ,$ts_id) ||
|
||||
$this->data['ts_id'] != (int)$ts_id && !parent::read((int)$ts_id))
|
||||
{
|
||||
return false; // no read rights, or entry not found
|
||||
}
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* saves a timesheet entry
|
||||
*
|
||||
* reimplemented to notify the link-class
|
||||
*
|
||||
* @param array $keys if given $keys are copied to data before saveing => allows a save as
|
||||
* @param boolean $touch_modified=true should modification date+user be set, default yes
|
||||
* @param boolean $ignore_acl=false should the acl be checked, returns true if no edit-rigts
|
||||
* @return int 0 on success and errno != 0 else
|
||||
*/
|
||||
function save($keys=null,$touch_modified=true,$ignore_acl=false)
|
||||
{
|
||||
if ($keys) $this->data_merge($keys);
|
||||
|
||||
if (!$ignore_acl && $this->data['ts_id'] && !$this->check_acl(EGW_ACL_EDIT))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ($touch_modified)
|
||||
{
|
||||
$this->data['ts_modifier'] = $GLOBALS['egw_info']['user']['account_id'];
|
||||
$this->data['ts_modified'] = $this->now;
|
||||
}
|
||||
if (!($err = parent::save(null)))
|
||||
{
|
||||
// notify the link-class about the update, as other apps may be subscribt to it
|
||||
$this->link->notify_update(TIMESHEET_APP,$this->data['ts_id'],$this->data);
|
||||
}
|
||||
return $err;
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes a timesheet entry identified by $keys or the loaded one, reimplemented to notify the link class (unlink)
|
||||
*
|
||||
* @param array $keys if given array with col => value pairs to characterise the rows to delete
|
||||
* @param boolean $ignore_acl=false should the acl be checked, returns false if no delete-rigts
|
||||
* @return int affected rows, should be 1 if ok, 0 if an error
|
||||
*/
|
||||
function delete($keys=null,$ignore_acl=false)
|
||||
{
|
||||
$ts_id = is_null($keys) ? $this->data['ts_id'] : (is_array($keys) ? $keys['ts_id'] : $keys);
|
||||
|
||||
if (!$this->check_acl(EGW_ACL_DELETE,$ts_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (($ret = parent::delete($keys)) && $ts_id)
|
||||
{
|
||||
// delete all links to timesheet entry $ts_id
|
||||
$this->link->unlink(0,TIMESHEET_APP,$ts_id);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the data from the db-format to your work-format
|
||||
*
|
||||
* reimplemented to adjust the timezone of the timestamps (adding $this->tz_offset_s to get user-time)
|
||||
* Please note, we do NOT call the method of the parent so_sql !!!
|
||||
*
|
||||
* @param array $data if given works on that array and returns result, else works on internal data-array
|
||||
* @return array with changed data
|
||||
*/
|
||||
function db2data($data=null)
|
||||
{
|
||||
if (!is_array($data))
|
||||
{
|
||||
$data = &$this->data;
|
||||
}
|
||||
foreach($this->timestamps as $name)
|
||||
{
|
||||
if (isset($data[$name]) && $data[$name]) $data[$name] += $this->tz_offset_s;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the data from your work-format to the db-format
|
||||
*
|
||||
* reimplemented to adjust the timezone of the timestamps (subtraction $this->tz_offset_s to get server-time)
|
||||
* Please note, we do NOT call the method of the parent so_sql !!!
|
||||
*
|
||||
* @param array $data if given works on that array and returns result, else works on internal data-array
|
||||
* @return array with changed data
|
||||
*/
|
||||
function data2db($data=null)
|
||||
{
|
||||
if ($intern = !is_array($data))
|
||||
{
|
||||
$data = &$this->data;
|
||||
}
|
||||
foreach($this->timestamps as $name)
|
||||
{
|
||||
if (isset($data[$name]) && $data[$name]) $data[$name] -= $this->tz_offset_s;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* get title for an timesheet entry identified by $entry
|
||||
*
|
||||
* Is called as hook to participate in the linking
|
||||
*
|
||||
* @param int/array $entry int ts_id or array with timesheet entry
|
||||
* @param string the title
|
||||
*/
|
||||
function link_title( $entry )
|
||||
{
|
||||
if (!is_array($entry))
|
||||
{
|
||||
$entry = $this->read( $entry );
|
||||
}
|
||||
if (!$entry)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
$format = $GLOBALS['egw_info']['user']['preferences']['common']['dateformat'];
|
||||
if (date('H:i',$entry['ts_start']) != '00:00') // dont show 00:00 time, as it means date only
|
||||
{
|
||||
$format .= ' '.($GLOBALS['egw_info']['user']['preferences']['common']['timeformat'] == 12 ? 'h:i a' : 'H:i');
|
||||
}
|
||||
return date($format,$entry['ts_start']).': '.$entry['ts_title'];
|
||||
}
|
||||
|
||||
/**
|
||||
* query timesheet for entries matching $pattern
|
||||
*
|
||||
* Is called as hook to participate in the linking
|
||||
*
|
||||
* @param string $pattern pattern to search
|
||||
* @return array with ts_id - title pairs of the matching entries
|
||||
*/
|
||||
function link_query( $pattern )
|
||||
{
|
||||
$criteria = array();
|
||||
foreach(array('ts_project','ts_title','ts_description') as $col)
|
||||
{
|
||||
$criteria[$col] = $pattern;
|
||||
}
|
||||
$result = array();
|
||||
foreach((array) $this->search($criteria,false,'','','%',false,'OR') as $ts )
|
||||
{
|
||||
$result[$ts['ts_id']] = $this->link_title($ts);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called by link-class to include timesheet in the appregistry of the linkage
|
||||
*
|
||||
* @param array/string $location location and other parameters (not used)
|
||||
* @return array with method-names
|
||||
*/
|
||||
function search_link($location)
|
||||
{
|
||||
return array(
|
||||
'query' => TIMESHEET_APP.'.botimesheet.link_query',
|
||||
'title' => TIMESHEET_APP.'.botimesheet.link_title',
|
||||
'view' => array(
|
||||
'menuaction' => TIMESHEET_APP.'.uitimesheet.view',
|
||||
),
|
||||
'view_id' => 'ts_id',
|
||||
'view_popup' => '600x400',
|
||||
'add' => array(
|
||||
'menuaction' => TIMESHEET_APP.'.uitimesheet.edit',
|
||||
),
|
||||
'add_app' => 'link_app',
|
||||
'add_id' => 'link_id',
|
||||
'add_popup' => '600x400',
|
||||
);
|
||||
}
|
||||
}
|
82
timesheet/inc/class.datasource_timesheet.inc.php
Normal file
82
timesheet/inc/class.datasource_timesheet.inc.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - ProjectManager - DataSource for TimeSheet *
|
||||
* http://www.egroupware.org *
|
||||
* Written and (c) 2005 by Ralf Becker <RalfBecker@outdoor-training.de> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
include_once(EGW_INCLUDE_ROOT.'/projectmanager/inc/class.datasource.inc.php');
|
||||
include_once('class.botimesheet.inc.php');
|
||||
|
||||
/**
|
||||
* DataSource for the TimeSheet
|
||||
*
|
||||
* @package timesheet
|
||||
* @author RalfBecker-AT-outdoor-training.de
|
||||
* @copyright (c) 2005 by RalfBecker-AT-outdoor-training.de
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
class datasource_timesheet extends datasource
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
function datasource_timesheet()
|
||||
{
|
||||
$this->datasource(TIMESHEET_APP);
|
||||
|
||||
$this->valid = PM_REAL_START|PM_REAL_END|PM_USED_TIME|PM_USED_BUDGET|PM_RESOURCES|PM_DETAILS|PM_COMPLETION;
|
||||
}
|
||||
|
||||
/**
|
||||
* get an entry from the underlaying app (if not given) and convert it into a datasource array
|
||||
*
|
||||
* @param mixed $data_id id as used in the link-class for that app, or complete entry as array
|
||||
* @return array/boolean array with the data supported by that source or false on error (eg. not found, not availible)
|
||||
*/
|
||||
function get($data_id)
|
||||
{
|
||||
// we use $GLOBALS['bocal'] as an already running instance is availible there
|
||||
if (!is_object($GLOBALS['botimesheet']))
|
||||
{
|
||||
$GLOBALS['bocal'] =& new botimesheet();
|
||||
}
|
||||
if (!is_array($data_id))
|
||||
{
|
||||
if (!(int) $data_id || !($data = $GLOBALS['botimesheet']->read((int) $data_id)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$data =& $data_id;
|
||||
}
|
||||
$ds = array(
|
||||
'pe_title' => $GLOBALS['botimesheet']->link_title($data),
|
||||
'pe_real_start' => $data['ts_start'],
|
||||
'pe_resources' => array($data['ts_owner']),
|
||||
'pe_details' => $data['ts_description'] ? nl2br($data['ts_description']) : '',
|
||||
'pe_used_budget' => $data['ts_quantity'] * $data['ts_unitprice'],
|
||||
'pe_completion' => 100,
|
||||
);
|
||||
if ($data['ts_duration'])
|
||||
{
|
||||
$ds['pe_real_end'] = $data['ts_start'] + 60*$data['ts_duration'];
|
||||
$ds['pe_used_time'] = $data['ts_duration'];
|
||||
}
|
||||
if ($this->debug)
|
||||
{
|
||||
echo "datasource_timesheet($data_id) data="; _debug_array($data);
|
||||
echo "datasource="; _debug_array($ds);
|
||||
}
|
||||
return $ds;
|
||||
}
|
||||
}
|
131
timesheet/inc/class.ts_admin_prefs_sidebox_hooks.inc.php
Normal file
131
timesheet/inc/class.ts_admin_prefs_sidebox_hooks.inc.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - TimeSheet: Admin-, Preferences- and SideboxMenu-Hooks *
|
||||
* http://www.eGroupWare.org *
|
||||
* Written and (c) 2005 by Ralf Becker <RalfBecker@outdoor-training.de> *
|
||||
* ------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
if (!defined('TIMESHEET_APP'))
|
||||
{
|
||||
define('TIMESHEET_APP','timesheet');
|
||||
}
|
||||
|
||||
class ts_admin_prefs_sidebox_hooks
|
||||
{
|
||||
var $public_functions = array(
|
||||
// 'check_set_default_prefs' => true,
|
||||
);
|
||||
var $config = array();
|
||||
|
||||
function pm_admin_prefs_sidebox_hooks()
|
||||
{
|
||||
$config =& CreateObject('phpgwapi.config',TIMESHEET_APP);
|
||||
$config->read_repository();
|
||||
$this->config =& $config->config_data;
|
||||
unset($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* hooks to build projectmanager's sidebox-menu plus the admin and preferences sections
|
||||
*
|
||||
* @param string/array $args hook args
|
||||
*/
|
||||
function all_hooks($args)
|
||||
{
|
||||
$appname = TIMESHEET_APP;
|
||||
$location = is_array($args) ? $args['location'] : $args;
|
||||
//echo "<p>ts_admin_prefs_sidebox_hooks::all_hooks(".print_r($args,True).") appname='$appname', location='$location'</p>\n";
|
||||
|
||||
if ($location == 'sidebox_menu')
|
||||
{
|
||||
$file = array(
|
||||
);
|
||||
display_sidebox($appname,$GLOBALS['egw_info']['apps'][$appname]['title'].' '.lang('Menu'),$file);
|
||||
}
|
||||
|
||||
if ($GLOBALS['egw_info']['user']['apps']['preferences'] && $location != 'admin')
|
||||
{
|
||||
$file = array(
|
||||
// 'Preferences' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uisettings.index&appname='.$appname),
|
||||
'Grant Access' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app='.$appname),
|
||||
'Edit Categories' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app=' . $appname . '&cats_level=True&global_cats=True')
|
||||
);
|
||||
if ($location == 'preferences')
|
||||
{
|
||||
display_section($appname,$file);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_sidebox($appname,lang('Preferences'),$file);
|
||||
}
|
||||
}
|
||||
|
||||
if ($GLOBALS['egw_info']['user']['apps']['admin'] && $location != 'preferences')
|
||||
{
|
||||
$file = Array(
|
||||
// 'Site configuration' => $GLOBALS['egw']->link('/index.php','menuaction=projectmanager.admin.config'),
|
||||
// 'Custom fields' => $GLOBALS['egw']->link('/index.php','menuaction=admin.customfields.edit&appname='.$appname),
|
||||
'Global Categories' => $GLOBALS['egw']->link('/index.php',array(
|
||||
'menuaction' => 'admin.uicategories.index',
|
||||
'appname' => $appname,
|
||||
'global_cats'=> True)),
|
||||
);
|
||||
if ($location == 'admin')
|
||||
{
|
||||
display_section($appname,$file);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_sidebox($appname,lang('Admin'),$file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* populates $GLOBALS['settings'] for the preferences
|
||||
*/
|
||||
function settings()
|
||||
{
|
||||
$this->check_set_default_prefs();
|
||||
|
||||
return true; // otherwise prefs say it cant find the file ;-)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if reasonable default preferences are set and set them if not
|
||||
*
|
||||
* It sets a flag in the app-session-data to be called only once per session
|
||||
*/
|
||||
function check_set_default_prefs()
|
||||
{
|
||||
if ($GLOBALS['egw']->session->appsession('default_prefs_set',TIMESHEET_APP))
|
||||
{
|
||||
return;
|
||||
}
|
||||
$GLOBALS['egw']->session->appsession('default_prefs_set',TIMESHEET_APP,'set');
|
||||
|
||||
$default_prefs =& $GLOBALS['egw']->preferences->default[TIMESHEET_APP];
|
||||
|
||||
$defaults = array(
|
||||
);
|
||||
foreach($defaults as $var => $default)
|
||||
{
|
||||
if (!isset($default_prefs[$var]) || $default_prefs[$var] === '')
|
||||
{
|
||||
$GLOBALS['egw']->preferences->add(TIMESHEET_APP,$var,$default,'default');
|
||||
$need_save = True;
|
||||
}
|
||||
}
|
||||
if ($need_save)
|
||||
{
|
||||
$GLOBALS['egw']->preferences->save_repository(False,'default');
|
||||
}
|
||||
}
|
||||
}
|
316
timesheet/inc/class.uitimesheet.inc.php
Normal file
316
timesheet/inc/class.uitimesheet.inc.php
Normal file
@ -0,0 +1,316 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - TimeSheet: user interface *
|
||||
* http://www.eGroupWare.org *
|
||||
* Written and (c) 2005 by Ralf Becker <RalfBecker@outdoor-training.de> *
|
||||
* ------------------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
require_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.uietemplate.inc.php');
|
||||
require_once('class.botimesheet.inc.php');
|
||||
|
||||
/**
|
||||
* User interface object of the TimeSheet
|
||||
*
|
||||
* @package timesheet
|
||||
* @author RalfBecker-AT-outdoor-training.de
|
||||
* @copyright (c) 2005 by RalfBecker-AT-outdoor-training.de
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
class uitimesheet extends botimesheet
|
||||
{
|
||||
var $public_functions = array(
|
||||
'view' => true,
|
||||
'edit' => true,
|
||||
'index' => true,
|
||||
);
|
||||
|
||||
function uitimesheet()
|
||||
{
|
||||
$this->botimesheet();
|
||||
}
|
||||
|
||||
function view()
|
||||
{
|
||||
$this->edit(null,true);
|
||||
}
|
||||
|
||||
function edit($content = null,$view = false)
|
||||
{
|
||||
$tabs = 'general|notes|links';
|
||||
|
||||
if (!is_array($content))
|
||||
{
|
||||
if ($view || (int)$_GET['ts_id'])
|
||||
{
|
||||
if (!$this->read((int)$_GET['ts_id']))
|
||||
{
|
||||
$GLOBALS['egw']->common->egw_header();
|
||||
echo "<script>alert('".lang('Permission denied!!!')."'); window.close();</script>\n";
|
||||
$GLOBALS['egw']->common->egw_exit();
|
||||
}
|
||||
if (!$view && !$this->check_acl(EGW_ACL_EDIT))
|
||||
{
|
||||
$view = true;
|
||||
}
|
||||
}
|
||||
else // new entry
|
||||
{
|
||||
$this->data = array(
|
||||
'ts_start' => $this->today,
|
||||
'ts_owner' => $GLOBALS['egw_info']['user']['account_id'],
|
||||
'cat_id' => (int) $_REQUEST['cat_id'],
|
||||
);
|
||||
}
|
||||
$referer = preg_match('/menuaction=([^&]+)/',$_SERVER['HTTP_REFERER'],$matches) ? $matches[1] : TIMESHEET_APP.'.uitimesheet.index';
|
||||
}
|
||||
else
|
||||
{
|
||||
list($button) = each($content['button']);
|
||||
$view = $content['view'];
|
||||
$referer = $content['referer'];
|
||||
$this->data = $content;
|
||||
foreach(array('button','view','referer',$tabs) as $key)
|
||||
{
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
switch($button)
|
||||
{
|
||||
case 'edit':
|
||||
if ($this->check_acl(EGW_ACL_EDIT)) $view = false;
|
||||
break;
|
||||
|
||||
case 'save':
|
||||
case 'save_new':
|
||||
case 'apply':
|
||||
if (!$this->data['ts_quantity']) // set the quantity (in h) from the duration (in min)
|
||||
{
|
||||
$this->data['ts_quantity'] = $this->data['ts_duration'] / 60.0;
|
||||
}
|
||||
if (!$this->data['ts_project']) $this->data['ts_project'] = $this->data['ts_project_blur'];
|
||||
|
||||
if ($this->save() != 0)
|
||||
{
|
||||
$msg = lang('Error saving the entry!!!');
|
||||
$button = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg = lang('Entry saved');
|
||||
if (is_array($content['link_to']['to_id']) && count($content['link_to']['to_id']))
|
||||
{
|
||||
$this->link->link(TIMESHEET_APP,$this->data['ts_id'],$content['link_to']['to_id']);
|
||||
}
|
||||
}
|
||||
$js = "opener.location.href='".$GLOBALS['egw']->link('/index.php',array(
|
||||
'menuaction' => $referer,
|
||||
'msg' => $msg,
|
||||
))."';";
|
||||
if ($button == 'apply') break;
|
||||
if ($button == 'save_new')
|
||||
{
|
||||
// create a new entry
|
||||
$this->data['ts_start'] += 60 * $this->data['ts_duration'];
|
||||
foreach(array('ts_id','ts_title','ts_description','ts_duration','ts_quantity','ts_modified','ts_modifier') as $name)
|
||||
{
|
||||
unset($this->data[$name]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// fall-through for save
|
||||
case 'delete':
|
||||
if ($button == 'delete')
|
||||
{
|
||||
$this->delete();
|
||||
$msg = lang('Entry deleted');
|
||||
$js = "opener.location.href=opener.location.href+'&msg=$msg'";
|
||||
}
|
||||
case 'cancel':
|
||||
$js .= 'window.close();';
|
||||
echo "<html>\n<body>\n<script>\n$js\n</script>\n</body>\n</html>\n";
|
||||
$GLOBALS['egw']->common->egw_exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
$preserv = $this->data + array(
|
||||
'view' => $view,
|
||||
'referer' => $referer,
|
||||
);
|
||||
$content = $this->data + array(
|
||||
'msg' => $msg,
|
||||
'view' => $view,
|
||||
$tabs => $content[$tabs],
|
||||
'link_to' => array(
|
||||
'to_id' => $content['link_to']['to_id'] ? $content['link_to']['to_id'] : $this->data['ts_id'],
|
||||
'to_app' => TIMESHEET_APP,
|
||||
),
|
||||
'js' => "<script>\n$js\n</script>\n",
|
||||
'ts_quantity_blur' => $this->data['ts_duration'] ? $this->data['ts_duration'] / 60.0 : '',
|
||||
);
|
||||
if (!$this->data['ts_id'] && isset($_GET['link_app']) && isset($_GET['link_id']) &&
|
||||
preg_match('/^[a-z_0-9-]+:[:a-z_0-9-]+$/i',$_GET['link_app'].':'.$_GET['link_id']) && // gard against XSS
|
||||
!is_array($content['link_to']['to_id']))
|
||||
{
|
||||
$this->link->link(TIMESHEET_APP,$content['link_to']['to_id'],$_GET['link_app'],$_GET['link_id']);
|
||||
// $content['ts_project'] = $this->link->title($_GET['link_app'],$_GET['link_id']);
|
||||
if ($_GET['link_app'] == 'projectmanager')
|
||||
{
|
||||
$links = array($_GET['link_id']);
|
||||
}
|
||||
}
|
||||
elseif ($this->data['ts_id'])
|
||||
{
|
||||
$links = $this->link->get_links(TIMESHEET_APP,$this->data['ts_id'],'projectmanager');
|
||||
}
|
||||
if ($links)
|
||||
{
|
||||
$preserv['ts_project_blur'] = $content['ts_project_blur'] = $this->link->title('projectmanager',array_shift($links));
|
||||
}
|
||||
$readonlys = array(
|
||||
'button[delete]' => !$this->data['ts_id'] || !$this->check_acl(EGW_ACL_DELETE),
|
||||
'button[edit]' => !$view || !$this->check_acl(EGW_ACL_EDIT),
|
||||
'button[save]' => $view,
|
||||
'button[save_new]' => $view,
|
||||
'button[apply]' => $view,
|
||||
);
|
||||
if ($view)
|
||||
{
|
||||
foreach($this->data as $key => $val)
|
||||
{
|
||||
$readonlys[$key] = true;
|
||||
}
|
||||
}
|
||||
$edit_grants = $this->grant_list(EGW_ACL_EDIT);
|
||||
if (count($edit_grants) == 1)
|
||||
{
|
||||
$readonlys['ts_owner'] = true;
|
||||
}
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('timesheet').' - '.
|
||||
($view ? lang('View') : ($this->data['ts_id'] ? lang('Edit') : lang('Add')));
|
||||
|
||||
$etpl =& new etemplate('timesheet.edit');
|
||||
|
||||
return $etpl->exec(TIMESHEET_APP.'.uitimesheet.edit',$content,array(
|
||||
'ts_owner' => $edit_grants,
|
||||
),$readonlys,$preserv,2);
|
||||
}
|
||||
|
||||
/**
|
||||
* query projects for nextmatch in the projects-list
|
||||
*
|
||||
* reimplemented from so_sql to disable action-buttons based on the acl and make some modification on the data
|
||||
*
|
||||
* @param array $query
|
||||
* @param array &$rows returned rows/cups
|
||||
* @param array &$readonlys eg. to disable buttons based on acl
|
||||
*/
|
||||
function get_rows($query,&$rows,&$readonlys)
|
||||
{
|
||||
$GLOBALS['egw']->session->appsession('index',TIMESHEET_APP,$query);
|
||||
|
||||
unset($query['col_filter']['cat_id']);
|
||||
if ($query['cat_id'])
|
||||
{
|
||||
if (!is_object($GLOBALS['egw']->categories))
|
||||
{
|
||||
$GLOBALS['egw']->categories =& CreateObject('phpgwapi.categories');
|
||||
}
|
||||
$cats = $GLOBALS['egw']->categories->return_all_children((int)$query['cat_id']);
|
||||
$query['col_filter']['cat_id'] = count($cats) > 1 ? $cats : $query['cat_id'];
|
||||
}
|
||||
if ($query['filter'])
|
||||
{
|
||||
$query['col_filter'][0] = $this->date_filter($query['filter']);
|
||||
}
|
||||
if (!$query['col_filter']['ts_owner']) unset($query['col_filter']['ts_owner']);
|
||||
|
||||
$total = parent::get_rows($query,$rows,$readonlys);
|
||||
|
||||
unset($query['col_filter'][0]);
|
||||
|
||||
$readonlys = array();
|
||||
foreach($rows as $n => $val)
|
||||
{
|
||||
$row =& $rows[$n];
|
||||
if (!$this->check_acl(EGW_ACL_EDIT,$row))
|
||||
{
|
||||
$readonlys["edit[$row[ts_id]]"] = true;
|
||||
}
|
||||
if (!$this->check_acl(EGW_ACL_DELETE,$row))
|
||||
{
|
||||
$readonlys["delete[$row[ts_id]]"] = true;
|
||||
}
|
||||
if ($query['col_filter']['ts_project'] || !$query['filter2'])
|
||||
{
|
||||
unset($row['ts_project']); // dont need or want to show it
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($links = $this->link->get_links(TIMESHEET_APP,$row['ts_id'],'projectmanager')))
|
||||
{
|
||||
$row['ts_link'] = array(
|
||||
'app' => 'projectmanager',
|
||||
'id' => array_shift($links),
|
||||
);
|
||||
}
|
||||
$row['ts_link']['title'] = $row['ts_project'];
|
||||
}
|
||||
if (!$query['filter2'])
|
||||
{
|
||||
unset($row['ts_description']);
|
||||
}
|
||||
}
|
||||
$rows['no_owner_col'] = $query['no_owner_col'];
|
||||
if ($query['filter'])
|
||||
{
|
||||
$rows['duration'] = $this->summary['duration'];
|
||||
$rows['price'] = $this->summary['price'];
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* List timesheet entries
|
||||
*
|
||||
* @param array $content=null
|
||||
*/
|
||||
function index($content = null,$msg='')
|
||||
{
|
||||
$etpl =& new etemplate('timesheet.index');
|
||||
|
||||
if ($_GET['msg']) $msg = $_GET['msg'];
|
||||
|
||||
$content = array(
|
||||
'nm' => $GLOBALS['egw']->session->appsession('index',TIMESHEET_APP),
|
||||
'msg' => $msg,
|
||||
);
|
||||
if (!is_array($content['nm']))
|
||||
{
|
||||
$date_filters = array('All');
|
||||
foreach($this->date_filters as $name => $date)
|
||||
{
|
||||
$date_filters[$name] = $name;
|
||||
}
|
||||
$content['nm'] = array(
|
||||
'get_rows' => TIMESHEET_APP.'.uitimesheet.get_rows',
|
||||
'options-filter' => $date_filters,
|
||||
'options-filter2' => array('No details','Details'),
|
||||
'order' => 'ts_start',// IO name of the column to sort after (optional for the sortheaders)
|
||||
'sort' => 'DESC',// IO direction of the sort: 'ASC' or 'DESC'
|
||||
);
|
||||
}
|
||||
$read_grants = $this->grant_list(EGW_ACL_READ);
|
||||
$content['nm']['no_owner_col'] = count($read_grants) == 1;
|
||||
|
||||
return $etpl->exec(TIMESHEET_APP.'.uitimesheet.index',$content,array(
|
||||
'ts_project' => $this->query_list('ts_project'),
|
||||
'ts_owner' => $read_grants,
|
||||
),$readonlys,$preserv);
|
||||
}
|
||||
}
|
39
timesheet/index.php
Normal file
39
timesheet/index.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - TimeSheet - time tracking for ProjectManager *
|
||||
* http://www.egroupware.org *
|
||||
* Written and (c) 2005 by Ralf Becker <RalfBecker@outdoor-training.de> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
include_once('setup/setup.inc.php');
|
||||
$ts_version = $setup_info[TIMESHEET_APP]['version'];
|
||||
unset($setup_info);
|
||||
|
||||
$GLOBALS['egw_info'] = array(
|
||||
'flags' => array(
|
||||
'currentapp' => TIMESHEET_APP,
|
||||
'noheader' => True,
|
||||
'nonavbar' => True
|
||||
));
|
||||
include('../header.inc.php');
|
||||
|
||||
if ($ts_version != $GLOBALS['egw_info']['apps'][TIMESHEET_APP]['version'])
|
||||
{
|
||||
$GLOBALS['egw']->common->egw_header();
|
||||
parse_navbar();
|
||||
echo '<p style="text-align: center; color:red; font-weight: bold;">'.lang('Your database is NOT up to date (%1 vs. %2), please run %3setup%4 to update your database.',
|
||||
$ts_version,$GLOBALS['egw_info']['apps'][TIMESHEET_APP]['version'],
|
||||
'<a href="../setup/">','</a>')."</p>\n";
|
||||
$GLOBALS['egw']->common->egw_exit();
|
||||
}
|
||||
|
||||
//ExecMethod(TIMESHEET_APP.'.pm_admin_prefs_sidebox_hooks.check_set_default_prefs');
|
||||
|
||||
$GLOBALS['egw']->redirect_link('/index.php',array('menuaction'=>TIMESHEET_APP.'.uitimesheet.index'));
|
19
timesheet/setup/etemplates.inc.php
Normal file
19
timesheet/setup/etemplates.inc.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
// eTemplates for Application 'timesheet', generated by soetemplate::dump4setup() 2005-12-19 01:52
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
$templ_version=1;
|
||||
|
||||
$templ_data[] = array('name' => 'timesheet.edit','template' => '','lang' => '','group' => '0','version' => '0.1.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:8:{i:0;a:8:{s:2:"c2";s:2:"th";s:2:"c3";s:3:"row";s:1:"A";s:3:"100";s:2:"c6";s:3:"row";s:2:"h6";s:14:",!@ts_modified";s:2:"c4";s:3:"row";s:2:"h2";s:2:"28";s:2:"h1";s:6:",!@msg";}i:1;a:2:{s:1:"A";a:5:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:4:"name";s:3:"msg";s:7:"no_lang";s:1:"1";s:5:"align";s:6:"center";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:11:",,,ts_owner";s:5:"label";s:4:"User";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:4:"name";s:8:"ts_owner";s:4:"span";s:3:"all";s:7:"no_lang";s:1:"1";}}i:3;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:13:",,,ts_project";s:5:"label";s:7:"Project";}s:1:"B";a:5:{s:4:"type";s:4:"text";s:4:"size";s:5:"65,80";s:4:"name";s:10:"ts_project";s:4:"span";s:3:"all";s:4:"blur";s:16:"@ts_project_blur";}}i:4;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"size";s:14:",,ts_unitprice";s:5:"label";s:9:"Unitprice";}s:1:"B";a:3:{s:4:"type";s:5:"float";s:4:"name";s:12:"ts_unitprice";s:4:"span";s:3:"all";}}i:5;a:2:{s:1:"A";a:4:{s:4:"type";s:3:"tab";s:5:"label";s:19:"General|Notes|Links";s:4:"name";s:19:"general|notes|links";s:4:"span";s:3:"all";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:6;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:13:"Last modified";}s:1:"B";a:4:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"2";i:1;a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:11:"ts_modified";s:8:"readonly";s:1:"1";}i:2;a:4:{s:4:"type";s:14:"select-account";s:4:"name";s:11:"ts_modifier";s:5:"label";s:2:"by";s:8:"readonly";s:1:"1";}}}i:7;a:2:{s:1:"A";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:5:"2,0,0";s:4:"span";s:1:"2";i:1;a:8:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"6";i:1;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Edit";s:4:"name";s:12:"button[edit]";s:4:"help";s:15:"Edit this entry";}i:2;a:4:{s:4:"type";s:6:"button";s:4:"name";s:16:"button[save_new]";s:5:"label";s:10:"Save & New";s:4:"help";s:34:"Saves this entry and add a new one";}i:3;a:4:{s:4:"type";s:6:"button";s:4:"name";s:12:"button[save]";s:5:"label";s:4:"Save";s:4:"help";s:22:"Saves the changes made";}i:4;a:4:{s:4:"type";s:6:"button";s:4:"name";s:13:"button[apply]";s:5:"label";s:5:"Apply";s:4:"help";s:24:"Applies the changes made";}i:5;a:5:{s:4:"type";s:6:"button";s:4:"name";s:14:"button[cancel]";s:5:"label";s:6:"Cancel";s:4:"help";s:44:"closes the window without saving the changes";s:7:"onclick";s:15:"window.close();";}i:6;a:2:{s:4:"type";s:4:"html";s:4:"name";s:2:"js";}}i:2;a:6:{s:4:"type";s:6:"button";s:5:"label";s:6:"Delete";s:5:"align";s:5:"right";s:4:"name";s:14:"button[delete]";s:4:"help";s:17:"Delete this entry";s:7:"onclick";s:36:"return confirm(\'Delete this entry\');";}}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:7;s:4:"cols";i:2;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1134772260',);
|
||||
|
||||
$templ_data[] = array('name' => 'timesheet.edit.general','template' => '','lang' => '','group' => '0','version' => '0.1.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:6:{i:0;a:5:{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:"c2";s:3:"row";}i:1;a:2:{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:4:{s:4:"type";s:4:"text";s:4:"size";s:5:"65,80";s:4:"name";s:8:"ts_title";s:6:"needed";s:1:"1";}}i:2;a:2:{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:3:{s:4:"type";s:10:"select-cat";s:4:"name";s:6:"cat_id";s:4:"size";s:4:"None";}}i:3;a:2:{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:9:"date-time";s:4:"name";s:8:"ts_start";s:6:"needed";s:1:"1";s:4:"size";s:2:",8";}}i:4;a:2:{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:2:",h";}}i:5;a:2:{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:4:{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:"rows";i:5;s:4:"cols";i:2;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' => '1134773043',);
|
||||
|
||||
$templ_data[] = array('name' => 'timesheet.edit.links','template' => '','lang' => '','group' => '0','version' => '0.1.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:7:{s:1:"A";s:3:"100";s:2:"h1";s:13:",@status_only";s:2:"h2";s:13:",@status_only";s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";s:2:"c3";s:2:"th";s:2:"c4";s:11:"row_off,top";}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:3:"all";s:5:"label";s:16:"Create new links";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:3:{s:4:"type";s:7:"link-to";s:4:"span";s:3:"all";s:4:"name";s:7:"link_to";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:3;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:3:"all";s:5:"label";s:14:"Existing links";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:4;a:2:{s:1:"A";a:3:{s:4:"type";s:9:"link-list";s:4:"span";s:3:"all";s:4:"name";s:7:"link_to";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:4;s:4:"cols";i:2;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' => '100%,150,,,,,auto','style' => '','modified' => '1134775301',);
|
||||
|
||||
$templ_data[] = array('name' => 'timesheet.edit.notes','template' => '','lang' => '','group' => '0','version' => '0.1.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:2:{i:0;a:1:{s:2:"c1";s:7:"row,top";}i:1;a:1:{s:1:"A";a:3:{s:4:"type";s:8:"textarea";s:4:"size";s:4:"8,70";s:4:"name";s:14:"ts_description";}}}s:4:"rows";i:1;s:4:"cols";i:1;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' => '1134773787',);
|
||||
|
||||
$templ_data[] = array('name' => 'timesheet.index','template' => '','lang' => '','group' => '0','version' => '0.1.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:4:{i:0;a:1:{s:2:"h1";s:6:",!@msg";}i:1;a:1:{s:1:"A";a:5:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";s:5:"align";s:6:"center";}}i:2;a:1:{s:1:"A";a:3:{s:4:"type";s:9:"nextmatch";s:4:"name";s:2:"nm";s:4:"size";s:20:"timesheet.index.rows";}}i:3;a:1:{s:1:"A";a:4:{s:4:"type";s:6:"button";s:5:"label";s:3:"Add";s:4:"name";s:3:"add";s:7:"onclick";s:163:"window.open(egw::link(\'/index.php\',\'menuaction=timesheet.uitimesheet.edit\'),\'_blank\',\'dependent=yes,width=600,height=400,scrollbars=yes,status=yes\'); return false;";}}}s:4:"rows";i:3;s:4:"cols";i:1;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1134799202',);
|
||||
|
||||
$templ_data[] = array('name' => 'timesheet.index.rows','template' => '','lang' => '','group' => '0','version' => '0.1.001','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:5:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";s:1:"A";s:3:"15%";s:1:"G";s:14:",@no_owner_col";s:1:"B";s:3:"50%";}i:1;a:8:{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:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"2";s:7:"no_lang";s:1:"1";i:1;a:4:{s:4:"type";s:22:"nextmatch-filterheader";s:4:"size";s:7:"Project";s:4:"name";s:10:"ts_project";s:7:"no_lang";s:1:"1";}i:2;a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Title";s:4:"name";s:8:"ts_title";}}s:1:"C";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:"D";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:8:"Quantity";s:4:"name";s:11:"ts_quantity";}s:1:"E";a:3:{s:4:"type";s:20:"nextmatch-sortheader";s:5:"label";s:5:"Price";s:4:"name";s:12:"ts_unitprice";}s:1:"F";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:3:{s:4:"type";s:5:"float";s:4:"name";s:5:"price";s:8:"readonly";s:1:"1";}}s:1:"G";a:4:{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:1:"H";a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"Actions";}}i:2;a:8:{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:"size";s:1:"b";}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:13:"date-duration";s:4:"name";s:19:"${row}[ts_duration]";s:8:"readonly";s:1:"1";s:4:"size";s:5:",,,,1";}s:1:"D";a:3:{s:4:"type";s:5:"label";s:4:"name";s:19:"${row}[ts_quantity]";s:7:"no_lang";s:1:"1";}s:1:"E";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:"F";a:3:{s:4:"type";s:5:"label";s:7:"no_lang";s:1:"1";s:4:"name";s:16:"${row}[ts_total]";}s:1:"G";a:3:{s:4:"type";s:14:"select-account";s:4:"name";s:16:"${row}[ts_owner]";s:8:"readonly";s:1:"1";}s:1:"H";a:5:{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:186:"window.open(egw::link(\'/index.php\',\'menuaction=timesheet.uitimesheet.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:186:"window.open(egw::link(\'/index.php\',\'menuaction=timesheet.uitimesheet.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:"rows";i:2;s:4:"cols";i:8;s:4:"size";s:4:"100%";s:7:"options";a:1:{i:0;s:4:"100%";}}}','size' => '100%','style' => '','modified' => '1134799629',);
|
||||
|
34
timesheet/setup/phpgw_de.lang
Normal file
34
timesheet/setup/phpgw_de.lang
Normal file
@ -0,0 +1,34 @@
|
||||
2 month ago timesheet de Vor 2 Monaten
|
||||
2 years ago timesheet de Vor 2 Jahren
|
||||
3 years ago timesheet de Vor 3 Jahren
|
||||
actions timesheet de Aktionen
|
||||
by timesheet de von
|
||||
create new links timesheet de Neue Verknüpfung erstellen
|
||||
delete this entry timesheet de Diesen Eintrag löschen
|
||||
edit this entry timesheet de diesen Eintrag bearbeiten
|
||||
empty if identical to duration timesheet de leer lassen wenn gleich Dauer
|
||||
entry deleted timesheet de Eintrag gelöscht
|
||||
entry saved timesheet de Eintrag gespeichert
|
||||
error saving the entry!!! timesheet de Fehler beim Speichern des Eintrags!!!
|
||||
existing links timesheet de Bestehende Verknüpfungen
|
||||
general timesheet de Allgemein
|
||||
last modified timesheet de Zuletzt geändert
|
||||
last month timesheet de Letzten Monat
|
||||
last week timesheet de Letzte Woche
|
||||
last year timesheet de Letztes Jahr
|
||||
links timesheet de Verknüpfungen
|
||||
no details timesheet de Keine Details
|
||||
permission denied!!! timesheet de Zugriff verweigert!!!
|
||||
price timesheet de Preis
|
||||
quantity timesheet de Menge
|
||||
save & new timesheet de Speichern & Neu
|
||||
saves the changes made timesheet de Speichert die Änderungen
|
||||
saves this entry and add a new one timesheet de Speichert diesen Eintrag und fügt einen neune hinzu
|
||||
this month timesheet de Diesen Monat
|
||||
this week timesheet de Diese Woche
|
||||
this year timesheet de Diese Jahr
|
||||
timesheet common de Stundenzettel
|
||||
unitprice timesheet de Preis pro Einheit
|
||||
view this entry timesheet de Diesen Eintrag anzeigen
|
||||
yesterday timesheet de Gestern
|
||||
your database is not up to date (%1 vs. %2), please run %3setup%4 to update your database. timesheet de Ihre Datenbank ist NICHT aktuell (%1 statt %2), bitte rufen sie %3setup%4 auf um die Datenbank zu aktualisieren.
|
34
timesheet/setup/phpgw_en.lang
Normal file
34
timesheet/setup/phpgw_en.lang
Normal file
@ -0,0 +1,34 @@
|
||||
2 month ago timesheet en 2 month ago
|
||||
2 years ago timesheet en 2 years ago
|
||||
3 years ago timesheet en 3 years ago
|
||||
actions timesheet en Actions
|
||||
by timesheet en by
|
||||
create new links timesheet en Create new links
|
||||
delete this entry timesheet en Delete this entry
|
||||
edit this entry timesheet en Edit this entry
|
||||
empty if identical to duration timesheet en empty if identical to duration
|
||||
entry deleted timesheet en Entry deleted
|
||||
entry saved timesheet en Entry saved
|
||||
error saving the entry!!! timesheet en Error saving the entry!!!
|
||||
existing links timesheet en Existing links
|
||||
general timesheet en General
|
||||
last modified timesheet en Last modified
|
||||
last month timesheet en Last month
|
||||
last week timesheet en Last week
|
||||
last year timesheet en Last year
|
||||
links timesheet en Links
|
||||
no details timesheet en no details
|
||||
permission denied!!! timesheet en Permission denied!!!
|
||||
price timesheet en Price
|
||||
quantity timesheet en Quantity
|
||||
save & new timesheet en Save & New
|
||||
saves the changes made timesheet en Saves the changes made
|
||||
saves this entry and add a new one timesheet en Saves this entry and add a new one
|
||||
this month timesheet en This month
|
||||
this week timesheet en This week
|
||||
this year timesheet en This year
|
||||
timesheet common en TimeSheet
|
||||
unitprice timesheet en Unitprice
|
||||
view this entry timesheet en View this entry
|
||||
yesterday timesheet en Yesterday
|
||||
your database is not up to date (%1 vs. %2), please run %3setup%4 to update your database. timesheet en Your database is NOT up to date (%1 vs. %2), please run %3setup%4 to update your database.
|
55
timesheet/setup/setup.inc.php
Normal file
55
timesheet/setup/setup.inc.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - TimeSheet - time tracking for ProjectManager *
|
||||
* http://www.egroupware.org *
|
||||
* Written and (c) 2005 by Ralf Becker <RalfBecker@outdoor-training.de> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
if (!defined('TIMESHEET_APP'))
|
||||
{
|
||||
define('TIMESHEET_APP','timesheet');
|
||||
}
|
||||
|
||||
$setup_info[TIMESHEET_APP]['name'] = TIMESHEET_APP;
|
||||
$setup_info[TIMESHEET_APP]['version'] = '0.1.001';
|
||||
$setup_info[TIMESHEET_APP]['app_order'] = 5;
|
||||
$setup_info[TIMESHEET_APP]['tables'] = array('egw_timesheet');
|
||||
$setup_info[TIMESHEET_APP]['enable'] = 1;
|
||||
|
||||
$setup_info[TIMESHEET_APP]['author'] =
|
||||
$setup_info[TIMESHEET_APP]['maintainer'] = array(
|
||||
'name' => 'Ralf Becker',
|
||||
'email' => 'RalfBecker@outdoor-training.de'
|
||||
);
|
||||
$setup_info[TIMESHEET_APP]['license'] = 'GPL';
|
||||
$setup_info[TIMESHEET_APP]['description'] =
|
||||
'Tracking times and other activities for the Projectmanager.';
|
||||
$setup_info[TIMESHEET_APP]['note'] =
|
||||
'The TimeSheet application is sponsored by:<ul>
|
||||
<li> <a href="http://www.stylite.de" target="_blank">Stylite GmbH</a></li>
|
||||
<li> <a href="http://www.outdoor-training.de" target="_blank">Outdoor Unlimited Training GmbH</a></li>
|
||||
</ul>';
|
||||
|
||||
/* The hooks this app includes, needed for hooks registration */
|
||||
$setup_info[TIMESHEET_APP]['hooks']['preferences'] = TIMESHEET_APP.'.ts_admin_prefs_sidebox_hooks.all_hooks';
|
||||
$setup_info[TIMESHEET_APP]['hooks']['settings'] = TIMESHEET_APP.'.ts_admin_prefs_sidebox_hooks.settings';
|
||||
$setup_info[TIMESHEET_APP]['hooks']['admin'] = TIMESHEET_APP.'.ts_admin_prefs_sidebox_hooks.all_hooks';
|
||||
$setup_info[TIMESHEET_APP]['hooks']['sidebox_menu'] = TIMESHEET_APP.'.ts_admin_prefs_sidebox_hooks.all_hooks';
|
||||
$setup_info[TIMESHEET_APP]['hooks']['search_link'] = TIMESHEET_APP.'.botimesheet.search_link';
|
||||
|
||||
/* Dependencies for this app to work */
|
||||
$setup_info[TIMESHEET_APP]['depends'][] = array(
|
||||
'appname' => 'phpgwapi',
|
||||
'versions' => Array('1.2','1.3')
|
||||
);
|
||||
$setup_info[TIMESHEET_APP]['depends'][] = array(
|
||||
'appname' => 'etemplate',
|
||||
'versions' => Array('1.2','1.3')
|
||||
);
|
37
timesheet/setup/tables_current.inc.php
Normal file
37
timesheet/setup/tables_current.inc.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Setup *
|
||||
* http://www.eGroupWare.org *
|
||||
* Created by eTemplates DB-Tools written by ralfbecker@outdoor-training.de *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
|
||||
$phpgw_baseline = array(
|
||||
'egw_timesheet' => array(
|
||||
'fd' => array(
|
||||
'ts_id' => array('type' => 'auto','nullable' => False),
|
||||
'ts_project' => array('type' => 'varchar','precision' => '80'),
|
||||
'ts_title' => array('type' => 'varchar','precision' => '80','nullable' => False),
|
||||
'ts_description' => array('type' => 'text'),
|
||||
'ts_start' => array('type' => 'int','precision' => '8','nullable' => False),
|
||||
'ts_duration' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0'),
|
||||
'ts_quantity' => array('type' => 'float','precision' => '8','nullable' => False),
|
||||
'ts_unitprice' => array('type' => 'float','precision' => '4'),
|
||||
'cat_id' => array('type' => 'int','precision' => '4','default' => '0'),
|
||||
'ts_owner' => array('type' => 'int','precision' => '4','nullable' => False),
|
||||
'ts_modified' => array('type' => 'int','precision' => '8','nullable' => False),
|
||||
'ts_modifier' => array('type' => 'int','precision' => '4','nullable' => False)
|
||||
),
|
||||
'pk' => array('ts_id'),
|
||||
'fk' => array(),
|
||||
'ix' => array('ts_project','ts_owner'),
|
||||
'uc' => array()
|
||||
)
|
||||
);
|
2
timesheet/templates/default/app.css
Normal file
2
timesheet/templates/default/app.css
Normal file
@ -0,0 +1,2 @@
|
||||
/* $Id$ */
|
||||
.redItalic { color: red; font-style: italics; }
|
134
timesheet/templates/default/edit.xet
Normal file
134
timesheet/templates/default/edit.xet
Normal file
@ -0,0 +1,134 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="timesheet.edit.general" template="" lang="" group="0" version="0.1.001">
|
||||
<grid width="100%" height="150">
|
||||
<columns>
|
||||
<column width="95"/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="row">
|
||||
<description options=",,,ts_title" value="Title"/>
|
||||
<textbox size="65" maxlength="80" id="ts_title" needed="1"/>
|
||||
</row>
|
||||
<row class="row">
|
||||
<description options=",,,cat_id" value="Category"/>
|
||||
<menulist>
|
||||
<menupopup type="select-cat" id="cat_id" options="None"/>
|
||||
</menulist>
|
||||
</row>
|
||||
<row class="row">
|
||||
<description options=",,,ts_start" value="Date"/>
|
||||
<date-time id="ts_start" needed="1" options=",8"/>
|
||||
</row>
|
||||
<row class="row">
|
||||
<description options=",,,ts_duration" value="Duration"/>
|
||||
<date-duration id="ts_duration" options=",h"/>
|
||||
</row>
|
||||
<row>
|
||||
<description options=",,,ts_quantity" value="Quantity"/>
|
||||
<textbox type="float" id="ts_quantity" statustext="empty if identical to duration" blur="@ts_quantity_blur"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="timesheet.edit.notes" template="" lang="" group="0" version="0.1.001">
|
||||
<grid width="100%" height="150">
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="row" valign="top">
|
||||
<textbox multiline="true" rows="8" cols="70" id="ts_description"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="timesheet.edit.links" template="" lang="" group="0" version="0.1.001">
|
||||
<grid width="100%" height="150" overflow="auto">
|
||||
<columns>
|
||||
<column width="100"/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th" disabled="@status_only">
|
||||
<description span="all" value="Create new links"/>
|
||||
</row>
|
||||
<row class="row" disabled="@status_only">
|
||||
<link-to span="all" id="link_to"/>
|
||||
</row>
|
||||
<row class="th">
|
||||
<description span="all" value="Existing links"/>
|
||||
</row>
|
||||
<row class="row_off" valign="top">
|
||||
<link-list span="all" id="link_to"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="timesheet.edit" template="" lang="" group="0" version="0.1.001">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column width="100"/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row disabled="!@msg">
|
||||
<description span="all" class="redItalic" id="msg" no_lang="1" align="center"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row class="th" height="28">
|
||||
<description options=",,,ts_owner" value="User"/>
|
||||
<menulist span="all">
|
||||
<menupopup id="ts_owner" no_lang="1"/>
|
||||
</menulist>
|
||||
</row>
|
||||
<row class="row">
|
||||
<description options=",,,ts_project" value="Project"/>
|
||||
<textbox size="65" maxlength="80" id="ts_project" span="all" blur="@ts_project_blur"/>
|
||||
</row>
|
||||
<row class="row">
|
||||
<description options=",,ts_unitprice" value="Unitprice"/>
|
||||
<textbox type="float" id="ts_unitprice" span="all"/>
|
||||
</row>
|
||||
<row>
|
||||
<tabbox span="all">
|
||||
<tabs>
|
||||
<tab label="General" statustext=""/>
|
||||
<tab label="Notes" statustext=""/>
|
||||
<tab label="Links" statustext=""/>
|
||||
</tabs>
|
||||
<tabpanels>
|
||||
<template id="timesheet.edit.general"/>
|
||||
<template id="timesheet.edit.notes"/>
|
||||
<template id="timesheet.edit.links"/>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
</row>
|
||||
<row class="row" disabled="!@ts_modified">
|
||||
<description value="Last modified"/>
|
||||
<hbox>
|
||||
<date-time id="ts_modified" readonly="true"/>
|
||||
<menulist>
|
||||
<menupopup type="select-account" id="ts_modifier" label="by" readonly="true"/>
|
||||
</menulist>
|
||||
</hbox>
|
||||
</row>
|
||||
<row>
|
||||
<hbox span="2" orient="0,0">
|
||||
<hbox>
|
||||
<button label="Edit" id="button[edit]" statustext="Edit this entry"/>
|
||||
<button id="button[save_new]" label="Save & New" statustext="Saves this entry and add a new one"/>
|
||||
<button id="button[save]" label="Save" statustext="Saves the changes made"/>
|
||||
<button id="button[apply]" label="Apply" statustext="Applies the changes made"/>
|
||||
<button id="button[cancel]" label="Cancel" statustext="closes the window without saving the changes" onclick="window.close();"/>
|
||||
<html id="js"/>
|
||||
</hbox>
|
||||
<button label="Delete" align="right" id="button[delete]" statustext="Delete this entry" onclick="return confirm('Delete this entry');"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
</overlay>
|
BIN
timesheet/templates/default/images/navbar.png
Normal file
BIN
timesheet/templates/default/images/navbar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
77
timesheet/templates/default/index.xet
Normal file
77
timesheet/templates/default/index.xet
Normal file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="timesheet.index.rows" template="" lang="" group="0" version="0.1.001">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column width="15%"/>
|
||||
<column width="50%"/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column disabled="@no_owner_col"/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th">
|
||||
<nextmatch-sortheader label="Date" id="ts_start"/>
|
||||
<vbox no_lang="1">
|
||||
<nextmatch-filterheader options="Project" id="ts_project" no_lang="1"/>
|
||||
<nextmatch-sortheader label="Title" id="ts_title"/>
|
||||
</vbox>
|
||||
<vbox>
|
||||
<nextmatch-sortheader label="Duration" id="ts_duration"/>
|
||||
<date-duration id="duration" options=",h,,,1" readonly="true"/>
|
||||
</vbox>
|
||||
<nextmatch-sortheader label="Quantity" id="ts_quantity"/>
|
||||
<nextmatch-sortheader label="Price" id="ts_unitprice"/>
|
||||
<vbox>
|
||||
<nextmatch-sortheader label="Total" id="ts_total"/>
|
||||
<textbox type="float" id="price" readonly="true"/>
|
||||
</vbox>
|
||||
<nextmatch-filterheader id="ts_owner" options="User" no_lang="1"/>
|
||||
<description value="Actions"/>
|
||||
</row>
|
||||
<row class="row">
|
||||
<date-time id="${row}[ts_start]" readonly="true" options=",8"/>
|
||||
<vbox>
|
||||
<link id="${row}[ts_link]" no_lang="1"/>
|
||||
<description id="${row}[ts_title]" no_lang="1" options="b"/>
|
||||
<description id="${row}[ts_description]" no_lang="1"/>
|
||||
</vbox>
|
||||
<date-duration id="${row}[ts_duration]" readonly="true" options=",,,,1"/>
|
||||
<description id="${row}[ts_quantity]" no_lang="1"/>
|
||||
<description no_lang="1" id="${row}[ts_unitprice]"/>
|
||||
<description no_lang="1" id="${row}[ts_total]"/>
|
||||
<menulist>
|
||||
<menupopup type="select-account" id="${row}[ts_owner]" readonly="true"/>
|
||||
</menulist>
|
||||
<hbox>
|
||||
<button image="view" label="View" id="view[$row_cont[ts_id]]" onclick="window.open(egw::link('/index.php','menuaction=timesheet.uitimesheet.view&ts_id=$row_cont[ts_id]'),'_blank','dependent=yes,width=600,height=400,scrollbars=yes,status=yes'); return false;" statustext="View this entry"/>
|
||||
<button image="edit" label="Edit" id="edit[$row_cont[ts_id]]" statustext="Edit this entry" onclick="window.open(egw::link('/index.php','menuaction=timesheet.uitimesheet.edit&ts_id=$row_cont[ts_id]'),'_blank','dependent=yes,width=600,height=400,scrollbars=yes,status=yes'); return false;"/>
|
||||
<button image="delete" label="Delete" id="delete[$row_cont[ts_id]]" statustext="Delete this entry" onclick="return confirm('Delete this entry');"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="timesheet.index" template="" lang="" group="0" version="0.1.001">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row disabled="!@msg">
|
||||
<description span="all" class="redItalic" no_lang="1" id="msg" align="center"/>
|
||||
</row>
|
||||
<row>
|
||||
<nextmatch id="nm" options="timesheet.index.rows"/>
|
||||
</row>
|
||||
<row>
|
||||
<button label="Add" id="add" onclick="window.open(egw::link('/index.php','menuaction=timesheet.uitimesheet.edit'),'_blank','dependent=yes,width=600,height=400,scrollbars=yes,status=yes'); return false;"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
</overlay>
|
7
timesheet/templates/default/preference_acl_row.tpl
Normal file
7
timesheet/templates/default/preference_acl_row.tpl
Normal file
@ -0,0 +1,7 @@
|
||||
<!-- $Id$ -->
|
||||
<tr class="{row_class}">
|
||||
<td>{user}</td>
|
||||
<td align="center"><input type="checkbox" name="{read}" value="Y"{read_selected}></td>
|
||||
<td align="center"><input type="checkbox" name="{edit}" value="Y"{edit_selected}></td>
|
||||
<td align="center"><input type="checkbox" name="{delete}" value="Y"{delete_selected}></td>
|
||||
</tr>
|
6
timesheet/templates/default/preference_colspan.tpl
Normal file
6
timesheet/templates/default/preference_colspan.tpl
Normal file
@ -0,0 +1,6 @@
|
||||
<tr class="th">
|
||||
<td>{string}</td>
|
||||
<td align="center" width="8%">{lang_read}</td>
|
||||
<td align="center" width="8%">{lang_edit}</td>
|
||||
<td align="center" width="8%">{lang_delete}</td>
|
||||
</tr>
|
Loading…
Reference in New Issue
Block a user