fix: accounts: a tag: query only matches account tags, not posting tags

Eg, `hledger accounts tag:t` lists only account a from this journal:

    account a  ; t:

    2025-01-01
        a          1
        b         -1  ; t:
This commit is contained in:
Simon Michael 2025-08-03 05:38:33 +01:00
parent aabc892277
commit f604b7a416
3 changed files with 25 additions and 2 deletions

View File

@ -98,6 +98,7 @@ module Hledger.Data.Journal (
journalAccountTypes,
journalAddAccountTypes,
journalPostingsAddAccountTags,
journalPostingsKeepAccountTagsOnly,
defaultBaseConversionAccount,
-- journalPrices,
journalBaseConversionAccount,
@ -114,7 +115,7 @@ module Hledger.Data.Journal (
-- * Tests
samplejournal,
samplejournalMaybeExplicit,
tests_Journal
tests_Journal,
--
)
where
@ -642,6 +643,13 @@ journalPostingsAddAccountTags :: Journal -> Journal
journalPostingsAddAccountTags j = journalMapPostings addtags j
where addtags p = p `postingAddTags` (journalInheritedAccountTags j $ paccount p)
-- | Remove all tags from the journal's postings except those provided by their account.
-- This is useful for the accounts report.
-- It does not remove tag declarations from the posting comments.
journalPostingsKeepAccountTagsOnly :: Journal -> Journal
journalPostingsKeepAccountTagsOnly j = journalMapPostings keepaccounttags j
where keepaccounttags p = p{ptags=[]} `postingAddTags` (journalInheritedAccountTags j $ paccount p)
-- | The account name to use for conversion postings generated by --infer-equity.
-- This is the first account declared with type V/Conversion,
-- or otherwise the defaultBaseConversionAccount (equity:conversion).

View File

@ -62,12 +62,16 @@ accounts opts@CliOpts{rawopts_=rawopts, reportspec_=ReportSpec{_rsQuery=query,_r
types = boolopt "types" rawopts
positions = boolopt "positions" rawopts
directives = boolopt "directives" rawopts
-- Modified queries. These may not work with boolean queries (#2371).
-- a depth limit will clip and exclude account names later, but we don't want to exclude accounts at this stage
nodepthq = dbg4 "nodepthq" $ filterQuery (not . queryIsDepth) query
-- just the acct: part of the query will be reapplied later, after clipping
acctq = dbg4 "acctq" $ filterQuery queryIsAcct query
dep = dbg4 "depth" $ queryDepth $ filterQuery queryIsDepth query
matchedused = dbg5 "matchedused" $ nub $ map paccount $ journalPostings $ filterJournalPostings nodepthq j
-- when finding accounts used by postings, we remove tags that were declared on the posting,
-- so that a tag: query will match account tags and not posting tags.
matchedused = dbg5 "matchedused" $ nub $ map paccount $ journalPostings $
filterJournalPostings nodepthq $ journalPostingsKeepAccountTagsOnly j
matcheddeclared = dbg5 "matcheddeclared" $
nub $
filter (matchesAccountExtra (journalAccountType j) (journalInheritedAccountTags j) nodepthq) $

View File

@ -92,3 +92,14 @@ trade:A-B:A
trade:A-B:B
a
b
# ** 11. A tag: query only matches account tags, not posting tags.
<
account a ; t:
2025-01-01
a 1
b -1 ; t:
$ hledger -f- accounts tag:t
a