Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Grouped entries #1312

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions extensions/ki_export/floaters.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
'download_pdf' => 1,
'customer_new_page' => 0,
'reverse_order' => 0,
'grouped_entries' => 0,
'pdf_format' => 'export_pdf',
'time_type' => 'dec_time'
];
Expand All @@ -45,6 +46,7 @@
case 'XLS':
$defaults = [
'reverse_order' => 0,
'grouped_entries' => 0,
];
$prefs = $database->user_get_preferences_by_prefix('ki_export.xls.');
$view->assign('prefs', array_merge($defaults, $prefs));
Expand All @@ -57,6 +59,7 @@
'column_delimiter' => ',',
'quote_char' => '"',
'reverse_order' => 0,
'grouped_entries' => 0,
];
$prefs = $database->user_get_preferences_by_prefix('ki_export.csv.');
$view->assign('prefs', array_merge($defaults, $prefs));
Expand All @@ -68,6 +71,7 @@
$defaults = [
'print_summary' => 1,
'reverse_order' => 0,
'grouped_entries' => 0,
];
$prefs = $database->user_get_preferences_by_prefix('ki_export.print.');
$view->assign('prefs', array_merge($defaults, $prefs));
Expand Down
14 changes: 11 additions & 3 deletions extensions/ki_export/private_func.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
* @param int $filter_type (-1 show time and expenses, 0: only show time entries, 1: only show expenses)
* @param bool $limitCommentSize should comments be cut off, when they are too long
* @param int $filter_refundable
* @param bool $groupedEntries
* @return array with time recordings and expenses chronologically sorted
*/
function export_get_data(
Expand All @@ -78,7 +79,8 @@ function export_get_data(
$filter_cleared = -1,
$filter_type = -1,
$limitCommentSize = true,
$filter_refundable = -1
$filter_refundable = -1,
$groupedEntries = false
) {
global $expense_ext_available;
$database = Kimai_Registry::getDatabase();
Expand All @@ -94,7 +96,11 @@ function export_get_data(
$activities,
$limit,
$reverse_order,
$filter_cleared
$filter_cleared,
0,
0,
false,
$groupedEntries
);
}

Expand Down Expand Up @@ -160,7 +166,9 @@ function export_get_data(
if ($timeSheetEntries[$timeSheetEntries_index]['end'] != 0) {
// active recordings will be omitted
$arr['type'] = 'timeSheet';
$arr['id'] = $timeSheetEntries[$timeSheetEntries_index]['timeEntryID'];
if (isset($timeSheetEntries[$timeSheetEntries_index]['timeEntryID'])) {
$arr['id'] = $timeSheetEntries[$timeSheetEntries_index]['timeEntryID'];
}
$arr['time_in'] = $timeSheetEntries[$timeSheetEntries_index]['start'];
$arr['time_out'] = $timeSheetEntries[$timeSheetEntries_index]['end'];
$arr['duration'] = $timeSheetEntries[$timeSheetEntries_index]['duration'];
Expand Down
30 changes: 21 additions & 9 deletions extensions/ki_export/processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
$default_location = strip_tags($_REQUEST['default_location']);

$reverse_order = isset($_REQUEST['reverse_order']);
$grouped_entries = isset($_REQUEST['grouped_entries']);

$filter_cleared = $_REQUEST['filter_cleared'];
$filter_refundable = $_REQUEST['filter_refundable'];
Expand Down Expand Up @@ -197,7 +198,8 @@
case 'export_html':
$database->user_set_preferences([
'print_summary' => isset($_REQUEST['print_summary']) ? 1 : 0,
'reverse_order' => isset($_REQUEST['reverse_order']) ? 1 : 0
'reverse_order' => isset($_REQUEST['reverse_order']) ? 1 : 0,
'grouped_entries' => isset($_REQUEST['grouped_entries']) ? 1 : 0
], 'ki_export.print.');

$exportData = export_get_data(
Expand All @@ -213,7 +215,8 @@
$filter_cleared,
$filter_type,
false,
$filter_refundable
$filter_refundable,
$grouped_entries
);
$timeSum = 0;
$wageSum = 0;
Expand Down Expand Up @@ -298,7 +301,8 @@
case 'export_xls':

$database->user_set_preferences([
'reverse_order' => isset($_REQUEST['reverse_order']) ? 1 : 0
'reverse_order' => isset($_REQUEST['reverse_order']) ? 1 : 0,
'grouped_entries' => isset($_REQUEST['grouped_entries']) ? 1 : 0
], 'ki_export.xls.');

$exportData = export_get_data(
Expand All @@ -314,7 +318,8 @@
$filter_cleared,
$filter_type,
false,
$filter_refundable
$filter_refundable,
$grouped_entries
);
$view->assign('exportData', count($exportData) > 0 ? $exportData : 0);

Expand All @@ -332,7 +337,8 @@
$database->user_set_preferences([
'column_delimiter' => $_REQUEST['column_delimiter'],
'quote_char' => $_REQUEST['quote_char'],
'reverse_order' => isset($_REQUEST['reverse_order']) ? 1 : 0
'reverse_order' => isset($_REQUEST['reverse_order']) ? 1 : 0,
'grouped_entries' => isset($_REQUEST['grouped_entries']) ? 1 : 0
], 'ki_export.csv.');

$exportData = export_get_data(
Expand All @@ -348,13 +354,15 @@
$filter_cleared,
$filter_type,
false,
$filter_refundable
$filter_refundable,
$grouped_entries
);
$column_delimiter = $_REQUEST['column_delimiter'];
$quote_char = $_REQUEST['quote_char'];

header('Content-Encoding: UTF-8');
header('Content-Disposition:attachment;filename=export.csv');
header('Content-Type: text/csv');
header('Content-Type: text/csv; charset=UTF-8');

$row = [];

Expand Down Expand Up @@ -503,6 +511,7 @@
'download_pdf' => isset($_REQUEST['download_pdf']) ? 1 : 0,
'customer_new_page' => isset($_REQUEST['customer_new_page']) ? 1 : 0,
'reverse_order' => isset($_REQUEST['reverse_order']) ? 1 : 0,
'grouped_entries' => isset($_REQUEST['grouped_entries']) ? 1 : 0,
'time_type' => 'dec_time',
'pdf_format' => 'export_pdf'
], 'ki_export.pdf.');
Expand All @@ -520,7 +529,8 @@
$filter_cleared,
$filter_type,
false,
$filter_refundable
$filter_refundable,
$grouped_entries
);

$orderedExportData = [];
Expand Down Expand Up @@ -556,6 +566,7 @@
'download_pdf' => isset($_REQUEST['download_pdf']) ? 1 : 0,
'customer_new_page' => isset($_REQUEST['customer_new_page']) ? 1 : 0,
'reverse_order' => isset($_REQUEST['reverse_order']) ? 1 : 0,
'grouped_entries' => isset($_REQUEST['grouped_entries']) ? 1 : 0,
'pdf_format' => 'export_pdf2'
], 'ki_export.pdf.');

Expand All @@ -572,7 +583,8 @@
$filter_cleared,
$filter_type,
false,
$filter_refundable
$filter_refundable,
$grouped_entries
);

// sort data into new array, where first dimension is customer and second dimension is project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@
</li>
<li>
<label for="reverse_order"><?php echo $this->translate('export_extension:reverse_order') ?>:</label>
<input type="checkbox" value="true" name="reverse_order" id="reverse_order"/>
<input type="checkbox" value="true" name="reverse_order" id="reverse_order" <?php if ($this->prefs['reverse_order']): ?> checked="checked" <?php endif; ?>/>
</li>
<li>
<label for="grouped_entries"><?php echo $this->translate('export_extension:grouped_entries') ?>:</label>
<input type="checkbox" value="true" name="grouped_entries" id="grouped_entries" <?php if ($this->prefs['grouped_entries']): ?> checked="checked" <?php endif; ?>/>
</li>
<li>
<?php echo $this->translate('export_extension:dl_hint') ?>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<label for="reverse_order"><?php echo $this->translate('export_extension:reverse_order') ?>:</label>
<input type="checkbox" value="true" name="reverse_order" id="reverse_order" <?php if ($this->prefs['reverse_order']): ?> checked="checked" <?php endif; ?>/>
</li>
<li>
<label for="grouped_entries"><?php echo $this->translate('export_extension:grouped_entries') ?>:</label>
<input type="checkbox" value="true" name="grouped_entries" id="grouped_entries" <?php if ($this->prefs['grouped_entries']): ?> checked="checked" <?php endif; ?>/>
</li>
<li>
<label for="time_type"><?php echo $this->translate('export_extension:time_type')?>:</label>
<select name="time_type" id="time_type">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
<label for="reverse_order"><?php echo $this->translate('export_extension:reverse_order') ?>:</label>
<input type="checkbox" value="true" name="reverse_order" id="reverse_order" <?php if ($this->prefs['reverse_order']): ?> checked="checked" <?php endif; ?>/>
</li>
<li>
<label for="grouped_entries"><?php echo $this->translate('export_extension:grouped_entries') ?>:</label>
<input type="checkbox" value="true" name="grouped_entries" id="grouped_entries" <?php if ($this->prefs['grouped_entries']): ?> checked="checked" <?php endif; ?>/>
</li>
<li>
<?php echo $this->translate('export_extension:dl_hint') ?>
</li>
Expand Down
4 changes: 4 additions & 0 deletions extensions/ki_export/templates/scripts/floaters/print.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
<label for="reverse_order"><?php echo $this->translate('export_extension:reverse_order') ?>:</label>
<input type="checkbox" value="true" name="reverse_order" id="reverse_order" <?php if ($this->prefs['reverse_order']): ?> checked="checked" <?php endif; ?>/>
</li>
<li>
<label for="grouped_entries"><?php echo $this->translate('export_extension:grouped_entries') ?>:</label>
<input type="checkbox" value="true" name="grouped_entries" id="grouped_entries" <?php if ($this->prefs['grouped_entries']): ?> checked="checked" <?php endif; ?>/>
</li>
</ul>
<div id="formbuttons">
<button type="button" class="btn_norm" onclick="floaterClose();"><?php echo $this->translate('cancel') ?></button>
Expand Down
1 change: 1 addition & 0 deletions language/de.php
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@
'times' => 'Zeiten',
'expenses' => 'Auslagen',
'reverse_order' => 'Ältere Einträge zuerst',
'grouped_entries' => 'Gruppierte Einträge',
'time_period' => 'Zeitraum',
'duration_unit' => 'Std.',
'cleared' => 'Abgerechnet',
Expand Down
1 change: 1 addition & 0 deletions language/en.php
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@
'times' => 'times',
'expenses' => 'expenses',
'reverse_order' => 'Older entries first',
'grouped_entries' => 'Grouped entries',
'time_period' => 'Time period',
'duration_unit' => 'h',
'time_type' => 'Time format',
Expand Down
78 changes: 59 additions & 19 deletions libraries/Kimai/Database/Mysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -2675,6 +2675,7 @@ public function timeSheet_whereClausesFromFilters($users, $customers, $projects,
* @param int $startRows
* @param int $limitRows
* @param bool $countOnly
* @param bool $groupedEntries
* @return array
*/
public function get_timeSheet(
Expand All @@ -2689,7 +2690,8 @@ public function get_timeSheet(
$filterCleared = null,
$startRows = 0,
$limitRows = 0,
$countOnly = false
$countOnly = false,
$groupedEntries = false
) {
// -1 for disabled, 0 for only not cleared entries
if (!is_numeric($filterCleared)) {
Expand Down Expand Up @@ -2735,27 +2737,62 @@ public function get_timeSheet(
$limit = '';
}

$select = 'SELECT timeSheet.*,
status.status,
customer.name AS customerName, customer.customerID as customerID,
activity.name AS activityName,
project.name AS projectName, project.comment AS projectComment,
user.name AS userName, user.alias AS userAlias ';

if ($countOnly) {
$select = 'SELECT COUNT(*) AS total';
$limit = '';
}
if ($groupedEntries) {
$query = "SELECT
DATE_FORMAT(FROM_UNIXTIME(`start`), '%Y-%m-%d') AS `aggrDate`,
MIN(`start`) AS `start`,
MAX(`end`) AS `end`,
SUM(`duration`) AS `duration`,
GROUP_CONCAT(DISTINCT `userID`) AS `userID`,
`projectID`,
`activityID`,
GROUP_CONCAT(`description` SEPARATOR '\\n') AS `description`,
GROUP_CONCAT(`timeSheet`.`comment` SEPARATOR ', ') AS `comment`,
`commentType`,
`cleared`,
GROUP_CONCAT(`location` SEPARATOR ', ') AS `location`,
GROUP_CONCAT(`trackingNumber` SEPARATOR ', ') AS `trackingNumber`,
`rate`,
`fixedRate`,
`timeSheet`.`budget`,
MIN(`timeSheet`.`approved`) as `approved`,
`statusID`,
MIN(`billable`) as `billable`,
`customer`.`name` AS `customerName`, `customer`.`customerID` as `customerID`,
`activity`.`name` AS `activityName`,
`project`.`name` AS `projectName`, `project`.`comment` AS `projectComment`,
`user`.`name` AS `userName`, `user`.`alias` AS `userAlias`
FROM `${p}timeSheet` AS `timeSheet`
JOIN `${p}projects` AS `project` USING (`projectID`)
JOIN `${p}customers` AS `customer` USING (`customerID`)
JOIN `${p}activities` AS `activity` USING (`activityID`)
JOIN `${p}users` AS `user` USING (`userID`) "
. (count($whereClauses) > 0 ? ' WHERE ' : ' ') . implode(' AND ', $whereClauses) .
' GROUP BY `aggrDate`, `projectID`, `activityID`, `rate`, `fixedRate`' .
' ORDER BY `start` ' . ($reverse_order ? 'ASC ' : 'DESC ') . $limit . ';';
} else {
$select = 'SELECT timeSheet.*,
status.status,
customer.name AS customerName, customer.customerID as customerID,
activity.name AS activityName,
project.name AS projectName, project.comment AS projectComment,
user.name AS userName, user.alias AS userAlias ';

if ($countOnly) {
$select = 'SELECT COUNT(*) AS total';
$limit = '';
}

$query = "$select
$query = "$select
FROM ${p}timeSheet AS timeSheet
JOIN ${p}projects AS project USING (projectID)
JOIN ${p}customers AS customer USING (customerID)
JOIN ${p}users AS user USING(userID)
JOIN ${p}statuses AS status USING(statusID)
JOIN ${p}activities AS activity USING(activityID) "
. (count($whereClauses) > 0 ? ' WHERE ' : ' ') . implode(' AND ', $whereClauses) .
' ORDER BY start ' . ($reverse_order ? 'ASC ' : 'DESC ') . $limit . ';';
JOIN ${p}users AS user USING (userID)
JOIN ${p}statuses AS status USING (statusID)
JOIN ${p}activities AS activity USING (activityID) "
. (count($whereClauses) > 0 ? ' WHERE ' : ' ') . implode(' AND ', $whereClauses) .
' ORDER BY start ' . ($reverse_order ? 'ASC ' : 'DESC ') . $limit . ';';
}

$result = $this->conn->Query($query);

Expand All @@ -2775,7 +2812,10 @@ public function get_timeSheet(
$this->conn->MoveFirst();
while (!$this->conn->EndOfSeek()) {
$row = $this->conn->Row();
$arr[$i]['timeEntryID'] = $row->timeEntryID;

if (!$groupedEntries) {
$arr[$i]['timeEntryID'] = $row->timeEntryID;
}

// Start time should not be less than the selected start time. This would confuse the user.
if ($start && $row->start <= $start) {
Expand Down