*** empty log message ***

This commit is contained in:
John Wiegley 2004-04-04 23:59:20 +00:00
parent f672024e06
commit 42a1c03968
4 changed files with 69 additions and 34 deletions

View file

@ -229,21 +229,25 @@ amount * gmp_amount::street(bool get_quotes) const
int max = 10; int max = 10;
while (--max >= 0) { while (--max >= 0) {
if (! amt->commdty()->price) { if (! amt->commdty()->price && ! amt->commdty()->sought) {
if (get_quotes) if (get_quotes)
get_commodity_price(amt->commdty()); get_commodity_price(amt->commdty());
amt->commdty()->sought = true;
if (! amt->commdty()->price) if (! amt->commdty()->price)
break; break;
} }
amount * old = amt; amount * old = amt;
amt = amt->value(amt->commdty()->price); amt = amt->value(amt->commdty()->price);
delete old;
if (amt->commdty() == old->commdty()) if (amt->commdty() == old->commdty()) {
delete old;
break; break;
} }
delete old;
}
return amt; return amt;
} }

View file

@ -37,6 +37,15 @@
(defvar ledger-version "1.1" (defvar ledger-version "1.1"
"The version of ledger.el currently loaded") "The version of ledger.el currently loaded")
(defgroup ledger nil
"Interface to the Ledger command-line accounting program."
:group 'data)
(defcustom ledger-binary-path (executable-find "ledger")
"Path to the ledger executable."
:type 'file
:group 'ledger)
(defun ledger-iterate-entries (callback) (defun ledger-iterate-entries (callback)
(goto-char (point-min)) (goto-char (point-min))
(let* ((now (current-time)) (let* ((now (current-time))
@ -87,7 +96,7 @@
(insert (insert
(with-temp-buffer (with-temp-buffer
(setq exit-code (setq exit-code
(apply 'call-process "/home/johnw/bin/ledger" nil t nil (apply 'call-process ledger-binary-path nil t nil
(cons "entry" args))) (cons "entry" args)))
(if (= 0 exit-code) (if (= 0 exit-code)
(buffer-substring (+ (point-min) 5) (point-max)) (buffer-substring (+ (point-min) 5) (point-max))
@ -123,15 +132,13 @@
(define-key map [(control ?c) (control ?a)] 'ledger-add-entry) (define-key map [(control ?c) (control ?a)] 'ledger-add-entry)
(define-key map [(control ?c) (control ?c)] 'ledger-toggle-current))) (define-key map [(control ?c) (control ?c)] 'ledger-toggle-current)))
(defun ledger-parse-entries (account &optional all-p) (defun ledger-parse-entries (account &optional all-p after-date)
;; `then' is 45 days ago (let (total entries)
(let ((then (time-subtract (current-time)
(seconds-to-time (* 45 24 60 60))))
total entries)
(ledger-iterate-entries (ledger-iterate-entries
(function (function
(lambda (start date mark desc) (lambda (start date mark desc)
(when (or all-p (not mark) (time-less-p then date)) (when (and (or all-p (not mark))
(time-less-p after-date date))
(forward-line) (forward-line)
(setq total 0.0) (setq total 0.0)
(while (looking-at (while (looking-at
@ -148,53 +155,76 @@
mark date desc (or amt total)) mark date desc (or amt total))
entries)))) entries))))
(forward-line)))))) (forward-line))))))
(nreverse entries))) entries))
(define-derived-mode ledger-reconcile-mode text-mode "Reconcile" (defvar ledger-reconcile-text "Reconcile")
(define-derived-mode ledger-reconcile-mode text-mode 'ledger-reconcile-text
"A mode for reconciling ledger entries." "A mode for reconciling ledger entries."
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map [? ] 'ledger-reconcile-toggle) (define-key map [? ] 'ledger-reconcile-toggle)
(use-local-map map))) (use-local-map map)))
(add-to-list 'minor-mode-alist
'(ledger-reconcile-mode ledger-reconcile-text))
(defvar ledger-buf nil) (defvar ledger-buf nil)
(make-variable-buffer-local 'ledger-buf) (defvar ledger-acct nil)
(defun ledger-reconcile-toggle () (defun ledger-reconcile-toggle ()
(interactive) (interactive)
(let ((where (get-text-property (point) 'where)) (let ((where (get-text-property (point) 'where))
(account ledger-acct)
cleared) cleared)
(with-current-buffer ledger-buf (with-current-buffer ledger-buf
(goto-char where) (goto-char where)
(setq cleared (ledger-toggle-current))) (setq cleared (ledger-toggle-current))
(save-buffer))
(if cleared (if cleared
(add-text-properties (line-beginning-position) (add-text-properties (line-beginning-position)
(line-end-position) (line-end-position)
(list 'face 'bold)) (list 'face 'bold))
(remove-text-properties (line-beginning-position) (remove-text-properties (line-beginning-position)
(line-end-position) (line-end-position)
(list 'face))))) (list 'face)))
(with-temp-buffer
(let ((exit-code
(apply 'call-process ledger-binary-path nil t nil
(list "-C" "balance" account))))
(if (/= 0 exit-code)
(setq ledger-reconcile-text "Reconcile [ERR]")
(goto-char (point-min))
(delete-horizontal-space)
(skip-syntax-forward "^ ")
(setq ledger-reconcile-text
(concat "Reconcile ["
(buffer-substring-no-properties (point-min) (point))
"]")))))))
(defun ledger-reconcile (account) (defun ledger-reconcile (account)
(interactive "sAccount to reconcile: ") (interactive "sAccount to reconcile: ")
(let ((items (save-excursion (let* ((then (time-subtract (current-time)
(seconds-to-time (* 90 24 60 60))))
(items (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(ledger-parse-entries account))) (ledger-parse-entries account t then)))
(buf (current-buffer))) (buf (current-buffer)))
(pop-to-buffer (generate-new-buffer "*Reconcile*")) (pop-to-buffer (generate-new-buffer "*Reconcile*"))
(ledger-reconcile-mode) (ledger-reconcile-mode)
(setq ledger-buf buf) (set (make-local-variable 'ledger-buf) buf)
(set (make-local-variable 'ledger-acct) account)
(dolist (item items) (dolist (item items)
(let ((beg (point))) (let ((beg (point)))
(insert (format "%s %-30s %8.2f\n" (insert (format "%s %-30s %8.2f\n"
(format-time-string "%Y.%m.%d" (nth 2 item)) (format-time-string "%Y/%m/%d" (nth 2 item))
(nth 3 item) (nth 4 item))) (nth 3 item) (nth 4 item)))
(if (nth 1 item) (if (nth 1 item)
(set-text-properties beg (1- (point)) (set-text-properties beg (1- (point))
(list 'face 'bold (list 'face 'bold
'where (nth 0 item))) 'where (nth 0 item)))
(set-text-properties beg (1- (point)) (set-text-properties beg (1- (point))
(list 'where (nth 0 item)))))) (list 'where (nth 0 item)))))
(goto-char (point-min)))) (goto-char (point-min)))))
(provide 'ledger) (provide 'ledger)

View file

@ -1,5 +1,5 @@
#ifndef _LEDGER_H #ifndef _LEDGER_H
#define _LEDGER_H "$Revision: 1.28 $" #define _LEDGER_H "$Revision: 1.29 $"
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// //
@ -40,6 +40,7 @@ class commodity
std::string symbol; std::string symbol;
mutable amount * price; // the current price mutable amount * price; // the current price
mutable bool sought;
bool prefix; bool prefix;
bool separate; bool separate;
@ -48,8 +49,8 @@ class commodity
int precision; int precision;
explicit commodity() : price(NULL), prefix(false), separate(true), explicit commodity() : price(NULL), sought(false),
thousands(false), european(false) {} prefix(false), separate(true), thousands(false), european(false) {}
explicit commodity(const std::string& sym, bool pre = false, explicit commodity(const std::string& sym, bool pre = false,
bool sep = true, bool thou = true, bool sep = true, bool thou = true,
@ -298,7 +299,7 @@ extern book * main_ledger;
inline commodity::commodity(const std::string& sym, bool pre, bool sep, inline commodity::commodity(const std::string& sym, bool pre, bool sep,
bool thou, bool euro, int prec) bool thou, bool euro, int prec)
: symbol(sym), price(NULL), prefix(pre), separate(sep), : symbol(sym), price(NULL), sought(false), prefix(pre), separate(sep),
thousands(thou), european(euro), precision(prec) { thousands(thou), european(euro), precision(prec) {
#ifdef DEBUG #ifdef DEBUG
std::pair<commodities_map_iterator, bool> result = std::pair<commodities_map_iterator, bool> result =

View file

@ -1,13 +1,13 @@
#include "ledger.h" #include "ledger.h"
#define LEDGER_VERSION "1.2" #define LEDGER_VERSION "1.3"
#include <fstream> #include <fstream>
#include <unistd.h> #include <unistd.h>
namespace ledger { namespace ledger {
static bool show_cleared = false; static bool cleared_only = false;
static bool show_virtual = true; static bool show_virtual = true;
static bool get_quotes = false; static bool get_quotes = false;
static bool show_children = false; static bool show_children = false;
@ -105,7 +105,7 @@ void report_balances(std::ostream& out, regexps_map& regexps)
for (entries_list_iterator i = main_ledger->entries.begin(); for (entries_list_iterator i = main_ledger->entries.begin();
i != main_ledger->entries.end(); i != main_ledger->entries.end();
i++) { i++) {
if ((show_cleared && ! (*i)->cleared) || ! matches_date_range(*i)) if ((cleared_only && ! (*i)->cleared) || ! matches_date_range(*i))
continue; continue;
for (std::list<transaction *>::iterator x = (*i)->xacts.begin(); for (std::list<transaction *>::iterator x = (*i)->xacts.begin();
@ -203,7 +203,7 @@ void print_register(const std::string& acct_name, std::ostream& out,
i != main_ledger->entries.end(); i != main_ledger->entries.end();
i++) { i++) {
if ((! have_beginning && ! have_ending && ! have_date_mask && if ((! have_beginning && ! have_ending && ! have_date_mask &&
! show_cleared && (*i)->cleared) || ! (cleared_only ? (*i)->cleared : ! (*i)->cleared)) ||
! matches_date_range(*i) || ! (*i)->matches(regexps)) ! matches_date_range(*i) || ! (*i)->matches(regexps))
continue; continue;
@ -374,7 +374,7 @@ void add_new_entry(int index, int argc, char **argv)
std::exit(1); std::exit(1);
} }
added.cleared = show_cleared; added.cleared = cleared_only;
if (index == argc) { if (index == argc) {
std::cerr << "Error: Too few arguments to 'entry'." << std::endl; std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
@ -591,7 +591,7 @@ int main(int argc, char * argv[])
case 'h': show_help(std::cout); break; case 'h': show_help(std::cout); break;
case 'f': file = new std::ifstream(optarg); break; case 'f': file = new std::ifstream(optarg); break;
case 'C': show_cleared = true; break; case 'C': cleared_only = true; break;
case 'R': show_virtual = false; break; case 'R': show_virtual = false; break;
case 's': show_children = true; break; case 's': show_children = true; break;
case 'S': show_sorted = true; break; case 'S': show_sorted = true; break;
@ -718,7 +718,7 @@ int main(int argc, char * argv[])
else if (command == "print") { else if (command == "print") {
if (show_sorted) if (show_sorted)
main_ledger->sort(cmp_entry_date()); main_ledger->sort(cmp_entry_date());
main_ledger->print(std::cout, regexps, true); main_ledger->print(std::cout, regexps, ! full_names);
} }
else if (command == "equity") { else if (command == "equity") {
equity_ledger(std::cout, regexps); equity_ledger(std::cout, regexps);