This allows period and comma to be used for decimal point and digit group separator or vice versa, and also flexible digit groups. See http://en.wikipedia.org/wiki/Decimal_separator . Digit group separators are possibly not worth the trouble and might not stay.
		
			
				
	
	
		
			64 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Haskell
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Haskell
		
	
	
	
	
	
{-|
 | 
						|
 | 
						|
A 'Commodity' is a symbol representing a currency or some other kind of
 | 
						|
thing we are tracking, and some display preferences that tell how to
 | 
						|
display 'Amount's of the commodity - is the symbol on the left or right,
 | 
						|
are thousands separated by comma, significant decimal places and so on.
 | 
						|
 | 
						|
-}
 | 
						|
module Hledger.Data.Commodity
 | 
						|
where
 | 
						|
import Hledger.Data.Utils
 | 
						|
import Hledger.Data.Types
 | 
						|
import qualified Data.Map as Map
 | 
						|
import Data.Map ((!))
 | 
						|
 | 
						|
 | 
						|
nonsimplecommoditychars = "0123456789-.@;\n \""
 | 
						|
 | 
						|
quoteCommoditySymbolIfNeeded s | any (`elem` nonsimplecommoditychars) s = "\"" ++ s ++ "\""
 | 
						|
                               | otherwise = s
 | 
						|
 | 
						|
-- convenient amount and commodity constructors, for tests etc.
 | 
						|
 | 
						|
unknown = Commodity {symbol="", side=L,spaced=False,decimalpoint='.',precision=0,separator=',',separatorpositions=[]}
 | 
						|
dollar  = Commodity {symbol="$",side=L,spaced=False,decimalpoint='.',precision=2,separator=',',separatorpositions=[]}
 | 
						|
euro    = Commodity {symbol="€",side=L,spaced=False,decimalpoint='.',precision=2,separator=',',separatorpositions=[]}
 | 
						|
pound   = Commodity {symbol="£",side=L,spaced=False,decimalpoint='.',precision=2,separator=',',separatorpositions=[]}
 | 
						|
hour    = Commodity {symbol="h",side=R,spaced=False,decimalpoint='.',precision=1,separator=',',separatorpositions=[]}
 | 
						|
 | 
						|
dollars n = Amount dollar n Nothing
 | 
						|
euros n   = Amount euro   n Nothing
 | 
						|
pounds n  = Amount pound  n Nothing
 | 
						|
hours n   = Amount hour   n Nothing
 | 
						|
 | 
						|
defaultcommodities = [dollar, euro, pound, hour, unknown]
 | 
						|
 | 
						|
-- | Look up one of the hard-coded default commodities. For use in tests.
 | 
						|
comm :: String -> Commodity
 | 
						|
comm sym = fromMaybe 
 | 
						|
              (error' "commodity lookup failed") 
 | 
						|
              $ find (\(Commodity{symbol=s}) -> s==sym) defaultcommodities
 | 
						|
 | 
						|
-- | Find the conversion rate between two commodities. Currently returns 1.
 | 
						|
conversionRate :: Commodity -> Commodity -> Double
 | 
						|
conversionRate _ _ = 1
 | 
						|
 | 
						|
-- | Convert a list of commodities to a map from commodity symbols to
 | 
						|
-- unique, display-preference-canonicalised commodities.
 | 
						|
canonicaliseCommodities :: [Commodity] -> Map.Map String Commodity
 | 
						|
canonicaliseCommodities cs =
 | 
						|
    Map.fromList [(s,firstc{precision=maxp}) | s <- symbols,
 | 
						|
                  let cs = commoditymap ! s,
 | 
						|
                  let firstc = head cs,
 | 
						|
                  let maxp = maximum $ map precision cs
 | 
						|
                 ]
 | 
						|
  where
 | 
						|
    commoditymap = Map.fromList [(s, commoditieswithsymbol s) | s <- symbols]
 | 
						|
    commoditieswithsymbol s = filter ((s==) . symbol) cs
 | 
						|
    symbols = nub $ map symbol cs
 | 
						|
 | 
						|
tests_Hledger_Data_Commodity = TestList [
 | 
						|
 ]
 | 
						|
 |