From fd823871f0ee840288d3b4fdd095cc2970f8adad Mon Sep 17 00:00:00 2001
From: Paul Beckingham
Date: Mon, 11 May 2009 23:07:50 -0400
Subject: [PATCH] Enhancement - timesheet report
- Version 1 of the timesheet report. Displays a specified number
of weeks tasks, both started and completed.
---
ChangeLog | 2 +
html/advanced.html | 11 +++-
html/task.html | 28 +--------
src/report.cpp | 140 ++++++++++++++++++++++++++++++++++++++++-----
src/task.cpp | 2 +-
5 files changed, 142 insertions(+), 41 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 74ec81581..a9eb3b9b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,6 +25,8 @@
example "task oldest 5" will display the 5 oldest tasks.
+ Modified the "stats" report so that it has the same aesthetics as the
other reports.
+ + New "timesheet" command displays tasks completed and started, per week,
+ and can display multiple weeks.
------ old releases ------------------------------
diff --git a/html/advanced.html b/html/advanced.html
index 976dcd2d6..fd5c3180e 100644
--- a/html/advanced.html
+++ b/html/advanced.html
@@ -231,9 +231,16 @@ Year Month Added Completed Deleted Net
report. It shows a colored bar graph and legend.
-
- ???
+ The timesheet report shows a list of tasks completed and started
+ during a one-week period. In the example above, 2 weeks of tasks
+ are shown.
+
+
+ By default, the report starts on a Monday. To override this
+ value, add an entry to your .taskrc file like this:
+
New "timesheet" command displays tasks completed and started, per week,
+ and can display multiple weeks.
(Find out what was new in prior versions)
-
+
Troubleshooting
Task has been built from source and tested in the following environments:
diff --git a/src/report.cpp b/src/report.cpp
index 18a12295c..ceed687c0 100644
--- a/src/report.cpp
+++ b/src/report.cpp
@@ -1346,42 +1346,156 @@ std::string handleReportTimesheet (TDB& tdb, T& task, Config& conf)
for (int week = 0; week < quantity; ++week)
{
- out << start.toString (conf.get ("dateformat", "m/d/Y"))
+ out << std::endl
+ << Text::colorize (Text::bold, Text::nocolor)
+ << start.toString (conf.get ("dateformat", "m/d/Y"))
<< " - "
<< end.toString (conf.get ("dateformat", "m/d/Y"))
+ << Text::colorize ()
<< std::endl;
// Render the completed table.
Table completed;
+ completed.setTableWidth (width);
+ completed.addColumn (" ");
+ completed.addColumn ("Project");
+ completed.addColumn ("Due");
+ completed.addColumn ("Description");
+
+ completed.setColumnUnderline (1);
+ completed.setColumnUnderline (2);
+ completed.setColumnUnderline (3);
+
+ completed.setColumnWidth (0, Table::minimum);
+ completed.setColumnWidth (1, Table::minimum);
+ completed.setColumnWidth (2, Table::minimum);
+ completed.setColumnWidth (3, Table::flexible);
+
+ completed.setColumnJustification (0, Table::left);
+ completed.setColumnJustification (1, Table::left);
+ completed.setColumnJustification (2, Table::right);
+ completed.setColumnJustification (3, Table::left);
+
foreach (t, tasks)
{
- // TODO If task completed within range.
+ // If task completed within range.
+ if (t->getStatus () == T::completed)
+ {
+ Date compDate (::atoi (t->getAttribute ("end").c_str ()));
+ if (compDate >= start && compDate < end)
+ {
+ int row = completed.addRow ();
+ completed.addCell (row, 1, t->getAttribute ("project"));
+
+ std::string due = t->getAttribute ("due");
+ if (due.length ())
+ {
+ Date d (::atoi (due.c_str ()));
+ due = d.toString (conf.get ("dateformat", "m/d/Y"));
+ completed.addCell (row, 2, due);
+ }
+
+ std::string description = t->getDescription ();
+ std::string when;
+ std::map annotations;
+ t->getAnnotations (annotations);
+ foreach (anno, annotations)
+ {
+ Date dt (anno->first);
+ when = dt.toString (conf.get ("dateformat", "m/d/Y"));
+ description += "\n" + when + " " + anno->second;
+ }
+ completed.addCell (row, 3, description);
+
+ if (conf.get ("color", true) || conf.get (std::string ("_forcecolor"), false))
+ {
+ Text::color fg = Text::colorCode (t->getAttribute ("fg"));
+ Text::color bg = Text::colorCode (t->getAttribute ("bg"));
+ autoColorize (*t, fg, bg, conf);
+ completed.setRowFg (row, fg);
+ completed.setRowBg (row, bg);
+ }
+ }
+ }
}
- out << " Completed (" << completed.rowCount () << ")" << std::endl;
+ out << " Completed (" << completed.rowCount () << " tasks)" << std::endl;
if (completed.rowCount ())
- out << optionalBlankLine (conf)
- << completed.render ()
+ out << completed.render ()
<< std::endl;
- else
- out << " None" << std::endl;
// Now render the started table.
Table started;
+ started.setTableWidth (width);
+ started.addColumn (" ");
+ started.addColumn ("Project");
+ started.addColumn ("Due");
+ started.addColumn ("Description");
+
+ started.setColumnUnderline (1);
+ started.setColumnUnderline (2);
+ started.setColumnUnderline (3);
+
+ started.setColumnWidth (0, Table::minimum);
+ started.setColumnWidth (1, Table::minimum);
+ started.setColumnWidth (2, Table::minimum);
+ started.setColumnWidth (3, Table::flexible);
+
+ started.setColumnJustification (0, Table::left);
+ started.setColumnJustification (1, Table::left);
+ started.setColumnJustification (2, Table::right);
+ started.setColumnJustification (3, Table::left);
foreach (t, tasks)
{
- // TODO If task started withing range, but not completed withing range.
+ // If task started within range, but not completed withing range.
+ if (t->getStatus () == T::pending &&
+ t->getAttribute ("start") != "")
+ {
+ Date startDate (::atoi (t->getAttribute ("start").c_str ()));
+ if (startDate >= start && startDate < end)
+ {
+ int row = started.addRow ();
+ started.addCell (row, 1, t->getAttribute ("project"));
+
+ std::string due = t->getAttribute ("due");
+ if (due.length ())
+ {
+ Date d (::atoi (due.c_str ()));
+ due = d.toString (conf.get ("dateformat", "m/d/Y"));
+ started.addCell (row, 2, due);
+ }
+
+ std::string description = t->getDescription ();
+ std::string when;
+ std::map annotations;
+ t->getAnnotations (annotations);
+ foreach (anno, annotations)
+ {
+ Date dt (anno->first);
+ when = dt.toString (conf.get ("dateformat", "m/d/Y"));
+ description += "\n" + when + " " + anno->second;
+ }
+ started.addCell (row, 3, description);
+
+ if (conf.get ("color", true) || conf.get (std::string ("_forcecolor"), false))
+ {
+ Text::color fg = Text::colorCode (t->getAttribute ("fg"));
+ Text::color bg = Text::colorCode (t->getAttribute ("bg"));
+ autoColorize (*t, fg, bg, conf);
+ started.setRowFg (row, fg);
+ started.setRowBg (row, bg);
+ }
+ }
+ }
}
- out << " Started (" << started.rowCount () << ")" << std::endl;
+ out << " Started (" << started.rowCount () << " tasks)" << std::endl;
if (started.rowCount ())
- out << optionalBlankLine (conf)
- << started.render ()
+ out << started.render ()
+ << std::endl
<< std::endl;
- else
- out << " None" << std::endl;
// Prior week.
start -= 7 * 86400;
diff --git a/src/task.cpp b/src/task.cpp
index 92c34ed4b..4a9481b97 100644
--- a/src/task.cpp
+++ b/src/task.cpp
@@ -153,7 +153,7 @@ static std::string shortUsage (Config& conf)
table.addCell (row, 2, "Shows a report of task status by project");
row = table.addRow ();
- table.addCell (row, 1, "task timesheet [duration]");
+ table.addCell (row, 1, "task timesheet [weeks]");
table.addCell (row, 2, "Shows a weekly report of tasks completed and started");
row = table.addRow ();