Use Amount objects, use the XML output in bal()
This commit is contained in:
		
							parent
							
								
									dd260aa021
								
							
						
					
					
						commit
						af6e28d168
					
				
					 2 changed files with 62 additions and 21 deletions
				
			
		|  | @ -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,20 +110,40 @@ 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 | ||||
| 
 | ||||
|  | @ -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 | ||||
| 
 | ||||
|     def __repr__(self): | ||||
|         return ('<{self.__class__.__name__} "{self.account}"' + | ||||
|                 ' {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.account}"' + | ||||
|                 ' {self.symbol} {self.amount}>').format(self=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()) | ||||
|  |  | |||
|  | @ -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() | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Joar Wandborg
						Joar Wandborg