lib: (divide|multiply)[Mixed]AmountAndPrice (#928)
Divide/multiply amounts *and* their total price, if they have one. Helpful for keeping transactions balanced when transaction modifiers are multiplying amounts.
This commit is contained in:
parent
b053942e9b
commit
d7919003ae
@ -59,6 +59,8 @@ module Hledger.Data.Amount (
|
||||
costOfAmount,
|
||||
divideAmount,
|
||||
multiplyAmount,
|
||||
divideAmountAndPrice,
|
||||
multiplyAmountAndPrice,
|
||||
amountValue,
|
||||
amountTotalPriceToUnitPrice,
|
||||
-- ** rendering
|
||||
@ -91,6 +93,8 @@ module Hledger.Data.Amount (
|
||||
costOfMixedAmount,
|
||||
divideMixedAmount,
|
||||
multiplyMixedAmount,
|
||||
divideMixedAmountAndPrice,
|
||||
multiplyMixedAmountAndPrice,
|
||||
averageMixedAmounts,
|
||||
isNegativeAmount,
|
||||
isNegativeMixedAmount,
|
||||
@ -214,7 +218,7 @@ costOfAmount a@Amount{aquantity=q, aprice=price} =
|
||||
-- | Replace an amount's TotalPrice, if it has one, with an equivalent UnitPrice.
|
||||
-- Has no effect on amounts without one.
|
||||
-- Also increases the unit price's display precision to show one extra decimal place,
|
||||
-- to help the unit-priced amounts to still balance.
|
||||
-- to help keep transaction amounts balancing.
|
||||
-- Does Decimal division, might be some rounding/irrational number issues.
|
||||
amountTotalPriceToUnitPrice :: Amount -> Amount
|
||||
amountTotalPriceToUnitPrice
|
||||
@ -230,6 +234,22 @@ divideAmount n a@Amount{aquantity=q} = a{aquantity=q/n}
|
||||
multiplyAmount :: Quantity -> Amount -> Amount
|
||||
multiplyAmount n a@Amount{aquantity=q} = a{aquantity=q*n}
|
||||
|
||||
-- | Divide an amount's quantity (and its total price, if it has one) by a constant.
|
||||
-- The total price will be kept positive regardless of the multiplier's sign.
|
||||
divideAmountAndPrice :: Quantity -> Amount -> Amount
|
||||
divideAmountAndPrice n a@Amount{aquantity=q,aprice=p} = a{aquantity=q/n, aprice=f p}
|
||||
where
|
||||
f (TotalPrice a) = TotalPrice $ abs $ n `divideAmount` a
|
||||
f p = p
|
||||
|
||||
-- | Multiply an amount's quantity (and its total price, if it has one) by a constant.
|
||||
-- The total price will be kept positive regardless of the multiplier's sign.
|
||||
multiplyAmountAndPrice :: Quantity -> Amount -> Amount
|
||||
multiplyAmountAndPrice n a@Amount{aquantity=q,aprice=p} = a{aquantity=q*n, aprice=f p}
|
||||
where
|
||||
f (TotalPrice a) = TotalPrice $ abs $ n `multiplyAmount` a
|
||||
f p = p
|
||||
|
||||
-- | Is this amount negative ? The price is ignored.
|
||||
isNegativeAmount :: Amount -> Bool
|
||||
isNegativeAmount Amount{aquantity=q} = q < 0
|
||||
@ -553,6 +573,16 @@ divideMixedAmount n = mapMixedAmount (divideAmount n)
|
||||
multiplyMixedAmount :: Quantity -> MixedAmount -> MixedAmount
|
||||
multiplyMixedAmount n = mapMixedAmount (multiplyAmount n)
|
||||
|
||||
-- | Divide a mixed amount's quantities (and total prices, if any) by a constant.
|
||||
-- The total prices will be kept positive regardless of the multiplier's sign.
|
||||
divideMixedAmountAndPrice :: Quantity -> MixedAmount -> MixedAmount
|
||||
divideMixedAmountAndPrice n = mapMixedAmount (divideAmountAndPrice n)
|
||||
|
||||
-- | Multiply a mixed amount's quantities (and total prices, if any) by a constant.
|
||||
-- The total prices will be kept positive regardless of the multiplier's sign.
|
||||
multiplyMixedAmountAndPrice :: Quantity -> MixedAmount -> MixedAmount
|
||||
multiplyMixedAmountAndPrice n = mapMixedAmount (multiplyAmountAndPrice n)
|
||||
|
||||
-- | Calculate the average of some mixed amounts.
|
||||
averageMixedAmounts :: [MixedAmount] -> MixedAmount
|
||||
averageMixedAmounts [] = 0
|
||||
|
||||
@ -154,7 +154,7 @@ instance ToMarkup Quantity
|
||||
toMarkup = toMarkup . show
|
||||
|
||||
-- | An amount's price (none, per unit, or total) in another commodity.
|
||||
-- Note the price should be a positive number, although this is not enforced.
|
||||
-- The price amount should always be positive.
|
||||
data Price = NoPrice | UnitPrice Amount | TotalPrice Amount
|
||||
deriving (Eq,Ord,Typeable,Data,Generic,Show)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user