lib: Auto-postings with Amount queries should filter only those commodities which match the query.

Also corrects a regression introduced in
8ab29f84b32288a34ae7627a2204081fae31900f where transaction modifier
postings without multipliers would incorrectly be filtered by commodity.
This commit is contained in:
Stephen Morgan 2021-07-01 12:01:00 +10:00 committed by Simon Michael
parent 9ffed51f54
commit e2198ff1ee
2 changed files with 28 additions and 6 deletions

View File

@ -12,7 +12,7 @@ module Hledger.Data.TransactionModifier (
) )
where where
import Control.Applicative ((<|>)) import Control.Applicative ((<|>), liftA2)
import Data.Maybe (catMaybes) import Data.Maybe (catMaybes)
import qualified Data.Text as T import qualified Data.Text as T
import Data.Time.Calendar (Day) import Data.Time.Calendar (Day)
@ -21,7 +21,7 @@ import Hledger.Data.Dates
import Hledger.Data.Amount import Hledger.Data.Amount
import Hledger.Data.Transaction (txnTieKnot) import Hledger.Data.Transaction (txnTieKnot)
import Hledger.Query (Query, filterQuery, matchesAmount, matchesPosting, import Hledger.Query (Query, filterQuery, matchesAmount, matchesPosting,
parseQuery, queryIsSym, simplifyQuery) parseQuery, queryIsAmt, queryIsSym, simplifyQuery)
import Hledger.Data.Posting (commentJoin, commentAddTag) import Hledger.Data.Posting (commentJoin, commentAddTag)
import Hledger.Utils (dbg6, wrap) import Hledger.Utils (dbg6, wrap)
@ -81,8 +81,7 @@ transactionModifierToFunction refdate TransactionModifier{tmquerytxt, tmpostingr
q <- simplifyQuery . fst <$> parseQuery refdate tmquerytxt q <- simplifyQuery . fst <$> parseQuery refdate tmquerytxt
let let
fs = map (tmPostingRuleToFunction q tmquerytxt) tmpostingrules fs = map (tmPostingRuleToFunction q tmquerytxt) tmpostingrules
generatePostings ps = [p' | p <- ps generatePostings ps = concatMap (\p -> p : map ($p) (if q `matchesPosting` p then fs else [])) ps
, p' <- if q `matchesPosting` p then p:[f p | f <- fs] else [p]]
Right $ \t@(tpostings -> ps) -> txnTieKnot t{tpostings=generatePostings ps} Right $ \t@(tpostings -> ps) -> txnTieKnot t{tpostings=generatePostings ps}
-- | Converts a 'TransactionModifier''s posting rule to a 'Posting'-generating function, -- | Converts a 'TransactionModifier''s posting rule to a 'Posting'-generating function,
@ -106,9 +105,9 @@ tmPostingRuleToFunction query querytxt pr =
} }
where where
qry = "= " <> querytxt qry = "= " <> querytxt
symq = filterQuery queryIsSym query symq = filterQuery (liftA2 (||) queryIsSym queryIsAmt) query
amount' = case postingRuleMultiplier pr of amount' = case postingRuleMultiplier pr of
Nothing -> const . filterMixedAmount (symq `matchesAmount`) $ pamount pr Nothing -> const $ pamount pr
Just n -> \p -> Just n -> \p ->
-- Multiply the old posting's amount by the posting rule's multiplier. -- Multiply the old posting's amount by the posting rule's multiplier.
let let

View File

@ -348,6 +348,9 @@ $ hledger -f- print --auto
= assets cur:USD = assets cur:USD
(b:USD) *1 (b:USD) *1
= assets cur:EUR
(b:USD) 5 USD
2017-12-14 2017-12-14
revenue:job -10 EUR revenue:job -10 EUR
revenue:job -10 USD revenue:job -10 USD
@ -358,6 +361,26 @@ $ hledger -f- print --auto
revenue:job -10 EUR revenue:job -10 EUR
revenue:job -10 USD revenue:job -10 USD
assets assets
(b:USD) 5 USD ; generated-posting: = assets cur:EUR
(b:USD) 10 USD ; generated-posting: = assets cur:USD (b:USD) 10 USD ; generated-posting: = assets cur:USD
>=0 >=0
# 19. Auto-generated postings match only the amounts which match amount query.
<
= assets amt:>50
(b) *1
2017-12-14
revenue:job -10 USD
revenue:job -100 EUR
assets
$ hledger -f- print --auto
2017-12-14 ; modified:
revenue:job -10 USD
revenue:job -100 EUR
assets
(b) 100 EUR ; generated-posting: = assets amt:>50
>=0