diff --git a/hledger/Hledger/Cli/Commands/Prices.hs b/hledger/Hledger/Cli/Commands/Prices.hs index f1179fbe6..c9f5a5c9a 100755 --- a/hledger/Hledger/Cli/Commands/Prices.hs +++ b/hledger/Hledger/Cli/Commands/Prices.hs @@ -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. diff --git a/hledger/test/prices.test b/hledger/test/prices.test index 129ce4986..cbd34f32d 100644 --- a/hledger/test/prices.test +++ b/hledger/test/prices.test @@ -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