Feature/pivot implicit tags (#460)
* Add implicit tags code/desc/payee for --pivot Additionally allow using of transaction inherited tags. * Use original posting in query by account name To be able to query on individual postings and by account name it is useful to have access to original account name (before pivot). Especially this is useful when all postings within transaction gets the same pivot name due. As a side effect we'll match by alias. Note: to query on amt it usually expected to see matches with inferred amounts.
This commit is contained in:
parent
2f5b96b4ae
commit
76867c98a3
@ -25,6 +25,7 @@ module Hledger.Data.Posting (
|
|||||||
hasAmount,
|
hasAmount,
|
||||||
postingAllTags,
|
postingAllTags,
|
||||||
transactionAllTags,
|
transactionAllTags,
|
||||||
|
postingAllImplicitTags,
|
||||||
relatedPostings,
|
relatedPostings,
|
||||||
removePrices,
|
removePrices,
|
||||||
-- * date operations
|
-- * date operations
|
||||||
@ -168,6 +169,18 @@ postingStatus Posting{pstatus=s, ptransaction=mt}
|
|||||||
Nothing -> Uncleared
|
Nothing -> Uncleared
|
||||||
| otherwise = s
|
| 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.
|
-- | Tags for this posting including any inherited from its parent transaction.
|
||||||
postingAllTags :: Posting -> [Tag]
|
postingAllTags :: Posting -> [Tag]
|
||||||
postingAllTags p = ptags p ++ maybe [] ttags (ptransaction p)
|
postingAllTags p = ptags p ++ maybe [] ttags (ptransaction p)
|
||||||
|
|||||||
@ -659,6 +659,8 @@ compareAmount ord q Amount{aquantity=aq} = case ord of Lt -> aq < q
|
|||||||
AbsEq -> abs aq == abs q
|
AbsEq -> abs aq == abs q
|
||||||
|
|
||||||
-- | Does the match expression match this posting ?
|
-- | Does the match expression match this posting ?
|
||||||
|
--
|
||||||
|
-- Note that for account match we try both original and effective account
|
||||||
matchesPosting :: Query -> Posting -> Bool
|
matchesPosting :: Query -> Posting -> Bool
|
||||||
matchesPosting (Not q) p = not $ q `matchesPosting` p
|
matchesPosting (Not q) p = not $ q `matchesPosting` p
|
||||||
matchesPosting (Any) _ = True
|
matchesPosting (Any) _ = True
|
||||||
@ -667,7 +669,8 @@ matchesPosting (Or qs) p = any (`matchesPosting` p) qs
|
|||||||
matchesPosting (And qs) p = all (`matchesPosting` p) qs
|
matchesPosting (And qs) p = all (`matchesPosting` p) qs
|
||||||
matchesPosting (Code r) p = regexMatchesCI r $ maybe "" (T.unpack . tcode) $ ptransaction p
|
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 (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 (Date span) p = span `spanContainsDate` postingDate p
|
||||||
matchesPosting (Date2 span) p = span `spanContainsDate` postingDate2 p
|
matchesPosting (Date2 span) p = span `spanContainsDate` postingDate2 p
|
||||||
matchesPosting (Status Uncleared) p = postingStatus p /= Cleared
|
matchesPosting (Status Uncleared) p = postingStatus p /= Cleared
|
||||||
|
|||||||
@ -93,7 +93,7 @@ pivot tag j = j{jtxns = map pivotTrans . jtxns $ j}
|
|||||||
pivotPosting p
|
pivotPosting p
|
||||||
| Just (_ , value) <- tagTuple = p{paccount = joinAccountNames tag value, porigin = Just $ originalPosting p}
|
| Just (_ , value) <- tagTuple = p{paccount = joinAccountNames tag value, porigin = Just $ originalPosting p}
|
||||||
| _ <- tagTuple = 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
|
-- | Apply the anonymisation transformation on a journal, if option is present
|
||||||
anonymiseByOpts :: CliOpts -> Journal -> Journal
|
anonymiseByOpts :: CliOpts -> Journal -> Journal
|
||||||
|
|||||||
@ -93,3 +93,42 @@ hledger -f - register tag:foo=bar
|
|||||||
>>>2
|
>>>2
|
||||||
>>>=0
|
>>>=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
|
||||||
|
|||||||
@ -121,3 +121,16 @@ alias E=F
|
|||||||
|
|
||||||
>>>2
|
>>>2
|
||||||
>>>=0
|
>>>=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
|
||||||
|
|||||||
@ -38,3 +38,87 @@ hledger -f- --pivot budget bal --no-total
|
|||||||
2 EUR assets:bank account
|
2 EUR assets:bank account
|
||||||
-2 EUR budget:Freifunk
|
-2 EUR budget:Freifunk
|
||||||
>>>=0
|
>>>=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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user