{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Hledger.Data.Account
( nullacct
, accountsFromPostings
, accountTree
, showAccounts
, showAccountsBoringFlag
, printAccounts
, lookupAccount
, parentAccounts
, accountsLevels
, mapAccounts
, anyAccounts
, filterAccounts
, sumAccounts
, clipAccounts
, clipAccountsAndAggregate
, pruneAccounts
, flattenAccounts
, accountSetDeclarationInfo
, sortAccountNamesByDeclaration
, sortAccountTreeByAmount
) where
import qualified Data.HashSet as HS
import qualified Data.HashMap.Strict as HM
import Data.List (find, foldl', sortOn)
import Data.List.Extra (groupOn)
import qualified Data.Map as M
import Data.Ord (Down(..))
import Safe (headMay)
import Text.Printf (printf)
import Hledger.Data.AccountName (expandAccountName, clipOrEllipsifyAccountName)
import Hledger.Data.Amount
import Hledger.Data.Types
instance Show Account where
show :: Account -> String
show Account{Bool
Int
[Account]
Maybe Account
Maybe AccountDeclarationInfo
AccountName
MixedAmount
aibalance :: Account -> MixedAmount
aebalance :: Account -> MixedAmount
anumpostings :: Account -> Int
aboring :: Account -> Bool
aparent :: Account -> Maybe Account
asubs :: Account -> [Account]
adeclarationinfo :: Account -> Maybe AccountDeclarationInfo
aname :: Account -> AccountName
aibalance :: MixedAmount
aebalance :: MixedAmount
anumpostings :: Int
aboring :: Bool
aparent :: Maybe Account
asubs :: [Account]
adeclarationinfo :: Maybe AccountDeclarationInfo
aname :: AccountName
..} = forall r. PrintfType r => String -> r
printf String
"Account %s (boring:%s, postings:%d, ebalance:%s, ibalance:%s)"
AccountName
aname
(if Bool
aboring then String
"y" else String
"n" :: String)
Int
anumpostings
(WideBuilder -> String
wbUnpack forall a b. (a -> b) -> a -> b
$ AmountDisplayOpts -> MixedAmount -> WideBuilder
showMixedAmountB AmountDisplayOpts
noColour MixedAmount
aebalance)
(WideBuilder -> String
wbUnpack forall a b. (a -> b) -> a -> b
$ AmountDisplayOpts -> MixedAmount -> WideBuilder
showMixedAmountB AmountDisplayOpts
noColour MixedAmount
aibalance)
instance Eq Account where
== :: Account -> Account -> Bool
(==) Account
a Account
b = Account -> AccountName
aname Account
a forall a. Eq a => a -> a -> Bool
== Account -> AccountName
aname Account
b
nullacct :: Account
nullacct = Account
{ aname :: AccountName
aname = AccountName
""
, adeclarationinfo :: Maybe AccountDeclarationInfo
adeclarationinfo = forall a. Maybe a
Nothing
, asubs :: [Account]
asubs = []
, aparent :: Maybe Account
aparent = forall a. Maybe a
Nothing
, aboring :: Bool
aboring = Bool
False
, anumpostings :: Int
anumpostings = Int
0
, aebalance :: MixedAmount
aebalance = MixedAmount
nullmixedamt
, aibalance :: MixedAmount
aibalance = MixedAmount
nullmixedamt
}
accountsFromPostings :: [Posting] -> [Account]
accountsFromPostings :: [Posting] -> [Account]
accountsFromPostings [Posting]
ps =
let
summed :: HashMap AccountName (Int, MixedAmount)
summed = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Posting
p -> forall k v.
(Eq k, Hashable k) =>
(v -> v -> v) -> k -> v -> HashMap k v -> HashMap k v
HM.insertWith forall {a}.
Num a =>
(a, MixedAmount) -> (a, MixedAmount) -> (a, MixedAmount)
addAndIncrement (Posting -> AccountName
paccount Posting
p) (Int
1, Posting -> MixedAmount
pamount Posting
p)) forall a. Monoid a => a
mempty [Posting]
ps
where addAndIncrement :: (a, MixedAmount) -> (a, MixedAmount) -> (a, MixedAmount)
addAndIncrement (a
n, MixedAmount
a) (a
m, MixedAmount
b) = (a
n forall a. Num a => a -> a -> a
+ a
m, MixedAmount
a MixedAmount -> MixedAmount -> MixedAmount
`maPlus` MixedAmount
b)
acctstree :: Account
acctstree = AccountName -> [AccountName] -> Account
accountTree AccountName
"root" forall a b. (a -> b) -> a -> b
$ forall k v. HashMap k v -> [k]
HM.keys HashMap AccountName (Int, MixedAmount)
summed
acctswithebals :: Account
acctswithebals = (Account -> Account) -> Account -> Account
mapAccounts Account -> Account
setnumpsebalance Account
acctstree
where setnumpsebalance :: Account -> Account
setnumpsebalance Account
a = Account
a{anumpostings :: Int
anumpostings=Int
numps, aebalance :: MixedAmount
aebalance=MixedAmount
total}
where (Int
numps, MixedAmount
total) = forall k v. (Eq k, Hashable k) => v -> k -> HashMap k v -> v
HM.lookupDefault (Int
0, MixedAmount
nullmixedamt) (Account -> AccountName
aname Account
a) HashMap AccountName (Int, MixedAmount)
summed
acctswithibals :: Account
acctswithibals = Account -> Account
sumAccounts Account
acctswithebals
acctswithparents :: Account
acctswithparents = Account -> Account
tieAccountParents Account
acctswithibals
acctsflattened :: [Account]
acctsflattened = Account -> [Account]
flattenAccounts Account
acctswithparents
in
[Account]
acctsflattened
accountTree :: AccountName -> [AccountName] -> Account
accountTree :: AccountName -> [AccountName] -> Account
accountTree AccountName
rootname [AccountName]
as = Account
nullacct{aname :: AccountName
aname=AccountName
rootname, asubs :: [Account]
asubs=forall a b. (a -> b) -> [a] -> [b]
map (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry AccountName -> FastTree AccountName -> Account
accountTree') forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [(k, a)]
M.assocs Map AccountName (FastTree AccountName)
m }
where
T Map AccountName (FastTree AccountName)
m = forall a. Ord a => [[a]] -> FastTree a
treeFromPaths forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map AccountName -> [AccountName]
expandAccountName [AccountName]
as :: FastTree AccountName
accountTree' :: AccountName -> FastTree AccountName -> Account
accountTree' AccountName
a (T Map AccountName (FastTree AccountName)
m') =
Account
nullacct{
aname :: AccountName
aname=AccountName
a
,asubs :: [Account]
asubs=forall a b. (a -> b) -> [a] -> [b]
map (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry AccountName -> FastTree AccountName -> Account
accountTree') forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [(k, a)]
M.assocs Map AccountName (FastTree AccountName)
m'
}
newtype FastTree a = T (M.Map a (FastTree a))
deriving (Int -> FastTree a -> ShowS
forall a. Show a => Int -> FastTree a -> ShowS
forall a. Show a => [FastTree a] -> ShowS
forall a. Show a => FastTree a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FastTree a] -> ShowS
$cshowList :: forall a. Show a => [FastTree a] -> ShowS
show :: FastTree a -> String
$cshow :: forall a. Show a => FastTree a -> String
showsPrec :: Int -> FastTree a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> FastTree a -> ShowS
Show, FastTree a -> FastTree a -> Bool
forall a. Eq a => FastTree a -> FastTree a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FastTree a -> FastTree a -> Bool
$c/= :: forall a. Eq a => FastTree a -> FastTree a -> Bool
== :: FastTree a -> FastTree a -> Bool
$c== :: forall a. Eq a => FastTree a -> FastTree a -> Bool
Eq, FastTree a -> FastTree a -> Bool
FastTree a -> FastTree a -> Ordering
FastTree a -> FastTree a -> FastTree a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (FastTree a)
forall a. Ord a => FastTree a -> FastTree a -> Bool
forall a. Ord a => FastTree a -> FastTree a -> Ordering
forall a. Ord a => FastTree a -> FastTree a -> FastTree a
min :: FastTree a -> FastTree a -> FastTree a
$cmin :: forall a. Ord a => FastTree a -> FastTree a -> FastTree a
max :: FastTree a -> FastTree a -> FastTree a
$cmax :: forall a. Ord a => FastTree a -> FastTree a -> FastTree a
>= :: FastTree a -> FastTree a -> Bool
$c>= :: forall a. Ord a => FastTree a -> FastTree a -> Bool
> :: FastTree a -> FastTree a -> Bool
$c> :: forall a. Ord a => FastTree a -> FastTree a -> Bool
<= :: FastTree a -> FastTree a -> Bool
$c<= :: forall a. Ord a => FastTree a -> FastTree a -> Bool
< :: FastTree a -> FastTree a -> Bool
$c< :: forall a. Ord a => FastTree a -> FastTree a -> Bool
compare :: FastTree a -> FastTree a -> Ordering
$ccompare :: forall a. Ord a => FastTree a -> FastTree a -> Ordering
Ord)
mergeTrees :: (Ord a) => FastTree a -> FastTree a -> FastTree a
mergeTrees :: forall a. Ord a => FastTree a -> FastTree a -> FastTree a
mergeTrees (T Map a (FastTree a)
m) (T Map a (FastTree a)
m') = forall a. Map a (FastTree a) -> FastTree a
T (forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
M.unionWith forall a. Ord a => FastTree a -> FastTree a -> FastTree a
mergeTrees Map a (FastTree a)
m Map a (FastTree a)
m')
treeFromPath :: [a] -> FastTree a
treeFromPath :: forall a. [a] -> FastTree a
treeFromPath [] = forall a. Map a (FastTree a) -> FastTree a
T forall k a. Map k a
M.empty
treeFromPath (a
x:[a]
xs) = forall a. Map a (FastTree a) -> FastTree a
T (forall k a. k -> a -> Map k a
M.singleton a
x (forall a. [a] -> FastTree a
treeFromPath [a]
xs))
treeFromPaths :: (Ord a) => [[a]] -> FastTree a
treeFromPaths :: forall a. Ord a => [[a]] -> FastTree a
treeFromPaths = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' forall a. Ord a => FastTree a -> FastTree a -> FastTree a
mergeTrees (forall a. Map a (FastTree a) -> FastTree a
T forall k a. Map k a
M.empty) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. [a] -> FastTree a
treeFromPath
tieAccountParents :: Account -> Account
tieAccountParents :: Account -> Account
tieAccountParents = Maybe Account -> Account -> Account
tie forall a. Maybe a
Nothing
where
tie :: Maybe Account -> Account -> Account
tie Maybe Account
parent a :: Account
a@Account{Bool
Int
[Account]
Maybe Account
Maybe AccountDeclarationInfo
AccountName
MixedAmount
aibalance :: MixedAmount
aebalance :: MixedAmount
anumpostings :: Int
aboring :: Bool
aparent :: Maybe Account
asubs :: [Account]
adeclarationinfo :: Maybe AccountDeclarationInfo
aname :: AccountName
aibalance :: Account -> MixedAmount
aebalance :: Account -> MixedAmount
anumpostings :: Account -> Int
aboring :: Account -> Bool
aparent :: Account -> Maybe Account
asubs :: Account -> [Account]
adeclarationinfo :: Account -> Maybe AccountDeclarationInfo
aname :: Account -> AccountName
..} = Account
a'
where
a' :: Account
a' = Account
a{aparent :: Maybe Account
aparent=Maybe Account
parent, asubs :: [Account]
asubs=forall a b. (a -> b) -> [a] -> [b]
map (Maybe Account -> Account -> Account
tie (forall a. a -> Maybe a
Just Account
a')) [Account]
asubs}
parentAccounts :: Account -> [Account]
parentAccounts :: Account -> [Account]
parentAccounts Account{aparent :: Account -> Maybe Account
aparent=Maybe Account
Nothing} = []
parentAccounts Account{aparent :: Account -> Maybe Account
aparent=Just Account
a} = Account
aforall a. a -> [a] -> [a]
:Account -> [Account]
parentAccounts Account
a
accountsLevels :: Account -> [[Account]]
accountsLevels :: Account -> [[Account]]
accountsLevels = forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> Bool
null) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a) -> a -> [a]
iterate (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Account -> [Account]
asubs) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> [a] -> [a]
:[])
mapAccounts :: (Account -> Account) -> Account -> Account
mapAccounts :: (Account -> Account) -> Account -> Account
mapAccounts Account -> Account
f Account
a = Account -> Account
f Account
a{asubs :: [Account]
asubs = forall a b. (a -> b) -> [a] -> [b]
map ((Account -> Account) -> Account -> Account
mapAccounts Account -> Account
f) forall a b. (a -> b) -> a -> b
$ Account -> [Account]
asubs Account
a}
anyAccounts :: (Account -> Bool) -> Account -> Bool
anyAccounts :: (Account -> Bool) -> Account -> Bool
anyAccounts Account -> Bool
p Account
a
| Account -> Bool
p Account
a = Bool
True
| Bool
otherwise = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((Account -> Bool) -> Account -> Bool
anyAccounts Account -> Bool
p) forall a b. (a -> b) -> a -> b
$ Account -> [Account]
asubs Account
a
sumAccounts :: Account -> Account
sumAccounts :: Account -> Account
sumAccounts Account
a
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ Account -> [Account]
asubs Account
a = Account
a{aibalance :: MixedAmount
aibalance=Account -> MixedAmount
aebalance Account
a}
| Bool
otherwise = Account
a{aibalance :: MixedAmount
aibalance=MixedAmount
ibal, asubs :: [Account]
asubs=[Account]
subs}
where
subs :: [Account]
subs = forall a b. (a -> b) -> [a] -> [b]
map Account -> Account
sumAccounts forall a b. (a -> b) -> a -> b
$ Account -> [Account]
asubs Account
a
ibal :: MixedAmount
ibal = forall (t :: * -> *). Foldable t => t MixedAmount -> MixedAmount
maSum forall a b. (a -> b) -> a -> b
$ Account -> MixedAmount
aebalance Account
a forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map Account -> MixedAmount
aibalance [Account]
subs
clipAccounts :: Int -> Account -> Account
clipAccounts :: Int -> Account -> Account
clipAccounts Int
0 Account
a = Account
a{asubs :: [Account]
asubs=[]}
clipAccounts Int
d Account
a = Account
a{asubs :: [Account]
asubs=[Account]
subs}
where
subs :: [Account]
subs = forall a b. (a -> b) -> [a] -> [b]
map (Int -> Account -> Account
clipAccounts (Int
dforall a. Num a => a -> a -> a
-Int
1)) forall a b. (a -> b) -> a -> b
$ Account -> [Account]
asubs Account
a
clipAccountsAndAggregate :: Maybe Int -> [Account] -> [Account]
clipAccountsAndAggregate :: Maybe Int -> [Account] -> [Account]
clipAccountsAndAggregate Maybe Int
Nothing [Account]
as = [Account]
as
clipAccountsAndAggregate (Just Int
d) [Account]
as = [Account]
combined
where
clipped :: [Account]
clipped = [Account
a{aname :: AccountName
aname=Maybe Int -> AccountName -> AccountName
clipOrEllipsifyAccountName (forall a. a -> Maybe a
Just Int
d) forall a b. (a -> b) -> a -> b
$ Account -> AccountName
aname Account
a} | Account
a <- [Account]
as]
combined :: [Account]
combined = [Account
a{aebalance :: MixedAmount
aebalance=forall (t :: * -> *). Foldable t => t MixedAmount -> MixedAmount
maSum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Account -> MixedAmount
aebalance [Account]
same}
| same :: [Account]
same@(Account
a:[Account]
_) <- forall k a. Eq k => (a -> k) -> [a] -> [[a]]
groupOn Account -> AccountName
aname [Account]
clipped]
pruneAccounts :: (Account -> Bool) -> Account -> Maybe Account
pruneAccounts :: (Account -> Bool) -> Account -> Maybe Account
pruneAccounts Account -> Bool
p = forall a. [a] -> Maybe a
headMay forall b c a. (b -> c) -> (a -> b) -> a -> c
. Account -> [Account]
prune
where
prune :: Account -> [Account]
prune Account
a
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Account]
prunedsubs = if Account -> Bool
p Account
a then [] else [Account
a']
| Bool
otherwise = [Account
a']
where
prunedsubs :: [Account]
prunedsubs = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Account -> [Account]
prune forall a b. (a -> b) -> a -> b
$ Account -> [Account]
asubs Account
a
a' :: Account
a' = Account
a{asubs :: [Account]
asubs=[Account]
prunedsubs}
flattenAccounts :: Account -> [Account]
flattenAccounts :: Account -> [Account]
flattenAccounts Account
a = Account -> [Account] -> [Account]
squish Account
a []
where squish :: Account -> [Account] -> [Account]
squish Account
a' [Account]
as = Account
a' forall a. a -> [a] -> [a]
: forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
Prelude.foldr Account -> [Account] -> [Account]
squish [Account]
as (Account -> [Account]
asubs Account
a')
filterAccounts :: (Account -> Bool) -> Account -> [Account]
filterAccounts :: (Account -> Bool) -> Account -> [Account]
filterAccounts Account -> Bool
p Account
a
| Account -> Bool
p Account
a = Account
a forall a. a -> [a] -> [a]
: forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Account -> Bool) -> Account -> [Account]
filterAccounts Account -> Bool
p) (Account -> [Account]
asubs Account
a)
| Bool
otherwise = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Account -> Bool) -> Account -> [Account]
filterAccounts Account -> Bool
p) (Account -> [Account]
asubs Account
a)
sortAccountTreeByAmount :: NormalSign -> Account -> Account
sortAccountTreeByAmount :: NormalSign -> Account -> Account
sortAccountTreeByAmount NormalSign
normalsign = (Account -> Account) -> Account -> Account
mapAccounts forall a b. (a -> b) -> a -> b
$ \Account
a -> Account
a{asubs :: [Account]
asubs=[Account] -> [Account]
sortSubs forall a b. (a -> b) -> a -> b
$ Account -> [Account]
asubs Account
a}
where
sortSubs :: [Account] -> [Account]
sortSubs = case NormalSign
normalsign of
NormalSign
NormallyPositive -> forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (\Account
a -> (forall a. a -> Down a
Down forall a b. (a -> b) -> a -> b
$ Account -> MixedAmount
amt Account
a, Account -> AccountName
aname Account
a))
NormalSign
NormallyNegative -> forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (\Account
a -> (Account -> MixedAmount
amt Account
a, Account -> AccountName
aname Account
a))
amt :: Account -> MixedAmount
amt = MixedAmount -> MixedAmount
mixedAmountStripPrices forall b c a. (b -> c) -> (a -> b) -> a -> c
. Account -> MixedAmount
aibalance
accountSetDeclarationInfo :: Journal -> Account -> Account
accountSetDeclarationInfo :: Journal -> Account -> Account
accountSetDeclarationInfo Journal
j a :: Account
a@Account{Bool
Int
[Account]
Maybe Account
Maybe AccountDeclarationInfo
AccountName
MixedAmount
aibalance :: MixedAmount
aebalance :: MixedAmount
anumpostings :: Int
aboring :: Bool
aparent :: Maybe Account
asubs :: [Account]
adeclarationinfo :: Maybe AccountDeclarationInfo
aname :: AccountName
aibalance :: Account -> MixedAmount
aebalance :: Account -> MixedAmount
anumpostings :: Account -> Int
aboring :: Account -> Bool
aparent :: Account -> Maybe Account
asubs :: Account -> [Account]
adeclarationinfo :: Account -> Maybe AccountDeclarationInfo
aname :: Account -> AccountName
..} =
Account
a{ adeclarationinfo :: Maybe AccountDeclarationInfo
adeclarationinfo=forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup AccountName
aname forall a b. (a -> b) -> a -> b
$ Journal -> [(AccountName, AccountDeclarationInfo)]
jdeclaredaccounts Journal
j }
sortAccountNamesByDeclaration :: Journal -> Bool -> [AccountName] -> [AccountName]
sortAccountNamesByDeclaration :: Journal -> Bool -> [AccountName] -> [AccountName]
sortAccountNamesByDeclaration Journal
j Bool
keepparents [AccountName]
as =
(if Bool
keepparents then forall a. a -> a
id else forall a. (a -> Bool) -> [a] -> [a]
filter (forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
`HS.member` forall a. (Eq a, Hashable a) => [a] -> HashSet a
HS.fromList [AccountName]
as)) forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map Account -> AccountName
aname forall a b. (a -> b) -> a -> b
$
forall a. Int -> [a] -> [a]
drop Int
1 forall a b. (a -> b) -> a -> b
$
Account -> [Account]
flattenAccounts forall a b. (a -> b) -> a -> b
$
Account -> Account
sortAccountTreeByDeclaration forall a b. (a -> b) -> a -> b
$
(Account -> Account) -> Account -> Account
mapAccounts (Journal -> Account -> Account
accountSetDeclarationInfo Journal
j) forall a b. (a -> b) -> a -> b
$
AccountName -> [AccountName] -> Account
accountTree AccountName
"root"
[AccountName]
as
sortAccountTreeByDeclaration :: Account -> Account
sortAccountTreeByDeclaration :: Account -> Account
sortAccountTreeByDeclaration Account
a
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ Account -> [Account]
asubs Account
a = Account
a
| Bool
otherwise = Account
a{asubs :: [Account]
asubs=
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn Account -> (Int, AccountName)
accountDeclarationOrderAndName forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map Account -> Account
sortAccountTreeByDeclaration forall a b. (a -> b) -> a -> b
$ Account -> [Account]
asubs Account
a
}
accountDeclarationOrderAndName :: Account -> (Int, AccountName)
accountDeclarationOrderAndName :: Account -> (Int, AccountName)
accountDeclarationOrderAndName Account
a = (Int
adeclarationorder', Account -> AccountName
aname Account
a)
where
adeclarationorder' :: Int
adeclarationorder' = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Bounded a => a
maxBound AccountDeclarationInfo -> Int
adideclarationorder forall a b. (a -> b) -> a -> b
$ Account -> Maybe AccountDeclarationInfo
adeclarationinfo Account
a
lookupAccount :: AccountName -> [Account] -> Maybe Account
lookupAccount :: AccountName -> [Account] -> Maybe Account
lookupAccount AccountName
a = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((forall a. Eq a => a -> a -> Bool
==AccountName
a)forall b c a. (b -> c) -> (a -> b) -> a -> c
.Account -> AccountName
aname)
printAccounts :: Account -> IO ()
printAccounts :: Account -> IO ()
printAccounts = String -> IO ()
putStrLn forall b c a. (b -> c) -> (a -> b) -> a -> c
. Account -> String
showAccounts
showAccounts :: Account -> String
showAccounts = [String] -> String
unlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall {t}. PrintfType t => Account -> t
showAccountDebug forall b c a. (b -> c) -> (a -> b) -> a -> c
. Account -> [Account]
flattenAccounts
showAccountsBoringFlag :: Account -> String
showAccountsBoringFlag = [String] -> String
unlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. Account -> Bool
aboring) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Account -> [Account]
flattenAccounts
showAccountDebug :: Account -> t
showAccountDebug Account
a = forall r. PrintfType r => String -> r
printf String
"%-25s %4s %4s %s"
(Account -> AccountName
aname Account
a)
(WideBuilder -> String
wbUnpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. AmountDisplayOpts -> MixedAmount -> WideBuilder
showMixedAmountB AmountDisplayOpts
noColour forall a b. (a -> b) -> a -> b
$ Account -> MixedAmount
aebalance Account
a)
(WideBuilder -> String
wbUnpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. AmountDisplayOpts -> MixedAmount -> WideBuilder
showMixedAmountB AmountDisplayOpts
noColour forall a b. (a -> b) -> a -> b
$ Account -> MixedAmount
aibalance Account
a)
(if Account -> Bool
aboring Account
a then String
"b" else String
" " :: String)