Centralise commodity tracking logic
Per Ledger behaviour, commodities considered equivalent if same name regardless of whether prefix or suffix Commodity display drawn from Ledger data, no longer explicitly specified in config
This commit is contained in:
parent
b200501e37
commit
3fa8f8a829
@ -1,7 +1,7 @@
|
|||||||
# Set up how we will call Ledger
|
# Set up how we will call Ledger
|
||||||
ledger_file: /path/to/ledger.journal
|
ledger_file: /path/to/ledger.journal
|
||||||
ledger_args: ['--pedantic', '--recursive-aliases']
|
ledger_args: ['--pedantic', '--recursive-aliases']
|
||||||
report_commodity: ['$', True] # True if prefix, False if suffix
|
report_commodity: '$'
|
||||||
|
|
||||||
# Tell ledger-pyreport about the top-level account categories
|
# Tell ledger-pyreport about the top-level account categories
|
||||||
assets_account: Assets
|
assets_account: Assets
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# Set up how we will call Ledger
|
# Set up how we will call Ledger
|
||||||
ledger_file: demo/ledger.journal
|
ledger_file: demo/ledger.journal
|
||||||
ledger_args: []
|
ledger_args: []
|
||||||
report_commodity: ['$', True] # True if prefix, False if suffix
|
report_commodity: '$'
|
||||||
|
|
||||||
# Tell ledger-pyreport about the top-level account categories
|
# Tell ledger-pyreport about the top-level account categories
|
||||||
assets_account: Assets
|
assets_account: Assets
|
||||||
|
@ -40,11 +40,10 @@ def trial():
|
|||||||
compare = int(flask.request.args['compare'])
|
compare = int(flask.request.args['compare'])
|
||||||
cash = flask.request.args.get('cash', False)
|
cash = flask.request.args.get('cash', False)
|
||||||
|
|
||||||
report_commodity = Commodity(*config['report_commodity'])
|
|
||||||
|
|
||||||
if compare == 0:
|
if compare == 0:
|
||||||
# Get trial balance
|
# Get trial balance
|
||||||
l = ledger.raw_transactions_at_date(date)
|
l = ledger.raw_transactions_at_date(date)
|
||||||
|
report_commodity = l.get_commodity(config['report_commodity'])
|
||||||
if cash:
|
if cash:
|
||||||
l = accounting.ledger_to_cash(l, report_commodity)
|
l = accounting.ledger_to_cash(l, report_commodity)
|
||||||
trial_balance = accounting.trial_balance(l, date, pstart, report_commodity)
|
trial_balance = accounting.trial_balance(l, date, pstart, report_commodity)
|
||||||
@ -67,6 +66,7 @@ def trial():
|
|||||||
pstarts = [pstart.replace(year=pstart.year - i) for i in range(0, compare + 1)]
|
pstarts = [pstart.replace(year=pstart.year - i) for i in range(0, compare + 1)]
|
||||||
|
|
||||||
l = ledger.raw_transactions_at_date(date)
|
l = ledger.raw_transactions_at_date(date)
|
||||||
|
report_commodity = l.get_commodity(config['report_commodity'])
|
||||||
if cash:
|
if cash:
|
||||||
l = accounting.ledger_to_cash(l, report_commodity)
|
l = accounting.ledger_to_cash(l, report_commodity)
|
||||||
trial_balances = [accounting.trial_balance(l.clone(), d, p, report_commodity) for d, p in zip(dates, pstarts)]
|
trial_balances = [accounting.trial_balance(l.clone(), d, p, report_commodity) for d, p in zip(dates, pstarts)]
|
||||||
@ -89,8 +89,8 @@ def balance():
|
|||||||
dates = [date.replace(year=date.year - i) for i in range(0, compare + 1)]
|
dates = [date.replace(year=date.year - i) for i in range(0, compare + 1)]
|
||||||
pstarts = [pstart.replace(year=pstart.year - i) for i in range(0, compare + 1)]
|
pstarts = [pstart.replace(year=pstart.year - i) for i in range(0, compare + 1)]
|
||||||
|
|
||||||
report_commodity = Commodity(*config['report_commodity'])
|
|
||||||
l = ledger.raw_transactions_at_date(date)
|
l = ledger.raw_transactions_at_date(date)
|
||||||
|
report_commodity = l.get_commodity(config['report_commodity'])
|
||||||
if cash:
|
if cash:
|
||||||
l = accounting.ledger_to_cash(l, report_commodity)
|
l = accounting.ledger_to_cash(l, report_commodity)
|
||||||
balance_sheets = [accounting.balance_sheet(accounting.trial_balance(l.clone(), d, p, report_commodity)) for d, p in zip(dates, pstarts)]
|
balance_sheets = [accounting.balance_sheet(accounting.trial_balance(l.clone(), d, p, report_commodity)) for d, p in zip(dates, pstarts)]
|
||||||
@ -122,8 +122,8 @@ def pandl():
|
|||||||
dates_beg = [date_beg.replace(year=date_beg.year - i) for i in range(0, compare + 1)]
|
dates_beg = [date_beg.replace(year=date_beg.year - i) for i in range(0, compare + 1)]
|
||||||
dates_end = [date_end.replace(year=date_end.year - i) for i in range(0, compare + 1)]
|
dates_end = [date_end.replace(year=date_end.year - i) for i in range(0, compare + 1)]
|
||||||
|
|
||||||
report_commodity = Commodity(*config['report_commodity'])
|
|
||||||
l = ledger.raw_transactions_at_date(date_end)
|
l = ledger.raw_transactions_at_date(date_end)
|
||||||
|
report_commodity = l.get_commodity(config['report_commodity'])
|
||||||
if cash:
|
if cash:
|
||||||
l = accounting.ledger_to_cash(l, report_commodity)
|
l = accounting.ledger_to_cash(l, report_commodity)
|
||||||
pandls = [accounting.trial_balance(l.clone(), de, db, report_commodity) for de, db in zip(dates_end, dates_beg)]
|
pandls = [accounting.trial_balance(l.clone(), de, db, report_commodity) for de, db in zip(dates_end, dates_beg)]
|
||||||
@ -146,8 +146,8 @@ def cashflow():
|
|||||||
dates_beg = [date_beg.replace(year=date_beg.year - i) for i in range(0, compare + 1)]
|
dates_beg = [date_beg.replace(year=date_beg.year - i) for i in range(0, compare + 1)]
|
||||||
dates_end = [date_end.replace(year=date_end.year - i) for i in range(0, compare + 1)]
|
dates_end = [date_end.replace(year=date_end.year - i) for i in range(0, compare + 1)]
|
||||||
|
|
||||||
report_commodity = Commodity(*config['report_commodity'])
|
|
||||||
l = ledger.raw_transactions_at_date(date_end)
|
l = ledger.raw_transactions_at_date(date_end)
|
||||||
|
report_commodity = l.get_commodity(config['report_commodity'])
|
||||||
|
|
||||||
cash_accounts = [a for a in l.accounts.values() if a.is_cash]
|
cash_accounts = [a for a in l.accounts.values() if a.is_cash]
|
||||||
|
|
||||||
@ -193,10 +193,9 @@ def transactions():
|
|||||||
cash = flask.request.args.get('cash', False)
|
cash = flask.request.args.get('cash', False)
|
||||||
commodity = flask.request.args.get('commodity', False)
|
commodity = flask.request.args.get('commodity', False)
|
||||||
|
|
||||||
report_commodity = Commodity(*config['report_commodity'])
|
|
||||||
|
|
||||||
# General ledger
|
# General ledger
|
||||||
l = ledger.raw_transactions_at_date(date_end)
|
l = ledger.raw_transactions_at_date(date_end)
|
||||||
|
report_commodity = l.get_commodity(config['report_commodity'])
|
||||||
if cash:
|
if cash:
|
||||||
l = accounting.ledger_to_cash(l, report_commodity)
|
l = accounting.ledger_to_cash(l, report_commodity)
|
||||||
|
|
||||||
@ -240,10 +239,9 @@ def transaction():
|
|||||||
cash = flask.request.args.get('cash', False)
|
cash = flask.request.args.get('cash', False)
|
||||||
commodity = flask.request.args.get('commodity', False)
|
commodity = flask.request.args.get('commodity', False)
|
||||||
|
|
||||||
report_commodity = Commodity(*config['report_commodity'])
|
|
||||||
|
|
||||||
# General ledger
|
# General ledger
|
||||||
l = ledger.raw_transactions_at_date(None)
|
l = ledger.raw_transactions_at_date(None)
|
||||||
|
report_commodity = l.get_commodity(config['report_commodity'])
|
||||||
if cash:
|
if cash:
|
||||||
l = accounting.ledger_to_cash(l, report_commodity)
|
l = accounting.ledger_to_cash(l, report_commodity)
|
||||||
|
|
||||||
@ -326,9 +324,8 @@ def debug_noncash_transactions():
|
|||||||
pstart = datetime.strptime(flask.request.args['pstart'], '%Y-%m-%d')
|
pstart = datetime.strptime(flask.request.args['pstart'], '%Y-%m-%d')
|
||||||
account = flask.request.args.get('account')
|
account = flask.request.args.get('account')
|
||||||
|
|
||||||
report_commodity = Commodity(*config['report_commodity'])
|
|
||||||
|
|
||||||
l = ledger.raw_transactions_at_date(date)
|
l = ledger.raw_transactions_at_date(date)
|
||||||
|
report_commodity = l.get_commodity(config['report_commodity'])
|
||||||
account = l.get_account(account)
|
account = l.get_account(account)
|
||||||
|
|
||||||
transactions = [t for t in l.transactions if any(p.account == account for p in t.postings)]
|
transactions = [t for t in l.transactions if any(p.account == account for p in t.postings)]
|
||||||
@ -343,9 +340,8 @@ def debug_imbalances():
|
|||||||
pstart = datetime.strptime(flask.request.args['pstart'], '%Y-%m-%d')
|
pstart = datetime.strptime(flask.request.args['pstart'], '%Y-%m-%d')
|
||||||
cash = flask.request.args.get('cash', False)
|
cash = flask.request.args.get('cash', False)
|
||||||
|
|
||||||
report_commodity = Commodity(*config['report_commodity'])
|
|
||||||
|
|
||||||
l = ledger.raw_transactions_at_date(date)
|
l = ledger.raw_transactions_at_date(date)
|
||||||
|
report_commodity = l.get_commodity(config['report_commodity'])
|
||||||
if cash:
|
if cash:
|
||||||
l = accounting.ledger_to_cash(l, report_commodity)
|
l = accounting.ledger_to_cash(l, report_commodity)
|
||||||
|
|
||||||
|
@ -104,7 +104,11 @@ def raw_transactions_at_date(date):
|
|||||||
if ';' in comment:
|
if ';' in comment:
|
||||||
comment = comment[comment.index(';')+1:].strip()
|
comment = comment[comment.index(';')+1:].strip()
|
||||||
|
|
||||||
posting = Posting(transaction, ledger.get_account(account_str), parse_amount(amount_str), comment=comment)
|
amount = parse_amount(amount_str)
|
||||||
|
posting = Posting(transaction, ledger.get_account(account_str), amount, comment=comment)
|
||||||
transaction.postings.append(posting)
|
transaction.postings.append(posting)
|
||||||
|
|
||||||
|
if amount.commodity.name not in ledger.commodities:
|
||||||
|
ledger.commodities[amount.commodity.name] = amount.commodity.strip_price()
|
||||||
|
|
||||||
return ledger
|
return ledger
|
||||||
|
@ -27,6 +27,7 @@ class Ledger:
|
|||||||
self.accounts = {}
|
self.accounts = {}
|
||||||
self.transactions = []
|
self.transactions = []
|
||||||
|
|
||||||
|
self.commodities = {}
|
||||||
self.prices = []
|
self.prices = []
|
||||||
|
|
||||||
def clone(self):
|
def clone(self):
|
||||||
@ -51,6 +52,9 @@ class Ledger:
|
|||||||
|
|
||||||
return account
|
return account
|
||||||
|
|
||||||
|
def get_commodity(self, name):
|
||||||
|
return self.commodities[name]
|
||||||
|
|
||||||
def get_price(self, commodity_from, commodity_to, date):
|
def get_price(self, commodity_from, commodity_to, date):
|
||||||
prices = [p for p in self.prices if p[1] == commodity_from.name and p[2].commodity == commodity_to and p[0].date() <= date.date()]
|
prices = [p for p in self.prices if p[1] == commodity_from.name and p[2].commodity == commodity_to and p[0].date() <= date.date()]
|
||||||
|
|
||||||
@ -89,7 +93,7 @@ class Posting:
|
|||||||
return '<Posting "{}" {}>'.format(self.account.name, self.amount.tostr(False))
|
return '<Posting "{}" {}>'.format(self.account.name, self.amount.tostr(False))
|
||||||
|
|
||||||
def exchange(self, commodity, date):
|
def exchange(self, commodity, date):
|
||||||
if self.amount.commodity.name == commodity.name and self.amount.commodity.is_prefix == commodity.is_prefix:
|
if self.amount.commodity.name == commodity.name:
|
||||||
return Amount(self.amount)
|
return Amount(self.amount)
|
||||||
|
|
||||||
return self.amount.exchange(commodity, True) # Cost basis
|
return self.amount.exchange(commodity, True) # Cost basis
|
||||||
@ -235,10 +239,10 @@ class Amount:
|
|||||||
return Amount(other - self.amount, self.commodity)
|
return Amount(other - self.amount, self.commodity)
|
||||||
|
|
||||||
def exchange(self, commodity, is_cost, price=None):
|
def exchange(self, commodity, is_cost, price=None):
|
||||||
if self.commodity.name == commodity.name and self.commodity.is_prefix == commodity.is_prefix:
|
if self.commodity.name == commodity.name:
|
||||||
return Amount(self)
|
return Amount(self)
|
||||||
|
|
||||||
if is_cost and self.commodity.price and self.commodity.price.commodity.name == commodity.name and self.commodity.price.commodity.is_prefix == commodity.is_prefix:
|
if is_cost and self.commodity.price and self.commodity.price.commodity.name == commodity.name:
|
||||||
return Amount(self.amount * self.commodity.price.amount, commodity)
|
return Amount(self.amount * self.commodity.price.amount, commodity)
|
||||||
|
|
||||||
if price:
|
if price:
|
||||||
@ -268,7 +272,7 @@ class Balance:
|
|||||||
def exchange(self, commodity, is_cost, date=None, ledger=None):
|
def exchange(self, commodity, is_cost, date=None, ledger=None):
|
||||||
result = Amount(0, commodity)
|
result = Amount(0, commodity)
|
||||||
for amount in self.amounts:
|
for amount in self.amounts:
|
||||||
if is_cost or (amount.commodity.name == commodity.name and amount.commodity.is_prefix == amount.commodity.is_prefix):
|
if is_cost or amount.commodity.name == commodity.name:
|
||||||
result += amount.exchange(commodity, is_cost)
|
result += amount.exchange(commodity, is_cost)
|
||||||
else:
|
else:
|
||||||
if any(p[1] == amount.commodity.name for p in ledger.prices):
|
if any(p[1] == amount.commodity.name for p in ledger.prices):
|
||||||
@ -338,7 +342,10 @@ class Commodity:
|
|||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not isinstance(other, Commodity):
|
if not isinstance(other, Commodity):
|
||||||
return False
|
return False
|
||||||
return self.name == other.name and self.is_prefix == other.is_prefix and self.price == other.price
|
return self.name == other.name and self.price == other.price
|
||||||
|
|
||||||
|
def strip_price(self):
|
||||||
|
return Commodity(self.name, self.is_prefix)
|
||||||
|
|
||||||
class TrialBalance:
|
class TrialBalance:
|
||||||
def __init__(self, ledger, date, pstart):
|
def __init__(self, ledger, date, pstart):
|
||||||
|
Reference in New Issue
Block a user