From 2e4cfccf1b29b534c7f50997ab1856d149c984ca Mon Sep 17 00:00:00 2001 From: Stephen Morgan Date: Thu, 3 Feb 2022 20:22:38 +1100 Subject: [PATCH] fix: types: Make sure type: query will correctly match subtypes, so type:a will also match cash accounts, and type:e will also match conversion accounts. --- hledger-lib/Hledger/Data/Types.hs | 14 ++++++++++++++ hledger-lib/Hledger/Query.hs | 14 +++++++------- hledger/test/query-type.test | 13 +++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/hledger-lib/Hledger/Data/Types.hs b/hledger-lib/Hledger/Data/Types.hs index 7cac48ec8..bf509f9bd 100644 --- a/hledger-lib/Hledger/Data/Types.hs +++ b/hledger-lib/Hledger/Data/Types.hs @@ -162,6 +162,20 @@ instance Show AccountType where show Cash = "C" show Conversion = "V" +-- | Check whether the first argument is a subtype of the second: either equal +-- or one of the defined subtypes. +isAccountSubtypeOf :: AccountType -> AccountType -> Bool +isAccountSubtypeOf Asset Asset = True +isAccountSubtypeOf Liability Liability = True +isAccountSubtypeOf Equity Equity = True +isAccountSubtypeOf Revenue Revenue = True +isAccountSubtypeOf Expense Expense = True +isAccountSubtypeOf Cash Cash = True +isAccountSubtypeOf Cash Asset = True +isAccountSubtypeOf Conversion Conversion = True +isAccountSubtypeOf Conversion Equity = True +isAccountSubtypeOf _ _ = False + -- not worth the trouble, letters defined in accountdirectivep for now --instance Read AccountType -- where diff --git a/hledger-lib/Hledger/Query.hs b/hledger-lib/Hledger/Query.hs index 3cf9c7de7..de0c23ae1 100644 --- a/hledger-lib/Hledger/Query.hs +++ b/hledger-lib/Hledger/Query.hs @@ -672,12 +672,12 @@ matchesAccount _ _ = True -- at least one of them (and any negated tag: terms must match none). -- matchesAccountExtra :: (AccountName -> Maybe AccountType) -> (AccountName -> [Tag]) -> Query -> AccountName -> Bool -matchesAccountExtra atypes atags (Not q ) a = not $ matchesAccountExtra atypes atags q a -matchesAccountExtra atypes atags (Or qs) a = any (\q -> matchesAccountExtra atypes atags q a) qs -matchesAccountExtra atypes atags (And qs) a = all (\q -> matchesAccountExtra atypes atags q a) qs +matchesAccountExtra atypes atags (Not q ) a = not $ matchesAccountExtra atypes atags q a +matchesAccountExtra atypes atags (Or qs ) a = any (\q -> matchesAccountExtra atypes atags q a) qs +matchesAccountExtra atypes atags (And qs ) a = all (\q -> matchesAccountExtra atypes atags q a) qs +matchesAccountExtra atypes _ (Type ts) a = maybe False (\t -> any (t `isAccountSubtypeOf`) ts) $ atypes a matchesAccountExtra _ atags (Tag npat vpat) a = matchesTags npat vpat $ atags a -matchesAccountExtra atypes _ (Type ts) a = maybe False (`elem` ts) $ atypes a -matchesAccountExtra _ _ q a = matchesAccount q a +matchesAccountExtra _ _ q a = matchesAccount q a -- | Does the match expression match this posting ? -- When matching account name, and the posting has been transformed @@ -711,8 +711,8 @@ matchesPostingExtra :: (AccountName -> Maybe AccountType) -> Query -> Posting -> matchesPostingExtra atype (Not q ) p = not $ matchesPostingExtra atype q p matchesPostingExtra atype (Or qs) p = any (\q -> matchesPostingExtra atype q p) qs matchesPostingExtra atype (And qs) p = all (\q -> matchesPostingExtra atype q p) qs -matchesPostingExtra atype (Type ts) p = maybe False (`elem` ts) . atype $ paccount p -matchesPostingExtra _ q p = matchesPosting q p +matchesPostingExtra atype (Type ts) p = maybe False (\t -> any (t `isAccountSubtypeOf`) ts) . atype $ paccount p +matchesPostingExtra _ q p = matchesPosting q p -- | Does the match expression match this transaction ? matchesTransaction :: Query -> Transaction -> Bool diff --git a/hledger/test/query-type.test b/hledger/test/query-type.test index 8c27a9ad4..841819303 100644 --- a/hledger/test/query-type.test +++ b/hledger/test/query-type.test @@ -71,15 +71,18 @@ a:aa # 10. type: is aware of inferred account types. < account assets +account assets:cash account liabilities $ hledger -f- accounts type:a assets +assets:cash # 11. type: can identify cash accounts in the default case < account assets account assets:cash +account liabilities $ hledger -f- accounts type:c assets:cash @@ -120,3 +123,13 @@ $ hledger -f- reg --auto type:a $ hledger -f- reg --auto type:x 2022-02-02 Test (expenses:b) 1 1 + +# 15. type:a matches cash accounts and type:e matches conversion accounts +< +2022-02-02 Test + (assets:cash) 1 + (equity:conversion) 2 + +$ hledger -f- reg type:ae +2022-02-02 Test (assets:cash) 1 1 + (equity:conversion) 2 3