Everything it said was a problem has been done legitimately in our books at
one point or another.
* Variation in contract can happen in different line items of an invoice or
"group of contractor" situations.
* Variation in cost can happen because one invoice spans a period of time,
like donation matching programs. There is probably still value in a tool
that checks to make sure we use consistent rates each day, but that
affects all kinds of transactions, not just accruals, so it would be
done better in a separate tool.
* Variation in account happens because invoices legitimately span accrual
accounts, like donation matching programs with fees payable.
So: it's gone, good riddance.
This adds almost all the metadata that's relevant to accruals.
I considered adding statement, but that cuased rows to get spaced out a lot,
and statement's kind of a low-value column, so I decided against it.
Ultimately I would like to make this configurable but that's for the
future.
It is more common than I realized that we split an invoice by
entity on the accrual side, so this supports that better.
It still disregards inconsistency between accrual entity and payment entity
for reporting purposes, to help keep reporting clean around automatic
imports.
The changes to BaseReport._report shook out because at this point, the group
key is effectively arbitrary and shouldn't be used for any reporting
purposes.
This works fine with how we're currently using it, makes transformation
methods easier to implement, and avoids potential bugs where a balance is
initialized with a bad mapping.
So far we've been implicitly relying on this by the user passing search
terms that filter out the opening balance transaction. That will stop
happening with the aging report, so we need to do it ourselves.
This was an early mistake, it makes data consistency mistakes too
easy, and I only used it once so far in actual code. Going to fix
this now so I can more safely build on top of this data structure.
It turns out the provided implementation gets us most of the way there,
we just needed to add handling for the special case of zero balances.
Now it's confirmed with tests.