Skip to content

Commit 7df94dd

Browse files
committed
Initial implementation of a simple week view.
1 parent bdbadef commit 7df94dd

6 files changed

Lines changed: 168 additions & 157 deletions

File tree

WEB-INF/lib/ttTimeHelper.class.php

Lines changed: 96 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -766,31 +766,57 @@ static function getGroupedRecordsForInterval($user_id, $start_date, $end_date) {
766766
return $groupedRecords;
767767
}
768768

769-
/* This is work in progress, not working properly.
770-
static function getDurationsForWeek($user_id, $start_date, $end_date) {
769+
// getDataForWeekView - builds an array to render a table of durations for week view.
770+
static function getDataForWeekView($user_id, $start_date, $end_date) {
771771
// Start by obtaining all records in interval.
772-
// Then, iterate through them to build an array.
773772
$records = ttTimeHelper::getRecordsForInterval($user_id, $start_date, $end_date);
774-
$durations_with_labels = array();
775773

774+
$dataArray = array();
775+
776+
// Iterate through records and build $dataArray cell by cell.
776777
foreach ($records as $record) {
778+
// Create record id without suffix.
777779
$record_id_no_suffix = ttTimeHelper::makeRecordIdentifier($record);
778780
// Handle potential multiple records with the same attributes by using a numerical suffix.
779781
$suffix = 0;
780782
$record_id = $record_id_no_suffix.'_'.$suffix;
781-
while (!empty($durations_with_labels[$record_id][$record['date']])) {
783+
$day_header = substr($record['date'], 8); // Day number in month.
784+
while (ttTimeHelper::cellExists($record_id, $day_header, $dataArray)) {
782785
$suffix++;
783786
$record_id = $record_id_no_suffix.'_'.$suffix;
784787
}
785-
$groupedRecords[$record_identifier][$record['date']] = array('id'=>$record['id'], 'duration'=>$record['duration']);
786-
$groupedRecords[$record_identifier]['client'] = $record['client'];
787-
$groupedRecords[$record_identifier]['cf_1_value'] = $record['cf_1_value'];
788-
$groupedRecords[$record_identifier]['project'] = $record['project'];
789-
$groupedRecords[$record_identifier]['task'] = $record['task'];
790-
$groupedRecords[$record_identifier]['billable'] = $record['billable'];
788+
// Find row.
789+
$pos = ttTimeHelper::findRow($record_id, $dataArray);
790+
if ($pos < 0) {
791+
$dataArray[] = array('id' => $record_id,'label' => ttTimeHelper::makeRecordLabel($record)); // Insert row.
792+
$pos = ttTimeHelper::findRow($record_id, $dataArray);
793+
}
794+
// Insert cell data from $record.
795+
$dataArray[$pos][$day_header] = array('id' => $record['id'],'duration' => $record['duration']);
791796
}
797+
return $dataArray;
798+
}
799+
800+
// cellExists is a helper function for getDataForWeekView() to see if a cell with a given label
801+
// and a day header already exists.
802+
static function cellExists($record_id, $day_header, $dataArray) {
803+
foreach($dataArray as $row) {
804+
if ($row['id'] == $record_id && !empty($row[$day_header]['duration']))
805+
return true;
806+
}
807+
return false;
808+
}
809+
810+
// findRow returns an existing row position in $dataArray, -1 otherwise.
811+
static function findRow($record_id, $dataArray) {
812+
$pos = 0; // Row position in array.
813+
foreach($dataArray as $row) {
814+
if ($row['id'] == $record_id)
815+
return $pos;
816+
$pos++; // Increment for search.
817+
}
818+
return -1; // Row not found.
792819
}
793-
*/
794820

795821
// makeRecordIdentifier - builds a string identifying a record for a grouped display (such as a week view).
796822
// For example:
@@ -820,6 +846,39 @@ static function makeRecordIdentifier($record) {
820846
return $record_identifier;
821847
}
822848

849+
// makeRecordLabel - builds a human readable label for a row in week view,
850+
// which is a combination ot record properties.
851+
// Client - Project - Task - Custom field 1.
852+
// Note that billable property is not part of the label. Instead, we intend to
853+
// identify such records with a different color in week view.
854+
static function makeRecordLabel($record) {
855+
// TODO: debug this function.
856+
global $user;
857+
// Start with client.
858+
if ($user->isPluginEnabled('cl'))
859+
$label = $record['client'];
860+
861+
// Add project.
862+
$project = $record['project'] ? $record['project'] : '';
863+
if (!empty($label)) $label .= ' - ';
864+
$label .= $project;
865+
866+
// Add task.
867+
$task = $record['task'] ? $record['task'] : '';
868+
if (!empty($label)) $label .= ' - ';
869+
$label .= $task;
870+
871+
// Add custom field 1.
872+
if ($user->isPluginEnabled('cf')) {
873+
if ($record['cf_1_value']) {
874+
if (!empty($label)) $label .= ' - ';
875+
$label .= $record['cf_1_value'];
876+
}
877+
}
878+
879+
return $label;
880+
}
881+
823882
// getGroupedRecordsTotals - returns day totals for grouped records.
824883
static function getGroupedRecordsTotals($groupedRecords) {
825884
$groupedRecordsTotals = array();
@@ -843,7 +902,7 @@ static function getGroupedRecordsTotals($groupedRecords) {
843902
static function getDayHeadersForWeek($start_date) {
844903
$dayHeaders = array();
845904
$objDate = new DateAndTime(DB_DATEFORMAT, $start_date);
846-
$dayHeaders['day_header_0'] = $objDate->getDate();
905+
$dayHeaders['day_header_0'] = (string)$objDate->getDate(); // It returns an int on first call. Why?
847906
$objDate->incDay();
848907
$dayHeaders['day_header_1'] = $objDate->getDate();
849908
$objDate->incDay();
@@ -859,4 +918,28 @@ static function getDayHeadersForWeek($start_date) {
859918
unset($objDate);
860919
return $dayHeaders;
861920
}
921+
922+
// getDayTotals calculates total durations for each day from the existing data in $dataArray.
923+
static function getDayTotals($dataArray, $dayHeaders) {
924+
$dayTotals = array();
925+
926+
// Insert label.
927+
global $i18n;
928+
$dayTotals['label'] = $i18n->getKey('label.total');
929+
930+
foreach ($dataArray as $row) {
931+
foreach($dayHeaders as $dayHeader) {
932+
if (array_key_exists($dayHeader, $row)) {
933+
$minutes = ttTimeHelper::toMinutes($row[$dayHeader]['duration']);
934+
$dayTotals[$dayHeader] += $minutes;
935+
}
936+
}
937+
}
938+
// Convert minutes to hh:mm for display.
939+
foreach($dayHeaders as $dayHeader) {
940+
$dayTotals[$dayHeader] = ttTimeHelper::toAbsDuration($dayTotals[$dayHeader]);
941+
}
942+
return $dayTotals;
943+
}
862944
}
945+

WEB-INF/templates/footer.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<br>
1313
<table cellspacing="0" cellpadding="4" width="100%" border="0">
1414
<tr>
15-
<td align="center">&nbsp;Anuko Time Tracker 1.12.3.3693 | Copyright &copy; <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
15+
<td align="center">&nbsp;Anuko Time Tracker 1.13.3.3694 | Copyright &copy; <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
1616
<a href="https://www.anuko.com/lp/tt_4.htm" target="_blank">{$i18n.footer.credits}</a> |
1717
<a href="https://www.anuko.com/lp/tt_5.htm" target="_blank">{$i18n.footer.license}</a> |
1818
<a href="https://www.anuko.com/lp/tt_7.htm" target="_blank">{$i18n.footer.improve}</a>

WEB-INF/templates/time.tpl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@
88

99
{$forms.timeRecordForm.open}
1010
<table cellspacing="4" cellpadding="0" border="0">
11-
{if defined(WEEK_VIEW_DEBUG)}
1211
<tr>
1312
<td align="center" colspan=2">
1413
<a href="time.php?date={$selected_date->toString()}">{$i18n.label.day_view}</a>&nbsp;/&nbsp;<a href="week.php?date={$selected_date->toString()}">{$i18n.label.week_view}</a>
1514
</td>
1615
</tr>
17-
{/if}
1816
<tr>
1917
<td valign="top">
2018
<table>

WEB-INF/templates/week.tpl

Lines changed: 1 addition & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -38,87 +38,11 @@
3838
<td>{$forms.weekTimeForm.week_durations.control}</td>
3939
</tr>
4040
</table>
41-
42-
<table width="720">
43-
<tr>
44-
<td valign="top">
45-
{if $grouped_records}
46-
<table border="0" cellpadding="3" cellspacing="1" width="100%">
47-
<tr>
48-
{if ($user->isPluginEnabled('cl') || ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode))}
49-
<td class="tableHeader"></td>
50-
{/if}
51-
{if ($user->isPluginEnabled('cf') || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
52-
<td class="tableHeader"></td>
53-
{/if}
54-
<td class="tableHeader">{$day_header_0}</td>
55-
<td class="tableHeader">{$day_header_1}</td>
56-
<td class="tableHeader">{$day_header_2}</td>
57-
<td class="tableHeader">{$day_header_3}</td>
58-
<td class="tableHeader">{$day_header_4}</td>
59-
<td class="tableHeader">{$day_header_5}</td>
60-
<td class="tableHeader">{$day_header_6}</td>
61-
</tr>
62-
{foreach $grouped_records as $record}
63-
<tr bgcolor="{cycle values="#f5f5f5,#ffffff"}" {if !$record.billable} class="not_billable" {/if}>
64-
{if ($user->isPluginEnabled('cl') || ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode))}
65-
<td valign="top">{$record.project|escape}<p>{$record.client|escape}</td>
66-
{/if}
67-
{if ($user->isPluginEnabled('cf') || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
68-
<td valign="top">{$record.task|escape}<p>{$record.cf_1_value|escape}</td>
69-
{/if}
70-
<td valign="top">{$record.$date_0.duration}</td>
71-
<td valign="top">{$record.$date_1.duration}</td>
72-
<td valign="top">{$record.$date_2.duration}</td>
73-
<td valign="top">{$record.$date_3.duration}</td>
74-
<td valign="top">{$record.$date_4.duration}</td>
75-
<td valign="top">{$record.$date_5.duration}</td>
76-
<td valign="top">{$record.$date_6.duration}</td>
77-
</tr>
78-
{/foreach}
79-
<tr>
80-
{if ($user->isPluginEnabled('cl') || ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode))}
81-
<td class="tableHeader"></td>
82-
{/if}
83-
{if ($user->isPluginEnabled('cf') || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)}
84-
<td class="tableHeader"></td>
85-
{/if}
86-
<td class="tableHeader">{$grouped_records_totals.$date_0}</td>
87-
<td class="tableHeader">{$grouped_records_totals.$date_1}</td>
88-
<td class="tableHeader">{$grouped_records_totals.$date_2}</td>
89-
<td class="tableHeader">{$grouped_records_totals.$date_3}</td>
90-
<td class="tableHeader">{$grouped_records_totals.$date_4}</td>
91-
<td class="tableHeader">{$grouped_records_totals.$date_5}</td>
92-
<td class="tableHeader">{$grouped_records_totals.$date_6}</td>
93-
</tr>
94-
</table>
95-
{/if}
96-
</td>
97-
</tr>
98-
</table>
9941
<!--
100-
{if $time_records}
101-
<table cellpadding="3" cellspacing="1" width="720">
102-
<tr>
103-
<td align="left">{$i18n.label.week_total}: {$week_total}</td>
104-
<td align="right">{$i18n.label.day_total}: {$day_total}</td>
105-
</tr>
106-
{if $user->isPluginEnabled('mq')}
107-
<tr>
108-
<td align="left">{$i18n.label.month_total}: {$month_total}</td>
109-
{if $over_quota}
110-
<td align="right">{$i18n.form.time.over_quota}: <span style="color: green;">{$quota_remaining}</span></td>
111-
{else}
112-
<td align="right">{$i18n.form.time.remaining_quota}: <span style="color: red;">{$quota_remaining}</span></td>
113-
{/if}
114-
</tr>
115-
{/if}
116-
</table>
117-
{/if}
118-
-->
11942
<table>
12043
<tr>
12144
<td align="center" colspan="2">{$forms.weekTimeForm.btn_submit.control}</td>
12245
</tr>
12346
</table>
47+
-->
12448
{$forms.weekTimeForm.close}

table_test.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function render(&$table, $value, $row, $column, $selected = false) {
7373
// Define rendering class for a single cell for time entry in week view table.
7474
class TimeCellRenderer extends DefaultCellRenderer {
7575
function render(&$table, $value, $row, $column, $selected = false) {
76-
$field_name = $table->getValueAtName($row,$column)['id']; // Our text field names (and ids) are like x_y (row_column).
76+
$field_name = $table->getValueAt($row,$column)['id']; // Our text field names (and ids) are like x_y (row_column).
7777
$field = new TextField($field_name);
7878
$field->setFormName($table->getFormName());
7979
$field->setSize(2);

0 commit comments

Comments
 (0)