lib: Fix filtering by payee and note (#598)
This commit is contained in:
parent
466a323533
commit
72cf6a8219
@ -187,16 +187,18 @@ transactionPayee :: Transaction -> Text
|
|||||||
transactionPayee = fst . payeeAndNoteFromDescription . tdescription
|
transactionPayee = fst . payeeAndNoteFromDescription . tdescription
|
||||||
|
|
||||||
transactionNote :: Transaction -> Text
|
transactionNote :: Transaction -> Text
|
||||||
transactionNote = fst . payeeAndNoteFromDescription . tdescription
|
transactionNote = snd . payeeAndNoteFromDescription . tdescription
|
||||||
|
|
||||||
-- | Parse a transaction's description into payee and note (aka narration) fields,
|
-- | Parse a transaction's description into payee and note (aka narration) fields,
|
||||||
-- assuming a convention of separating these with | (like Beancount).
|
-- assuming a convention of separating these with | (like Beancount).
|
||||||
-- Ie, everything up to the first | is the payee, everything after it is the note.
|
-- Ie, everything up to the first | is the payee, everything after it is the note.
|
||||||
-- When there's no |, payee == note == description.
|
-- When there's no |, payee == note == description.
|
||||||
payeeAndNoteFromDescription :: Text -> (Text,Text)
|
payeeAndNoteFromDescription :: Text -> (Text,Text)
|
||||||
payeeAndNoteFromDescription t = (textstrip p, textstrip $ T.tail n)
|
payeeAndNoteFromDescription t
|
||||||
|
| T.null n = (t, t)
|
||||||
|
| otherwise = (textstrip p, textstrip $ T.drop 1 n)
|
||||||
where
|
where
|
||||||
(p,n) = T.breakOn "|" t
|
(p, n) = T.span (/= '|') t
|
||||||
|
|
||||||
-- | Tags for this posting including implicit and any inherited from its parent transaction.
|
-- | Tags for this posting including implicit and any inherited from its parent transaction.
|
||||||
postingAllImplicitTags :: Posting -> [Tag]
|
postingAllImplicitTags :: Posting -> [Tag]
|
||||||
|
|||||||
@ -225,6 +225,8 @@ prefixes = map (<>":") [
|
|||||||
,"amt"
|
,"amt"
|
||||||
,"code"
|
,"code"
|
||||||
,"desc"
|
,"desc"
|
||||||
|
,"payee"
|
||||||
|
,"note"
|
||||||
,"acct"
|
,"acct"
|
||||||
,"date"
|
,"date"
|
||||||
,"date2"
|
,"date2"
|
||||||
@ -260,6 +262,8 @@ parseQueryTerm d (T.stripPrefix "not:" -> Just s) =
|
|||||||
Right _ -> Left Any -- not:somequeryoption will be ignored
|
Right _ -> Left Any -- not:somequeryoption will be ignored
|
||||||
parseQueryTerm _ (T.stripPrefix "code:" -> Just s) = Left $ Code $ T.unpack s
|
parseQueryTerm _ (T.stripPrefix "code:" -> Just s) = Left $ Code $ T.unpack s
|
||||||
parseQueryTerm _ (T.stripPrefix "desc:" -> Just s) = Left $ Desc $ T.unpack s
|
parseQueryTerm _ (T.stripPrefix "desc:" -> Just s) = Left $ Desc $ T.unpack s
|
||||||
|
parseQueryTerm _ (T.stripPrefix "payee:" -> Just s) = Left $ Tag "payee" $ Just $ T.unpack s
|
||||||
|
parseQueryTerm _ (T.stripPrefix "note:" -> Just s) = Left $ Tag "note" $ Just $ T.unpack s
|
||||||
parseQueryTerm _ (T.stripPrefix "acct:" -> Just s) = Left $ Acct $ T.unpack s
|
parseQueryTerm _ (T.stripPrefix "acct:" -> Just s) = Left $ Acct $ T.unpack s
|
||||||
parseQueryTerm d (T.stripPrefix "date2:" -> Just s) =
|
parseQueryTerm d (T.stripPrefix "date2:" -> Just s) =
|
||||||
case parsePeriodExpr d s of Left e -> error' $ "\"date2:"++T.unpack s++"\" gave a "++showDateParseError e
|
case parsePeriodExpr d s of Left e -> error' $ "\"date2:"++T.unpack s++"\" gave a "++showDateParseError e
|
||||||
@ -294,6 +298,8 @@ tests_parseQueryTerm = [
|
|||||||
"status:!" `gives` (Left $ StatusQ Pending)
|
"status:!" `gives` (Left $ StatusQ Pending)
|
||||||
"status:0" `gives` (Left $ StatusQ Unmarked)
|
"status:0" `gives` (Left $ StatusQ Unmarked)
|
||||||
"status:" `gives` (Left $ StatusQ Unmarked)
|
"status:" `gives` (Left $ StatusQ Unmarked)
|
||||||
|
"payee:x" `gives` (Left $ Tag "payee" (Just "x"))
|
||||||
|
"note:x" `gives` (Left $ Tag "note" (Just "x"))
|
||||||
"real:1" `gives` (Left $ Real True)
|
"real:1" `gives` (Left $ Real True)
|
||||||
"date:2008" `gives` (Left $ Date $ DateSpan (Just $ parsedate "2008/01/01") (Just $ parsedate "2009/01/01"))
|
"date:2008" `gives` (Left $ Date $ DateSpan (Just $ parsedate "2008/01/01") (Just $ parsedate "2009/01/01"))
|
||||||
"date:from 2012/5/17" `gives` (Left $ Date $ DateSpan (Just $ parsedate "2012/05/17") Nothing)
|
"date:from 2012/5/17" `gives` (Left $ Date $ DateSpan (Just $ parsedate "2012/05/17") Nothing)
|
||||||
@ -684,8 +690,10 @@ matchesPosting q@(Amt _ _) Posting{pamount=amt} = q `matchesMixedAmount` amt
|
|||||||
-- matchesPosting (Empty True) Posting{pamount=a} = isZeroMixedAmount a
|
-- matchesPosting (Empty True) Posting{pamount=a} = isZeroMixedAmount a
|
||||||
matchesPosting (Empty _) _ = True
|
matchesPosting (Empty _) _ = True
|
||||||
matchesPosting (Sym r) Posting{pamount=Mixed as} = any (regexMatchesCI $ "^" ++ r ++ "$") $ map (T.unpack . acommodity) as
|
matchesPosting (Sym r) Posting{pamount=Mixed as} = any (regexMatchesCI $ "^" ++ r ++ "$") $ map (T.unpack . acommodity) as
|
||||||
matchesPosting (Tag n v) p = not $ null $ matchedTags n v $ postingAllTags p
|
matchesPosting (Tag n v) p = case (n, v) of
|
||||||
-- matchesPosting _ _ = False
|
("payee", Just v) -> maybe False (regexMatchesCI v . T.unpack . transactionPayee) $ ptransaction p
|
||||||
|
("note", Just v) -> maybe False (regexMatchesCI v . T.unpack . transactionNote) $ ptransaction p
|
||||||
|
(n, v) -> matchesTags n v $ postingAllTags p
|
||||||
|
|
||||||
tests_matchesPosting = [
|
tests_matchesPosting = [
|
||||||
"matchesPosting" ~: do
|
"matchesPosting" ~: do
|
||||||
@ -737,9 +745,10 @@ matchesTransaction q@(Amt _ _) t = any (q `matchesPosting`) $ tpostings t
|
|||||||
matchesTransaction (Empty _) _ = True
|
matchesTransaction (Empty _) _ = True
|
||||||
matchesTransaction (Depth d) t = any (Depth d `matchesPosting`) $ tpostings t
|
matchesTransaction (Depth d) t = any (Depth d `matchesPosting`) $ tpostings t
|
||||||
matchesTransaction q@(Sym _) t = any (q `matchesPosting`) $ tpostings t
|
matchesTransaction q@(Sym _) t = any (q `matchesPosting`) $ tpostings t
|
||||||
matchesTransaction (Tag n v) t = not $ null $ matchedTags n v $ transactionAllTags t
|
matchesTransaction (Tag n v) t = case (n, v) of
|
||||||
|
("payee", Just v) -> regexMatchesCI v . T.unpack . transactionPayee $ t
|
||||||
-- matchesTransaction _ _ = False
|
("note", Just v) -> regexMatchesCI v . T.unpack . transactionNote $ t
|
||||||
|
(n, v) -> matchesTags n v $ transactionAllTags t
|
||||||
|
|
||||||
tests_matchesTransaction = [
|
tests_matchesTransaction = [
|
||||||
"matchesTransaction" ~: do
|
"matchesTransaction" ~: do
|
||||||
@ -749,14 +758,16 @@ tests_matchesTransaction = [
|
|||||||
assertBool "" $ (Desc "x x") `matchesTransaction` nulltransaction{tdescription="x x"}
|
assertBool "" $ (Desc "x x") `matchesTransaction` nulltransaction{tdescription="x x"}
|
||||||
-- see posting for more tag tests
|
-- see posting for more tag tests
|
||||||
assertBool "" $ (Tag "foo" (Just "a")) `matchesTransaction` nulltransaction{ttags=[("foo","bar")]}
|
assertBool "" $ (Tag "foo" (Just "a")) `matchesTransaction` nulltransaction{ttags=[("foo","bar")]}
|
||||||
|
assertBool "" $ (Tag "payee" (Just "payee")) `matchesTransaction` nulltransaction{tdescription="payee|note"}
|
||||||
|
assertBool "" $ (Tag "note" (Just "note")) `matchesTransaction` nulltransaction{tdescription="payee|note"}
|
||||||
-- a tag match on a transaction also matches posting tags
|
-- a tag match on a transaction also matches posting tags
|
||||||
assertBool "" $ (Tag "postingtag" Nothing) `matchesTransaction` nulltransaction{tpostings=[nullposting{ptags=[("postingtag","")]}]}
|
assertBool "" $ (Tag "postingtag" Nothing) `matchesTransaction` nulltransaction{tpostings=[nullposting{ptags=[("postingtag","")]}]}
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | Filter a list of tags by matching against their names and
|
-- | Filter a list of tags by matching against their names and
|
||||||
-- optionally also their values.
|
-- optionally also their values.
|
||||||
matchedTags :: Regexp -> Maybe Regexp -> [Tag] -> [Tag]
|
matchesTags :: Regexp -> Maybe Regexp -> [Tag] -> Bool
|
||||||
matchedTags namepat valuepat tags = filter (match namepat valuepat) tags
|
matchesTags namepat valuepat = not . null . filter (match namepat valuepat)
|
||||||
where
|
where
|
||||||
match npat Nothing (n,_) = regexMatchesCI npat (T.unpack n) -- XXX
|
match npat Nothing (n,_) = regexMatchesCI npat (T.unpack n) -- XXX
|
||||||
match npat (Just vpat) (n,v) = regexMatchesCI npat (T.unpack n) && regexMatchesCI vpat (T.unpack v)
|
match npat (Just vpat) (n,v) = regexMatchesCI npat (T.unpack n) && regexMatchesCI vpat (T.unpack v)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user