diff --git a/hledger-lib/Hledger/Data/Journal.hs b/hledger-lib/Hledger/Data/Journal.hs index 63703d256b5..01df13cb1af 100644 --- a/hledger-lib/Hledger/Data/Journal.hs +++ b/hledger-lib/Hledger/Data/Journal.hs @@ -111,7 +111,7 @@ import Control.Monad.State.Strict (StateT) import Data.Char (toUpper, isDigit) import Data.Default (Default(..)) import Data.Foldable (toList) -import Data.List ((\\), find, foldl', sortBy, union, intercalate) +import Data.List ((\\), find, foldl', sortBy, intercalate) import Data.List.Extra (nubSort) import qualified Data.Map.Strict as M import Data.Maybe (catMaybes, fromMaybe, mapMaybe, maybeToList) @@ -404,9 +404,14 @@ journalAccountTags Journal{jdeclaredaccounttags} a = M.findWithDefault [] a jdec -- | Which tags are in effect for this account, including tags inherited from parent accounts ? journalInheritedAccountTags :: Journal -> AccountName -> [Tag] journalInheritedAccountTags j a = - foldl' (\ts a' -> ts `union` journalAccountTags j a') [] as + fst $ foldl' + (\(ts, nms) (ts', nms') -> + (ts <> filter (\(nm, _) -> nm `S.notMember` nms) ts', nms `S.union` nms')) + (ats, S.fromList $ fst <$> ats) + asts where - as = a : parentAccountNames a + ats = journalAccountTags j a + asts = (\ts -> (ts, S.fromList $ fst <$> ts)) <$> journalAccountTags j <$> parentAccountNames a -- PERF: cache in journal ? -- | Find up to N most similar and most recent transactions matching diff --git a/hledger-lib/Hledger/Data/Posting.hs b/hledger-lib/Hledger/Data/Posting.hs index 494720c0d38..94412e091f7 100644 --- a/hledger-lib/Hledger/Data/Posting.hs +++ b/hledger-lib/Hledger/Data/Posting.hs @@ -372,7 +372,12 @@ postingStatus Posting{pstatus=s, ptransaction=mt} = case s of -- | Tags for this posting including any inherited from its parent transaction. postingAllTags :: Posting -> [Tag] -postingAllTags p = ptags p ++ maybe [] ttags (ptransaction p) +postingAllTags p = ptags p + ++ filter + (\(nm, _) -> nm `S.notMember` pTagNames) + (maybe [] ttags (ptransaction p)) + where + pTagNames = S.fromList (fst <$> ptags p) -- | Tags for this transaction including any from its postings. transactionAllTags :: Transaction -> [Tag] diff --git a/hledger/test/query-tag.test b/hledger/test/query-tag.test index 3c887d3cc80..f490d07b510 100644 --- a/hledger/test/query-tag.test +++ b/hledger/test/query-tag.test @@ -214,3 +214,50 @@ $ hledger -f- bal -N tag:type=a # 21. $ hledger -f- reg -w80 tag:type=a 2022-01-01 (a:aa) 1 1 + +# 22. Postings can override the tags of their parents +< +2022-11-17 Aldi + ; concerns: me + Assets -30 € + Costs:Food 20 € + Loaned 10 € ; concerns: you + +$ hledger -f- reg tag:concerns=me --pivot=concerns +2022-11-17 Aldi me -30 € -30 € + me 20 € -10 € + +# 23. Accounts can override the tags of their parents +< +account a ; atag:A +account a:b ; atag:B + +$ hledger -f- accounts tag:atag=a +a + +# 24. Transactions can override the tags of used accounts +< +account a ; atag:A +account a:b ; atag:B +2023-01-01 Test + ; atag:C + (a:b) 10 € + +$ hledger -f- bal --pivot=atag + 10 € C +-------------------- + 10 € + +# 25. Postings can override the tags of their accounts +< +account a ; atag:A +account a:b ; atag:B + +2023-01-01 Test + ; atag:C + (a:b) 10 € ; atag:D + +$ hledger -f- bal --pivot=atag + 10 € D +-------------------- + 10 €