Function: timeclock-generate-report
timeclock-generate-report is an interactive and byte-compiled function
defined in timeclock.el.gz.
Signature
(timeclock-generate-report &optional HTML-P)
Documentation
Generate a summary report based on the current timelog file.
By default, the report is in plain text, but if the optional argument HTML-P is non-nil, HTML markup is added.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/timeclock.el.gz
(defun timeclock-generate-report (&optional html-p)
"Generate a summary report based on the current timelog file.
By default, the report is in plain text, but if the optional argument
HTML-P is non-nil, HTML markup is added."
(interactive "P")
(let ((log (timeclock-log-data))
(today (timeclock-day-base)))
(if html-p (insert "<p>"))
(insert "Currently ")
(let ((project (nth 2 timeclock-last-event))
(begin (nth 1 timeclock-last-event))
done)
(if (timeclock-currently-in-p)
(insert "IN")
(if (zerop (length project))
(progn (insert "Done Working Today")
(setq done t))
(insert "OUT")))
(unless done
(insert " since " (format-time-string "%Y/%m/%d %-I:%M %p" begin))
(if html-p
(insert "<br>\n<b>")
(insert "\n*"))
(if (timeclock-currently-in-p)
(insert "Working on "))
(if html-p
(insert project "</b><br>\n")
(insert project "*\n"))
(let ((proj-data (cdr (assoc project (timeclock-project-alist log))))
(two-weeks-ago (time-subtract today (* 2 7 24 60 60)))
two-week-len today-len)
(while proj-data
(if (not (time-less-p
(timeclock-entry-begin (car proj-data)) today))
(setq today-len (timeclock-entry-list-length proj-data)
proj-data nil)
(if (and (null two-week-len)
(not (time-less-p
(timeclock-entry-begin (car proj-data))
two-weeks-ago)))
(setq two-week-len (timeclock-entry-list-length proj-data)))
(setq proj-data (cdr proj-data))))
(if (null two-week-len)
(setq two-week-len today-len))
(if html-p (insert "<p>"))
(if today-len
(insert "\nTime spent on this task today: "
(timeclock-seconds-to-string today-len)
". In the last two weeks: "
(timeclock-seconds-to-string two-week-len))
(if two-week-len
(insert "\nTime spent on this task in the last two weeks: "
(timeclock-seconds-to-string two-week-len))))
(if html-p (insert "<br>"))
(insert "\n"
(timeclock-seconds-to-string (timeclock-workday-elapsed))
" worked today, "
(timeclock-seconds-to-string (timeclock-workday-remaining))
" remaining, done at "
(timeclock-when-to-leave-string) "\n")))
(if html-p (insert "<p>"))
(insert "\nThere have been "
(number-to-string
(length (timeclock-day-alist log)))
" days of activity, starting "
(caar (last (timeclock-day-alist log))))
(if html-p (insert "</p>"))
(when html-p
(insert "<p>
<table>
<td width=\"25\"><br></td><td>
<table border=1 cellpadding=3>
<tr><th><i>Statistics</i></th>
<th>Entire</th>
<th>-30 days</th>
<th>-3 mons</th>
<th>-6 mons</th>
<th>-1 year</th>
</tr>")
(let* ((day-list (timeclock-day-list))
(thirty-days-ago (time-subtract today (* 30 24 60 60)))
(three-months-ago (time-subtract today (* 90 24 60 60)))
(six-months-ago (time-subtract today (* 180 24 60 60)))
(one-year-ago (time-subtract today (* 365 24 60 60)))
(time-in (vector (list t) (list t) (list t) (list t) (list t)))
(time-out (vector (list t) (list t) (list t) (list t) (list t)))
(breaks (vector (list t) (list t) (list t) (list t) (list t)))
(workday (vector (list t) (list t) (list t) (list t) (list t)))
(lengths (vector 0 thirty-days-ago three-months-ago
six-months-ago one-year-ago)))
;; collect statistics from complete timelog
(dolist (day day-list)
(dotimes (i 5)
(unless (time-less-p
(timeclock-day-begin day)
(aref lengths i))
(let ((base (timeclock-day-base (timeclock-day-begin day))))
(nconc (aref time-in i)
(list (float-time (time-subtract
(timeclock-day-begin day)
base))))
(let ((span (timeclock-day-span day))
(len (timeclock-day-length day))
(req (timeclock-day-required day)))
;; If the day's actual work length is less than
;; 70% of its span, then likely the exit time
;; and break amount are not worthwhile adding to
;; the statistic
(when (and (> span 0)
(> (/ (float len) (float span)) 0.70))
(nconc (aref time-out i)
(list (float-time (time-subtract
(timeclock-day-end day)
base))))
(nconc (aref breaks i) (list (- span len))))
(if req
(setq len (+ len (- timeclock-workday req))))
(nconc (aref workday i) (list len)))))))
;; average statistics
(dotimes (i 5)
(aset time-in i (timeclock-mean (cdr (aref time-in i))))
(aset time-out i (timeclock-mean (cdr (aref time-out i))))
(aset breaks i (timeclock-mean (cdr (aref breaks i))))
(aset workday i (timeclock-mean (cdr (aref workday i)))))
;; Output the HTML table
(insert "<tr>\n")
(insert "<td align=\"center\">Time in</td>\n")
(dotimes (i 5)
(insert "<td align=\"right\">"
(timeclock-seconds-to-string (aref time-in i))
"</td>\n"))
(insert "</tr>\n")
(insert "<tr>\n")
(insert "<td align=\"center\">Time out</td>\n")
(dotimes (i 5)
(insert "<td align=\"right\">"
(timeclock-seconds-to-string (aref time-out i))
"</td>\n"))
(insert "</tr>\n")
(insert "<tr>\n")
(insert "<td align=\"center\">Break</td>\n")
(dotimes (i 5)
(insert "<td align=\"right\">"
(timeclock-seconds-to-string (aref breaks i))
"</td>\n"))
(insert "</tr>\n")
(insert "<tr>\n")
(insert "<td align=\"center\">Workday</td>\n")
(dotimes (i 5)
(insert "<td align=\"right\">"
(timeclock-seconds-to-string (aref workday i))
"</td>\n"))
(insert "</tr>\n"))
(insert "<tfoot>
<td colspan=\"6\" align=\"center\">
<i>These are approximate figures</i></td>
</tfoot>
</table>
</td></table>")))))