diff --git a/config.example.yml b/config.example.yml index 3c44fc2..2c92c9b 100644 --- a/config.example.yml +++ b/config.example.yml @@ -1,7 +1,7 @@ # Set up how we will call Ledger ledger_file: /path/to/ledger.journal 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 assets_account: Assets diff --git a/demo/config.yml b/demo/config.yml index 98e5a26..16eae18 100644 --- a/demo/config.yml +++ b/demo/config.yml @@ -1,7 +1,7 @@ # Set up how we will call Ledger ledger_file: demo/ledger.journal ledger_args: [] -report_commodity: ['$', True] # True if prefix, False if suffix +report_commodity: '$' # Tell ledger-pyreport about the top-level account categories assets_account: Assets diff --git a/ledger_pyreport/__init__.py b/ledger_pyreport/__init__.py index bc43202..b649fb5 100644 --- a/ledger_pyreport/__init__.py +++ b/ledger_pyreport/__init__.py @@ -40,11 +40,10 @@ def trial(): compare = int(flask.request.args['compare']) cash = flask.request.args.get('cash', False) - report_commodity = Commodity(*config['report_commodity']) - if compare == 0: # Get trial balance l = ledger.raw_transactions_at_date(date) + report_commodity = l.get_commodity(config['report_commodity']) if cash: l = accounting.ledger_to_cash(l, 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)] l = ledger.raw_transactions_at_date(date) + report_commodity = l.get_commodity(config['report_commodity']) if cash: 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)] @@ -89,8 +89,8 @@ def balance(): 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)] - report_commodity = Commodity(*config['report_commodity']) l = ledger.raw_transactions_at_date(date) + report_commodity = l.get_commodity(config['report_commodity']) if cash: 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)] @@ -122,8 +122,8 @@ def pandl(): 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)] - report_commodity = Commodity(*config['report_commodity']) l = ledger.raw_transactions_at_date(date_end) + report_commodity = l.get_commodity(config['report_commodity']) if cash: 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)] @@ -146,8 +146,8 @@ def cashflow(): 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)] - report_commodity = Commodity(*config['report_commodity']) 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] @@ -193,10 +193,9 @@ def transactions(): cash = flask.request.args.get('cash', False) commodity = flask.request.args.get('commodity', False) - report_commodity = Commodity(*config['report_commodity']) - # General ledger l = ledger.raw_transactions_at_date(date_end) + report_commodity = l.get_commodity(config['report_commodity']) if cash: l = accounting.ledger_to_cash(l, report_commodity) @@ -240,10 +239,9 @@ def transaction(): cash = flask.request.args.get('cash', False) commodity = flask.request.args.get('commodity', False) - report_commodity = Commodity(*config['report_commodity']) - # General ledger l = ledger.raw_transactions_at_date(None) + report_commodity = l.get_commodity(config['report_commodity']) if cash: 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') account = flask.request.args.get('account') - report_commodity = Commodity(*config['report_commodity']) - l = ledger.raw_transactions_at_date(date) + report_commodity = l.get_commodity(config['report_commodity']) account = l.get_account(account) 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') cash = flask.request.args.get('cash', False) - report_commodity = Commodity(*config['report_commodity']) - l = ledger.raw_transactions_at_date(date) + report_commodity = l.get_commodity(config['report_commodity']) if cash: l = accounting.ledger_to_cash(l, report_commodity) diff --git a/ledger_pyreport/ledger.py b/ledger_pyreport/ledger.py index 2655df8..d5a9938 100644 --- a/ledger_pyreport/ledger.py +++ b/ledger_pyreport/ledger.py @@ -104,7 +104,11 @@ def raw_transactions_at_date(date): if ';' in comment: 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) + + if amount.commodity.name not in ledger.commodities: + ledger.commodities[amount.commodity.name] = amount.commodity.strip_price() return ledger diff --git a/ledger_pyreport/model.py b/ledger_pyreport/model.py index baa6edf..e936ffc 100644 --- a/ledger_pyreport/model.py +++ b/ledger_pyreport/model.py @@ -27,6 +27,7 @@ class Ledger: self.accounts = {} self.transactions = [] + self.commodities = {} self.prices = [] def clone(self): @@ -51,6 +52,9 @@ class Ledger: return account + def get_commodity(self, name): + return self.commodities[name] + 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()] @@ -89,7 +93,7 @@ class Posting: return ''.format(self.account.name, self.amount.tostr(False)) 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 self.amount.exchange(commodity, True) # Cost basis @@ -235,10 +239,10 @@ class Amount: return Amount(other - self.amount, self.commodity) 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) - 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) if price: @@ -268,7 +272,7 @@ class Balance: def exchange(self, commodity, is_cost, date=None, ledger=None): result = Amount(0, commodity) 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) else: if any(p[1] == amount.commodity.name for p in ledger.prices): @@ -338,7 +342,10 @@ class Commodity: def __eq__(self, other): if not isinstance(other, Commodity): 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: def __init__(self, ledger, date, pstart):