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 @@

Advanced Usage

report. It shows a colored bar graph and legend.

- % task timesheet + % task timesheet 2

- ??? + 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: +

weekstart=Sunday

% task calendar diff --git a/html/task.html b/html/task.html index d9db48fad..320b05941 100644 --- a/html/task.html +++ b/html/task.html @@ -164,36 +164,14 @@

New in version 1.7.0 (?)

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.

    (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 ();