fix: prices: Do not try to generate prices when there would be a zero

denominator.

Also correctly generate reverse prices for zero amounts.
This commit is contained in:
Stephen Morgan 2021-11-15 12:51:26 +11:00 committed by Simon Michael
parent 1c90c7f97a
commit 3dce61ea09
2 changed files with 42 additions and 11 deletions

View File

@ -35,16 +35,16 @@ prices opts j = do
q = _rsQuery $ reportspec_ opts
ps = filter (matchesPosting q) $ allPostings j
mprices = jpricedirectives j
cprices =
map (stylePriceDirectiveExceptPrecision styles) $
cprices =
map (stylePriceDirectiveExceptPrecision styles) $
concatMap postingsPriceDirectivesFromCosts ps
rcprices =
map (stylePriceDirectiveExceptPrecision styles) $
concatMap (postingsPriceDirectivesFromCosts . postingTransformAmount (mapMixedAmount invertPrice))
rcprices =
map (stylePriceDirectiveExceptPrecision styles) $
concatMap (postingsPriceDirectivesFromCosts . postingTransformAmount (mapMixedAmount invertPrice))
ps
allprices =
mprices
++ ifBoolOpt "infer-market-prices" cprices
allprices =
mprices
++ ifBoolOpt "infer-market-prices" cprices
++ ifBoolOpt "infer-reverse-prices" rcprices -- TODO: shouldn't this show reversed P prices also ? valuation will use them
mapM_ (T.putStrLn . showPriceDirective) $
@ -79,8 +79,10 @@ invertPrice a =
a { aprice = Just $ TotalPrice pa' } where
pa' = ((1 / aquantity a) `divideAmount` pa) { aprice = Nothing }
Just (TotalPrice pa) ->
a { aquantity = aquantity pa * signum (aquantity a), acommodity = acommodity pa, aprice = Just $ TotalPrice pa' } where
a { aquantity = aquantity pa * nonZeroSignum (aquantity a), acommodity = acommodity pa, aprice = Just $ TotalPrice pa' } where
pa' = pa { aquantity = abs $ aquantity a, acommodity = acommodity a, aprice = Nothing, astyle = astyle a }
where
nonZeroSignum x = if x < 0 then -1 else 1
postingsPriceDirectivesFromCosts :: Posting -> [PriceDirective]
postingsPriceDirectivesFromCosts p = mapMaybe (amountPriceDirectiveFromCost date) . amountsRaw $ pamount p
@ -89,11 +91,11 @@ postingsPriceDirectivesFromCosts p = mapMaybe (amountPriceDirectiveFromCost date
amountPriceDirectiveFromCost :: Day -> Amount -> Maybe PriceDirective
amountPriceDirectiveFromCost d a =
case aprice a of
Nothing -> Nothing
Just (UnitPrice pa) -> Just
PriceDirective { pddate = d, pdcommodity = acommodity a, pdamount = pa }
Just (TotalPrice pa) -> Just
Just (TotalPrice pa) | aquantity a /= 0 -> Just
PriceDirective { pddate = d, pdcommodity = acommodity a, pdamount = abs (aquantity a) `divideAmount'` pa }
_ -> Nothing
-- | Given a map of standard amount display styles, apply the
-- appropriate one, if any, to this price directive's amount.

View File

@ -80,3 +80,32 @@ P 2019-01-02 X 1.000,1 A
P 2019-02-01 X 1.000,2345 A
P 2019-02-02 X 1.000,2 A
<
;; Total asset value should be 400 USD + 1000 USD = 1400 USD
2021-10-15 Broker initial balance (equity ABC)
Assets:Broker = 4 ABC @@ 400 USD
Equity:Opening Balances
2021-10-15 Broker initial balance (USD)
Assets:Broker = 1000 USD
Equity:Opening Balances
# 6. Inferring prices should play well with balance assertions involving mixing
# of prices and no prices. (#1736)
$ hledger -f- prices --infer-market-prices
P 2021-10-15 ABC 100.0 USD
<
2021-10-15
(a) 1 A @@ 0 B
2021-10-16
(b) 0 A @@ 1 B
# 7. Gracefully ignore any postings which would result in an infinite price.
$ hledger -f- prices --infer-market-prices
P 2021-10-15 A 0.0 B
# 8. Same for reverse prices
$ hledger -f- prices --infer-reverse-prices
P 2021-10-16 B 0.0 A