lib: flip the arguments of (divide|multiply)[Mixed]Amount (api change)

Also, start using a mapMixedAmount helper.
This commit is contained in:
Simon Michael 2018-11-13 17:25:32 -08:00
parent 9e8b1612b0
commit b053942e9b
6 changed files with 25 additions and 21 deletions

View File

@ -223,12 +223,12 @@ amountTotalPriceToUnitPrice
amountTotalPriceToUnitPrice a = a
-- | Divide an amount's quantity by a constant.
divideAmount :: Amount -> Quantity -> Amount
divideAmount a@Amount{aquantity=q} d = a{aquantity=q/d}
divideAmount :: Quantity -> Amount -> Amount
divideAmount n a@Amount{aquantity=q} = a{aquantity=q/n}
-- | Multiply an amount's quantity by a constant.
multiplyAmount :: Amount -> Quantity -> Amount
multiplyAmount a@Amount{aquantity=q} d = a{aquantity=q*d}
multiplyAmount :: Quantity -> Amount -> Amount
multiplyAmount n a@Amount{aquantity=q} = a{aquantity=q*n}
-- | Is this amount negative ? The price is ignored.
isNegativeAmount :: Amount -> Bool
@ -536,23 +536,27 @@ filterMixedAmountByCommodity c (Mixed as) = Mixed as'
[] -> [nullamt{acommodity=c}]
as'' -> [sum as'']
-- | Apply a transform to a mixed amount's component 'Amount's.
mapMixedAmount :: (Amount -> Amount) -> MixedAmount -> MixedAmount
mapMixedAmount f (Mixed as) = Mixed $ map f as
-- | Convert a mixed amount's component amounts to the commodity of their
-- assigned price, if any.
costOfMixedAmount :: MixedAmount -> MixedAmount
costOfMixedAmount (Mixed as) = Mixed $ map costOfAmount as
-- | Divide a mixed amount's quantities by a constant.
divideMixedAmount :: MixedAmount -> Quantity -> MixedAmount
divideMixedAmount (Mixed as) d = Mixed $ map (`divideAmount` d) as
divideMixedAmount :: Quantity -> MixedAmount -> MixedAmount
divideMixedAmount n = mapMixedAmount (divideAmount n)
-- | Multiply a mixed amount's quantities by a constant.
multiplyMixedAmount :: MixedAmount -> Quantity -> MixedAmount
multiplyMixedAmount (Mixed as) d = Mixed $ map (`multiplyAmount` d) as
multiplyMixedAmount :: Quantity -> MixedAmount -> MixedAmount
multiplyMixedAmount n = mapMixedAmount (multiplyAmount n)
-- | Calculate the average of some mixed amounts.
averageMixedAmounts :: [MixedAmount] -> MixedAmount
averageMixedAmounts [] = 0
averageMixedAmounts as = sum as `divideMixedAmount` fromIntegral (length as)
averageMixedAmounts as = fromIntegral (length as) `divideMixedAmount` sum as
-- | Is this mixed amount negative, if it can be normalised to a single commodity ?
isNegativeMixedAmount :: MixedAmount -> Maybe Bool

View File

@ -469,7 +469,7 @@ priceInferrerFor t pt = inferprice
fromamount = head $ filter ((==fromcommodity).acommodity) sumamounts
tocommodity = head $ filter (/=fromcommodity) sumcommodities
toamount = head $ filter ((==tocommodity).acommodity) sumamounts
unitprice = toamount `divideAmount` (aquantity fromamount)
unitprice = (aquantity fromamount) `divideAmount` toamount
unitprecision = max 2 ((asprecision $ astyle $ toamount) + (asprecision $ astyle $ fromamount))
inferprice p = p

View File

@ -97,7 +97,7 @@ tmPostingRuleToFunction pr =
pramount = dbg6 "pramount" $ head $ amounts $ pamount pr
matchedamount = dbg6 "matchedamount" $ pamount p
unitpricedmatchedamount = dbg6 "unitpricedmatchedamount" $ mixedAmountTotalPriceToUnitPrice matchedamount
Mixed as = dbg6 "scaledmatchedamount" $ unitpricedmatchedamount `multiplyMixedAmount` n
Mixed as = dbg6 "scaledmatchedamount" $ n `multiplyMixedAmount` unitpricedmatchedamount
in
case acommodity pramount of
"" -> Mixed as

View File

@ -77,12 +77,12 @@ postingsReport opts q j = (totallabel, items)
historical = balancetype_ opts == HistoricalBalance
precedingsum = sumPostings precedingps
precedingavg | null precedingps = 0
| otherwise = precedingsum `divideMixedAmount` (fromIntegral $ length precedingps)
| otherwise = divideMixedAmount (fromIntegral $ length precedingps) precedingsum
startbal | average_ opts = if historical then precedingavg else 0
| otherwise = if historical then precedingsum else 0
startnum = if historical then length precedingps + 1 else 1
runningcalc | average_ opts = \i avg amt -> avg + (amt - avg) `divideMixedAmount` (fromIntegral i) -- running average
| otherwise = \_ bal amt -> bal + amt -- running total
runningcalc | average_ opts = \i avg amt -> divideMixedAmount (fromIntegral i) avg + amt - avg -- running average
| otherwise = \_ bal amt -> bal + amt -- running total
totallabel = "Total"

View File

@ -49,11 +49,11 @@ prices opts j = do
showPrice :: MarketPrice -> String
showPrice mp = unwords ["P", show $ mpdate mp, T.unpack . quoteCommoditySymbolIfNeeded $ mpcommodity mp, showAmountWithZeroCommodity $ mpamount mp]
divideAmount' :: Amount -> Quantity -> Amount
divideAmount' a d = a' where
a' = (a `divideAmount` d) { astyle = style' }
divideAmount' :: Quantity -> Amount -> Amount
divideAmount' n a = a' where
a' = (n `divideAmount` a) { astyle = style' }
style' = (astyle a) { asprecision = precision' }
extPrecision = (1+) . floor . logBase 10 $ (realToFrac d :: Double)
extPrecision = (1+) . floor . logBase 10 $ (realToFrac n :: Double)
precision' = extPrecision + asprecision (astyle a)
invertPrice :: Amount -> Amount
@ -63,7 +63,7 @@ invertPrice a =
UnitPrice pa -> invertPrice
-- normalize to TotalPrice
a { aprice = TotalPrice pa' } where
pa' = (pa `divideAmount` (1 / aquantity a)) { aprice = NoPrice }
pa' = ((1 / aquantity a) `divideAmount` pa) { aprice = NoPrice }
TotalPrice pa ->
a { aquantity = aquantity pa * signum (aquantity a), acommodity = acommodity pa, aprice = TotalPrice pa' } where
pa' = pa { aquantity = abs $ aquantity a, acommodity = acommodity a, aprice = NoPrice, astyle = astyle a }
@ -75,7 +75,7 @@ amountCost d a =
UnitPrice pa -> Just
MarketPrice { mpdate = d, mpcommodity = acommodity a, mpamount = pa }
TotalPrice pa -> Just
MarketPrice { mpdate = d, mpcommodity = acommodity a, mpamount = pa `divideAmount'` abs (aquantity a) }
MarketPrice { mpdate = d, mpcommodity = acommodity a, mpamount = abs (aquantity a) `divideAmount'` pa }
postingCosts :: Posting -> [MarketPrice]
postingCosts p = mapMaybe (amountCost date) . amounts $ pamount p where

View File

@ -187,7 +187,7 @@ compoundBalanceCommand CompoundBalanceCommandSpec{..} opts@CliOpts{reportopts_=r
where zeros = replicate numcols nullmixedamt
grandtotal = sum coltotals
grandavg | null coltotals = nullmixedamt
| otherwise = grandtotal `divideMixedAmount` fromIntegral (length coltotals)
| otherwise = fromIntegral (length coltotals) `divideMixedAmount` grandtotal
in
(coltotals, grandtotal, grandavg)
colspans =