{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE CPP #-}
module Hledger.Cli.Commands.Accounts (
accountsmode
,accounts
) where
#if !(MIN_VERSION_base(4,11,0))
import Data.Monoid
#endif
import Data.List
import qualified Data.Text as T
import qualified Data.Text.IO as T
import System.Console.CmdArgs.Explicit as C
import Hledger
import Hledger.Cli.CliOptions
accountsmode = hledgerCommandMode
$(embedFileRelative "Hledger/Cli/Commands/Accounts.txt")
[flagNone ["declared"] (setboolopt "declared") "show account names declared with account directives"
,flagNone ["used"] (setboolopt "used") "show account names referenced by transactions"
,flagNone ["tree"] (setboolopt "tree") "show short account names, as a tree"
,flagNone ["flat"] (setboolopt "flat") "show full account names, as a list (default)"
,flagReq ["drop"] (\s opts -> Right $ setopt "drop" s opts) "N" "flat mode: omit N leading account name parts"
]
[generalflagsgroup1]
hiddenflags
([], Just $ argsFlag "[QUERY]")
accounts :: CliOpts -> Journal -> IO ()
accounts CliOpts{rawopts_=rawopts, reportopts_=ropts} j = do
d <- getCurrentDay
let tree = tree_ ropts
declared = boolopt "declared" rawopts
used = boolopt "used" rawopts
q = queryFromOpts d ropts
nodepthq = dbg1 "nodepthq" $ filterQuery (not . queryIsDepth) q
acctq = dbg1 "acctq" $ filterQuery queryIsAcct q
depth = dbg1 "depth" $ queryDepth $ filterQuery queryIsDepth q
matcheddeclaredaccts = dbg1 "matcheddeclaredaccts" $ filter (matchesAccount nodepthq) $ map fst $ jdeclaredaccounts j
matchedusedaccts = dbg5 "matchedusedaccts" $ map paccount $ journalPostings $ filterJournalPostings nodepthq j
accts = dbg5 "accts to show" $
if | declared && not used -> matcheddeclaredaccts
| not declared && used -> matchedusedaccts
| otherwise -> matcheddeclaredaccts ++ matchedusedaccts
sortedaccts = sortAccountNamesByDeclaration j tree accts
clippedaccts =
dbg1 "clippedaccts" $
filter (matchesAccount acctq) $
nub $
filter (not . T.null) $
map (clipAccountName depth) $
sortedaccts
mapM_ (T.putStrLn . render) clippedaccts
where
render a
| tree_ ropts = T.replicate (2 * (accountNameLevel a - 1)) " " <> accountLeafName a
| otherwise = accountNameDrop (drop_ ropts) a