module Penny.Cabin.Balance (
T.report
, T.nullConvert
, T.converter
, BalanceOpts(..)
, balanceReport
, defaultOptions
, balanceAsIs
) where
import qualified Penny.Cabin.Balance.Tree as T
import qualified Penny.Cabin.Balance.Parser as P
import qualified Penny.Cabin.Balance.Help as H
import qualified Penny.Cabin.Chunk as Chunk
import qualified Penny.Cabin.Colors as C
import qualified Penny.Cabin.Colors.DarkBackground as Dark
import qualified Penny.Cabin.Interface as I
import qualified Penny.Cabin.Options as CO
import qualified Penny.Copper as Cop
import qualified Penny.Lincoln as L
import qualified Penny.Lincoln.Balance as Bal
import qualified Penny.Shield as S
import qualified Control.Monad.Exception.Synchronous as Ex
import qualified Data.Text as X
import System.Console.MultiArg.Prim (Parser)
data BalanceOpts = BalanceOpts {
drCrColors :: C.DrCrColors
, baseColors :: C.BaseColors
, balanceFormat :: L.BottomLine -> X.Text
, colorPref :: Chunk.Colors
, showZeroBalances :: CO.ShowZeroBalances
, defaultTimeZone :: Cop.DefaultTimeZone
, convert :: Maybe (L.Commodity, L.DateTime)
}
toParseOpts :: BalanceOpts -> P.ParseOpts
toParseOpts b = P.ParseOpts {
P.drCrColors = drCrColors b
, P.baseColors = baseColors b
, P.colorPref = colorPref b
, P.showZeroBalances = showZeroBalances b
, P.convert = convert b
}
toTreeOpts :: P.ParseOpts -> BalanceOpts -> T.TreeOpts
toTreeOpts p b = T.TreeOpts {
T.drCrColors = P.drCrColors p
, T.baseColors = P.baseColors p
, T.balanceFormat = balanceFormat b
, T.showZeroBalances = P.showZeroBalances p
}
parser :: (S.Runtime -> BalanceOpts) -> Parser I.ReportFunc
parser frt = do
parsed <- P.parseOptions
let rf rt _ _ ps pps = do
let bo = frt rt
po = toParseOpts bo
po' <- Ex.mapException showParseErr $
parsed rt (defaultTimeZone bo) po
let to = toTreeOpts po' bo
conv <- case P.convert po' of
Nothing -> return $ T.nullConvert ps
Just co -> T.converter co pps ps
return
. Chunk.chunksToText (P.colorPref po')
. concat
. T.report to
$ conv
return rf
showParseErr :: P.Error -> X.Text
showParseErr = X.pack . show
balanceReport :: (S.Runtime -> BalanceOpts) -> I.Report
balanceReport f = I.Report H.help "balance" (parser f)
defaultOptions :: Cop.DefaultTimeZone -> S.Runtime -> BalanceOpts
defaultOptions dtz rt = BalanceOpts {
drCrColors = Dark.drCrColors
, baseColors = Dark.baseColors
, balanceFormat = balanceAsIs
, colorPref = CO.maxCapableColors rt
, showZeroBalances = CO.ShowZeroBalances False
, defaultTimeZone = dtz
, convert = Nothing
}
balanceAsIs :: L.BottomLine -> X.Text
balanceAsIs n = case n of
L.Zero -> X.pack "--"
L.NonZero c -> X.pack . show . L.unQty . Bal.qty $ c