import argparse import csv from decimal import Decimal, getcontext, ROUND_UP import simplejson as json ACCOUNT_LEDGER_PRECISION = Decimal('0.01') getcontext().prec = 18 def _format_ledger_account_entry(event_id, ledger_params): return { 'abacus_event_id': event_id, 'account_id': ledger_params.get('account_id'), 'contract_id': ledger_params.get('contract_id'), 'currency_amount': ledger_params.get('account_ledger_amount'), 'currency_code': ledger_params.get('currency_code'), 'model_type': 'account' } def _format_ledger_deposit_entry(event_id, ledger_params): """Format ledger_deposit params. Return a dict. Args: ledger_params (dict): shared ledger parameters Returns: A dict of formatted ledger_deposit entries. """ return { 'abacus_event_id': event_id, 'account_id': ledger_params.get('account_id'), 'contract_id': ledger_params.get('contract_id'), 'currency_code': ledger_params.get('currency_code'), 'model_type': 'deposit', 'remaining_amount': ledger_params.get('remainder'), 'rounded_amount': ledger_params.get('rounded_amount') } def _breakdown_amount(base_amount): """Convert amount to ledger, rounded, and remainder amounts.""" rounded_amount = base_amount.quantize( ACCOUNT_LEDGER_PRECISION, rounding=ROUND_UP ) remainder = base_amount - rounded_amount account_ledger_amount = rounded_amount return { 'account_ledger_amount': account_ledger_amount, 'remainder': remainder, 'rounded_amount': rounded_amount } parser = argparse.ArgumentParser( description='Generate account and deposit entries for bulk ledgers request') parser.add_argument('event', type=int, help='abacus_event_id for ledger entries') parser.add_argument('file', type=argparse.FileType('r'), help='path to csv file (see test_data.csv for example)') args = parser.parse_args() amounts = [] amount_reader = csv.DictReader(args.file, delimiter=',') for row in amount_reader: amounts.append(row) entries = [] for amount in amounts: base_amount = Decimal(amount.get('AMOUNT')) ledger_params = _breakdown_amount(base_amount) ledger_params.update({ 'account_id': int(amount.get('ACCOUNT_ID')), 'contract_id': int(amount.get('CONTRACT_ID')), 'currency_code': amount.get('CURRENCY_CODE'), }) if ledger_params['rounded_amount'] != Decimal(0.00): entries.append(_format_ledger_account_entry(args.event, ledger_params)) if ledger_params['remainder'] != Decimal(0.00): entries.append(_format_ledger_deposit_entry(args.event, ledger_params)) # In case John needs you to dump out the same file but with rounded numbers: # print(f"{int(amount.get('ACCOUNT_ID'))},{int(amount.get('CONTRACT_ID'))},{ledger_params['account_ledger_amount']},{amount.get('CURRENCY_CODE')}") print(json.dumps(entries, indent=4))