38
votes

So, at work we use flexitime (flex hours, flexi hours...) which is nice but can be hard to keep track of. I'm currently using org-mode to keep track of my hours (org-clock-(out|in)) but I'd like to extend that to automagically calculate if I've worked more than 8 hours (surplus time should be added to my flexitime 'account') or less (depending on how long lunch break I took etc), the balance on my flexitime 'account' and such.

Does anyone else use Emacs for this?

I'm currently using a very basic setup to track my time:

(defun check-in ()
  (interactive)
  (let (pbuf (current-buffer))
    (find-file (convert-standard-filename "whatnot"))
    (goto-char (point-max))
    (insert "\n")
    (org-insert-heading)
    (org-insert-time-stamp (current-time))
    (org-clock-in)
    (save-buffer)
    (switch-to-buffer pbuf)))

(defun check-out ()
  (interactive)
  (let (pbuf (current-buffer))
    (find-file (convert-standard-filename "whatnot"))
    (goto-char (point-max))
    (org-clock-out)
    (save-buffer)
    (switch-to-buffer pbuf)))
1
Your code confuses the current-buffer with the buffer displayed in the selected-window. Calling switch-to-buffer from Elisp is generally a sign of such problems. Instead of current-buffer+find-file+switch-to-buffer, you want to use (with-current-buffer (find-file-noselect ...) ...). One more note: don't bother calling convert-standard-filename since it probably doesn't really do what you think, and your code will work just as well without it.Stefan

1 Answers

4
votes

Assuming that I understood your problem correctly, I hacked together a quick solution. First, you should ensure that you create only one outline entry per day, if you are checking in and out multiple times. Define the following function that'll compute the overtime for a given day.

(defun compute-overtime (duration-string)
  "Computes overtime duration string for the given time DURATION-STRING."
  (let (minutes-in-a-workday
        work-minutes
        overtime-minutes)
    (defconst minutes-in-a-workday 480)
    (setq work-minutes (org-duration-string-to-minutes duration-string)
          overtime-minutes (- work-minutes minutes-in-a-workday))
    (if (< overtime-minutes 0) (setq overtime-minutes 0))
    (org-minutes-to-hh:mm-string overtime-minutes)))

Then, use this in a clock table formula in the file whatnot.

#+BEGIN: clocktable :maxlevel 1 :emphasize nil :scope file :formula "$3='(compute-overtime $2)::@2$3=string(\"Overtime\")"    
#+END: clocktable

Hit C-c C-c when you are on the clock table to regenerate it.

You can get the total overtime by summing the overtimes using another formula. But, I haven't worked that out.