all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Huchler <stefan.huchler@mail.de>
To: emacs-orgmode@gnu.org
Subject: org-capture template to type in bills from shops in ledger format
Date: Sun, 02 Jun 2019 02:05:04 +0200	[thread overview]
Message-ID: <87woi4rgwf.fsf@mail.de> (raw)

I wrote this template to capture my bills from mostly one shop, but it
has support for multiple shops and the important feature is that it
suggests previous item names and remembers last prices, that gives you
lot's of autocompletion if you repetetivly buy often the same stuff over
and over again.

#+begin_src emacs-lisp
%(let* ((default-directory (file-name-directory "%F"))
	(map-file "shop-items.txt"))
   (load-file "helper.el")
   (require 'dash)
   (let* ((shops (if (file-exists-p map-file)
		     (read-from-file map-file) '()))
	  (names (mapcar 'car shops))
	  (shop-name (ido-completing-read "Shop: " names nil nil nil))
	  (new-prices) (new-names) (new-amounts)
	  (products (assoc-default shop-name shops)))
     (while (let* ((names (mapcar 'car products))
     		   (name (ido-completing-read "Name: " names))
       		   (amount (read-number "Amount: " 1))
     		   (item (alist-get name products))
     		   (item (if (stringp item) (string-to-number item) item))
       		   (price (read-number "Price: " (or item 2.00))))
     	      (setq new-names (append new-names (list name)))
     	      (setq new-prices (append new-prices (list price)))	   
     	      (setq new-amounts (append new-amounts (list amount)))
     	      (y-or-n-p "More items? ")))
     (let* ((-compare-fn (lambda (x y) (equal (car x) (car y))))
     	    (new-products (mapcar* 'cons new-names new-prices))
     	    (combined-products (-distinct (append new-products products)))
	    (combined-shops (-distinct (append `((,shop-name . ,combined-products)) shops)))
     	    (format-string "      expenses:food:%s \t\t%s St @ =€%s")
     	    (format-function (lambda (name amount price)
     			       (format format-string name amount price)))
	    (product-lines (mapcar* format-function new-names
     					     new-amounts new-prices))
     	    (shopping-items (s-join "\n" product-lines))
     	    (total (reduce '+ (mapcar* '* new-amounts new-prices))))
       (print-to-file map-file combined-shops)
       (concat (format "  %(org-read-date nil nil) * %s\n%s"
     		       shop-name shopping-items)
     	       (format "\n      assets:bank:chequing\t\t€-%s"
       		       (read-string "Total: " (format "%.2f" total)))))))
#+end_src

Any thoughts? It's supposed to output into a org file with a embeded
ledger src block so you would have to check the alignment if you would
want to output to a normal ledger file.

here are the 2 functions from helper.el:

#+begin_src emacs-lisp
(defun print-to-file (filename data)
  (with-temp-file filename
    (let* ((print-length 5000))
      (prin1 data (current-buffer)))))

(defun read-from-file (filename)
  (with-temp-buffer
    (insert-file-contents filename)
    (cl-assert (eq (point) (point-min)))
    (read (current-buffer))))
#+end_src

Maybe that's useful for somebody else or somebody wants to suggest other
features or something. The only thing I would maybe consider to switch
is to use a json format for the shop-items.txt for the prices for easier
manual editing.

that's how I set it up:

#+begin_src emacs-lisp
("s" "(S)hopping" plain
	 (file+function "path/finances.org"
			(lambda () ""
			  (progn (org-babel-goto-named-src-block "balance")   
				 (org-babel-goto-src-block-head)(forward-line))))
	 "%[~/capture-templates/template-name]" 
	 :jump-to-captured t
	 :empty-lines-after 1
	 :immediate-finish nil)
#+end_src         

             reply	other threads:[~2019-06-02  0:17 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-02  0:05 Stefan Huchler [this message]
2019-06-02 13:37 ` org-capture template to type in bills from shops in ledger format Michael Welle
2019-06-04 16:42   ` Stefan Huchler
2019-06-22 14:14 ` Stefan Huchler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87woi4rgwf.fsf@mail.de \
    --to=stefan.huchler@mail.de \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.