Refactored accounting.client
This commit is contained in:
parent
032175cd26
commit
f0a5db5a29
2 changed files with 89 additions and 58 deletions
|
@ -11,55 +11,60 @@ import requests
|
||||||
from accounting.models import Transaction, Posting, Amount
|
from accounting.models import Transaction, Posting, Amount
|
||||||
from accounting.transport import AccountingDecoder, AccountingEncoder
|
from accounting.transport import AccountingDecoder, AccountingEncoder
|
||||||
|
|
||||||
# TODO: Client should be a class
|
_log = logging.getLogger(__name__)
|
||||||
|
|
||||||
HOST = None
|
|
||||||
|
|
||||||
|
|
||||||
def insert_paypal_transaction(amount):
|
class Client:
|
||||||
|
def __init__(self, host=None, json_encoder=None,
|
||||||
|
json_decoder=None):
|
||||||
|
self.host = host or 'http://localhost:5000'
|
||||||
|
self.json_encoder = json_encoder or AccountingEncoder
|
||||||
|
self.json_decoder = json_decoder or AccountingDecoder
|
||||||
|
|
||||||
|
def get_balance(self):
|
||||||
|
balance = self.get('/balance')
|
||||||
|
return balance['balance_report']
|
||||||
|
|
||||||
|
def get(self, path):
|
||||||
|
response = requests.get(self.host + path)
|
||||||
|
|
||||||
|
return self._decode_response(response)
|
||||||
|
|
||||||
|
def _decode_response(self, response):
|
||||||
|
response_data = response.json(cls=self.json_decoder)
|
||||||
|
|
||||||
|
_log.debug('response_data: %s', response_data)
|
||||||
|
|
||||||
|
return response_data
|
||||||
|
|
||||||
|
def post(self, path, payload, **kw):
|
||||||
|
kw.update({'headers': {'Content-Type': 'application/json'}})
|
||||||
|
kw.update({'data': json.dumps(payload, cls=self.json_encoder)})
|
||||||
|
|
||||||
|
return self._decode_response(requests.post(self.host + path, **kw))
|
||||||
|
|
||||||
|
def simple_transaction(self, from_acc, to_acc, amount):
|
||||||
t = Transaction(
|
t = Transaction(
|
||||||
date=datetime.today(),
|
date=datetime.today(),
|
||||||
payee='PayPal donation',
|
payee='PayPal donation',
|
||||||
postings=[
|
postings=[
|
||||||
Posting(account='Income:Donations:PayPal',
|
Posting(account=from_acc,
|
||||||
amount=Amount(symbol='$', amount=-amount)),
|
amount=Amount(symbol='$', amount=-amount)),
|
||||||
Posting(account='Assets:Checking',
|
Posting(account=to_acc,
|
||||||
amount=Amount(symbol='$', amount=amount))
|
amount=Amount(symbol='$', amount=amount))
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
response = requests.post(HOST + '/transaction',
|
return self.post('/transaction', {'transactions': [t]})
|
||||||
headers={'Content-Type': 'application/json'},
|
|
||||||
data=json.dumps({'transactions': [t]},
|
|
||||||
cls=AccountingEncoder))
|
|
||||||
|
|
||||||
print(response.json(cls=AccountingDecoder))
|
def get_register(self):
|
||||||
|
register = self.get('/register')
|
||||||
|
|
||||||
|
return register['register_report']
|
||||||
|
|
||||||
|
|
||||||
def get_balance():
|
def print_transactions(transactions):
|
||||||
response = requests.get(HOST + '/balance')
|
for transaction in transactions:
|
||||||
|
|
||||||
balance = response.json(cls=AccountingDecoder)
|
|
||||||
|
|
||||||
_recurse_accounts(balance['balance_report'])
|
|
||||||
|
|
||||||
|
|
||||||
def _recurse_accounts(accounts, level=0):
|
|
||||||
for account in accounts:
|
|
||||||
print(' ' * level + ' + {account.name}'.format(account=account) +
|
|
||||||
' ' + '-' * (80 - len(str(account.name)) - level))
|
|
||||||
for amount in account.amounts:
|
|
||||||
print(' ' * level + ' {amount.symbol} {amount.amount}'.format(
|
|
||||||
amount=amount))
|
|
||||||
_recurse_accounts(account.accounts, level+1)
|
|
||||||
|
|
||||||
|
|
||||||
def get_register():
|
|
||||||
response = requests.get(HOST + '/register')
|
|
||||||
|
|
||||||
register = response.json(cls=AccountingDecoder)
|
|
||||||
|
|
||||||
for transaction in register['register_report']:
|
|
||||||
print('{date} {t.payee:.<69}'.format(
|
print('{date} {t.payee:.<69}'.format(
|
||||||
date=transaction.date.strftime('%Y-%m-%d'),
|
date=transaction.date.strftime('%Y-%m-%d'),
|
||||||
t=transaction))
|
t=transaction))
|
||||||
|
@ -71,6 +76,16 @@ def get_register():
|
||||||
posting.amount.symbol + ' ' + str(posting.amount.amount))
|
posting.amount.symbol + ' ' + str(posting.amount.amount))
|
||||||
|
|
||||||
|
|
||||||
|
def print_balance_accounts(accounts, level=0):
|
||||||
|
for account in accounts:
|
||||||
|
print(' ' * level + ' + {account.name}'.format(account=account) +
|
||||||
|
' ' + '-' * (80 - len(str(account.name)) - level))
|
||||||
|
for amount in account.amounts:
|
||||||
|
print(' ' * level + ' {amount.symbol} {amount.amount}'.format(
|
||||||
|
amount=amount))
|
||||||
|
print_balance_accounts(account.accounts, level+1)
|
||||||
|
|
||||||
|
|
||||||
def main(argv=None, prog=None):
|
def main(argv=None, prog=None):
|
||||||
global HOST
|
global HOST
|
||||||
if argv is None:
|
if argv is None:
|
||||||
|
@ -78,26 +93,39 @@ def main(argv=None, prog=None):
|
||||||
argv = sys.argv[1:]
|
argv = sys.argv[1:]
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(prog=prog)
|
parser = argparse.ArgumentParser(prog=prog)
|
||||||
parser.add_argument('-p', '--paypal', type=Decimal)
|
actions = parser.add_subparsers(title='Actions', dest='action')
|
||||||
parser.add_argument('-b', '--balance', action='store_true')
|
|
||||||
parser.add_argument('-r', '--register', action='store_true')
|
insert = actions.add_parser('insert',
|
||||||
|
aliases=['in'])
|
||||||
|
insert.add_argument('from_account')
|
||||||
|
insert.add_argument('to_account')
|
||||||
|
insert.add_argument('amount', type=Decimal)
|
||||||
|
|
||||||
|
balance = actions.add_parser('balance', aliases=['bal'])
|
||||||
|
|
||||||
|
register = actions.add_parser('register', aliases=['reg'])
|
||||||
|
|
||||||
parser.add_argument('-v', '--verbosity',
|
parser.add_argument('-v', '--verbosity',
|
||||||
default='WARNING',
|
default='WARNING',
|
||||||
help=('Filter logging output. Possible values:' +
|
help=('Filter logging output. Possible values:' +
|
||||||
' CRITICAL, ERROR, WARNING, INFO, DEBUG'))
|
' CRITICAL, ERROR, WARNING, INFO, DEBUG'))
|
||||||
parser.add_argument('--host', default='http://localhost:5000')
|
parser.add_argument('--host', default='http://localhost:5000')
|
||||||
args = parser.parse_args(argv)
|
|
||||||
|
|
||||||
HOST = args.host
|
args = parser.parse_args(argv)
|
||||||
|
|
||||||
logging.basicConfig(level=getattr(logging, args.verbosity))
|
logging.basicConfig(level=getattr(logging, args.verbosity))
|
||||||
|
|
||||||
if args.paypal:
|
client = Client(args.host)
|
||||||
insert_paypal_transaction(args.paypal)
|
|
||||||
elif args.balance:
|
if args.action in ['insert', 'in']:
|
||||||
get_balance()
|
print(client.simple_transaction(args.from_account, args.to_account,
|
||||||
elif args.register:
|
args.amount))
|
||||||
get_register()
|
elif args.action in ['balance', 'bal']:
|
||||||
|
print_balance_accounts(client.get_balance())
|
||||||
|
elif args.action in ['register', 'reg']:
|
||||||
|
print_transactions(client.get_register())
|
||||||
|
else:
|
||||||
|
parser.print_help()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
|
@ -33,10 +33,13 @@ def balance_report():
|
||||||
|
|
||||||
return jsonify(balance_report=report_data)
|
return jsonify(balance_report=report_data)
|
||||||
|
|
||||||
|
@app.route('/transaction', methods=['GET'])
|
||||||
|
def transaction_get():
|
||||||
|
return jsonify(transactions=ledger.reg())
|
||||||
|
|
||||||
@app.route('/transaction', methods=['POST'])
|
@app.route('/transaction', methods=['POST'])
|
||||||
@jsonify_exceptions
|
@jsonify_exceptions
|
||||||
def transaction():
|
def transaction_post():
|
||||||
'''
|
'''
|
||||||
REST/JSON endpoint for transactions.
|
REST/JSON endpoint for transactions.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue