mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-27 12:24:43 +03:00
--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
|
||||
-- is, in each commodity, amounts will use the display settings of the
|
||||
-- first amount detected, and the greatest precision of the amounts
|
||||
-- detected.
|
||||
canonicaliseAmounts :: RawLedger -> RawLedger
|
||||
canonicaliseAmounts l@(RawLedger ms ps es f) = RawLedger ms ps (map fixEntryAmounts es) f
|
||||
-- detected. Also, amounts are converted to cost basis if that flag is
|
||||
-- active.
|
||||
canonicaliseAmounts :: Bool -> RawLedger -> RawLedger
|
||||
canonicaliseAmounts costbasis l@(RawLedger ms ps es f) = RawLedger ms ps (map fixEntryAmounts es) f
|
||||
where
|
||||
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
|
||||
fixMixedAmount (Mixed as) = Mixed $ map fixAmount as
|
||||
fixAmount (Amount c q pri) = Amount (canonicalcommodity c) q pri
|
||||
canonicalcommodity c@(Commodity {symbol=s}) =
|
||||
(firstoccurrenceof c){precision=maximum $ map precision $ commoditieswithsymbol s}
|
||||
firstoccurrenceof Commodity{symbol=s} = head $ commoditieswithsymbol s
|
||||
-- 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)
|
||||
fixAmount | costbasis = fixcommodity . costOfAmount
|
||||
| otherwise = fixcommodity
|
||||
fixcommodity a = a{commodity=canonicalcommodity $ commodity a}
|
||||
canonicalcommodity c = (firstoccurrenceof c){precision=maxprecision c}
|
||||
where
|
||||
commoditiesmap :: Map.Map String [Commodity]
|
||||
commoditiesmap = Map.fromList [(symbol $ head cs,cs) |
|
||||
cs <- groupBy samesymbol $ rawLedgerCommodities l]
|
||||
samesymbol c1 c2 = symbol c1 == symbol c2
|
||||
firstoccurrenceof c = head $ rawLedgerCommoditiesWithSymbol l (symbol c)
|
||||
maxprecision c = maximum $ map precision $ rawLedgerCommoditiesWithSymbol l (symbol c)
|
||||
|
||||
-- | Get just the amounts from a ledger, in the order parsed.
|
||||
rawLedgerAmounts :: RawLedger -> [MixedAmount]
|
||||
rawLedgerAmounts = map amount . rawLedgerTransactions
|
||||
-- | Get all amount commodities with a given symbol, in the order parsed.
|
||||
-- Must be called with a good symbol or it will fail.
|
||||
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.
|
||||
rawLedgerCommodities :: RawLedger -> [Commodity]
|
||||
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.
|
||||
rawLedgerPrecisions :: RawLedger -> [Int]
|
||||
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
|
||||
**** more formats
|
||||
**** periods
|
||||
*** commodity @ rate, for tracking client hours in main ledger
|
||||
*** actual/effective entry & txn dates, for ?
|
||||
*** --display, for reconciling recent transactions with real balance
|
||||
*** 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 ['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 ['B'] ["cost","basis"] (NoArg CostBasis) "report cost basis of commodities",
|
||||
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 ['R'] ["real"] (NoArg Real) "report only on real (non-virtual) transactions",
|
||||
@ -44,6 +45,7 @@ data Opt =
|
||||
Begin String |
|
||||
End String |
|
||||
Cleared |
|
||||
CostBasis |
|
||||
Depth String |
|
||||
Empty |
|
||||
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
|
||||
-n, --collapse balance report: no grand total
|
||||
|
||||
Commodity reporting:
|
||||
-B, --basis, --cost report cost basis of commodities
|
||||
|
||||
Commands:
|
||||
balance [REGEXP]... show balance totals for matching accounts
|
||||
register [REGEXP]... show register of matching transactions
|
||||
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:
|
||||
|
||||
@ -146,7 +150,6 @@ ledger features not supported:
|
||||
-L, --price-exp MINS download quotes only if newer than MINS (def: 1440)
|
||||
-Q, --download download price information when needed
|
||||
-O, --quantity report commodity totals (this is the default)
|
||||
-B, --basis report cost basis of commodities
|
||||
-V, --market report last known market value
|
||||
-g, --performance report gain/loss for each displayed transaction
|
||||
-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 always shows timelog balances in hours
|
||||
- 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
|
||||
-- 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
|
||||
assertparseequal timelog1 (parsewith timelog timelog1_str)
|
||||
@ -239,6 +239,23 @@ balancecommand_tests = TestList [
|
||||
" $-2 cash\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
|
||||
gives (opts,pats) e = do
|
||||
l <- ledgerfromfile pats "sample.ledger"
|
||||
|
@ -70,10 +70,11 @@ parseLedgerAndDo :: [Opt] -> [String] -> ([Opt] -> [String] -> Ledger -> IO ())
|
||||
parseLedgerAndDo opts args cmd =
|
||||
ledgerFilePathFromOpts opts >>= parseLedgerFile >>= either printParseError runcmd
|
||||
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
|
||||
e = endDateFromOpts opts
|
||||
(apats,dpats) = parseAccountDescriptionArgs args
|
||||
c = Cleared `elem` opts
|
||||
r = Real `elem` opts
|
||||
costbasis = CostBasis `elem` opts
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user