reports: Add RelatedPostings.balance_at_cost() method.
This makes it easy to get results similar to `ledger -V`.
This commit is contained in:
parent
52fa66bba1
commit
81d216f282
2 changed files with 65 additions and 0 deletions
|
@ -199,6 +199,16 @@ class RelatedPostings(Sequence[data.Posting]):
|
|||
except NameError:
|
||||
return Balance()
|
||||
|
||||
def balance_at_cost(self) -> Balance:
|
||||
balance = MutableBalance()
|
||||
for post in self:
|
||||
if post.cost is None:
|
||||
balance.add_amount(post.units)
|
||||
else:
|
||||
number = post.units.number * post.cost.number
|
||||
balance.add_amount(data.Amount(number, post.cost.currency))
|
||||
return balance
|
||||
|
||||
def meta_values(self,
|
||||
key: MetaKey,
|
||||
default: Optional[MetaValue]=None,
|
||||
|
|
|
@ -135,6 +135,61 @@ def test_iter_with_balance_credit_card(credit_card_cycle):
|
|||
def test_iter_with_balance_two_acccruals(two_accruals_three_payments):
|
||||
check_iter_with_balance(two_accruals_three_payments)
|
||||
|
||||
def test_balance_at_cost_mixed():
|
||||
txn = testutil.Transaction(postings=[
|
||||
('Expenses:Other', '22'),
|
||||
('Expenses:Other', '30', 'EUR', ('1.1',)),
|
||||
('Expenses:Other', '40', 'EUR'),
|
||||
('Expenses:Other', '50', 'USD', ('1.1', 'EUR')),
|
||||
])
|
||||
related = core.RelatedPostings(data.Posting.from_txn(txn))
|
||||
balance = related.balance_at_cost()
|
||||
amounts = set(balance.values())
|
||||
assert amounts == {testutil.Amount(55, 'USD'), testutil.Amount(95, 'EUR')}
|
||||
|
||||
def test_balance_at_single_currency_cost():
|
||||
txn = testutil.Transaction(postings=[
|
||||
('Expenses:Other', '22'),
|
||||
('Expenses:Other', '30', 'EUR', ('1.1',)),
|
||||
('Expenses:Other', '40', 'GBP', ('1.1',)),
|
||||
])
|
||||
related = core.RelatedPostings(data.Posting.from_txn(txn))
|
||||
balance = related.balance_at_cost()
|
||||
amounts = set(balance.values())
|
||||
assert amounts == {testutil.Amount(99)}
|
||||
|
||||
def test_balance_at_cost_zeroed_out():
|
||||
txn = testutil.Transaction(postings=[
|
||||
('Income:Other', '-22'),
|
||||
('Assets:Receivable:Accounts', '20', 'EUR', ('1.1',)),
|
||||
])
|
||||
related = core.RelatedPostings(data.Posting.from_txn(txn))
|
||||
balance = related.balance_at_cost()
|
||||
assert balance.is_zero()
|
||||
|
||||
def test_balance_at_cost_singleton():
|
||||
txn = testutil.Transaction(postings=[
|
||||
('Assets:Receivable:Accounts', '20', 'EUR', ('1.1',)),
|
||||
])
|
||||
related = core.RelatedPostings(data.Posting.from_txn(txn))
|
||||
balance = related.balance_at_cost()
|
||||
amounts = set(balance.values())
|
||||
assert amounts == {testutil.Amount(22)}
|
||||
|
||||
def test_balance_at_cost_singleton_without_cost():
|
||||
txn = testutil.Transaction(postings=[
|
||||
('Assets:Receivable:Accounts', '20'),
|
||||
])
|
||||
related = core.RelatedPostings(data.Posting.from_txn(txn))
|
||||
balance = related.balance_at_cost()
|
||||
amounts = set(balance.values())
|
||||
assert amounts == {testutil.Amount(20)}
|
||||
|
||||
def test_balance_at_cost_empty():
|
||||
related = core.RelatedPostings()
|
||||
balance = related.balance_at_cost()
|
||||
assert balance.is_zero()
|
||||
|
||||
def test_meta_values_empty():
|
||||
related = core.RelatedPostings()
|
||||
assert related.meta_values('key') == set()
|
||||
|
|
Loading…
Reference in a new issue