Changeset - af6e28d1680a
[Not reviewed]
0 2 0
Joar Wandborg - 10 years ago 2013-12-09 20:49:38
joar@wandborg.se
Use Amount objects, use the XML output in bal()
2 files changed with 62 insertions and 21 deletions:
0 comments (0 inline, 0 general)
accounting/__init__.py
Show inline comments
...
 
@@ -40,7 +40,6 @@ class Ledger:
 
                    _log.info('Waiting for one second... %d/%d', i, timeout)
 
                    time.sleep(1)
 

	
 

	
 
        process = self.get_process()
 

	
 
        self.locked = True
...
 
@@ -111,25 +110,45 @@ class Ledger:
 
            return output
 

	
 
    def bal(self):
 
        output = self.send_command('bal --format "%A|%t\\\\n"')
 
        output = self.send_command('xml')
 

	
 
        if output is None:
 
            raise RuntimeError('bal call returned no output')
 

	
 
        accounts = []
 

	
 
        for line in output.split(b'\n'):
 
            try:
 
                name, balance =  line.decode('utf8').split('|')
 
            except ValueError:
 
                continue
 
        xml = ElementTree.fromstring(output.decode('utf8'))
 

	
 
            accounts.append(Account(name=name, balance=balance))
 
        accounts = self._recurse_accounts(xml.find('./accounts'))
 

	
 
        return accounts
 

	
 
    def _recurse_accounts(self, root):
 
        accounts = []
 

	
 
        for account in root.findall('./account'):
 
            name = account.find('./fullname').text
 

	
 
            amounts = []
 

	
 
            account_amounts = account.findall('./account-total/balance/amount') or \
 
                    account.findall('./account-amount/amount')
 

	
 
            if account_amounts:
 
                for amount in account_amounts:
 
                    quantity = amount.find('./quantity').text
 
                    symbol = amount.find('./commodity/symbol').text
 

	
 
                    amounts.append(Amount(amount=quantity, symbol=symbol))
 

	
 
            accounts.append(Account(name=name,
 
                                    amounts=amounts,
 
                                    accounts=self._recurse_accounts(account)))
 

	
 
        return accounts
 

	
 
    def reg(self):
 
        output = self.send_command( 'xml')
 
        output = self.send_command('xml')
 

	
 
        if output is None:
 
            raise RuntimeError('reg call returned no output')
...
 
@@ -152,7 +171,8 @@ class Ledger:
 
                    './post-amount/amount/commodity/symbol').text
 

	
 
                postings.append(
 
                    Posting(account=account, amount=amount, symbol=symbol))
 
                    Posting(account=account,
 
                            amount=Amount(amount=amount, symbol=symbol)))
 

	
 
            entries.append(
 
                Transaction(date=date, payee=payee, postings=postings))
...
 
@@ -170,33 +190,44 @@ class Transaction:
 
        return ('<{self.__class__.__name__} {date}' +
 
                ' {self.payee} {self.postings}').format(
 
                    self=self,
 
                    date=self.date.isoformat())
 
                    date=self.date.strftime('%Y-%m-%d'))
 

	
 

	
 
class Posting:
 
    def __init__(self, account=None, amount=None, symbol=None):
 
    def __init__(self, account=None, amount=None):
 
        self.account = account
 
        self.amount = amount
 
        self.symbol = symbol
 

	
 
    def __repr__(self):
 
        return ('<{self.__class__.__name__} "{self.account}"' +
 
                ' {self.symbol} {self.amount}>').format(self=self)
 
                ' {self.amount}>').format(self=self)
 

	
 

	
 
class Amount:
 
    def __init__(self, amount=None, symbol=None):
 
        self.amount = amount
 
        self.symbol = symbol
 

	
 
    def __repr__(self):
 
        return ('<{self.__class__.__name__} {self.symbol}' +
 
                ' {self.amount}>').format(self=self)
 

	
 

	
 
class Account:
 
    def __init__(self, name=None, balance=None):
 
    def __init__(self, name=None, amounts=None, accounts=None):
 
        self.name = name
 
        self.balance = balance
 
        self.amounts = amounts
 
        self.accounts = accounts
 

	
 
    def __repr__(self):
 
        return '<{self.__class__.__name__}: "{self.name}" {self.balance} >'.format(
 
            self=self)
 
        return ('<{self.__class__.__name__} "{self.name}" {self.amounts}' +
 
                ' {self.accounts}>').format(self=self)
 

	
 

	
 
def main(argv=None):
 
    if argv is None:
 
        argv = sys.argv
 
    logging.basicConfig(level=logging.DEBUG)
 
    logging.basicConfig(level=logging.INFO)
 
    ledger = Ledger(ledger_file='non-profit-test-data.ledger')
 
    print(ledger.bal())
 
    print(ledger.reg())
accounting/web.py
Show inline comments
...
 
@@ -2,7 +2,7 @@ import logging
 

	
 
from flask import Flask, g, jsonify, json
 

	
 
from accounting import Ledger, Account, Posting, Transaction
 
from accounting import Ledger, Account, Posting, Transaction, Amount
 

	
 

	
 
logging.basicConfig(level=logging.DEBUG)
...
 
@@ -11,12 +11,14 @@ app.config.from_pyfile('config.py')
 

	
 
ledger = Ledger(ledger_file=app.config['LEDGER_FILE'])
 

	
 

	
 
class AccountingEncoder(json.JSONEncoder):
 
    def default(self, o):
 
        if isinstance(o, Account):
 
            return dict(
 
                name=o.name,
 
                balance=o.balance
 
                amounts=o.amounts,
 
                accounts=o.accounts
 
            )
 
        elif isinstance(o, Transaction):
 
            return dict(
...
 
@@ -28,23 +30,31 @@ class AccountingEncoder(json.JSONEncoder):
 
            return dict(
 
                account=o.account,
 
                amount=o.amount,
 
            )
 
        elif isinstance(o, Amount):
 
            return dict(
 
                amount=o.amount,
 
                symbol=o.symbol
 
            )
 

	
 
        return json.JSONEncoder.default(self, o)
 

	
 

	
 
app.json_encoder = AccountingEncoder
 

	
 

	
 
@app.route('/')
 
def index():
 
    return 'Hello World!'
 

	
 

	
 
@app.route('/balance')
 
def balance_report():
 
    report_data = ledger.bal()
 

	
 
    return jsonify(balance_report=report_data)
 

	
 

	
 
@app.route('/register')
 
def register_report():
 
    report_data = ledger.reg()
0 comments (0 inline, 0 general)