Changeset - f21ac740f24c
[Not reviewed]
0 3 0
Brett Smith - 4 years ago 2020-06-15 14:16:34
brettcsmith@brettcsmith.org
data: Add Posting.at_cost() method.
3 files changed with 32 insertions and 14 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/data.py
Show inline comments
...
 
@@ -405,12 +405,18 @@ class Posting(BasePosting):
 
            # everything, and ignore entries that lack a postings attribute.
 
            try:
 
                yield from cls.from_txn(entry)  # type:ignore[arg-type]
 
            except AttributeError:
 
                pass
 

	
 
    def at_cost(self) -> Amount:
 
        if self.cost is None:
 
            return self.units
 
        else:
 
            return Amount(self.units.number * self.cost.number, self.cost.currency)
 

	
 

	
 
_KT = TypeVar('_KT', bound=Hashable)
 
_VT = TypeVar('_VT')
 
class _SizedDict(collections.OrderedDict, MutableMapping[_KT, _VT]):
 
    def __init__(self, maxsize: int=128) -> None:
 
        self.maxsize = maxsize
conservancy_beancount/reports/core.py
Show inline comments
...
 
@@ -353,28 +353,16 @@ class RelatedPostings(Sequence[data.Posting]):
 
        balance = MutableBalance()
 
        for post in self:
 
            balance += post.units
 
            yield post, balance
 

	
 
    def balance(self) -> Balance:
 
        for _, balance in self.iter_with_balance():
 
            pass
 
        try:
 
            return balance
 
        except NameError:
 
            return Balance()
 
        return Balance(post.units for post in self)
 

	
 
    def balance_at_cost(self) -> Balance:
 
        balance = MutableBalance()
 
        for post in self:
 
            if post.cost is None:
 
                balance += post.units
 
            else:
 
                number = post.units.number * post.cost.number
 
                balance += data.Amount(number, post.cost.currency)
 
        return balance
 
        return Balance(post.at_cost() for post in self)
 

	
 
    def meta_values(self,
 
                    key: MetaKey,
 
                    default: Optional[MetaValue]=None,
 
    ) -> Set[Optional[MetaValue]]:
 
        return {post.meta.get(key, default) for post in self}
tests/test_data_posting.py
Show inline comments
...
 
@@ -79,6 +79,30 @@ def test_from_entries_mix_txns_and_other_directives(simple_txn):
 
        simple_txn,
 
    ]
 
    for source, post in zip(simple_txn.postings, data.Posting.from_entries(entries)):
 
        assert all(source[x] == post[x] for x in range(len(source) - 1))
 
        assert isinstance(post.account, data.Account)
 
        assert post.meta['note']  # Only works with PostingMeta
 

	
 
@pytest.mark.parametrize('cost_num', [105, 110, 115])
 
def test_at_cost(cost_num):
 
    post = data.Posting(
 
        'Income:Donations',
 
        testutil.Amount(25, 'EUR'),
 
        testutil.Cost(cost_num, 'JPY'),
 
        None,
 
        '*',
 
        None,
 
    )
 
    assert post.at_cost() == testutil.Amount(25 * cost_num, 'JPY')
 

	
 
def test_at_cost_no_cost():
 
    amount = testutil.Amount(25, 'EUR')
 
    post = data.Posting(
 
        'Income:Donations',
 
        amount,
 
        None,
 
        None,
 
        '*',
 
        None,
 
    )
 
    assert post.at_cost() == amount
0 comments (0 inline, 0 general)