fix a sign bug with negative total-priced (@@) amounts
This commit is contained in:
		
							parent
							
								
									091ec4e51f
								
							
						
					
					
						commit
						bfe935e18c
					
				| @ -125,45 +125,12 @@ convertMixedAmountToSimilarCommodity c (Mixed as) = Amount c total Nothing | ||||
| -- - price amounts must be MixedAmounts with exactly one component Amount (or there will be a runtime error) | ||||
| -- - price amounts should be positive, though this is not currently enforced | ||||
| costOfAmount :: Amount -> Amount | ||||
| costOfAmount a@(Amount _ q price) | ||||
|     | isNothing price      = a | ||||
|     | isZeroMixedAmount up = nullamt | ||||
|     | otherwise            = Amount pc (q*pq) Nothing | ||||
|     where | ||||
|       unitprice@(Just up) = priceAndQuantityToMaybeUnitPrice price q | ||||
|       (Amount pc pq _) = | ||||
|           case price of | ||||
|             Just (UnitPrice  pa) -> head $ amounts pa | ||||
|             Just (TotalPrice _)  -> head $ amounts $ fromJust unitprice | ||||
|             _ -> error "impossible case, programmer error" | ||||
| 
 | ||||
| -- | Convert a (unit or total) Price and quantity to a MixedAmount unit price. | ||||
| priceAndQuantityToMaybeUnitPrice :: Maybe Price -> Double -> Maybe MixedAmount | ||||
| priceAndQuantityToMaybeUnitPrice Nothing _               = Nothing | ||||
| priceAndQuantityToMaybeUnitPrice (Just (UnitPrice a)) _  = Just a | ||||
| priceAndQuantityToMaybeUnitPrice (Just (TotalPrice a)) q = Just $ a `divideMixedAmount` q | ||||
| 
 | ||||
| -- | Get the string representation of an amount, based on its commodity's | ||||
| -- display settings. | ||||
| showAmount :: Amount -> String | ||||
| showAmount (Amount (Commodity {symbol="AUTO"}) _ _) = "" -- can appear in an error message | ||||
| showAmount a@(Amount (Commodity {symbol=sym,side=side,spaced=spaced}) _ pri) = | ||||
|     case side of | ||||
|       L -> printf "%s%s%s%s" sym' space quantity price | ||||
|       R -> printf "%s%s%s%s" quantity space sym' price | ||||
|     where | ||||
|       sym' = quoteCommoditySymbolIfNeeded sym | ||||
|       space = if (spaced && not (null sym')) then " " else "" | ||||
|       quantity = showAmount' a | ||||
|       price = maybe "" showPrice pri | ||||
| 
 | ||||
| showPrice :: Price -> String | ||||
| showPrice (UnitPrice pa)  = " @ "  ++ showMixedAmount pa | ||||
| showPrice (TotalPrice pa) = " @@ " ++ showMixedAmount pa | ||||
| 
 | ||||
| showPriceDebug :: Price -> String | ||||
| showPriceDebug (UnitPrice pa)  = " @ "  ++ showMixedAmountDebug pa | ||||
| showPriceDebug (TotalPrice pa) = " @@ " ++ showMixedAmountDebug pa | ||||
| costOfAmount a@(Amount _ q price) = | ||||
|     case price of | ||||
|       Nothing -> a | ||||
|       Just (UnitPrice  (Mixed [Amount pc pq Nothing])) -> Amount pc (pq*q) Nothing | ||||
|       Just (TotalPrice (Mixed [Amount pc pq Nothing])) -> Amount pc (pq*signum q) Nothing | ||||
|       _ -> error' "costOfAmount: Malformed price encountered, programmer error" | ||||
| 
 | ||||
| -- | Get the string representation of an amount, based on its commodity's | ||||
| -- display settings except using the specified precision. | ||||
| @ -186,10 +153,34 @@ showAmountWithoutPrice a = showAmount a{price=Nothing} | ||||
| showAmountWithoutPriceOrCommodity :: Amount -> String | ||||
| showAmountWithoutPriceOrCommodity a@Amount{commodity=c} = showAmount a{commodity=c{symbol=""}, price=Nothing} | ||||
| 
 | ||||
| showPrice :: Price -> String | ||||
| showPrice (UnitPrice pa)  = " @ "  ++ showMixedAmount pa | ||||
| showPrice (TotalPrice pa) = " @@ " ++ showMixedAmount pa | ||||
| 
 | ||||
| showPriceDebug :: Price -> String | ||||
| showPriceDebug (UnitPrice pa)  = " @ "  ++ showMixedAmountDebug pa | ||||
| showPriceDebug (TotalPrice pa) = " @@ " ++ showMixedAmountDebug pa | ||||
| 
 | ||||
| -- | Get the string representation of an amount, based on its commodity's | ||||
| -- display settings. Amounts which look like zero are rendered without sign or commodity. | ||||
| showAmount :: Amount -> String | ||||
| showAmount (Amount (Commodity {symbol="AUTO"}) _ _) = "" -- can appear in an error message | ||||
| showAmount a@(Amount (Commodity {symbol=sym,side=side,spaced=spaced}) _ pri) = | ||||
|     case side of | ||||
|       L -> printf "%s%s%s%s" sym' space quantity' price | ||||
|       R -> printf "%s%s%s%s" quantity' space sym' price | ||||
|     where | ||||
|       quantity = showamountquantity a | ||||
|       displayingzero = null $ filter (`elem` "123456789") $ quantity | ||||
|       (quantity',sym') | displayingzero = ("0","") | ||||
|                        | otherwise      = (quantity,quoteCommoditySymbolIfNeeded sym) | ||||
|       space = if (not (null sym') && spaced) then " " else "" | ||||
|       price = maybe "" showPrice pri | ||||
| 
 | ||||
| -- | Get the string representation of the number part of of an amount, | ||||
| -- using the display settings from its commodity. | ||||
| showAmount' :: Amount -> String | ||||
| showAmount' (Amount (Commodity {decimalpoint=d,precision=p,separator=s,separatorpositions=spos}) q _) = | ||||
| showamountquantity :: Amount -> String | ||||
| showamountquantity (Amount (Commodity {decimalpoint=d,precision=p,separator=s,separatorpositions=spos}) q _) = | ||||
|     punctuatenumber d s spos $ qstr | ||||
|     where | ||||
|     qstr -- | p == maxprecision && isint q = printf "%d" (round q::Integer) | ||||
| @ -487,4 +478,10 @@ tests_Hledger_Data_Amount = TestList [ | ||||
| 
 | ||||
|   ,"punctuatethousands 3" ~: punctuatethousands "-100" `is` "-100" | ||||
| 
 | ||||
|   ,"costOfAmount" ~: do | ||||
|     costOfAmount (euros 1) `is` euros 1 | ||||
|     costOfAmount (euros 2){price=Just $ UnitPrice $ Mixed [dollars 2]} `is` dollars 4 | ||||
|     costOfAmount (euros 1){price=Just $ TotalPrice $ Mixed [dollars 2]} `is` dollars 2 | ||||
|     costOfAmount (euros (-1)){price=Just $ TotalPrice $ Mixed [dollars 2]} `is` dollars (-2) | ||||
| 
 | ||||
|   ] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user