diff --git a/timesheet/inc/class.timesheet_bo.inc.php b/timesheet/inc/class.timesheet_bo.inc.php
index 59f1f67fc2..deea0a4644 100644
--- a/timesheet/inc/class.timesheet_bo.inc.php
+++ b/timesheet/inc/class.timesheet_bo.inc.php
@@ -137,6 +137,7 @@ class timesheet_bo extends Api\Storage
'ts_description' => 'Description',
'ts_start' => 'Start',
'ts_duration' => 'Duration',
+ 'ts_paused' => 'Paused',
'ts_quantity' => 'Quantity',
'ts_unitprice' => 'Unitprice',
'ts_owner' => 'Owner',
@@ -506,7 +507,7 @@ class timesheet_bo extends Api\Storage
//_debug_array($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();
}
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
// joining of the cutomfield table is triggered by criteria being set with either a string or an array
$cols = ['SUM(ts_duration) AS duration',
+ 'SUM(COALESCE(ts_paused,0)) AS paused',
"SUM($total_sql) AS price",
'MAX(ts_modified) AS max_modified'];
if($this->quantity_sum)
@@ -569,7 +571,7 @@ class timesheet_bo extends Api\Storage
parent::search($criteria,array(
(string)$sum_ts_id[$type],"''","''","''",'MIN(ts_start)','SUM(ts_duration) AS ts_duration',
($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);
$sum_extra_cols[$type][0] = '0';
}
@@ -792,7 +794,7 @@ class timesheet_bo extends Api\Storage
{
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 = [];
if($ignore_acl)
diff --git a/timesheet/inc/class.timesheet_merge.inc.php b/timesheet/inc/class.timesheet_merge.inc.php
index 6f4c8c9f1d..69c8a5b6e3 100644
--- a/timesheet/inc/class.timesheet_merge.inc.php
+++ b/timesheet/inc/class.timesheet_merge.inc.php
@@ -37,6 +37,7 @@ class timesheet_merge extends Api\Storage\Merge
*/
protected $numeric_fields = array(
'$$ts_duration$$',
+ '$$ts_paused$$',
'$$ts_quantity$$',
'$$ts_unitprice$$'
);
@@ -132,7 +133,7 @@ class timesheet_merge extends Api\Storage\Merge
$array = $record->get_record_array();
$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);
}
@@ -204,4 +205,4 @@ class timesheet_merge extends Api\Storage\Merge
}
return $placeholders;
}
-}
+}
\ No newline at end of file
diff --git a/timesheet/inc/class.timesheet_ui.inc.php b/timesheet/inc/class.timesheet_ui.inc.php
index 2ece32adf6..ee7a06114a 100644
--- a/timesheet/inc/class.timesheet_ui.inc.php
+++ b/timesheet/inc/class.timesheet_ui.inc.php
@@ -99,7 +99,7 @@ class timesheet_ui extends timesheet_bo
// are we supposed to add pending events, to a new or an existing timesheet
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));
$start = $this->data['events'][0]['tse_time'];
$this->data['ts_start'] = $start;
@@ -107,6 +107,7 @@ class timesheet_ui extends timesheet_bo
$this->data['end_time'] = '';
$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_paused'] = $paused ? round($paused / 60.0) : null;
// check if any of the events contains an app::id to link the timesheet to
foreach($pending as $event)
{
diff --git a/timesheet/lang/egw_de.lang b/timesheet/lang/egw_de.lang
index 24ed546aac..4bae7ce516 100644
--- a/timesheet/lang/egw_de.lang
+++ b/timesheet/lang/egw_de.lang
@@ -108,6 +108,8 @@ overwrite time common de Zeit überschreiben
overwriting start or stop time timesheet de Überschreiben der Start- oder Stop-Zeit
parent admin de Übergeordnet
pause common de Pause
+pause time timesheet de Pausenzeit
+paused timesheet de Pausen
permission denied!!! timesheet de Zugriff verweigert!
permissions error - %1 could not %2 timesheet de Fehler in den Zugriffsberechtigungen - %1 nicht möglich %2
prevent deleting admin de Verhindert Löschung
diff --git a/timesheet/lang/egw_en.lang b/timesheet/lang/egw_en.lang
index 9183a8de92..b1624f054d 100644
--- a/timesheet/lang/egw_en.lang
+++ b/timesheet/lang/egw_en.lang
@@ -108,6 +108,8 @@ overwrite time common en Overwrite time
overwriting start or stop time timesheet en Overwriting start or stop time
parent admin en Parent
pause common en Pause
+pause time timesheet en Pause time
+paused timesheet en Paused
permission denied!!! timesheet en Permission denied!
permissions error - %1 could not %2 timesheet en Permissions error - %1 could not %2
prevent deleting admin en Prevent deleting
diff --git a/timesheet/setup/setup.inc.php b/timesheet/setup/setup.inc.php
index 2dde50bca4..fe84a80c84 100644
--- a/timesheet/setup/setup.inc.php
+++ b/timesheet/setup/setup.inc.php
@@ -16,7 +16,7 @@ if (!defined('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]['tables'] = array('egw_timesheet','egw_timesheet_extra','egw_timesheet_events');
$setup_info[TIMESHEET_APP]['enable'] = 1;
@@ -52,4 +52,4 @@ $setup_info[TIMESHEET_APP]['hooks']['config_validate'] = 'EGroupware\\Timesheet\
$setup_info[TIMESHEET_APP]['depends'][] = array(
'appname' => 'api',
'versions' => Array('23.1')
-);
\ No newline at end of file
+);
diff --git a/timesheet/setup/tables_current.inc.php b/timesheet/setup/tables_current.inc.php
index 1e588df2e9..5b33203b6f 100644
--- a/timesheet/setup/tables_current.inc.php
+++ b/timesheet/setup/tables_current.inc.php
@@ -19,7 +19,7 @@ $phpgw_baseline = array(
'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_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_unitprice' => array('type' => 'float','precision' => '4','comment' => 'unitprice'),
'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'),
'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_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'),
'fk' => array(),
@@ -64,4 +65,4 @@ $phpgw_baseline = array(
'ix' => array('ts_id'),
'uc' => array('tse_id')
)
-);
+);
\ No newline at end of file
diff --git a/timesheet/setup/tables_update.inc.php b/timesheet/setup/tables_update.inc.php
index f353b11b90..5dfc263c9f 100644
--- a/timesheet/setup/tables_update.inc.php
+++ b/timesheet/setup/tables_update.inc.php
@@ -233,4 +233,15 @@ function timesheet_upgrade21_1()
function timesheet_upgrade22_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';
}
\ No newline at end of file
diff --git a/timesheet/src/Events.php b/timesheet/src/Events.php
index a5ff8bee19..184121e4cd 100644
--- a/timesheet/src/Events.php
+++ b/timesheet/src/Events.php
@@ -218,17 +218,18 @@ class Events extends Api\Storage\Base
*/
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!");
}
$ids = array_keys($events);
$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'])))
{
- $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;
+ $paused += $period_paused;
}
$title = self::workingTimeTitle($events, $start);
$bo->init($period_ts);
@@ -240,6 +241,7 @@ class Events extends Api\Storage\Base
'end_time' => '',
'ts_duration' => $minutes = round($time / 60),
'ts_quantity' => $minutes / 60.0,
+ 'ts_paused' => round($paused / 60),
'ts_owner' => $this->user,
]);
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)
{
+ // 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)
{
$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;
}
+ if ($timer['paused'])
+ {
+ $timer['pause_started'] = $row['tse_time'];
+ }
$timer['last'] = $row['tse_time'];
$timer['id'] = $row['tse_id'];
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).
*
* @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)
*/
- public static function get($filter, int &$total=null)
+ public static function get($filter, ?int &$total=null, ?int &$paused=null)
{
if (!is_array($filter))
{
@@ -392,7 +408,7 @@ class Events extends Api\Storage\Base
'offset' => 0,
'paused' => false,
];
- $total = $open = 0;
+ $total = $open = $paused = 0;
$events = [];
foreach(self::getInstance()->search('', false, 'tse_id', '', '',
false, 'AND', false, $filter) as $row)
@@ -411,6 +427,7 @@ class Events extends Api\Storage\Base
$row['total'] = $total + $timer['offset'] / 1000;
}
$row['time'] = $time / 1000;
+ $row['paused'] = !empty($timer['was_paused']) ? $paused += $timer['was_paused']/1000 : null;
$events[$row['tse_id']] = $row;
}
// 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).
*
* @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
*/
- public static function getPending($overall=false, int &$time=null)
+ public static function getPending($overall=false, ?int &$time=null, ?int &$paused=null)
{
return self::get([
'ts_id' => null,
'account_id' => self::getInstance()->user,
($overall ? '' : 'NOT ').'(tse_type & '.self::OVERALL.')',
- ], $time);
+ ], $time, $paused);
}
/**
diff --git a/timesheet/src/JsTimesheet.php b/timesheet/src/JsTimesheet.php
index 9454b2a669..0a78f611ef 100644
--- a/timesheet/src/JsTimesheet.php
+++ b/timesheet/src/JsTimesheet.php
@@ -52,6 +52,7 @@ class JsTimesheet extends Api\CalDAV\JsBase
'description' => $timesheet['description'],
'start' => self::UTCDateTime($timesheet['start'], true),
'duration' => (int)$timesheet['duration'],
+ 'paused' => (int)$timesheet['paused'],
'project' => $timesheet['project_blur'] ?? null,
'pm_id' => !empty($timesheet['pm_id']) ? (int)$timesheet['pm_id'] : null,
'quantity' => (double)$timesheet['quantity'],
@@ -132,6 +133,10 @@ class JsTimesheet extends Api\CalDAV\JsBase
}
break;
+ case 'paused':
+ $timesheet['ts_paused'] = self::parseInt($value);
+ break;
+
case 'pricelist':
$timesheet['pl_id'] = self::parseInt($value);
break;
diff --git a/timesheet/templates/default/edit.xet b/timesheet/templates/default/edit.xet
index 0f872dde79..03a8cfb2e0 100644
--- a/timesheet/templates/default/edit.xet
+++ b/timesheet/templates/default/edit.xet
@@ -38,15 +38,13 @@
-
-
-
-
+
-
-
+
+
+
@@ -86,6 +84,7 @@
+
@@ -93,6 +92,7 @@
+
@@ -100,6 +100,7 @@
+
diff --git a/timesheet/templates/default/index.xet b/timesheet/templates/default/index.xet
index f4d6e31fc8..6f93fe71fa 100644
--- a/timesheet/templates/default/index.xet
+++ b/timesheet/templates/default/index.xet
@@ -19,6 +19,7 @@
+
@@ -54,16 +55,20 @@
-
+
+
+
+
+
-
+
-
+
@@ -80,8 +85,8 @@
-
+
+