mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-26 03:42:25 +03:00
balance: combine boring account names properly when matching account patterns
This commit is contained in:
parent
b840d69d67
commit
ec1b5b9bce
30
Ledger.hs
30
Ledger.hs
@ -34,14 +34,19 @@ instance Show Ledger where
|
||||
(length $ periodic_entries $ rawledger l))
|
||||
(length $ accountnames l)
|
||||
|
||||
-- at startup, we augment the parsed ledger entries with an account map
|
||||
-- and other things useful for performance
|
||||
cacheLedger :: LedgerFile -> Ledger
|
||||
cacheLedger l =
|
||||
-- at startup, to improve performance, we refine the parsed ledger entries:
|
||||
-- 1. filter based on account/description patterns, if any
|
||||
-- 2. cache per-account info
|
||||
-- also, figure out the precision(s) to use
|
||||
cacheLedger :: [String] -> [String] -> LedgerFile -> Ledger
|
||||
cacheLedger acctpats descpats l =
|
||||
let
|
||||
ant = rawLedgerAccountNameTree l
|
||||
(acctpats', descpats') = (wilddefault acctpats, wilddefault descpats)
|
||||
ant = filterAccountNameTree acctpats' True 9999 $ rawLedgerAccountNameTree l
|
||||
ans = flatten ant
|
||||
ts = rawLedgerTransactions l
|
||||
filterTxnsByAcctpats ts = concat [filter (matchTransactionAccount $ mkRegex r) ts | r <- acctpats']
|
||||
allts = rawLedgerTransactions l
|
||||
ts = filterTxnsByAcctpats allts
|
||||
sortedts = sortBy (comparing account) ts
|
||||
groupedts = groupBy (\t1 t2 -> account t1 == account t2) sortedts
|
||||
tmap = Map.union
|
||||
@ -50,7 +55,7 @@ cacheLedger l =
|
||||
txns = (tmap !)
|
||||
subaccts a = filter (isAccountNamePrefixOf a) ans
|
||||
subtxns a = concat [txns a | a <- [a] ++ subaccts a]
|
||||
lprecision = maximum $ map (precision . amount) ts
|
||||
lprecision = maximum $ map (precision . amount) allts
|
||||
bmap = Map.union
|
||||
(Map.fromList [(a, (sumTransactions $ subtxns a){precision=lprecision}) | a <- ans])
|
||||
(Map.fromList [(a,nullamt) | a <- ans])
|
||||
@ -75,17 +80,14 @@ ledgerTransactions l =
|
||||
setprecisions = map (transactionSetPrecision (lprecision l))
|
||||
|
||||
ledgerTransactionsMatching :: ([String],[String]) -> Ledger -> [Transaction]
|
||||
ledgerTransactionsMatching ([],[]) l = ledgerTransactionsMatching ([".*"],[".*"]) l
|
||||
ledgerTransactionsMatching (rs,[]) l = ledgerTransactionsMatching (rs,[".*"]) l
|
||||
ledgerTransactionsMatching ([],rs) l = ledgerTransactionsMatching ([".*"],rs) l
|
||||
ledgerTransactionsMatching (acctpats,descpats) l =
|
||||
intersect
|
||||
(concat [filter (matchTransactionAccount r) ts | r <- acctregexps])
|
||||
(concat [filter (matchTransactionDescription r) ts | r <- descregexps])
|
||||
where
|
||||
ts = ledgerTransactions l
|
||||
acctregexps = map mkRegex acctpats
|
||||
descregexps = map mkRegex descpats
|
||||
acctregexps = map mkRegex $ wilddefault acctpats
|
||||
descregexps = map mkRegex $ wilddefault descpats
|
||||
|
||||
ledgerAccountTreeMatching :: Ledger -> [String] -> Bool -> Int -> Tree Account
|
||||
ledgerAccountTreeMatching l [] showsubs maxdepth =
|
||||
@ -164,7 +166,7 @@ showLedgerAccounts :: Ledger -> [String] -> Bool -> Int -> String
|
||||
showLedgerAccounts l acctpats showsubs maxdepth =
|
||||
concatMap
|
||||
(showAccountTree l)
|
||||
(branches (ledgerAccountTreeMatching l acctpats showsubs maxdepth))
|
||||
(branches $ ledgerAccountTreeMatching l acctpats showsubs maxdepth)
|
||||
|
||||
showAccountTree :: Ledger -> Tree Account -> String
|
||||
showAccountTree l = showAccountTree' l 0 . pruneBoringBranches
|
||||
@ -183,7 +185,7 @@ showAccountTree' l indentlevel t
|
||||
subsindented i = concatMap (showAccountTree' l (indentlevel+i)) subs
|
||||
bal = printf "%20s" $ show $ abalance $ acct
|
||||
indent = replicate (indentlevel * 2) ' '
|
||||
prefix = concatMap (++ ":") $ map accountLeafName boringparents
|
||||
prefix = concatMap (++ ":") $ map accountLeafName $ reverse boringparents
|
||||
boringparents = takeWhile (isBoringAccountName l) $ parentAccountNames $ aname acct
|
||||
leafname = accountLeafName $ aname acct
|
||||
|
||||
|
4
Tests.hs
4
Tests.hs
@ -283,7 +283,7 @@ ledger7 = LedgerFile
|
||||
}
|
||||
]
|
||||
|
||||
l7 = cacheLedger ledger7
|
||||
l7 = cacheLedger [] [] ledger7
|
||||
|
||||
timelogentry1_str = "i 2007/03/11 16:19:00 hledger\n"
|
||||
timelogentry1 = TimeLogEntry 'i' "2007/03/11 16:19:00" "hledger"
|
||||
@ -380,7 +380,7 @@ test_ledgerAccountNames =
|
||||
(rawLedgerAccountNames ledger7)
|
||||
|
||||
test_cacheLedger =
|
||||
assertEqual' 15 (length $ Map.keys $ accounts $ cacheLedger ledger7)
|
||||
assertEqual' 15 (length $ Map.keys $ accounts $ cacheLedger [] [] ledger7)
|
||||
|
||||
test_showLedgerAccounts =
|
||||
assertEqual' 4 (length $ lines $ showLedgerAccounts l7 [] False 1)
|
||||
|
@ -9,6 +9,10 @@ import Amount
|
||||
import Currency
|
||||
|
||||
|
||||
instance Show Transaction where
|
||||
show (Transaction eno d desc a amt) =
|
||||
unwords [d,desc,a,show amt]
|
||||
|
||||
-- we use the entry number e to remember the grouping of txns
|
||||
flattenEntry :: (LedgerEntry, Int) -> [Transaction]
|
||||
flattenEntry (LedgerEntry d _ _ desc _ ts, e) =
|
||||
|
3
Utils.hs
3
Utils.hs
@ -25,6 +25,9 @@ import Test.QuickCheck hiding (test, Testable)
|
||||
import Test.HUnit
|
||||
|
||||
|
||||
wilddefault [] = [".*"]
|
||||
wilddefault a = a
|
||||
|
||||
-- lists
|
||||
|
||||
splitAtElement :: Eq a => a -> [a] -> [[a]]
|
||||
|
24
hledger.hs
24
hledger.hs
@ -42,24 +42,24 @@ test = do
|
||||
|
||||
register :: [Flag] -> [String] -> [String] -> IO ()
|
||||
register opts acctpats descpats = do
|
||||
doWithLedger opts printregister
|
||||
doWithLedger opts acctpats descpats printregister
|
||||
where
|
||||
printregister l =
|
||||
putStr $ showTransactionsWithBalances
|
||||
(sortBy (comparing date) (ledgerTransactionsMatching (acctpats,descpats) l))
|
||||
(sortBy (comparing date) (ledgerTransactionsMatching (acctpats, descpats) l))
|
||||
nullamt{precision=lprecision l}
|
||||
|
||||
printcmd :: [Flag] -> IO ()
|
||||
printcmd :: [Flag] -> IO () -- XXX acctpats descpats ?
|
||||
printcmd opts = do
|
||||
doWithLedger opts printentries
|
||||
doWithLedger opts [] [] printentries
|
||||
where
|
||||
printentries l = putStr $ showEntries $ setprecision $ entries $ rawledger l
|
||||
where
|
||||
setprecision = map (entrySetPrecision (lprecision l))
|
||||
|
||||
balance :: [Flag] -> [String] -> [String] -> IO ()
|
||||
balance opts acctpats _ = do
|
||||
doWithLedger opts printbalance
|
||||
balance opts acctpats _ = do -- XXX descpats
|
||||
doWithLedger opts acctpats [] printbalance
|
||||
where
|
||||
printbalance l =
|
||||
putStr $ showLedgerAccounts l acctpats showsubs maxdepth
|
||||
@ -71,14 +71,14 @@ balance opts acctpats _ = do
|
||||
|
||||
-- utils
|
||||
|
||||
doWithLedger :: [Flag] -> (Ledger -> IO ()) -> IO ()
|
||||
doWithLedger opts cmd = do
|
||||
ledgerFilePath opts >>= parseLedgerFile >>= doWithParsed cmd
|
||||
doWithLedger :: [Flag] -> [String] -> [String] -> (Ledger -> IO ()) -> IO ()
|
||||
doWithLedger opts acctpats descpats cmd = do
|
||||
ledgerFilePath opts >>= parseLedgerFile >>= doWithParsed acctpats descpats cmd
|
||||
|
||||
doWithParsed :: (Ledger -> IO ()) -> (Either ParseError LedgerFile) -> IO ()
|
||||
doWithParsed cmd parsed = do
|
||||
doWithParsed :: [String] -> [String] -> (Ledger -> IO ()) -> (Either ParseError LedgerFile) -> IO ()
|
||||
doWithParsed acctpats descpats cmd parsed = do
|
||||
case parsed of Left e -> parseError e
|
||||
Right l -> cmd $ cacheLedger l
|
||||
Right l -> cmd $ cacheLedger acctpats descpats l
|
||||
|
||||
|
||||
{-
|
||||
|
Loading…
Reference in New Issue
Block a user