diff --git a/hledger-lib/Hledger/Data/Journal.hs b/hledger-lib/Hledger/Data/Journal.hs index 7044e8ad0..7fbe13cbc 100644 --- a/hledger-lib/Hledger/Data/Journal.hs +++ b/hledger-lib/Hledger/Data/Journal.hs @@ -98,6 +98,31 @@ journalAccountNameTree = accountNameTreeFrom . journalAccountNames -- Various kinds of filtering on journals. We do it differently depending -- on the command. +------------------------------------------------------------------------------- +-- filtering V2 + +-- | Keep only transactions matching the query expression. +-- filterJournalTransactions2 :: Matcher -> Journal -> Journal +-- filterJournalTransactions2 = undefined +-- pats j@Journal{jtxns=ts} = j{jtxns=filter matchdesc ts} +-- where matchdesc = matchpats pats . tdescription + +-- | Keep only postings matching the query expression. +-- This can leave unbalanced transactions. +filterJournalPostings2 :: Matcher -> Journal -> Journal +filterJournalPostings2 m j@Journal{jtxns=ts} = j{jtxns=map filterpostings ts} + where filterpostings t@Transaction{tpostings=ps} = t{tpostings=filter (m `matches`) ps} + +matches :: Matcher -> Posting -> Bool +matches (MatchOr ms) p = any (`matches` p) ms +matches (MatchAnd ms) p = all (`matches` p) ms +matches (MatchAcct True r) p = containsRegex r $ paccount p +matches (MatchAcct False r) p = not $ matches (MatchAcct True r) p +matches _ _ = False + +------------------------------------------------------------------------------- +-- filtering V1 + -- | Keep only transactions we are interested in, as described by the -- filter specification. filterJournalTransactions :: FilterSpec -> Journal -> Journal diff --git a/hledger-lib/Hledger/Data/Types.hs b/hledger-lib/Hledger/Data/Types.hs index 1e4547365..ddb23b7c8 100644 --- a/hledger-lib/Hledger/Data/Types.hs +++ b/hledger-lib/Hledger/Data/Types.hs @@ -187,7 +187,7 @@ data Account = Account { abalance :: MixedAmount -- ^ sum of postings in this account and subaccounts } --- | A generic, pure specification of how to filter transactions and postings. +-- | A generic, pure specification of how to filter (or search) transactions and postings. data FilterSpec = FilterSpec { datespan :: DateSpan -- ^ only include if in this date span ,cleared :: Maybe Bool -- ^ only include if cleared\/uncleared\/don't care @@ -198,3 +198,17 @@ data FilterSpec = FilterSpec { ,depth :: Maybe Int } deriving (Show) +-- | A more general way to match transactions and postings, successor to FilterSpec. (?) +-- If the first boolean is False, it's a negative match. +data Matcher = MatchDesc Bool String -- ^ match if description matches this regexp + | MatchAcct Bool String -- ^ match postings whose account matches this regexp + | MatchOtherAcct Bool String -- ^ match postings whose transaction contains a posting to an account matching this regexp + | MatchADate Bool DateSpan -- ^ match if actual date in this date span + | MatchEDate Bool DateSpan -- ^ match if effective date in this date span + | MatchStatus Bool Bool -- ^ match if cleared status has this value + | MatchReal Bool Bool -- ^ match if "realness" (involves a real non-virtual account ?) has this value + | MatchEmpty Bool Bool -- ^ match if "emptiness" (amount is zero ?) has this value + | MatchDepth Bool Int -- ^ match if account depth is less than or equal to this value + | MatchAnd [Matcher] -- ^ match if all match + | MatchOr [Matcher] -- ^ match if any match + deriving (Show)