Added rudimentary target checking to reconcile.
This commit is contained in:
parent
15d838d1f8
commit
d31913871f
4 changed files with 152 additions and 11 deletions
|
|
@ -2542,7 +2542,7 @@ all of the uncleared transactions. The reconcile buffer has several functions:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item SPACE
|
@item SPACE
|
||||||
toggles the cleared status of a transaction, and show cleared balance inthe minibuffer
|
toggles the cleared status of a transaction, and shows pending balance in the mini-buffer
|
||||||
@item RETURN
|
@item RETURN
|
||||||
moves the cursor to that transaction in the ledger.
|
moves the cursor to that transaction in the ledger.
|
||||||
@item C-x C-s
|
@item C-x C-s
|
||||||
|
|
@ -2555,6 +2555,8 @@ all of the uncleared transactions. The reconcile buffer has several functions:
|
||||||
add entry
|
add entry
|
||||||
@item D
|
@item D
|
||||||
delete entry
|
delete entry
|
||||||
|
@item t
|
||||||
|
change target reconciliation amount
|
||||||
@item g
|
@item g
|
||||||
reconcile new account
|
reconcile new account
|
||||||
@item b
|
@item b
|
||||||
|
|
@ -2570,6 +2572,14 @@ show all transaction meeting the regex, cleared or not. This behavior
|
||||||
can be disabled by setting @code{ledger-fold-on-reconcile} to nil in the
|
can be disabled by setting @code{ledger-fold-on-reconcile} to nil in the
|
||||||
emacs customization menus.
|
emacs customization menus.
|
||||||
|
|
||||||
|
When you reconcile an account you nromally know the final balance you
|
||||||
|
are aiming at. When you enter the reconciliation mode ledger will ask
|
||||||
|
for a target balance. Enter the amount you are aiming for (the default
|
||||||
|
commodity can be chaged in the customization window). Each time you
|
||||||
|
toggle a posting to pending, ledger will calculate the new balance of
|
||||||
|
the account and display the new balance and the difference to make the
|
||||||
|
target.
|
||||||
|
|
||||||
@node Generating Reports, , Reconciling accounts, Using EMACS
|
@node Generating Reports, , Reconciling accounts, Using EMACS
|
||||||
@subsection Generating Reports
|
@subsection Generating Reports
|
||||||
|
|
||||||
|
|
|
||||||
93
lisp/ldg-commodities.el
Normal file
93
lisp/ldg-commodities.el
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
;;; ldg-commodities.el --- Helper code for use with the "ledger" command-line tool
|
||||||
|
|
||||||
|
;; Copyright (C) 2003-2013 John Wiegley (johnw AT gnu DOT org)
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;; This is free software; you can redistribute it and/or modify it under
|
||||||
|
;; the terms of the GNU General Public License as published by the Free
|
||||||
|
;; Software Foundation; either version 2, or (at your option) any later
|
||||||
|
;; version.
|
||||||
|
;;
|
||||||
|
;; This is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
;; for more details.
|
||||||
|
;;
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
||||||
|
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||||
|
;; MA 02111-1307, USA.
|
||||||
|
|
||||||
|
;; A sample entry sorting function, which works if entry dates are of
|
||||||
|
;; the form YYYY/mm/dd.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;; Helper functions to deal with commoditized numbers. A commoditized
|
||||||
|
;; number will be a cons of value and string where the string contains
|
||||||
|
;; the commodity
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(defcustom ledger-reconcile-default-commodity "$"
|
||||||
|
"the default commodity for use in target calculations in ledger reconcile"
|
||||||
|
:type 'string
|
||||||
|
:group 'ledger)
|
||||||
|
|
||||||
|
(defun ledger-string-balance-to-commoditized-amount (str)
|
||||||
|
(let ((fields (split-string str "[\n\r]"))) ; break any balances
|
||||||
|
; with multi commodities
|
||||||
|
; into a list
|
||||||
|
(mapcar '(lambda (str)
|
||||||
|
(let* ((parts (split-string str)) ;break into number and commodity string
|
||||||
|
(first (car parts))
|
||||||
|
(second (cadr parts)))
|
||||||
|
;"^-*[1-9][0-9]*[.,][0-9]*"
|
||||||
|
(if (string-match "^-*[1-9]+" first)
|
||||||
|
(list (string-to-number first) second)
|
||||||
|
(list (string-to-number second) first))))
|
||||||
|
fields)))
|
||||||
|
|
||||||
|
|
||||||
|
(defun -commodity (c1 c2)
|
||||||
|
(if (string= (cadr c1) (cadr c2))
|
||||||
|
(list (- (car c1) (car c2)) (cadr c1))
|
||||||
|
(error "Can't subtract different commodities %S from %S" c2 c1)))
|
||||||
|
|
||||||
|
(defun +commodity (c1 c2)
|
||||||
|
(if (string= (cadr c1) (cadr c2))
|
||||||
|
(list (+ (car c1) (car c2)) (cadr c1))
|
||||||
|
(error "Can't add different commodities, %S to %S" c1 c2)))
|
||||||
|
|
||||||
|
(defun ledger-commodity-to-string (c1)
|
||||||
|
(let ((val (number-to-string (car c1)))
|
||||||
|
(commodity (cadr c1)))
|
||||||
|
(if (> (length commodity) 1)
|
||||||
|
(concat val " " commodity)
|
||||||
|
(concat commodity " " val))))
|
||||||
|
|
||||||
|
(defun ledger-read-commodity-string (comm)
|
||||||
|
(interactive (list (read-from-minibuffer
|
||||||
|
(concat "Enter commoditized amount (" ledger-reconcile-default-commodity "): "))))
|
||||||
|
(let ((parts (split-string comm)))
|
||||||
|
(if parts
|
||||||
|
(if (/= (length parts) 2) ;;assume a number was entered and use default commodity
|
||||||
|
(list (string-to-number (car parts))
|
||||||
|
ledger-reconcile-default-commodity)
|
||||||
|
(let ((valp1 (string-to-number (car parts)))
|
||||||
|
(valp2 (string-to-number (cadr parts))))
|
||||||
|
(cond ((and (= valp1 valp2) (= 0 valp1));; means neither contained a valid number (both = 0)
|
||||||
|
(list 0 ""))
|
||||||
|
((and (/= 0 valp1) (= valp2 0))
|
||||||
|
(list valp1 (cadr parts)))
|
||||||
|
((and (/= 0 valp2) (= valp1 0))
|
||||||
|
(list valp2 (car parts)))
|
||||||
|
(t
|
||||||
|
(error "cannot understand commodity"))))))))
|
||||||
|
|
||||||
|
(provide 'ldg-commodities)
|
||||||
|
|
||||||
|
;;; ldg-commodities.el ends here
|
||||||
|
|
@ -46,6 +46,8 @@
|
||||||
(require 'ldg-sort)
|
(require 'ldg-sort)
|
||||||
(require 'ldg-fonts)
|
(require 'ldg-fonts)
|
||||||
(require 'ldg-occur)
|
(require 'ldg-occur)
|
||||||
|
(require 'ldg-commodities)
|
||||||
|
|
||||||
|
|
||||||
(autoload #'ledger-texi-update-test "ldg-texi" nil t)
|
(autoload #'ledger-texi-update-test "ldg-texi" nil t)
|
||||||
(autoload #'ledger-texi-update-examples "ldg-texi" nil t)
|
(autoload #'ledger-texi-update-examples "ldg-texi" nil t)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
(defvar ledger-buf nil)
|
(defvar ledger-buf nil)
|
||||||
(defvar ledger-bufs nil)
|
(defvar ledger-bufs nil)
|
||||||
(defvar ledger-acct nil)
|
(defvar ledger-acct nil)
|
||||||
|
(defvar ledger-target nil)
|
||||||
|
|
||||||
(defcustom ledger-recon-buffer-name "*Reconcile*"
|
(defcustom ledger-recon-buffer-name "*Reconcile*"
|
||||||
"Name to use for reconciliation window"
|
"Name to use for reconciliation window"
|
||||||
|
|
@ -54,19 +55,42 @@
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'ledger)
|
:group 'ledger)
|
||||||
|
|
||||||
|
|
||||||
|
(defun ledger-reconcile-get-balances ()
|
||||||
|
"Calculate the cleared and uncleared balance of the account being reconciled,
|
||||||
|
return a list with the account, uncleared and cleared balances as numbers"
|
||||||
|
(interactive)
|
||||||
|
(let ((buffer ledger-buf)
|
||||||
|
(account ledger-acct)
|
||||||
|
(val nil))
|
||||||
|
(with-temp-buffer
|
||||||
|
(ledger-exec-ledger buffer (current-buffer)
|
||||||
|
; note that in the line below, the --format option is
|
||||||
|
; separated from the actual format string. emacs does not
|
||||||
|
; split arguments like the shell does, so you need to
|
||||||
|
; specify the individual fields in the command line.
|
||||||
|
"balance" "--limit" "cleared or pending"
|
||||||
|
"--format" "(\"%(amount)\")" account)
|
||||||
|
(setq val (read (buffer-substring-no-properties (point-min) (point-max)))))))
|
||||||
|
|
||||||
(defun ledger-display-balance ()
|
(defun ledger-display-balance ()
|
||||||
"Calculate the cleared balance of the account being reconciled"
|
"Calculate the cleared balance of the account being reconciled"
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((buffer ledger-buf)
|
(let* ((pending (car (ledger-string-balance-to-commoditized-amount
|
||||||
(account ledger-acct))
|
(car (ledger-reconcile-get-balances)))))
|
||||||
(with-temp-buffer
|
(target-delta (if ledger-target
|
||||||
(ledger-exec-ledger buffer (current-buffer) "balance" "--limit" "cleared or pending" account)
|
(-commodity ledger-target pending)
|
||||||
(goto-char (1- (point-max)))
|
nil)))
|
||||||
(goto-char (line-beginning-position))
|
|
||||||
(delete-horizontal-space)
|
(if target-delta
|
||||||
(message "Current pending balance = %s"
|
(message "Pending balance: %s, Difference from target: %s"
|
||||||
(buffer-substring-no-properties (point)
|
(ledger-commodity-to-string pending)
|
||||||
(line-end-position))))))
|
(ledger-commodity-to-string target-delta))
|
||||||
|
(message "Pending balance: %s"
|
||||||
|
(ledger-commodity-to-string pending)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defun is-stdin (file)
|
(defun is-stdin (file)
|
||||||
"True if ledger file is standard input"
|
"True if ledger file is standard input"
|
||||||
|
|
@ -323,6 +347,8 @@ Spliting the windows of BUF if needed"
|
||||||
(if ledger-fold-on-reconcile
|
(if ledger-fold-on-reconcile
|
||||||
(ledger-occur-change-regex account ledger-buf))
|
(ledger-occur-change-regex account ledger-buf))
|
||||||
(set-buffer (get-buffer ledger-recon-buffer-name))
|
(set-buffer (get-buffer ledger-recon-buffer-name))
|
||||||
|
(setq ledger-target
|
||||||
|
(call-interactively #'ledger-read-commodity-string))
|
||||||
(unless (get-buffer-window rbuf)
|
(unless (get-buffer-window rbuf)
|
||||||
(ledger-reconcile-open-windows buf rbuf))
|
(ledger-reconcile-open-windows buf rbuf))
|
||||||
(ledger-reconcile-refresh))
|
(ledger-reconcile-refresh))
|
||||||
|
|
@ -337,10 +363,18 @@ Spliting the windows of BUF if needed"
|
||||||
(ledger-reconcile-mode)
|
(ledger-reconcile-mode)
|
||||||
(set (make-local-variable 'ledger-buf) buf)
|
(set (make-local-variable 'ledger-buf) buf)
|
||||||
(set (make-local-variable 'ledger-acct) account)
|
(set (make-local-variable 'ledger-acct) account)
|
||||||
|
(set (make-local-variable 'ledger-target)
|
||||||
|
(call-interactively #'ledger-read-commodity-string))
|
||||||
(ledger-do-reconcile))))))
|
(ledger-do-reconcile))))))
|
||||||
|
|
||||||
(defvar ledger-reconcile-mode-abbrev-table)
|
(defvar ledger-reconcile-mode-abbrev-table)
|
||||||
|
|
||||||
|
(defun ledger-reconcile-change-target ()
|
||||||
|
(setq ledger-target (call-interactively #'ledger-read-commodity-string)))
|
||||||
|
; (setq ledger-target
|
||||||
|
; (if (and target (> (length target) 0))
|
||||||
|
; (ledger-string-balance-to-commoditized-amount target))))
|
||||||
|
|
||||||
(defun ledger-reconcile-display-internals ()
|
(defun ledger-reconcile-display-internals ()
|
||||||
(interactive)
|
(interactive)
|
||||||
(message "%S %S" ledger-acct ledger-buf))
|
(message "%S %S" ledger-acct ledger-buf))
|
||||||
|
|
@ -358,6 +392,7 @@ Spliting the windows of BUF if needed"
|
||||||
(define-key map [?g] 'ledger-reconcile);
|
(define-key map [?g] 'ledger-reconcile);
|
||||||
(define-key map [?n] 'next-line)
|
(define-key map [?n] 'next-line)
|
||||||
(define-key map [?p] 'previous-line)
|
(define-key map [?p] 'previous-line)
|
||||||
|
(define-key map [?t] 'ledger-reconcile-change-target)
|
||||||
(define-key map [?s] 'ledger-reconcile-save)
|
(define-key map [?s] 'ledger-reconcile-save)
|
||||||
(define-key map [?q] 'ledger-reconcile-quit)
|
(define-key map [?q] 'ledger-reconcile-quit)
|
||||||
(define-key map [?b] 'ledger-display-balance)
|
(define-key map [?b] 'ledger-display-balance)
|
||||||
|
|
@ -376,6 +411,7 @@ Spliting the windows of BUF if needed"
|
||||||
(define-key map [menu-bar ldg-recon-menu tog] '("Toggle Entry" . ledger-reconcile-toggle))
|
(define-key map [menu-bar ldg-recon-menu tog] '("Toggle Entry" . ledger-reconcile-toggle))
|
||||||
(define-key map [menu-bar ldg-recon-menu sep3] '("--"))
|
(define-key map [menu-bar ldg-recon-menu sep3] '("--"))
|
||||||
(define-key map [menu-bar ldg-recon-menu bal] '("Show Cleared Balance" . ledger-display-balance))
|
(define-key map [menu-bar ldg-recon-menu bal] '("Show Cleared Balance" . ledger-display-balance))
|
||||||
|
(define-key map [menu-bar ldg-recon-menu tgt] '("Change Target Balance" . ledger-reconcile-change-target))
|
||||||
(define-key map [menu-bar ldg-recon-menu sep4] '("--"))
|
(define-key map [menu-bar ldg-recon-menu sep4] '("--"))
|
||||||
(define-key map [menu-bar ldg-recon-menu rna] '("Reconcile New Account" . ledger-reconcile))
|
(define-key map [menu-bar ldg-recon-menu rna] '("Reconcile New Account" . ledger-reconcile))
|
||||||
(define-key map [menu-bar ldg-recon-menu sep5] '("--"))
|
(define-key map [menu-bar ldg-recon-menu sep5] '("--"))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue