--basis/-B flag, to show all priced amounts on cost basis. Also a --cost alias.
This commit is contained in:
		
							parent
							
								
									2d49bc4100
								
							
						
					
					
						commit
						52ff46a326
					
				| @ -83,35 +83,39 @@ filterRawLedgerTransactionsByRealness True (RawLedger ms ps es f) = | |||||||
| -- | Give all a ledger's amounts their canonical display settings.  That | -- | Give all a ledger's amounts their canonical display settings.  That | ||||||
| -- is, in each commodity, amounts will use the display settings of the | -- is, in each commodity, amounts will use the display settings of the | ||||||
| -- first amount detected, and the greatest precision of the amounts | -- first amount detected, and the greatest precision of the amounts | ||||||
| -- detected. | -- detected. Also, amounts are converted to cost basis if that flag is | ||||||
| canonicaliseAmounts :: RawLedger -> RawLedger | -- active. | ||||||
| canonicaliseAmounts l@(RawLedger ms ps es f) = RawLedger ms ps (map fixEntryAmounts es) f | canonicaliseAmounts :: Bool -> RawLedger -> RawLedger | ||||||
|  | canonicaliseAmounts costbasis l@(RawLedger ms ps es f) = RawLedger ms ps (map fixEntryAmounts es) f | ||||||
|     where  |     where  | ||||||
|       fixEntryAmounts (Entry d s c de co ts pr) = Entry d s c de co (map fixRawTransactionAmounts ts) pr |       fixEntryAmounts (Entry d s c de co ts pr) = Entry d s c de co (map fixRawTransactionAmounts ts) pr | ||||||
|       fixRawTransactionAmounts (RawTransaction ac a c t) = RawTransaction ac (fixMixedAmount a) c t |       fixRawTransactionAmounts (RawTransaction ac a c t) = RawTransaction ac (fixMixedAmount a) c t | ||||||
|       fixMixedAmount (Mixed as) = Mixed $ map fixAmount as |       fixMixedAmount (Mixed as) = Mixed $ map fixAmount as | ||||||
|       fixAmount (Amount c q pri) = Amount (canonicalcommodity c) q pri |       fixAmount | costbasis = fixcommodity . costOfAmount | ||||||
|       canonicalcommodity c@(Commodity {symbol=s}) = |                 | otherwise = fixcommodity | ||||||
|           (firstoccurrenceof c){precision=maximum $ map precision $ commoditieswithsymbol s} |       fixcommodity a = a{commodity=canonicalcommodity $ commodity a} | ||||||
|       firstoccurrenceof Commodity{symbol=s} = head $ commoditieswithsymbol s |       canonicalcommodity c = (firstoccurrenceof c){precision=maxprecision c} | ||||||
|       -- Get ledger's amounts' commodities with a given symbol, in the order parsed. |  | ||||||
|       -- Call with a good symbol or it will fail. |  | ||||||
|       commoditieswithsymbol :: String -> [Commodity] |  | ||||||
|       commoditieswithsymbol s = fromMaybe (error $ "no such commodity "++s) (Map.lookup s commoditiesmap) |  | ||||||
|           where |           where | ||||||
|             commoditiesmap :: Map.Map String [Commodity] |             firstoccurrenceof c = head $ rawLedgerCommoditiesWithSymbol l (symbol c) | ||||||
|             commoditiesmap = Map.fromList [(symbol $ head cs,cs) | |             maxprecision c = maximum $ map precision $ rawLedgerCommoditiesWithSymbol l (symbol c) | ||||||
|                                            cs <- groupBy samesymbol $ rawLedgerCommodities l] |  | ||||||
|             samesymbol c1 c2 = symbol c1 == symbol c2 |  | ||||||
| 
 | 
 | ||||||
| -- | Get just the amounts from a ledger, in the order parsed. | -- | Get all amount commodities with a given symbol, in the order parsed. | ||||||
| rawLedgerAmounts :: RawLedger -> [MixedAmount] | -- Must be called with a good symbol or it will fail. | ||||||
| rawLedgerAmounts = map amount . rawLedgerTransactions | rawLedgerCommoditiesWithSymbol :: RawLedger -> String -> [Commodity] | ||||||
|  | rawLedgerCommoditiesWithSymbol l s =  | ||||||
|  |     fromMaybe (error $ "no such commodity "++s) (Map.lookup s map) | ||||||
|  |     where | ||||||
|  |       map = Map.fromList [(symbol $ head cs,cs) | cs <- groupBy same $ rawLedgerCommodities l] | ||||||
|  |       same c1 c2 = symbol c1 == symbol c2 | ||||||
| 
 | 
 | ||||||
| -- | Get just the ammount commodities from a ledger, in the order parsed. | -- | Get just the ammount commodities from a ledger, in the order parsed. | ||||||
| rawLedgerCommodities :: RawLedger -> [Commodity] | rawLedgerCommodities :: RawLedger -> [Commodity] | ||||||
| rawLedgerCommodities = map commodity . concatMap amounts . rawLedgerAmounts | rawLedgerCommodities = map commodity . concatMap amounts . rawLedgerAmounts | ||||||
| 
 | 
 | ||||||
|  | -- | Get just the amounts from a ledger, in the order parsed. | ||||||
|  | rawLedgerAmounts :: RawLedger -> [MixedAmount] | ||||||
|  | rawLedgerAmounts = map amount . rawLedgerTransactions | ||||||
|  | 
 | ||||||
| -- | Get just the amount precisions from a ledger, in the order parsed. | -- | Get just the amount precisions from a ledger, in the order parsed. | ||||||
| rawLedgerPrecisions :: RawLedger -> [Int] | rawLedgerPrecisions :: RawLedger -> [Int] | ||||||
| rawLedgerPrecisions = map precision . rawLedgerCommodities | rawLedgerPrecisions = map precision . rawLedgerCommodities | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								NOTES
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								NOTES
									
									
									
									
									
								
							| @ -15,7 +15,6 @@ implementations were its consequences." --Niklaus Wirth | |||||||
| *** flexible date expressions, for easier time reports | *** flexible date expressions, for easier time reports | ||||||
| **** more formats | **** more formats | ||||||
| **** periods | **** periods | ||||||
| *** commodity @ rate, for tracking client hours in main ledger |  | ||||||
| *** actual/effective entry & txn dates, for ? | *** actual/effective entry & txn dates, for ? | ||||||
| *** --display, for reconciling recent transactions with real balance | *** --display, for reconciling recent transactions with real balance | ||||||
| *** more ledger features from README | *** more ledger features from README | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ options = [ | |||||||
|  Option ['b'] ["begin"]        (ReqArg Begin "YYYY/MM/DD") "report on entries on or after this date", |  Option ['b'] ["begin"]        (ReqArg Begin "YYYY/MM/DD") "report on entries on or after this date", | ||||||
|  Option ['e'] ["end"]          (ReqArg End "YYYY/MM/DD")   "report on entries prior to this date", |  Option ['e'] ["end"]          (ReqArg End "YYYY/MM/DD")   "report on entries prior to this date", | ||||||
|  Option ['C'] ["cleared"]      (NoArg  Cleared)            "report only on cleared entries", |  Option ['C'] ["cleared"]      (NoArg  Cleared)            "report only on cleared entries", | ||||||
|  |  Option ['B'] ["cost","basis"] (NoArg  CostBasis)          "report cost basis of commodities", | ||||||
|  Option []    ["depth"]        (ReqArg Depth "N")          "balance report: maximum account depth to show", |  Option []    ["depth"]        (ReqArg Depth "N")          "balance report: maximum account depth to show", | ||||||
|  Option ['E'] ["empty"]        (NoArg  Empty)              "balance report: show accounts with zero balance", |  Option ['E'] ["empty"]        (NoArg  Empty)              "balance report: show accounts with zero balance", | ||||||
|  Option ['R'] ["real"]         (NoArg  Real)               "report only on real (non-virtual) transactions", |  Option ['R'] ["real"]         (NoArg  Real)               "report only on real (non-virtual) transactions", | ||||||
| @ -44,6 +45,7 @@ data Opt = | |||||||
|     Begin String |  |     Begin String |  | ||||||
|     End String |  |     End String |  | ||||||
|     Cleared |  |     Cleared |  | ||||||
|  |     CostBasis |  | ||||||
|     Depth String |  |     Depth String |  | ||||||
|     Empty |  |     Empty |  | ||||||
|     Real |  |     Real |  | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README
									
									
									
									
									
								
							| @ -73,14 +73,18 @@ This version of hledger mimics a subset of ledger 2.6.1: | |||||||
|    -E, --empty            balance report: show accounts with zero balance |    -E, --empty            balance report: show accounts with zero balance | ||||||
|    -n, --collapse         balance report: no grand total |    -n, --collapse         balance report: no grand total | ||||||
|   |   | ||||||
|  |    Commodity reporting: | ||||||
|  |    -B, --basis, --cost    report cost basis of commodities | ||||||
|  | 
 | ||||||
|    Commands: |    Commands: | ||||||
|    balance  [REGEXP]...   show balance totals for matching accounts |    balance  [REGEXP]...   show balance totals for matching accounts | ||||||
|    register [REGEXP]...   show register of matching transactions |    register [REGEXP]...   show register of matching transactions | ||||||
|    print    [REGEXP]...   print all matching entries |    print    [REGEXP]...   print all matching entries | ||||||
| 
 | 
 | ||||||
| hledger-only features: | hledger-specific features: | ||||||
| 
 | 
 | ||||||
| -  --depth=N              balance report: maximum account depth to show |    --depth=N              balance report: maximum account depth to show | ||||||
|  |    --cost                 alias for basis | ||||||
| 
 | 
 | ||||||
| ledger features not supported: | ledger features not supported: | ||||||
| 
 | 
 | ||||||
| @ -146,7 +150,6 @@ ledger features not supported: | |||||||
|    -L, --price-exp MINS   download quotes only if newer than MINS (def: 1440) |    -L, --price-exp MINS   download quotes only if newer than MINS (def: 1440) | ||||||
|    -Q, --download         download price information when needed |    -Q, --download         download price information when needed | ||||||
|    -O, --quantity         report commodity totals (this is the default) |    -O, --quantity         report commodity totals (this is the default) | ||||||
|    -B, --basis            report cost basis of commodities |  | ||||||
|    -V, --market           report last known market value |    -V, --market           report last known market value | ||||||
|    -g, --performance      report gain/loss for each displayed transaction |    -g, --performance      report gain/loss for each displayed transaction | ||||||
|    -G, --gain             report net gain/loss |    -G, --gain             report net gain/loss | ||||||
| @ -162,3 +165,4 @@ Some other differences: | |||||||
| - hledger talks about the entry and transaction "description", which ledger calls "note" | - hledger talks about the entry and transaction "description", which ledger calls "note" | ||||||
| - hledger always shows timelog balances in hours | - hledger always shows timelog balances in hours | ||||||
| - hledger doesn't require a space after flags like -f | - hledger doesn't require a space after flags like -f | ||||||
|  | - hledger keeps differently-priced amounts of the same commodity separate | ||||||
							
								
								
									
										19
									
								
								Tests.hs
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								Tests.hs
									
									
									
									
									
								
							| @ -88,7 +88,7 @@ misc_tests = TestList [ | |||||||
|   , |   , | ||||||
|   "canonicaliseAmounts" ~: do |   "canonicaliseAmounts" ~: do | ||||||
|     -- all amounts use the greatest precision |     -- all amounts use the greatest precision | ||||||
|     assertequal [2,2] (rawLedgerPrecisions $ canonicaliseAmounts $ rawLedgerWithAmounts ["1","2.00"]) |     assertequal [2,2] (rawLedgerPrecisions $ canonicaliseAmounts False $ rawLedgerWithAmounts ["1","2.00"]) | ||||||
|   , |   , | ||||||
|   "timeLog" ~: do |   "timeLog" ~: do | ||||||
|     assertparseequal timelog1 (parsewith timelog timelog1_str) |     assertparseequal timelog1 (parsewith timelog timelog1_str) | ||||||
| @ -239,6 +239,23 @@ balancecommand_tests = TestList [ | |||||||
|    "                 $-2    cash\n" ++ |    "                 $-2    cash\n" ++ | ||||||
|    "                  $1    saving\n" ++ |    "                  $1    saving\n" ++ | ||||||
|    "") |    "") | ||||||
|  |  , | ||||||
|  |   "balance report with cost basis" ~: do | ||||||
|  |     let l = cacheLedger [] $  | ||||||
|  |             filterRawLedger Nothing Nothing [] False False $  | ||||||
|  |             canonicaliseAmounts True $ -- enable cost basis adjustment | ||||||
|  |             rawledgerfromstring | ||||||
|  |              ("" ++ | ||||||
|  |               "2008/1/1 test           \n" ++ | ||||||
|  |               "  a:b          10h @ $50\n" ++ | ||||||
|  |               "  c:d                   \n" ++ | ||||||
|  |               "\n") | ||||||
|  |     assertequal  | ||||||
|  |              ("                $500  a\n" ++ | ||||||
|  |               "               $-500  c\n" ++ | ||||||
|  |               "" | ||||||
|  |              ) | ||||||
|  |              (showBalanceReport [] [] l) | ||||||
|  ] where |  ] where | ||||||
|     gives (opts,pats) e = do  |     gives (opts,pats) e = do  | ||||||
|       l <- ledgerfromfile pats "sample.ledger" |       l <- ledgerfromfile pats "sample.ledger" | ||||||
|  | |||||||
| @ -70,10 +70,11 @@ parseLedgerAndDo :: [Opt] -> [String] -> ([Opt] -> [String] -> Ledger -> IO ()) | |||||||
| parseLedgerAndDo opts args cmd =  | parseLedgerAndDo opts args cmd =  | ||||||
|     ledgerFilePathFromOpts opts >>= parseLedgerFile >>= either printParseError runcmd |     ledgerFilePathFromOpts opts >>= parseLedgerFile >>= either printParseError runcmd | ||||||
|     where |     where | ||||||
|       runcmd = cmd opts args . cacheLedger apats . filterRawLedger b e dpats c r . canonicaliseAmounts |       runcmd = cmd opts args . cacheLedger apats . filterRawLedger b e dpats c r . canonicaliseAmounts costbasis | ||||||
|       b = beginDateFromOpts opts |       b = beginDateFromOpts opts | ||||||
|       e = endDateFromOpts opts |       e = endDateFromOpts opts | ||||||
|       (apats,dpats) = parseAccountDescriptionArgs args |       (apats,dpats) = parseAccountDescriptionArgs args | ||||||
|       c = Cleared `elem` opts |       c = Cleared `elem` opts | ||||||
|       r = Real `elem` opts |       r = Real `elem` opts | ||||||
|  |       costbasis = CostBasis `elem` opts | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user