emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* org-capture template to type in bills from shops in ledger format
@ 2019-06-02  0:05 Stefan Huchler
  2019-06-02 13:37 ` Michael Welle
  2019-06-22 14:14 ` Stefan Huchler
  0 siblings, 2 replies; 4+ messages in thread
From: Stefan Huchler @ 2019-06-02  0:05 UTC (permalink / raw)
  To: emacs-orgmode

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         

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: org-capture template to type in bills from shops in ledger format
  2019-06-02  0:05 org-capture template to type in bills from shops in ledger format Stefan Huchler
@ 2019-06-02 13:37 ` Michael Welle
  2019-06-04 16:42   ` Stefan Huchler
  2019-06-22 14:14 ` Stefan Huchler
  1 sibling, 1 reply; 4+ messages in thread
From: Michael Welle @ 2019-06-02 13:37 UTC (permalink / raw)
  To: emacs-orgmode

Hello,

Stefan Huchler <stefan.huchler@mail.de> writes:

> 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.
nice. I do something similar with a simple Perl script and an SQL
database as a backend and sometimes I mull over about what's wrong
with me ;). On the other hand, I've Org tables telling me when I got
hair cuts in the last 10 years or so.

Regards
hmw

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: org-capture template to type in bills from shops in ledger format
  2019-06-02 13:37 ` Michael Welle
@ 2019-06-04 16:42   ` Stefan Huchler
  0 siblings, 0 replies; 4+ messages in thread
From: Stefan Huchler @ 2019-06-04 16:42 UTC (permalink / raw)
  To: emacs-orgmode

Michael Welle <mwe012008@gmx.net> writes:

> nice. I do something similar with a simple Perl script and an SQL
> database as a backend and sometimes I mull over about what's wrong
> with me ;). On the other hand, I've Org tables telling me when I got
> hair cuts in the last 10 years or so.

Did find a Bug in my code, it only works if you have opened up the
current buffer because %F only gives the path of the current open
buffer.

(default-directory (file-name-directory "%F"))

The easiest solution would be to put the 2 functions from helper.el with
a progn around it in the template file, then you don't need the
load-file statement anymore.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: org-capture template to type in bills from shops in ledger format
  2019-06-02  0:05 org-capture template to type in bills from shops in ledger format Stefan Huchler
  2019-06-02 13:37 ` Michael Welle
@ 2019-06-22 14:14 ` Stefan Huchler
  1 sibling, 0 replies; 4+ messages in thread
From: Stefan Huchler @ 2019-06-22 14:14 UTC (permalink / raw)
  To: emacs-orgmode

If somebody is interested I uploaded a reworked version of this there:

https://github.com/spiderbit/org-capture-ledger-shopping


Stefan Huchler <stefan.huchler@mail.de> writes:

> 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         

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-06-22 14:14 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-02  0:05 org-capture template to type in bills from shops in ledger format Stefan Huchler
2019-06-02 13:37 ` Michael Welle
2019-06-04 16:42   ` Stefan Huchler
2019-06-22 14:14 ` Stefan Huchler

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).