imp: check: check ordereddates before balance assertions, when both are enabled

This commit is contained in:
Simon Michael 2024-05-02 20:21:54 -10:00
parent 4abb8ffc2e
commit ea58a7ccd7
7 changed files with 49 additions and 8 deletions

View File

@ -48,8 +48,7 @@ import Hledger.Data.Balancing (journalBalanceTransactions, defbalancingopts)
journalStrictChecks :: Journal -> Either String ()
journalStrictChecks j = do
-- keep the order of checks here synced with Check.md and Hledger.Cli.Commands.Check.Check.
-- journalCheckOrdereddates j
-- journalCheckBalanceAssertions j
-- balanced is checked earlier, in journalFinalise
journalCheckCommodities j
journalCheckAccounts j

View File

@ -228,6 +228,7 @@ readJournal iopts@InputOpts{strict_} mpath txt = do
-- | Read a Journal from this file, or from stdin if the file path is -,
-- with strict checks if enabled, or return an error message.
-- (Note strict checks are disabled temporarily here when this is called by readJournalFiles).
-- The file path can have a READER: prefix.
--
-- The reader (data format) to use is determined from (in priority order):

View File

@ -313,9 +313,11 @@ initialiseAndParseJournal parser iopts f txt =
--
-- - infer market prices from costs if enabled
--
-- - check all accounts have been declared if in strict mode
--
-- - check all commodities have been declared if in strict mode
-- One correctness check (parseable) has already passed when this function is called.
-- Up to three more are performed here:
-- - ordereddates (when enabled), done before balance assertions
-- - autobalanced (and with --strict, balanced ?), in the journalBalanceTransactions step.
-- Others (commodities, accounts) are done later by journalStrictChecks.
--
journalFinalise :: InputOpts -> FilePath -> Text -> ParsedJournal -> ExceptT String IO Journal
journalFinalise iopts@InputOpts{..} f txt pj = do
@ -342,7 +344,16 @@ journalFinalise iopts@InputOpts{..} f txt pj = do
-- >>= Right . dbg0With (concatMap (T.unpack.showTransaction).jtxns)
-- >>= \j -> deepseq (concatMap (T.unpack.showTransaction).jtxns $ j) (return j)
<&> dbg9With (lbl "amounts after styling, forecasting, auto-posting".showJournalAmountsDebug)
>>= journalBalanceTransactions balancingopts_ -- infer balance assignments and missing amounts and maybe check balance assertions.
-- Ensure ordereddates is checked before balance assertions.
-- Currently ordereddates is not part of strict mode and can only be enabled by the check command,
-- and that will not run for a while yet. So for now, this dirty hack (uses unsafePerformIO):
>>= (\j -> let args = progArgs in
if "check" `elem` args && "ordereddates" `elem` args
then journalCheckOrdereddates j <&> const j
else Right j) -- the outer parentheses are needed
>>= journalBalanceTransactions balancingopts_ -- infer balance assignments and missing amounts and (unless disabled) check balance assertions.
<&> dbg9With (lbl "amounts after transaction-balancing".showJournalAmountsDebug)
-- <&> dbg9With (("journalFinalise amounts after styling, forecasting, auto postings, transaction balancing"<>).showJournalAmountsDebug)
>>= journalInferCommodityStyles -- infer commodity styles once more now that all posting amounts are present

View File

@ -96,12 +96,11 @@ runCheck _opts j (chck,_) = do
d <- getCurrentDay
let
results = case chck of
-- these checks are assumed to have passed earlier during journal parsing:
-- these checks are assumed to have passed earlier during journal parsing (if enabled):
Parseable -> Right ()
Autobalanced -> Right ()
Balanced -> Right ()
Assertions -> Right ()
Accounts -> journalCheckAccounts j
Commodities -> journalCheckCommodities j
Ordereddates -> journalCheckOrdereddates j

View File

@ -61,6 +61,8 @@ These other checks are not wanted by everyone, but can be run using the `check`
- **ordereddates** - within each file, transactions are ordered by date.
This is a simple and effective error catcher, and you should use it.
Alas! not everyone wants it. If you do, use `hledger check -s ordereddates`.
Note, this check is performed early, before balance assertions
(because copy-pasted dates are often the root cause of balance assertion failures).
- **payees** - all payees used by transactions [must be declared](#payee-directive).
This will force you to always use known/declared payee names.

View File

@ -30,3 +30,8 @@ $ hledger -f- check commodities
$ hledger -f- check commodities
>2 /commodity "\$" has not been declared/
>=1
# ** 5. The commodities check is enabled in strict mode, ahead of accounts.
$ hledger -f- check -s
>2 /commodity "\$" has not been declared/
>=1

View File

@ -24,6 +24,30 @@ $ hledger -f- check ordereddates --date2
>2 /date .*is out of order/
>=1
# ** 4. ordereddates is checked before balance assertions, when both are enabled
<
2024-01-02
(a) 1 = 9
2024-01-01
(a) 1
$ hledger -f - check assertions ordereddates
>2 /date .*is out of order/
>=1
# ** 5. enabling the ordereddates check does not disable the balance assertions check
<
2024-01-01
(a) 1
2024-01-02
(a) 1 = 9
$ hledger -f - check assertions ordereddates
>2 /Balance assertion failed/
>=1
# XXX not supported: With a query, only matched transactions' dates are checked.
# <
# 2020-01-01 a