simple currency handling
This commit is contained in:
		
							parent
							
								
									c370d34de6
								
							
						
					
					
						commit
						3de3e861ee
					
				| @ -5,39 +5,79 @@ import Utils | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| type Date     = String | type Date     = String | ||||||
| type Status = Bool | 
 | ||||||
|  | -- generic tree. each node is a tuple of the node type and a | ||||||
|  | -- list of subtrees | ||||||
|  | newtype Tree a = Tree { node :: (a, [Tree a]) } deriving (Show,Eq) | ||||||
|  | branches = snd . node | ||||||
| 
 | 
 | ||||||
| -- amounts | -- amounts | ||||||
| -- amount arithmetic currently ignores currency conversion | {- a simple amount is a currency, quantity pair: | ||||||
|  |    0  | ||||||
|  |    $1  | ||||||
|  |    £-50 | ||||||
|  |    EUR 3.44  | ||||||
|  |    HRS 1.5 | ||||||
|  |    DAYS 3 | ||||||
|  |    GOOG 500 | ||||||
|  | 
 | ||||||
|  |    a mixed amount is one or more simple amounts: | ||||||
|  |    $50, EUR 3, APPL 500 | ||||||
|  |    HRS 16, $13.55, oranges 6 | ||||||
|  | 
 | ||||||
|  |    arithmetic: | ||||||
|  |    $1 - $5 = $-4 | ||||||
|  |    $1 + EUR 0.76 = $2 | ||||||
|  |    EUR0.76 + $1 = EUR 1.52 | ||||||
|  |    EUR0.76 - $1 = 0 | ||||||
|  |    ($5, HRS 2) + $1 = ($6, HRS 2) | ||||||
|  |    ($50, EUR 3, APPL 500) + ($13.55, oranges 6) = $67.51, APPL 500, oranges 6 | ||||||
|  |    ($50, EUR 3) * $-1 = $-53.96 | ||||||
|  |    ($50, APPL 500) * $-1 = error | ||||||
|  |     | ||||||
|  | -} | ||||||
|  | 
 | ||||||
|  | type Currency = String | ||||||
| 
 | 
 | ||||||
| data Amount = Amount { | data Amount = Amount { | ||||||
|                       currency :: String, |                       currency :: Currency, | ||||||
|                       quantity :: Double |                       quantity :: Double | ||||||
|                      } deriving (Eq,Ord) |                      } deriving (Eq,Ord) | ||||||
| 
 | 
 | ||||||
|  | instance Show Amount where show = showAmountRoundedOrZero | ||||||
|  | 
 | ||||||
|  | showAmountRoundedOrZero :: Amount -> String | ||||||
|  | showAmountRoundedOrZero (Amount cur qty) = | ||||||
|  |     let rounded = printf "%.2f" qty in | ||||||
|  |     case rounded of | ||||||
|  |       "0.00"    -> "0" | ||||||
|  |       "-0.00"   -> "0" | ||||||
|  |       otherwise -> cur ++ rounded | ||||||
|  | 
 | ||||||
| instance Num Amount where | instance Num Amount where | ||||||
|     abs (Amount c q) = Amount c (abs q) |     abs (Amount c q) = Amount c (abs q) | ||||||
|     signum (Amount c q) = Amount c (signum q) |     signum (Amount c q) = Amount c (signum q) | ||||||
|     fromInteger i = Amount "$" (fromInteger i) |     fromInteger i = Amount "$" (fromInteger i) | ||||||
|     (+) = amountAdd |     (+) = amountAdd | ||||||
|     (-) = amountSub |     (-) = amountSub | ||||||
|     (*) = amountMult |     (*) = amountMul | ||||||
| Amount ca qa `amountAdd` Amount cb qb = Amount ca (qa + qb) | Amount ac aq `amountAdd` b = Amount ac (aq + (quantity $ toCurrency ac b)) | ||||||
| Amount ca qa `amountSub` Amount cb qb = Amount ca (qa - qb) | Amount ac aq `amountSub` b = Amount ac (aq - (quantity $ toCurrency ac b)) | ||||||
| Amount ca qa `amountMult` Amount cb qb = Amount ca (qa * qb) | Amount ac aq `amountMul` b = Amount ac (aq * (quantity $ toCurrency ac b)) | ||||||
| 
 | 
 | ||||||
| instance Show Amount where show = amountRoundedOrZero | toCurrency :: Currency -> Amount -> Amount | ||||||
|  | toCurrency newc (Amount oldc q) = | ||||||
|  |     Amount newc (q * (conversionRate oldc newc)) | ||||||
| 
 | 
 | ||||||
| amountRoundedOrZero :: Amount -> String | conversionRate :: Currency -> Currency -> Double | ||||||
| amountRoundedOrZero (Amount cur qty) = | conversionRate oldc newc = (rate newc) / (rate oldc) | ||||||
|     let rounded = printf "%.2f" qty in |  | ||||||
|     case rounded of |  | ||||||
|       "0.00"    -> "0" |  | ||||||
|       "-0.00"   -> "0" |  | ||||||
|       otherwise -> cur ++ rounded |  | ||||||
| 
 | 
 | ||||||
| -- generic tree. each node is a tuple of the node type and a | rate :: Currency -> Double | ||||||
| -- list of subtrees | rate "$"   = 1.0 | ||||||
| newtype Tree a = Tree { node :: (a, [Tree a]) } deriving (Show,Eq) | rate "EUR" = 0.760383 | ||||||
| branches = snd . node | rate "£"   = 0.512527 | ||||||
|  | rate _     = 1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | data MixedAmount = MixedAmount [Amount] deriving (Eq,Ord) | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								Entry.hs
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Entry.hs
									
									
									
									
									
								
							| @ -6,6 +6,8 @@ import BasicTypes | |||||||
| import Transaction | import Transaction | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | type EntryStatus   = Bool | ||||||
|  | 
 | ||||||
| -- a register entry is displayed as two or more lines like this: | -- a register entry is displayed as two or more lines like this: | ||||||
| -- date       description          account                 amount       balance | -- date       description          account                 amount       balance | ||||||
| -- DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaaaaa  AAAAAAAAAAA AAAAAAAAAAAA | -- DDDDDDDDDD dddddddddddddddddddd aaaaaaaaaaaaaaaaaaaaaa  AAAAAAAAAAA AAAAAAAAAAAA | ||||||
| @ -19,7 +21,7 @@ import Transaction | |||||||
| 
 | 
 | ||||||
| data Entry = Entry { | data Entry = Entry { | ||||||
|                     edate :: Date, |                     edate :: Date, | ||||||
|                     estatus :: Status, |                     estatus :: EntryStatus, | ||||||
|                     ecode :: String, |                     ecode :: String, | ||||||
|                     edescription :: String, |                     edescription :: String, | ||||||
|                     etransactions :: [Transaction] |                     etransactions :: [Transaction] | ||||||
|  | |||||||
| @ -68,5 +68,5 @@ showTransactionAndBalance t b = | |||||||
|     (replicate 32 ' ') ++ (showTransaction $ transaction t) ++ (showBalance b) |     (replicate 32 ' ') ++ (showTransaction $ transaction t) ++ (showBalance b) | ||||||
| 
 | 
 | ||||||
| showBalance :: Amount -> String | showBalance :: Amount -> String | ||||||
| showBalance b = printf " %12s" (amountRoundedOrZero b) | showBalance b = printf " %12s" (showAmountRoundedOrZero b) | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								TODO
									
									
									
									
									
								
							| @ -1,15 +1,17 @@ | |||||||
|  | make it fast | ||||||
|  |  profile | ||||||
|  | 
 | ||||||
| basic features | basic features | ||||||
|  handle mixed amounts and currencies |  balance report account matching | ||||||
|  |  -f - | ||||||
|  print |  print | ||||||
|  entry |  entry | ||||||
|  -j and -J graph data output |  -j and -J graph data output | ||||||
|  !include |  !include | ||||||
|  read timelog files |  read timelog files | ||||||
| 
 | 
 | ||||||
| make it fast |  | ||||||
|  profile |  | ||||||
| 
 |  | ||||||
| more features | more features | ||||||
|  |  handle mixed amounts | ||||||
|  3.0-style elision |  3.0-style elision | ||||||
|  -p period expressions |  -p period expressions | ||||||
|  -d display expressions |  -d display expressions | ||||||
|  | |||||||
| @ -86,13 +86,6 @@ printRegister opts args ledger = do | |||||||
| 
 | 
 | ||||||
| printBalance :: [Flag] -> [String] -> Ledger -> IO () | printBalance :: [Flag] -> [String] -> Ledger -> IO () | ||||||
| printBalance opts args ledger = do | printBalance opts args ledger = do | ||||||
| --   putStr $ showLedgerAccounts ledger acctpats depth |  | ||||||
| --       where  |  | ||||||
| --         (acctpats,_) = ledgerPatternArgs args |  | ||||||
| --         showsubs = (ShowSubs `elem` opts) |  | ||||||
| --         depth = case showsubs of |  | ||||||
| --                   True -> 999 |  | ||||||
| --                   False -> depthOption opts |  | ||||||
|   putStr $ case showsubs of |   putStr $ case showsubs of | ||||||
|              True -> showLedgerAccounts ledger 999 |              True -> showLedgerAccounts ledger 999 | ||||||
|              False -> showLedgerAccounts ledger 1 |              False -> showLedgerAccounts ledger 1 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user