mirror of
https://github.com/simonmichael/hledger.git
synced 2024-11-08 07:09:28 +03:00
122 lines
4.0 KiB
Haskell
122 lines
4.0 KiB
Haskell
module Account
|
|
where
|
|
import qualified Data.Map as Map
|
|
|
|
import Utils
|
|
import BasicTypes
|
|
import AccountName
|
|
import Entry
|
|
import Transaction
|
|
import EntryTransaction
|
|
import Ledger
|
|
|
|
|
|
-- an Account caches an account's name, balance (including sub-accounts)
|
|
-- and transactions (not including sub-accounts)
|
|
data Account = Account {
|
|
aname :: AccountName,
|
|
atransactions :: [EntryTransaction],
|
|
abalance :: Amount
|
|
}
|
|
|
|
instance Show Account where
|
|
show (Account a ts b) = printf "Account %s with %d transactions" a $ length ts
|
|
|
|
nullacct = Account "" [] nullamt
|
|
|
|
mkAccount :: Ledger -> AccountName -> Account
|
|
mkAccount l a =
|
|
Account
|
|
a
|
|
(transactionsInAccountNamed l a)
|
|
(aggregateBalanceInAccountNamed l a)
|
|
|
|
balanceInAccountNamed :: Ledger -> AccountName -> Amount
|
|
balanceInAccountNamed l a =
|
|
sumEntryTransactions (transactionsInAccountNamed l a)
|
|
|
|
aggregateBalanceInAccountNamed :: Ledger -> AccountName -> Amount
|
|
aggregateBalanceInAccountNamed l a =
|
|
sumEntryTransactions (aggregateTransactionsInAccountNamed l a)
|
|
|
|
transactionsInAccountNamed :: Ledger -> AccountName -> [EntryTransaction]
|
|
transactionsInAccountNamed l a =
|
|
ledgerTransactionsMatching (["^" ++ a ++ "$"], []) l
|
|
|
|
aggregateTransactionsInAccountNamed :: Ledger -> AccountName -> [EntryTransaction]
|
|
aggregateTransactionsInAccountNamed l a =
|
|
ledgerTransactionsMatching (["^" ++ a ++ "(:.+)?$"], []) l
|
|
|
|
-- a tree of Accounts
|
|
|
|
addDataToAccountNameTree :: Ledger -> Tree AccountName -> Tree Account
|
|
addDataToAccountNameTree l ant =
|
|
Node
|
|
(mkAccount l $ root ant)
|
|
(map (addDataToAccountNameTree l) $ branches ant)
|
|
|
|
-- would be straightforward except we want to elide boring accounts when
|
|
-- displaying account trees:
|
|
-- a (0 txns, only 1 subacct)
|
|
-- b (another boring acct.)
|
|
-- c
|
|
-- d
|
|
-- becomes:
|
|
-- a:b:c
|
|
-- d
|
|
showAccountTree :: Ledger -> Int -> Int -> Tree Account -> String
|
|
showAccountTree _ 0 _ _ = ""
|
|
showAccountTree l maxdepth indentlevel t
|
|
-- if this acct is boring, don't show it (unless this is as deep as we're going)
|
|
-- | (boringacct && (maxdepth > 1)) = subacctsindented 0
|
|
|
|
-- otherwise show normal indented account name with balance
|
|
-- if this acct has one or more boring parents, prepend their names
|
|
| otherwise =
|
|
bal ++ " " ++ indent ++ parentnames ++ leafname ++ "\n" ++ (subacctsindented 1)
|
|
|
|
where
|
|
boringacct = isBoringAccount2 l name
|
|
boringparents = takeWhile (isBoringAccount2 l) $ parentAccountNames name
|
|
bal = printf "%20s" $ show $ abalance $ root t
|
|
indent = replicate (indentlevel * 2) ' '
|
|
parentnames = concatMap (++ ":") $ map accountLeafName boringparents
|
|
leafname = accountLeafName name
|
|
name = aname $ root t
|
|
subacctsindented i =
|
|
case maxdepth > 1 of
|
|
True -> concatMap (showAccountTree l (maxdepth-1) (indentlevel+i)) $ branches t
|
|
False -> ""
|
|
|
|
isBoringAccount :: Tree Account -> Bool
|
|
isBoringAccount at =
|
|
(length txns == 0) && ((length subaccts) == 1) && (not $ name == "top")
|
|
where
|
|
a = root at
|
|
name = aname a
|
|
txns = atransactions a
|
|
subaccts = branches at
|
|
|
|
isBoringAccount2 :: Ledger -> AccountName -> Bool
|
|
isBoringAccount2 l a
|
|
| a == "top" = False
|
|
| (length txns == 0) && ((length subs) == 1) = True
|
|
| otherwise = False
|
|
where
|
|
txns = transactionsInAccountNamed l a
|
|
subs = subAccountNamesFrom (ledgerAccountNames l) a
|
|
|
|
ledgerAccountTreeMatching :: Ledger -> [String] -> Bool -> Int -> Tree Account
|
|
ledgerAccountTreeMatching l [] showsubs maxdepth =
|
|
ledgerAccountTreeMatching l [".*"] showsubs maxdepth
|
|
ledgerAccountTreeMatching l acctpats showsubs maxdepth =
|
|
addDataToAccountNameTree l $
|
|
filterAccountNameTree acctpats showsubs maxdepth $
|
|
ledgerAccountNameTree l
|
|
|
|
showLedgerAccounts :: Ledger -> [String] -> Bool -> Int -> String
|
|
showLedgerAccounts l acctpats showsubs maxdepth =
|
|
concatMap
|
|
(showAccountTree l 999 0)
|
|
(branches (ledgerAccountTreeMatching l acctpats showsubs maxdepth))
|