chore(finance/models): add documentation and test for `validity` (#11)

Currently, the `INVALID_TOTAL` case of the `Statement.validity` method
is tested indirectly via the admin tests and the behavior is hard to
trace back. We therefore add documentation and a targeted test.
main
Christian Merten 1 month ago committed by GitHub
parent 5d4f29be89
commit efe20bc721
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -162,6 +162,18 @@ class Statement(CommonModel):
@property
def transaction_issues(self):
"""
Returns a list of critical problems with the currently configured transactions. This is done
by calculating a list of required paiments. From this list, we deduce the total amount
every member should receive (this amount can be negative, due to org fees).
Finally, the amounts are compared to the total amounts paid out by currently setup transactions.
The list of required paiments is generated from:
- All covered bills that have a configured payer.
(Note: This means that `transaction_issues` might return an empty list, but the calculated
total still differs from the transaction total.)
- If the statement is associated with an excursion: allowances, subsidies, LJP paiment and org fee.
"""
needed_paiments = [(b.paid_by, b.amount) for b in self.bill_set.all() if b.costs_covered and b.paid_by]
if self.excursion is not None:
@ -206,6 +218,7 @@ class Statement(CommonModel):
@property
def transactions_match_expenses(self):
"""Returns true iff there are no transaction issues."""
return len(self.transaction_issues) == 0
@property
@ -223,7 +236,11 @@ class Statement(CommonModel):
@property
def total_valid(self):
"""Checks if the calculated total agrees with the total amount of all transactions."""
"""
Checks if the calculated total agrees with the total amount of all transactions.
Note: This is not the same as `transactions_match_expenses`. For details see the
docstring of `transaction_issues`.
"""
total_transactions = 0
for transaction in self.transaction_set.all():
total_transactions += transaction.amount
@ -231,6 +248,19 @@ class Statement(CommonModel):
@property
def validity(self):
"""
Returns the validity status of the statement. This is one of:
- `Statement.VALID`:
Everything is correct.
- `Statement.NON_MATCHING_TRANSACTIONS`:
There is a transaction issue (in the sense of `transaction_issues`).
- `Statement.MISSING_LEDGER`:
At least one transaction has no ledger configured.
- `Statement.INVALID_ALLOWANCE_TO`:
The members receiving allowance don't match the regulations.
- `Statement.INVALID_TOTAL`:
The total amount of transactions differs from the calculated total payout.
"""
if not self.transactions_match_expenses:
return Statement.NON_MATCHING_TRANSACTIONS
if not self.ledgers_configured:

@ -147,6 +147,9 @@ class StatementTestCase(TestCase):
refunded=False
)
self.st6 = Statement.objects.create(night_cost=self.night_cost)
Bill.objects.create(statement=self.st6, amount='42', costs_covered=True)
def test_org_fee(self):
# org fee should be collected if participants are older than 26
self.assertEqual(self.st5.excursion.old_participant_count, 3, 'Calculation of number of old people in excursion is incorrect.')
@ -488,6 +491,11 @@ class StatementTestCase(TestCase):
ljp_contrib = self.st_small.paid_ljp_contributions
self.assertEqual(ljp_contrib, 0)
def test_validity_paid_by_none(self):
# st6 has one covered bill with no payer, so no transaction issues,
# but total transaction amount (= 0) differs from actual total (> 0).
self.assertEqual(self.st6.validity, Statement.INVALID_TOTAL)
class LedgerTestCase(TestCase):
def setUp(self):

Loading…
Cancel
Save