diff --git a/hledger-lib/Hledger/Data/Posting.hs b/hledger-lib/Hledger/Data/Posting.hs index d320c0c64..3f045a4e3 100644 --- a/hledger-lib/Hledger/Data/Posting.hs +++ b/hledger-lib/Hledger/Data/Posting.hs @@ -25,6 +25,7 @@ module Hledger.Data.Posting ( hasAmount, postingAllTags, transactionAllTags, + postingAllImplicitTags, relatedPostings, removePrices, -- * date operations @@ -168,6 +169,18 @@ postingStatus Posting{pstatus=s, ptransaction=mt} Nothing -> Uncleared | otherwise = s +-- | Implicit tags for this transaction. +transactionImplicitTags :: Transaction -> [Tag] +transactionImplicitTags t = filter (not . T.null . snd) [("code", tcode t) + ,("desc", tdescription t) + ,("payee", tdescription t) + ] + +-- | Tags for this posting including implicit and any inherited from its parent transaction. +postingAllImplicitTags :: Posting -> [Tag] +postingAllImplicitTags p = ptags p ++ maybe [] transactionTags (ptransaction p) + where transactionTags t = ttags t ++ transactionImplicitTags t + -- | Tags for this posting including any inherited from its parent transaction. postingAllTags :: Posting -> [Tag] postingAllTags p = ptags p ++ maybe [] ttags (ptransaction p) diff --git a/hledger-lib/Hledger/Query.hs b/hledger-lib/Hledger/Query.hs index b35a65cb1..9437b68de 100644 --- a/hledger-lib/Hledger/Query.hs +++ b/hledger-lib/Hledger/Query.hs @@ -659,6 +659,8 @@ compareAmount ord q Amount{aquantity=aq} = case ord of Lt -> aq < q AbsEq -> abs aq == abs q -- | Does the match expression match this posting ? +-- +-- Note that for account match we try both original and effective account matchesPosting :: Query -> Posting -> Bool matchesPosting (Not q) p = not $ q `matchesPosting` p matchesPosting (Any) _ = True @@ -667,7 +669,8 @@ matchesPosting (Or qs) p = any (`matchesPosting` p) qs matchesPosting (And qs) p = all (`matchesPosting` p) qs matchesPosting (Code r) p = regexMatchesCI r $ maybe "" (T.unpack . tcode) $ ptransaction p matchesPosting (Desc r) p = regexMatchesCI r $ maybe "" (T.unpack . tdescription) $ ptransaction p -matchesPosting (Acct r) p = regexMatchesCI r $ T.unpack $ paccount p -- XXX pack +matchesPosting (Acct r) p = matchesPosting p || matchesPosting (originalPosting p) + where matchesPosting p = regexMatchesCI r $ T.unpack $ paccount p -- XXX pack matchesPosting (Date span) p = span `spanContainsDate` postingDate p matchesPosting (Date2 span) p = span `spanContainsDate` postingDate2 p matchesPosting (Status Uncleared) p = postingStatus p /= Cleared diff --git a/hledger/Hledger/Cli/Utils.hs b/hledger/Hledger/Cli/Utils.hs index b61b692cc..aebd8fbfd 100644 --- a/hledger/Hledger/Cli/Utils.hs +++ b/hledger/Hledger/Cli/Utils.hs @@ -93,7 +93,7 @@ pivot tag j = j{jtxns = map pivotTrans . jtxns $ j} pivotPosting p | Just (_ , value) <- tagTuple = p{paccount = joinAccountNames tag value, porigin = Just $ originalPosting p} | _ <- tagTuple = p - where tagTuple = find ((tag ==) . fst) . ptags $ p + where tagTuple = find ((tag ==) . fst) . postingAllImplicitTags $ p -- | Apply the anonymisation transformation on a journal, if option is present anonymiseByOpts :: CliOpts -> Journal -> Journal diff --git a/tests/journal/tags.test b/tests/journal/tags.test index b616da23a..fc940d4bb 100644 --- a/tests/journal/tags.test +++ b/tests/journal/tags.test @@ -93,3 +93,42 @@ hledger -f - register tag:foo=bar >>>2 >>>=0 +# 5. look for transactions without tags +hledger -f - print not:tag:. +<<< +2010/01/01 desc + a 1 + b -1 + +2010/01/02 + ; foo:some tag + c 2 + d -2 + +2010/01/03 + e 3 + f -3 + +2010/01/04 (code) + g 4 + h -4 +>>> +2010/01/01 desc + a 1 + b -1 + +2010/01/03 + e 3 + f -3 + +2010/01/04 (code) + g 4 + h -4 + +>>>=0 + +# 6. query is not affected by implicit tags +hledger -f ../../examples/sample.journal reg tag:d +>>> +>>>2 +>>>=0 diff --git a/tests/misc/account-aliases.test b/tests/misc/account-aliases.test index 5d17d4076..2fb61a530 100644 --- a/tests/misc/account-aliases.test +++ b/tests/misc/account-aliases.test @@ -121,3 +121,16 @@ alias E=F >>>2 >>>=0 + +# query will search both origin and substitution in alias +hledger -f- reg '^a$' '^b$' +<<< +alias a = b +1/1 + a 1 + b -1 +>>> +2017/01/01 b 1 1 + b -1 0 +>>>2 +>>>=0 diff --git a/tests/misc/pivot.test b/tests/misc/pivot.test index a5b638ff5..9c4c2ab26 100644 --- a/tests/misc/pivot.test +++ b/tests/misc/pivot.test @@ -38,3 +38,87 @@ hledger -f- --pivot budget bal --no-total 2 EUR assets:bank account -2 EUR budget:Freifunk >>>=0 + +# query on account will find either effective name or original one +hledger -f- --pivot TAG reg '^Account2$' '^TAG:fun$' not:hidden +<<< +2016/02/16 Test Transaction + Account1 2 EUR + ; TAG: fun + Account2 -1 EUR + ; TAG: value + Account2 -1 EUR + ; TAG: hidden +>>> +2016/02/16 Test Transaction TAG:fun 2 EUR 2 EUR + TAG:value -1 EUR 1 EUR +>>>=0 + +# pivot for implicit tag desc (technical sample) +hledger -f- --pivot desc reg -M +<<< +2016/02/16 Freifunk + assets:bank account 2 EUR ; date:03/01 + income:donations -2 EUR +>>> +2016/02 desc:Freifunk -2 EUR -2 EUR +2016/03 desc:Freifunk 2 EUR 0 +>>>=0 + +# pivot for implicit tag code (technical sample) +hledger -f- --pivot code reg -M +<<< +2016/02/16 (Freifunk) Donation Freifunk + assets:bank account 2 EUR ; date:03/01 + income:donations -2 EUR +>>> +2016/02 code:Freifunk -2 EUR -2 EUR +2016/03 code:Freifunk 2 EUR 0 +>>>=0 + +# use of pivot with code-based budgeting +hledger -f- --pivot code reg ^income +<<< +2016/02/16 (Freifunk) Donation Freifunk + assets:bank account 2 EUR + income:donations -2 EUR +>>> +2016/02/16 Donation Freifunk code:Freifunk -2 EUR -2 EUR +>>>=0 + +# get expenses balance by description/payee +hledger -f- --pivot desc bal --no-total --flat ^expense +<<< +2016/02/16 (1138) Auchan + assets:bank account + expense:snacks 2 EUR + expense:grocery 20 EUR + +2016/02/16 StarBars + assets:bank account + expense:coffee 5 EUR +>>> + 22 EUR desc:Auchan + 5 EUR desc:StarBars +>>>=0 + +# get daily expenses by description/payee +hledger -f- --pivot desc reg -D ^expense +<<< +2016/02/16 (1138) Auchan + assets:bank account + expense:snacks 2 EUR + expense:grocery 20 EUR + +2016/02/16 StarBars + assets:bank account + expense:coffee 5 EUR + +2016/02/17 (1139) Auchan + assets:bank account + expense:grocery 30 EUR +>>> +2016/02/16 desc:Auchan 22 EUR 22 EUR + desc:StarBars 5 EUR 27 EUR +2016/02/17 desc:Auchan 30 EUR 57 EUR +>>>=0