diff --git a/hledger-lib/Hledger/Data/Matching.hs b/hledger-lib/Hledger/Data/Matching.hs
index bc6ba6eb9..4e7c95bfc 100644
--- a/hledger-lib/Hledger/Data/Matching.hs
+++ b/hledger-lib/Hledger/Data/Matching.hs
@@ -28,8 +28,8 @@ import Hledger.Data.AccountName
-- import Hledger.Data.Amount
-- import Hledger.Data.Commodity (canonicaliseCommodities)
import Hledger.Data.Dates
--- import Hledger.Data.Transaction (journalTransactionWithDate,balanceTransaction)
--- import Hledger.Data.Posting
+import Hledger.Data.Posting
+import Hledger.Data.Transaction
-- import Hledger.Data.TimeLog
-- | A matcher is an arbitrary boolean expression of various search criteria.
@@ -136,10 +136,14 @@ parseMatcher _ ('d':'e':'p':'t':'h':':':s) = Left $ MatchDepth True $ readDef 0
parseMatcher _ "" = Left $ MatchAny
parseMatcher d s = parseMatcher d $ defaultprefix++":"++s
-parseStatus "*" = True
-parseStatus _ = False
+parseStatus :: String -> Bool
+parseStatus s = s `elem` (truestrings ++ ["*"])
-parseBool s = s `elem` ["t","true","1","on"]
+parseBool :: String -> Bool
+parseBool s = s `elem` truestrings
+
+truestrings :: [String]
+truestrings = ["t","true","1","on"]
-- | Quote-and-prefix-aware version of words - don't split on spaces which
-- are inside quotes, including quotes which may have one of the specified
@@ -203,6 +207,8 @@ matchesPosting (MatchEDate True span) p =
Nothing -> False
where d = maybe Nothing teffectivedate $ ptransaction p
matchesPosting (MatchEDate False span) p = not $ (MatchEDate True span) `matchesPosting` p
+matchesPosting (MatchStatus True status) p = status == postingCleared p
+matchesPosting (MatchStatus False status) p = status /= postingCleared p
matchesPosting _ _ = False
-- | Does the match expression match this transaction ?
@@ -220,6 +226,8 @@ matchesTransaction (MatchDate False span) t = not $ (MatchDate True span) `match
matchesTransaction (MatchEDate True span) Transaction{teffectivedate=Just d} = spanContainsDate span d
matchesTransaction _ Transaction{teffectivedate=Nothing} = False
matchesTransaction (MatchEDate False span) t = not $ (MatchEDate True span) `matchesTransaction` t
+matchesTransaction (MatchStatus True status) t = status == tstatus t
+matchesTransaction (MatchStatus False status) t = status /= tstatus t
matchesTransaction _ _ = False
-- | Does the match expression match this account ?
@@ -290,10 +298,24 @@ tests_Hledger_Data_Matching = TestList
parseQuery d "inacct:a desc:b" `is` (MatchDesc True "b", [QueryOptInAcct "b"])
parseQuery d "inacct:a inacct:b" `is` (MatchAny, [QueryOptInAcct "a"])
+ parseQuery d "status:1" `is` (MatchStatus True True, [])
+ parseQuery d "status:0" `is` (MatchStatus True False, [])
+
,"matchesAccount" ~: do
assertBool "positive acct match" $ matchesAccount (MatchAcct True "b:c") "a:bb:c:d"
-- assertBool "acct should match at beginning" $ not $ matchesAccount (MatchAcct True "a:b") "c:a:b"
- -- ,"matchesAccount" ~: do
- -- matchesAccount (MatchAcct )
+ ,"matchesPosting" ~: do
+ -- matching posting status..
+ assertBool "positive match on true posting status" $
+ (MatchStatus True True) `matchesPosting` nullposting{pstatus=True}
+ assertBool "negative match on true posting status" $
+ not $ (MatchStatus False True) `matchesPosting` nullposting{pstatus=True}
+ assertBool "positive match on false posting status" $
+ (MatchStatus True False) `matchesPosting` nullposting{pstatus=False}
+ assertBool "negative match on false posting status" $
+ not $ (MatchStatus False False) `matchesPosting` nullposting{pstatus=False}
+ assertBool "positive match on true posting status acquired from transaction" $
+ (MatchStatus True True) `matchesPosting` nullposting{pstatus=False,ptransaction=Just nulltransaction{tstatus=True}}
+
]
diff --git a/hledger-web/.hledger/web/templates/searchform.hamlet b/hledger-web/.hledger/web/templates/searchform.hamlet
index 372639d80..3518b95e0 100644
--- a/hledger-web/.hledger/web/templates/searchform.hamlet
+++ b/hledger-web/.hledger/web/templates/searchform.hamlet
@@ -23,6 +23,7 @@
acct:REGEXP to filter postings/transactions by account, #
desc:REGEXP by description, #
- date:PERIODEXP or edate:PERIODEXP by date or effective date.
+ date:PERIODEXP or edate:PERIODEXP by date or effective date,
+ status:BOOL by cleared status
not: to negate, use single or double quotes to include spaces, multiple patterns are AND'ed.