From 64ffdd7c9c761e330aab31328a64a211331a61a2 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Wed, 1 Nov 2023 13:40:25 +0000 Subject: [PATCH] dev: clarify some amount operations --- hledger-lib/Hledger/Data/Amount.hs | 2 +- hledger-lib/Hledger/Data/Valuation.hs | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/hledger-lib/Hledger/Data/Amount.hs b/hledger-lib/Hledger/Data/Amount.hs index d8c0389fc..3c190d063 100644 --- a/hledger-lib/Hledger/Data/Amount.hs +++ b/hledger-lib/Hledger/Data/Amount.hs @@ -325,7 +325,7 @@ transformAmount f a@Amount{aquantity=q,aprice=p} = a{aquantity=f q, aprice=f' <$ f' (TotalPrice a1@Amount{aquantity=pq}) = TotalPrice a1{aquantity = f pq} f' p' = p' --- | Divide an amount's quantity (and its total price, if it has one) by a constant. +-- | Divide an amount's quantity (and total cost, if any) by some number. divideAmount :: Quantity -> Amount -> Amount divideAmount n = transformAmount (/n) diff --git a/hledger-lib/Hledger/Data/Valuation.hs b/hledger-lib/Hledger/Data/Valuation.hs index 6800dcb80..75c2cf4f1 100644 --- a/hledger-lib/Hledger/Data/Valuation.hs +++ b/hledger-lib/Hledger/Data/Valuation.hs @@ -97,21 +97,25 @@ priceDirectiveToMarketPrice PriceDirective{..} = , mprate = aquantity pdamount } --- | Make one or more `MarketPrice` from an 'Amount' and its price directives. +-- | Infer a market price from the given amount and its cost (if any), +-- and make a corresponding price directive on the given date. amountPriceDirectiveFromCost :: Day -> Amount -> Maybe PriceDirective -amountPriceDirectiveFromCost d amt@Amount{acommodity=fromcomm, aquantity=fromq} = case aprice amt of - Just (UnitPrice pa) -> Just $ pd{pdamount=pa} - Just (TotalPrice pa) | fromq /= 0 -> Just $ pd{pdamount=fromq `divideAmountExtraPrecision` pa} - _ -> Nothing +amountPriceDirectiveFromCost d amt@Amount{acommodity=fromcomm, aquantity=n} = case aprice amt of + Just (UnitPrice u) -> Just $ pd{pdamount=u} + Just (TotalPrice t) | n /= 0 -> Just $ pd{pdamount=u} where u = divideAmountExtraPrecision n t} + _ -> Nothing where pd = PriceDirective{pddate = d, pdcommodity = fromcomm, pdamount = nullamt} - divideAmountExtraPrecision n a = (n `divideAmount` a) { astyle = style' } + -- | Divide an amount's quantity (and total cost, if any) by some number n, + -- and also increase its display precision by the number of digits in n's integer part, + -- to avoid showing a misleadingly rounded result. + divideAmountExtraPrecision n a = (divideAmount n a) { astyle = style' } where style' = (astyle a) { asprecision = precision' } precision' = case asprecision (astyle a) of NaturalPrecision -> NaturalPrecision - Precision p -> Precision $ (numDigitsInt $ truncate n) + p + Precision p -> Precision $ p + numDigitsInt (truncate n) ------------------------------------------------------------------------------ -- Converting things to value