mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-24 17:04:14 +01:00
* Timesheet: allow to record/document pause times with timer and manually
This commit is contained in:
parent
eaa4a6abd0
commit
f082055134
@ -137,6 +137,7 @@ class timesheet_bo extends Api\Storage
|
|||||||
'ts_description' => 'Description',
|
'ts_description' => 'Description',
|
||||||
'ts_start' => 'Start',
|
'ts_start' => 'Start',
|
||||||
'ts_duration' => 'Duration',
|
'ts_duration' => 'Duration',
|
||||||
|
'ts_paused' => 'Paused',
|
||||||
'ts_quantity' => 'Quantity',
|
'ts_quantity' => 'Quantity',
|
||||||
'ts_unitprice' => 'Unitprice',
|
'ts_unitprice' => 'Unitprice',
|
||||||
'ts_owner' => 'Owner',
|
'ts_owner' => 'Owner',
|
||||||
@ -506,7 +507,7 @@ class timesheet_bo extends Api\Storage
|
|||||||
//_debug_array($ids);
|
//_debug_array($ids);
|
||||||
if(empty($ids))
|
if(empty($ids))
|
||||||
{
|
{
|
||||||
$this->summary = array('duration' => 0, 'price' => null, 'quantity' => 0);
|
$this->summary = array('duration' => 0, 'paused' => 0, 'price' => null, 'quantity' => 0);
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
unset($criteria);
|
unset($criteria);
|
||||||
@ -520,6 +521,7 @@ class timesheet_bo extends Api\Storage
|
|||||||
// is not joined, as the join causes a multiplication of the sum per customfield found
|
// is not joined, as the join causes a multiplication of the sum per customfield found
|
||||||
// joining of the cutomfield table is triggered by criteria being set with either a string or an array
|
// joining of the cutomfield table is triggered by criteria being set with either a string or an array
|
||||||
$cols = ['SUM(ts_duration) AS duration',
|
$cols = ['SUM(ts_duration) AS duration',
|
||||||
|
'SUM(COALESCE(ts_paused,0)) AS paused',
|
||||||
"SUM($total_sql) AS price",
|
"SUM($total_sql) AS price",
|
||||||
'MAX(ts_modified) AS max_modified'];
|
'MAX(ts_modified) AS max_modified'];
|
||||||
if($this->quantity_sum)
|
if($this->quantity_sum)
|
||||||
@ -569,7 +571,7 @@ class timesheet_bo extends Api\Storage
|
|||||||
parent::search($criteria,array(
|
parent::search($criteria,array(
|
||||||
(string)$sum_ts_id[$type],"''","''","''",'MIN(ts_start)','SUM(ts_duration) AS ts_duration',
|
(string)$sum_ts_id[$type],"''","''","''",'MIN(ts_start)','SUM(ts_duration) AS ts_duration',
|
||||||
($this->quantity_sum ? "SUM(ts_quantity) AS ts_quantity" : '0'),
|
($this->quantity_sum ? "SUM(ts_quantity) AS ts_quantity" : '0'),
|
||||||
'0','NULL','0','0','0','0','0','0',"SUM($total_sql) AS ts_total"
|
'0','NULL','0','0','0','0','0','0',"SUM(COALESCE(ts_paused,0)) AS ts_paused","SUM($total_sql) AS ts_total"
|
||||||
),'GROUP BY '.$sum_sql[$type],$sum_extra_cols,$wildcard,$empty,$op,'UNION',$filter,$join,$need_full_no_count);
|
),'GROUP BY '.$sum_sql[$type],$sum_extra_cols,$wildcard,$empty,$op,'UNION',$filter,$join,$need_full_no_count);
|
||||||
$sum_extra_cols[$type][0] = '0';
|
$sum_extra_cols[$type][0] = '0';
|
||||||
}
|
}
|
||||||
@ -792,7 +794,7 @@ class timesheet_bo extends Api\Storage
|
|||||||
{
|
{
|
||||||
if(!$ids)
|
if(!$ids)
|
||||||
{
|
{
|
||||||
return array('duration' => 0, 'quantity' => 0, 'price' => 0, 'max_modified' => null);
|
return array('duration' => 0, 'paused' => 0, 'quantity' => 0, 'price' => 0, 'max_modified' => null);
|
||||||
}
|
}
|
||||||
$filter = [];
|
$filter = [];
|
||||||
if($ignore_acl)
|
if($ignore_acl)
|
||||||
|
@ -37,6 +37,7 @@ class timesheet_merge extends Api\Storage\Merge
|
|||||||
*/
|
*/
|
||||||
protected $numeric_fields = array(
|
protected $numeric_fields = array(
|
||||||
'$$ts_duration$$',
|
'$$ts_duration$$',
|
||||||
|
'$$ts_paused$$',
|
||||||
'$$ts_quantity$$',
|
'$$ts_quantity$$',
|
||||||
'$$ts_unitprice$$'
|
'$$ts_unitprice$$'
|
||||||
);
|
);
|
||||||
@ -132,7 +133,7 @@ class timesheet_merge extends Api\Storage\Merge
|
|||||||
|
|
||||||
$array = $record->get_record_array();
|
$array = $record->get_record_array();
|
||||||
$array['ts_total'] = $array['ts_quantity'] * $array['ts_unitprice'];
|
$array['ts_total'] = $array['ts_quantity'] * $array['ts_unitprice'];
|
||||||
foreach(array('ts_duration','ts_quantity','ts_unitprice','ts_total') as $key)
|
foreach(array('ts_duration','ts_paused','ts_quantity','ts_unitprice','ts_total') as $key)
|
||||||
{
|
{
|
||||||
$array[$key] = self::number_format($array[$key],2,$this->mimetype);
|
$array[$key] = self::number_format($array[$key],2,$this->mimetype);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ class timesheet_ui extends timesheet_bo
|
|||||||
// are we supposed to add pending events, to a new or an existing timesheet
|
// are we supposed to add pending events, to a new or an existing timesheet
|
||||||
if (isset($_REQUEST['events']))
|
if (isset($_REQUEST['events']))
|
||||||
{
|
{
|
||||||
$pending = Events::getPending($_REQUEST['events'] === 'overall', $time);
|
$pending = Events::getPending($_REQUEST['events'] === 'overall', $time, $paused);
|
||||||
$this->data['events'] = array_merge($this->data['events'], array_values($pending));
|
$this->data['events'] = array_merge($this->data['events'], array_values($pending));
|
||||||
$start = $this->data['events'][0]['tse_time'];
|
$start = $this->data['events'][0]['tse_time'];
|
||||||
$this->data['ts_start'] = $start;
|
$this->data['ts_start'] = $start;
|
||||||
@ -107,6 +107,7 @@ class timesheet_ui extends timesheet_bo
|
|||||||
$this->data['end_time'] = '';
|
$this->data['end_time'] = '';
|
||||||
$this->data['ts_duration'] = (int)$this->data['ts_duration'] + round($time / 60); // minutes
|
$this->data['ts_duration'] = (int)$this->data['ts_duration'] + round($time / 60); // minutes
|
||||||
$this->data['ts_quantity'] = (float)$this->data['ts_quantity'] + $this->data['ts_duration'] / 60.0; // hours
|
$this->data['ts_quantity'] = (float)$this->data['ts_quantity'] + $this->data['ts_duration'] / 60.0; // hours
|
||||||
|
$this->data['ts_paused'] = $paused ? round($paused / 60.0) : null;
|
||||||
// check if any of the events contains an app::id to link the timesheet to
|
// check if any of the events contains an app::id to link the timesheet to
|
||||||
foreach($pending as $event)
|
foreach($pending as $event)
|
||||||
{
|
{
|
||||||
|
@ -108,6 +108,8 @@ overwrite time common de Zeit überschreiben
|
|||||||
overwriting start or stop time timesheet de Überschreiben der Start- oder Stop-Zeit
|
overwriting start or stop time timesheet de Überschreiben der Start- oder Stop-Zeit
|
||||||
parent admin de Übergeordnet
|
parent admin de Übergeordnet
|
||||||
pause common de Pause
|
pause common de Pause
|
||||||
|
pause time timesheet de Pausenzeit
|
||||||
|
paused timesheet de Pausen
|
||||||
permission denied!!! timesheet de Zugriff verweigert!
|
permission denied!!! timesheet de Zugriff verweigert!
|
||||||
permissions error - %1 could not %2 timesheet de Fehler in den Zugriffsberechtigungen - %1 nicht möglich %2
|
permissions error - %1 could not %2 timesheet de Fehler in den Zugriffsberechtigungen - %1 nicht möglich %2
|
||||||
prevent deleting admin de Verhindert Löschung
|
prevent deleting admin de Verhindert Löschung
|
||||||
|
@ -108,6 +108,8 @@ overwrite time common en Overwrite time
|
|||||||
overwriting start or stop time timesheet en Overwriting start or stop time
|
overwriting start or stop time timesheet en Overwriting start or stop time
|
||||||
parent admin en Parent
|
parent admin en Parent
|
||||||
pause common en Pause
|
pause common en Pause
|
||||||
|
pause time timesheet en Pause time
|
||||||
|
paused timesheet en Paused
|
||||||
permission denied!!! timesheet en Permission denied!
|
permission denied!!! timesheet en Permission denied!
|
||||||
permissions error - %1 could not %2 timesheet en Permissions error - %1 could not %2
|
permissions error - %1 could not %2 timesheet en Permissions error - %1 could not %2
|
||||||
prevent deleting admin en Prevent deleting
|
prevent deleting admin en Prevent deleting
|
||||||
|
@ -16,7 +16,7 @@ if (!defined('TIMESHEET_APP'))
|
|||||||
}
|
}
|
||||||
|
|
||||||
$setup_info[TIMESHEET_APP]['name'] = TIMESHEET_APP;
|
$setup_info[TIMESHEET_APP]['name'] = TIMESHEET_APP;
|
||||||
$setup_info[TIMESHEET_APP]['version'] = '23.1';
|
$setup_info[TIMESHEET_APP]['version'] = '23.1.001';
|
||||||
$setup_info[TIMESHEET_APP]['app_order'] = 5;
|
$setup_info[TIMESHEET_APP]['app_order'] = 5;
|
||||||
$setup_info[TIMESHEET_APP]['tables'] = array('egw_timesheet','egw_timesheet_extra','egw_timesheet_events');
|
$setup_info[TIMESHEET_APP]['tables'] = array('egw_timesheet','egw_timesheet_extra','egw_timesheet_events');
|
||||||
$setup_info[TIMESHEET_APP]['enable'] = 1;
|
$setup_info[TIMESHEET_APP]['enable'] = 1;
|
||||||
|
@ -19,7 +19,7 @@ $phpgw_baseline = array(
|
|||||||
'ts_title' => array('type' => 'varchar','precision' => '255','nullable' => False,'comment' => 'title of the timesheet entry'),
|
'ts_title' => array('type' => 'varchar','precision' => '255','nullable' => False,'comment' => 'title of the timesheet entry'),
|
||||||
'ts_description' => array('type' => 'varchar','precision' => '16384','comment' => 'description of the timesheet entry'),
|
'ts_description' => array('type' => 'varchar','precision' => '16384','comment' => 'description of the timesheet entry'),
|
||||||
'ts_start' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'comment' => 'timestamp of the startdate'),
|
'ts_start' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'comment' => 'timestamp of the startdate'),
|
||||||
'ts_duration' => array('type' => 'int','precision' => '8','nullable' => False,'default' => '0','comment' => 'duration of the timesheet-entry'),
|
'ts_duration' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0','comment' => 'duration of the timesheet-entry'),
|
||||||
'ts_quantity' => array('type' => 'float','precision' => '8','nullable' => False,'comment' => 'quantity'),
|
'ts_quantity' => array('type' => 'float','precision' => '8','nullable' => False,'comment' => 'quantity'),
|
||||||
'ts_unitprice' => array('type' => 'float','precision' => '4','comment' => 'unitprice'),
|
'ts_unitprice' => array('type' => 'float','precision' => '4','comment' => 'unitprice'),
|
||||||
'cat_id' => array('type' => 'int','meta' => 'category','precision' => '4','default' => '0','comment' => 'category'),
|
'cat_id' => array('type' => 'int','meta' => 'category','precision' => '4','default' => '0','comment' => 'category'),
|
||||||
@ -28,7 +28,8 @@ $phpgw_baseline = array(
|
|||||||
'ts_modifier' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'account id of the last modifier'),
|
'ts_modifier' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'comment' => 'account id of the last modifier'),
|
||||||
'pl_id' => array('type' => 'int','precision' => '4','default' => '0','comment' => 'id of the linked project'),
|
'pl_id' => array('type' => 'int','precision' => '4','default' => '0','comment' => 'id of the linked project'),
|
||||||
'ts_status' => array('type' => 'int','precision' => '4','comment' => 'status of the timesheet-entry'),
|
'ts_status' => array('type' => 'int','precision' => '4','comment' => 'status of the timesheet-entry'),
|
||||||
'ts_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'comment' => 'Creation date of the timesheet')
|
'ts_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'comment' => 'Creation date of the timesheet'),
|
||||||
|
'ts_paused' => array('type' => 'int','precision' => '4','default' => '0','comment' => 'pause time(s) of the timesheet-entry')
|
||||||
),
|
),
|
||||||
'pk' => array('ts_id'),
|
'pk' => array('ts_id'),
|
||||||
'fk' => array(),
|
'fk' => array(),
|
||||||
|
@ -234,3 +234,14 @@ function timesheet_upgrade22_1()
|
|||||||
{
|
{
|
||||||
return $GLOBALS['setup_info']['timesheet']['currentver'] = '23.1';
|
return $GLOBALS['setup_info']['timesheet']['currentver'] = '23.1';
|
||||||
}
|
}
|
||||||
|
function timesheet_upgrade23_1()
|
||||||
|
{
|
||||||
|
$GLOBALS['egw_setup']->oProc->AddColumn('egw_timesheet','ts_paused',array(
|
||||||
|
'type' => 'int',
|
||||||
|
'precision' => '4',
|
||||||
|
'default' => '0',
|
||||||
|
'comment' => 'pause time(s) of the timesheet-entry'
|
||||||
|
));
|
||||||
|
|
||||||
|
return $GLOBALS['setup_info']['timesheet']['currentver'] = '23.1.001';
|
||||||
|
}
|
@ -218,17 +218,18 @@ class Events extends Api\Storage\Base
|
|||||||
*/
|
*/
|
||||||
public function storeWorkingTime()
|
public function storeWorkingTime()
|
||||||
{
|
{
|
||||||
if (!($events = self::getPending(true, $time)) || !$time)
|
if (!($events = self::getPending(true, $time, $paused)) || !$time)
|
||||||
{
|
{
|
||||||
throw new Api\Exception\AssertionFailed("No pending overall events!");
|
throw new Api\Exception\AssertionFailed("No pending overall events!");
|
||||||
}
|
}
|
||||||
$ids = array_keys($events);
|
$ids = array_keys($events);
|
||||||
$bo = new \timesheet_bo();
|
$bo = new \timesheet_bo();
|
||||||
// check if we already have a timesheet for the current periode
|
// check if we already have a timesheet for the current period
|
||||||
if (($period_ts = $bo->periodeWorkingTimesheet(reset($events)['tse_time'])))
|
if (($period_ts = $bo->periodeWorkingTimesheet(reset($events)['tse_time'])))
|
||||||
{
|
{
|
||||||
$events = array_merge(self::get(['ts_id' => $period_ts['ts_id']], $period_total), $events);
|
$events = array_merge(self::get(['ts_id' => $period_ts['ts_id']], $period_total, $period_paused), $events);
|
||||||
$time += $period_total;
|
$time += $period_total;
|
||||||
|
$paused += $period_paused;
|
||||||
}
|
}
|
||||||
$title = self::workingTimeTitle($events, $start);
|
$title = self::workingTimeTitle($events, $start);
|
||||||
$bo->init($period_ts);
|
$bo->init($period_ts);
|
||||||
@ -240,6 +241,7 @@ class Events extends Api\Storage\Base
|
|||||||
'end_time' => '',
|
'end_time' => '',
|
||||||
'ts_duration' => $minutes = round($time / 60),
|
'ts_duration' => $minutes = round($time / 60),
|
||||||
'ts_quantity' => $minutes / 60.0,
|
'ts_quantity' => $minutes / 60.0,
|
||||||
|
'ts_paused' => round($paused / 60),
|
||||||
'ts_owner' => $this->user,
|
'ts_owner' => $this->user,
|
||||||
]);
|
]);
|
||||||
self::addToTimesheet($bo->data['ts_id'], $ids);
|
self::addToTimesheet($bo->data['ts_id'], $ids);
|
||||||
@ -351,6 +353,15 @@ class Events extends Api\Storage\Base
|
|||||||
*/
|
*/
|
||||||
protected static function evaluate(array &$timer, array $row)
|
protected static function evaluate(array &$timer, array $row)
|
||||||
{
|
{
|
||||||
|
// paused timer is started or stopped
|
||||||
|
if ($timer['paused'] && !($row['tse_type'] & self::PAUSE))
|
||||||
|
{
|
||||||
|
$timer['was_paused'] = 60000 * round(($row['tse_time']->getTimestamp() - $timer['pause_started']->getTimestamp())/60);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($timer['was_paused']);
|
||||||
|
}
|
||||||
if ($row['tse_type'] & self::START)
|
if ($row['tse_type'] & self::START)
|
||||||
{
|
{
|
||||||
$timer['start'] = $timer['started'] = $row['tse_time'];
|
$timer['start'] = $timer['started'] = $row['tse_time'];
|
||||||
@ -367,6 +378,10 @@ class Events extends Api\Storage\Base
|
|||||||
{
|
{
|
||||||
$timer['paused'] = ($row['tse_type'] & self::PAUSE) === self::PAUSE;
|
$timer['paused'] = ($row['tse_type'] & self::PAUSE) === self::PAUSE;
|
||||||
}
|
}
|
||||||
|
if ($timer['paused'])
|
||||||
|
{
|
||||||
|
$timer['pause_started'] = $row['tse_time'];
|
||||||
|
}
|
||||||
$timer['last'] = $row['tse_time'];
|
$timer['last'] = $row['tse_time'];
|
||||||
$timer['id'] = $row['tse_id'];
|
$timer['id'] = $row['tse_id'];
|
||||||
return $time ?? null;
|
return $time ?? null;
|
||||||
@ -378,10 +393,11 @@ class Events extends Api\Storage\Base
|
|||||||
* Not stopped events-sequences are NOT returned (stopped sequences end with a stop event).
|
* Not stopped events-sequences are NOT returned (stopped sequences end with a stop event).
|
||||||
*
|
*
|
||||||
* @param int|array $filter
|
* @param int|array $filter
|
||||||
* @param int &$total=null on return time in seconds
|
* @param ?int &$total=null on return time in seconds
|
||||||
|
* @param ?int &$paused on return paused time in seconds
|
||||||
* @return array[] tse_id => array pairs plus extra key sum (time-sum in seconds)
|
* @return array[] tse_id => array pairs plus extra key sum (time-sum in seconds)
|
||||||
*/
|
*/
|
||||||
public static function get($filter, int &$total=null)
|
public static function get($filter, ?int &$total=null, ?int &$paused=null)
|
||||||
{
|
{
|
||||||
if (!is_array($filter))
|
if (!is_array($filter))
|
||||||
{
|
{
|
||||||
@ -392,7 +408,7 @@ class Events extends Api\Storage\Base
|
|||||||
'offset' => 0,
|
'offset' => 0,
|
||||||
'paused' => false,
|
'paused' => false,
|
||||||
];
|
];
|
||||||
$total = $open = 0;
|
$total = $open = $paused = 0;
|
||||||
$events = [];
|
$events = [];
|
||||||
foreach(self::getInstance()->search('', false, 'tse_id', '', '',
|
foreach(self::getInstance()->search('', false, 'tse_id', '', '',
|
||||||
false, 'AND', false, $filter) as $row)
|
false, 'AND', false, $filter) as $row)
|
||||||
@ -411,6 +427,7 @@ class Events extends Api\Storage\Base
|
|||||||
$row['total'] = $total + $timer['offset'] / 1000;
|
$row['total'] = $total + $timer['offset'] / 1000;
|
||||||
}
|
}
|
||||||
$row['time'] = $time / 1000;
|
$row['time'] = $time / 1000;
|
||||||
|
$row['paused'] = !empty($timer['was_paused']) ? $paused += $timer['was_paused']/1000 : null;
|
||||||
$events[$row['tse_id']] = $row;
|
$events[$row['tse_id']] = $row;
|
||||||
}
|
}
|
||||||
// remove open / unstopped timer events
|
// remove open / unstopped timer events
|
||||||
@ -427,16 +444,17 @@ class Events extends Api\Storage\Base
|
|||||||
* Not stopped events-sequences are NOT returned (stopped sequences end with a stop event).
|
* Not stopped events-sequences are NOT returned (stopped sequences end with a stop event).
|
||||||
*
|
*
|
||||||
* @param bool $overall
|
* @param bool $overall
|
||||||
* @param int &$time=null on return total time in seconds
|
* @param ?int &$time=null on return total time in seconds
|
||||||
|
* @param ?int &$paused=null on return total paused time in seconds
|
||||||
* @return array[] tse_id => array pairs
|
* @return array[] tse_id => array pairs
|
||||||
*/
|
*/
|
||||||
public static function getPending($overall=false, int &$time=null)
|
public static function getPending($overall=false, ?int &$time=null, ?int &$paused=null)
|
||||||
{
|
{
|
||||||
return self::get([
|
return self::get([
|
||||||
'ts_id' => null,
|
'ts_id' => null,
|
||||||
'account_id' => self::getInstance()->user,
|
'account_id' => self::getInstance()->user,
|
||||||
($overall ? '' : 'NOT ').'(tse_type & '.self::OVERALL.')',
|
($overall ? '' : 'NOT ').'(tse_type & '.self::OVERALL.')',
|
||||||
], $time);
|
], $time, $paused);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,6 +52,7 @@ class JsTimesheet extends Api\CalDAV\JsBase
|
|||||||
'description' => $timesheet['description'],
|
'description' => $timesheet['description'],
|
||||||
'start' => self::UTCDateTime($timesheet['start'], true),
|
'start' => self::UTCDateTime($timesheet['start'], true),
|
||||||
'duration' => (int)$timesheet['duration'],
|
'duration' => (int)$timesheet['duration'],
|
||||||
|
'paused' => (int)$timesheet['paused'],
|
||||||
'project' => $timesheet['project_blur'] ?? null,
|
'project' => $timesheet['project_blur'] ?? null,
|
||||||
'pm_id' => !empty($timesheet['pm_id']) ? (int)$timesheet['pm_id'] : null,
|
'pm_id' => !empty($timesheet['pm_id']) ? (int)$timesheet['pm_id'] : null,
|
||||||
'quantity' => (double)$timesheet['quantity'],
|
'quantity' => (double)$timesheet['quantity'],
|
||||||
@ -132,6 +133,10 @@ class JsTimesheet extends Api\CalDAV\JsBase
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'paused':
|
||||||
|
$timesheet['ts_paused'] = self::parseInt($value);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'pricelist':
|
case 'pricelist':
|
||||||
$timesheet['pl_id'] = self::parseInt($value);
|
$timesheet['pl_id'] = self::parseInt($value);
|
||||||
break;
|
break;
|
||||||
|
@ -38,14 +38,12 @@
|
|||||||
<row class="row" disabled="!@ts_viewtype">
|
<row class="row" disabled="!@ts_viewtype">
|
||||||
<et2-description value="comment"></et2-description>
|
<et2-description value="comment"></et2-description>
|
||||||
<et2-textarea id="ts_description_short" rows="5" cols="50"></et2-textarea>
|
<et2-textarea id="ts_description_short" rows="5" cols="50"></et2-textarea>
|
||||||
<et2-description></et2-description>
|
|
||||||
<et2-description></et2-description>
|
|
||||||
<et2-description></et2-description>
|
|
||||||
</row>
|
</row>
|
||||||
<row class="row" disabled="@ts_viewtype">
|
<row class="row" disabled="@ts_viewtype">
|
||||||
<et2-description value="Quantity" for="ts_quantity"></et2-description>
|
<et2-description value="Quantity" for="ts_quantity"></et2-description>
|
||||||
<et2-number statustext="empty if identical to duration" id="ts_quantity" precision="3" placeholder="@ts_quantity_blur"></et2-number>
|
<et2-number statustext="empty if identical to duration" id="ts_quantity" precision="3" placeholder="@ts_quantity_blur"></et2-number>
|
||||||
<et2-description></et2-description>
|
<et2-description></et2-description>
|
||||||
|
<et2-date-duration label="Pause time" id="ts_paused" displayFormat="hm" span="all"></et2-date-duration>
|
||||||
</row>
|
</row>
|
||||||
<row class="row" disabled="@ts_viewtype">
|
<row class="row" disabled="@ts_viewtype">
|
||||||
<et2-description value="Category" for="cat_id"></et2-description>
|
<et2-description value="Category" for="cat_id"></et2-description>
|
||||||
@ -86,6 +84,7 @@
|
|||||||
<column/>
|
<column/>
|
||||||
<column/>
|
<column/>
|
||||||
<column/>
|
<column/>
|
||||||
|
<column/>
|
||||||
</columns>
|
</columns>
|
||||||
<rows>
|
<rows>
|
||||||
<row class="th">
|
<row class="th">
|
||||||
@ -93,6 +92,7 @@
|
|||||||
<et2-description value="Recorded"></et2-description>
|
<et2-description value="Recorded"></et2-description>
|
||||||
<et2-description value="Type"></et2-description>
|
<et2-description value="Type"></et2-description>
|
||||||
<et2-description value="Duration"></et2-description>
|
<et2-description value="Duration"></et2-description>
|
||||||
|
<et2-description value="Paused"></et2-description>
|
||||||
<et2-description value="Sum"></et2-description>
|
<et2-description value="Sum"></et2-description>
|
||||||
</row>
|
</row>
|
||||||
<row id="timesheet-events::$row_cont[tse_id]">
|
<row id="timesheet-events::$row_cont[tse_id]">
|
||||||
@ -100,6 +100,7 @@
|
|||||||
<et2-date-time id="${row}[tse_timestamp]" readonly="true"></et2-date-time>
|
<et2-date-time id="${row}[tse_timestamp]" readonly="true"></et2-date-time>
|
||||||
<et2-select id="${row}[tse_type]" readonly="true"></et2-select>
|
<et2-select id="${row}[tse_type]" readonly="true"></et2-select>
|
||||||
<et2-date-duration id="${row}[time]" readonly="true" displayFormat="h:m" dataFormat="s"></et2-date-duration>
|
<et2-date-duration id="${row}[time]" readonly="true" displayFormat="h:m" dataFormat="s"></et2-date-duration>
|
||||||
|
<et2-date-duration id="${row}[paused]" readonly="true" displayFormat="h:m" dataFormat="s"></et2-date-duration>
|
||||||
<et2-date-duration id="${row}[total]" readonly="true" displayFormat="h:m" dataFormat="s"></et2-date-duration>
|
<et2-date-duration id="${row}[total]" readonly="true" displayFormat="h:m" dataFormat="s"></et2-date-duration>
|
||||||
</row>
|
</row>
|
||||||
</rows>
|
</rows>
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
<column width="70%"/>
|
<column width="70%"/>
|
||||||
<column width="15%"/>
|
<column width="15%"/>
|
||||||
<column width="60"/>
|
<column width="60"/>
|
||||||
|
<column width="60"/>
|
||||||
<column width="60" disabled="@no_ts_quantity"/>
|
<column width="60" disabled="@no_ts_quantity"/>
|
||||||
<column width="60" disabled="@no_ts_unitprice"/>
|
<column width="60" disabled="@no_ts_unitprice"/>
|
||||||
<column width="60" disabled="@no_ts_total"/>
|
<column width="60" disabled="@no_ts_total"/>
|
||||||
@ -54,16 +55,20 @@
|
|||||||
<nextmatch-sortheader label="Category" id="cat_id"/>
|
<nextmatch-sortheader label="Category" id="cat_id"/>
|
||||||
<et2-vbox>
|
<et2-vbox>
|
||||||
<nextmatch-sortheader label="Duration" id="ts_duration"/>
|
<nextmatch-sortheader label="Duration" id="ts_duration"/>
|
||||||
<et2-date-duration id="duration" readonly="true" displayFormat="hm"></et2-date-duration>
|
<et2-date-duration id="duration" readonly="true" displayFormat="hm" align="right"></et2-date-duration>
|
||||||
|
</et2-vbox>
|
||||||
|
<et2-vbox>
|
||||||
|
<nextmatch-sortheader label="Paused" id="ts_paused"/>
|
||||||
|
<et2-date-duration id="paused" readonly="true" displayFormat="hm" align="right"></et2-date-duration>
|
||||||
</et2-vbox>
|
</et2-vbox>
|
||||||
<et2-vbox>
|
<et2-vbox>
|
||||||
<nextmatch-sortheader label="Quantity" id="ts_quantity"/>
|
<nextmatch-sortheader label="Quantity" id="ts_quantity"/>
|
||||||
<et2-number id="quantity" readonly="true" precision="3"></et2-number>
|
<et2-number id="quantity" readonly="true" precision="3" align="right"></et2-number>
|
||||||
</et2-vbox>
|
</et2-vbox>
|
||||||
<nextmatch-sortheader label="Price" id="ts_unitprice"/>
|
<nextmatch-sortheader label="Price" id="ts_unitprice"/>
|
||||||
<et2-vbox>
|
<et2-vbox>
|
||||||
<nextmatch-sortheader label="Total" id="ts_total"/>
|
<nextmatch-sortheader label="Total" id="ts_total"/>
|
||||||
<et2-number id="price" readonly="true" precision="2"></et2-number>
|
<et2-number id="price" readonly="true" precision="2" align="right"></et2-number>
|
||||||
</et2-vbox>
|
</et2-vbox>
|
||||||
<et2-nextmatch-header-filter id="ts_owner" class="$cont[ownerClass]" noLang="1" emptyLabel="User"/>
|
<et2-nextmatch-header-filter id="ts_owner" class="$cont[ownerClass]" noLang="1" emptyLabel="User"/>
|
||||||
<nextmatch-sortheader label="Created" id="ts_created"/>
|
<nextmatch-sortheader label="Created" id="ts_created"/>
|
||||||
@ -80,8 +85,8 @@
|
|||||||
<et2-description id="${row}[ts_description]" class="ts_description" noLang="1"></et2-description>
|
<et2-description id="${row}[ts_description]" class="ts_description" noLang="1"></et2-description>
|
||||||
</et2-vbox>
|
</et2-vbox>
|
||||||
<et2-select-cat class="noWrap" id="${row}[cat_id]" readonly="true"></et2-select-cat>
|
<et2-select-cat class="noWrap" id="${row}[cat_id]" readonly="true"></et2-select-cat>
|
||||||
<et2-date-duration id="${row}[ts_duration]" readonly="true" align="right" displayFormat="hm"
|
<et2-date-duration id="${row}[ts_duration]" readonly="true" align="right" displayFormat="hm" selectUnit="false"></et2-date-duration>
|
||||||
selectUnit="false"></et2-date-duration>
|
<et2-date-duration id="${row}[ts_paused]" readonly="true" align="right" displayFormat="hm" selectUnit="false"></et2-date-duration>
|
||||||
<et2-number id="${row}[ts_quantity]" readonly="true" precision="3" noLang="1"></et2-number>
|
<et2-number id="${row}[ts_quantity]" readonly="true" precision="3" noLang="1"></et2-number>
|
||||||
<et2-description id="${row}[ts_unitprice]" noLang="1"></et2-description>
|
<et2-description id="${row}[ts_unitprice]" noLang="1"></et2-description>
|
||||||
<et2-number id="${row}[ts_total]" readonly="true" precision="2" noLang="1"></et2-number>
|
<et2-number id="${row}[ts_total]" readonly="true" precision="2" noLang="1"></et2-number>
|
||||||
|
Loading…
Reference in New Issue
Block a user