{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NamedFieldPuns #-}
module Hledger.UI.UIScreens
(screenUpdate
,esNew
,esUpdate
,msNew
,msUpdate
,asNew
,asUpdate
,asItemIndex
,csNew
,csUpdate
,csItemIndex
,bsNew
,bsUpdate
,bsItemIndex
,isNew
,isUpdate
,isItemIndex
,rsNew
,rsUpdate
,tsNew
,tsUpdate
)
where
import Brick.Widgets.List (listMoveTo, listSelectedElement, list)
import Data.List
import Data.Maybe
import Data.Time.Calendar (Day, diffDays)
import Safe
import qualified Data.Vector as V
import Hledger.Cli hiding (mode, progname,prognameandversion)
import Hledger.UI.UIOptions
import Hledger.UI.UITypes
import Hledger.UI.UIUtils
import Data.Function ((&))
screenUpdate :: UIOpts -> Day -> Journal -> Screen -> Screen
screenUpdate :: UIOpts -> Day -> Journal -> Screen -> Screen
screenUpdate UIOpts
opts Day
d Journal
j = \case
MS MenuScreenState
sst -> MenuScreenState -> Screen
MS (MenuScreenState -> Screen) -> MenuScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ MenuScreenState -> MenuScreenState
msUpdate MenuScreenState
sst
AS AccountsScreenState
sst -> AccountsScreenState -> Screen
AS (AccountsScreenState -> Screen) -> AccountsScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
asUpdate UIOpts
opts Day
d Journal
j AccountsScreenState
sst
CS AccountsScreenState
sst -> AccountsScreenState -> Screen
CS (AccountsScreenState -> Screen) -> AccountsScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
csUpdate UIOpts
opts Day
d Journal
j AccountsScreenState
sst
BS AccountsScreenState
sst -> AccountsScreenState -> Screen
BS (AccountsScreenState -> Screen) -> AccountsScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
bsUpdate UIOpts
opts Day
d Journal
j AccountsScreenState
sst
IS AccountsScreenState
sst -> AccountsScreenState -> Screen
IS (AccountsScreenState -> Screen) -> AccountsScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
isUpdate UIOpts
opts Day
d Journal
j AccountsScreenState
sst
RS RegisterScreenState
sst -> RegisterScreenState -> Screen
RS (RegisterScreenState -> Screen) -> RegisterScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ UIOpts
-> Day -> Journal -> RegisterScreenState -> RegisterScreenState
rsUpdate UIOpts
opts Day
d Journal
j RegisterScreenState
sst
TS TransactionScreenState
sst -> TransactionScreenState -> Screen
TS (TransactionScreenState -> Screen)
-> TransactionScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ TransactionScreenState -> TransactionScreenState
tsUpdate TransactionScreenState
sst
ES ErrorScreenState
sst -> ErrorScreenState -> Screen
ES (ErrorScreenState -> Screen) -> ErrorScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ ErrorScreenState -> ErrorScreenState
esUpdate ErrorScreenState
sst
esNew :: String -> Screen
esNew :: String -> Screen
esNew String
msg =
String -> Screen -> Screen
forall a. String -> a -> a
dbgui String
"esNew" (Screen -> Screen) -> Screen -> Screen
forall a b. (a -> b) -> a -> b
$
ErrorScreenState -> Screen
ES ESS {
_essError :: String
_essError = String
msg
,_essUnused :: ()
_essUnused = ()
}
esUpdate :: ErrorScreenState -> ErrorScreenState
esUpdate :: ErrorScreenState -> ErrorScreenState
esUpdate = String -> ErrorScreenState -> ErrorScreenState
forall a. String -> a -> a
dbgui String
"esUpdate`"
msNew :: Screen
msNew :: Screen
msNew =
String -> Screen -> Screen
forall a. String -> a -> a
dbgui String
"msNew" (Screen -> Screen) -> Screen -> Screen
forall a b. (a -> b) -> a -> b
$
MenuScreenState -> Screen
MS MSS { _mssList :: List Name MenuScreenItem
_mssList = Name -> Vector MenuScreenItem -> Int -> List Name MenuScreenItem
forall (t :: * -> *) n e.
Foldable t =>
n -> t e -> Int -> GenericList n t e
list Name
MenuList ([MenuScreenItem] -> Vector MenuScreenItem
forall a. [a] -> Vector a
V.fromList [MenuScreenItem]
items ) Int
1, _mssUnused :: ()
_mssUnused = () }
where
items :: [MenuScreenItem]
items = [
AccountName -> ScreenName -> MenuScreenItem
MenuScreenItem AccountName
"Cash accounts" ScreenName
CashScreen
,AccountName -> ScreenName -> MenuScreenItem
MenuScreenItem AccountName
"Balance sheet accounts" ScreenName
Balancesheet
,AccountName -> ScreenName -> MenuScreenItem
MenuScreenItem AccountName
"Income statement accounts" ScreenName
Incomestatement
,AccountName -> ScreenName -> MenuScreenItem
MenuScreenItem AccountName
"All accounts" ScreenName
Accounts
]
[
Int
csItemIndex,
Int
bsItemIndex,
Int
isItemIndex,
Int
asItemIndex
] = [Int
0..Int
3] :: [Int]
msUpdate :: MenuScreenState -> MenuScreenState
msUpdate :: MenuScreenState -> MenuScreenState
msUpdate = String -> MenuScreenState -> MenuScreenState
forall a. String -> a -> a
dbgui String
"msUpdate"
nullass :: Maybe AccountName -> AccountsScreenState
nullass Maybe AccountName
macct = ASS {
_assSelectedAccount :: AccountName
_assSelectedAccount = AccountName -> Maybe AccountName -> AccountName
forall a. a -> Maybe a -> a
fromMaybe AccountName
"" Maybe AccountName
macct
,_assList :: List Name AccountsScreenItem
_assList = Name
-> Vector AccountsScreenItem -> Int -> List Name AccountsScreenItem
forall (t :: * -> *) n e.
Foldable t =>
n -> t e -> Int -> GenericList n t e
list Name
AccountsList ([AccountsScreenItem] -> Vector AccountsScreenItem
forall a. [a] -> Vector a
V.fromList []) Int
1
}
asNew :: UIOpts -> Day -> Journal -> Maybe AccountName -> Screen
asNew :: UIOpts -> Day -> Journal -> Maybe AccountName -> Screen
asNew UIOpts
uopts Day
d Journal
j Maybe AccountName
macct = String -> Screen -> Screen
forall a. String -> a -> a
dbgui String
"asNew" (Screen -> Screen) -> Screen -> Screen
forall a b. (a -> b) -> a -> b
$ AccountsScreenState -> Screen
AS (AccountsScreenState -> Screen) -> AccountsScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
asUpdate UIOpts
uopts Day
d Journal
j (AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState -> AccountsScreenState
forall a b. (a -> b) -> a -> b
$ Maybe AccountName -> AccountsScreenState
nullass Maybe AccountName
macct
asUpdate :: UIOpts -> Day -> Journal -> AccountsScreenState -> AccountsScreenState
asUpdate :: UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
asUpdate UIOpts
uopts Day
d = String
-> (AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState
-> AccountsScreenState
forall a. String -> a -> a
dbgui String
"asUpdate" ((AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState -> AccountsScreenState)
-> (Journal -> AccountsScreenState -> AccountsScreenState)
-> Journal
-> AccountsScreenState
-> AccountsScreenState
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
ReportSpec
-> Day
-> CliOpts
-> (ReportOpts -> ReportOpts)
-> Query
-> Journal
-> AccountsScreenState
-> AccountsScreenState
asUpdateHelper ReportSpec
rspec Day
d CliOpts
copts ReportOpts -> ReportOpts
forall {a}. a -> a
roptsmod Query
extraquery
where
UIOpts{uoCliOpts :: UIOpts -> CliOpts
uoCliOpts=copts :: CliOpts
copts@CliOpts{reportspec_ :: CliOpts -> ReportSpec
reportspec_=ReportSpec
rspec}} = UIOpts
uopts
roptsmod :: a -> a
roptsmod = a -> a
forall {a}. a -> a
id
extraquery :: Query
extraquery = Query
Any
asUpdateHelper :: ReportSpec -> Day -> CliOpts -> (ReportOpts -> ReportOpts) -> Query -> Journal -> AccountsScreenState -> AccountsScreenState
asUpdateHelper :: ReportSpec
-> Day
-> CliOpts
-> (ReportOpts -> ReportOpts)
-> Query
-> Journal
-> AccountsScreenState
-> AccountsScreenState
asUpdateHelper ReportSpec
rspec0 Day
d CliOpts
copts ReportOpts -> ReportOpts
roptsModify Query
extraquery Journal
j AccountsScreenState
ass = String -> AccountsScreenState -> AccountsScreenState
forall a. String -> a -> a
dbgui String
"asUpdateHelper"
AccountsScreenState
ass{_assList=l}
where
ropts :: ReportOpts
ropts = ReportOpts -> ReportOpts
roptsModify (ReportOpts -> ReportOpts) -> ReportOpts -> ReportOpts
forall a b. (a -> b) -> a -> b
$ ReportSpec -> ReportOpts
_rsReportOpts ReportSpec
rspec0
rspec :: ReportSpec
rspec =
ReportOpts -> ReportSpec -> Either String ReportSpec
updateReportSpec
ReportOpts
ropts
ReportSpec
rspec0{_rsDay=d}
Either String ReportSpec
-> (Either String ReportSpec -> ReportSpec) -> ReportSpec
forall a b. a -> (a -> b) -> b
& (String -> ReportSpec)
-> (ReportSpec -> ReportSpec)
-> Either String ReportSpec
-> ReportSpec
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> String -> ReportSpec
forall a. HasCallStack => String -> a
error String
"asUpdateHelper: adjusting the query, should not have failed") ReportSpec -> ReportSpec
forall {a}. a -> a
id
ReportSpec -> (ReportSpec -> ReportSpec) -> ReportSpec
forall a b. a -> (a -> b) -> b
& Maybe DateSpan -> ReportSpec -> ReportSpec
reportSpecSetFutureAndForecast (InputOpts -> Maybe DateSpan
forecast_ (InputOpts -> Maybe DateSpan) -> InputOpts -> Maybe DateSpan
forall a b. (a -> b) -> a -> b
$ CliOpts -> InputOpts
inputopts_ CliOpts
copts)
ReportSpec -> (ReportSpec -> ReportSpec) -> ReportSpec
forall a b. a -> (a -> b) -> b
& Query -> ReportSpec -> ReportSpec
reportSpecAddQuery Query
extraquery
l :: List Name AccountsScreenItem
l = Int -> List Name AccountsScreenItem -> List Name AccountsScreenItem
forall (t :: * -> *) n e.
(Foldable t, Splittable t) =>
Int -> GenericList n t e -> GenericList n t e
listMoveTo Int
selidx (List Name AccountsScreenItem -> List Name AccountsScreenItem)
-> List Name AccountsScreenItem -> List Name AccountsScreenItem
forall a b. (a -> b) -> a -> b
$ Name
-> Vector AccountsScreenItem -> Int -> List Name AccountsScreenItem
forall (t :: * -> *) n e.
Foldable t =>
n -> t e -> Int -> GenericList n t e
list Name
AccountsList ([AccountsScreenItem] -> Vector AccountsScreenItem
forall a. [a] -> Vector a
V.fromList ([AccountsScreenItem] -> Vector AccountsScreenItem)
-> [AccountsScreenItem] -> Vector AccountsScreenItem
forall a b. (a -> b) -> a -> b
$ [AccountsScreenItem]
displayitems [AccountsScreenItem]
-> [AccountsScreenItem] -> [AccountsScreenItem]
forall a. [a] -> [a] -> [a]
++ [AccountsScreenItem]
blankitems) Int
1
where
selidx :: Int
selidx = Int -> [Int] -> Int
forall a. a -> [a] -> a
headDef Int
0 ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ [Maybe Int] -> [Int]
forall a. [Maybe a] -> [a]
catMaybes [
AccountName -> [AccountName] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemIndex AccountName
a [AccountName]
as
,(AccountName -> Bool) -> [AccountName] -> Maybe Int
forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex (AccountName
a AccountName -> AccountName -> Bool
`isAccountNamePrefixOf`) [AccountName]
as
,Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 ([AccountName] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((AccountName -> Bool) -> [AccountName] -> [AccountName]
forall a. (a -> Bool) -> [a] -> [a]
filter (AccountName -> AccountName -> Bool
forall a. Ord a => a -> a -> Bool
< AccountName
a) [AccountName]
as) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
]
where
a :: AccountName
a = AccountsScreenState -> AccountName
_assSelectedAccount AccountsScreenState
ass
as :: [AccountName]
as = (AccountsScreenItem -> AccountName)
-> [AccountsScreenItem] -> [AccountName]
forall a b. (a -> b) -> [a] -> [b]
map AccountsScreenItem -> AccountName
asItemAccountName [AccountsScreenItem]
displayitems
displayitems :: [AccountsScreenItem]
displayitems = ((AccountName, AccountName, Int, MixedAmount)
-> AccountsScreenItem)
-> [(AccountName, AccountName, Int, MixedAmount)]
-> [AccountsScreenItem]
forall a b. (a -> b) -> [a] -> [b]
map (AccountName, AccountName, Int, MixedAmount) -> AccountsScreenItem
displayitem [(AccountName, AccountName, Int, MixedAmount)]
items
where
([(AccountName, AccountName, Int, MixedAmount)]
items, MixedAmount
_) = Map AccountName AmountStyle -> BalanceReport -> BalanceReport
forall a. HasAmounts a => Map AccountName AmountStyle -> a -> a
styleAmounts Map AccountName AmountStyle
styles (BalanceReport -> BalanceReport) -> BalanceReport -> BalanceReport
forall a b. (a -> b) -> a -> b
$ ReportSpec -> Journal -> BalanceReport
balanceReport ReportSpec
rspec Journal
j
where
styles :: Map AccountName AmountStyle
styles = Rounding -> Journal -> Map AccountName AmountStyle
journalCommodityStylesWith Rounding
HardRounding Journal
j
displayitem :: (AccountName, AccountName, Int, MixedAmount) -> AccountsScreenItem
displayitem (AccountName
fullacct, AccountName
shortacct, Int
indent, MixedAmount
bal) =
AccountsScreenItem{asItemIndentLevel :: Int
asItemIndentLevel = Int
indent
,asItemAccountName :: AccountName
asItemAccountName = AccountName
fullacct
,asItemDisplayAccountName :: AccountName
asItemDisplayAccountName = AccountName -> AccountName -> AccountName
replaceHiddenAccountsNameWith AccountName
"All" (AccountName -> AccountName) -> AccountName -> AccountName
forall a b. (a -> b) -> a -> b
$ if ReportOpts -> Bool
tree_ ReportOpts
ropts then AccountName
shortacct else AccountName
fullacct
,asItemMixedAmount :: Maybe MixedAmount
asItemMixedAmount = MixedAmount -> Maybe MixedAmount
forall a. a -> Maybe a
Just MixedAmount
bal
}
blankitems :: [AccountsScreenItem]
blankitems = Int -> AccountsScreenItem -> [AccountsScreenItem]
forall a. Int -> a -> [a]
replicate Int
uiNumBlankItems
AccountsScreenItem{asItemIndentLevel :: Int
asItemIndentLevel = Int
0
,asItemAccountName :: AccountName
asItemAccountName = AccountName
""
,asItemDisplayAccountName :: AccountName
asItemDisplayAccountName = AccountName
""
,asItemMixedAmount :: Maybe MixedAmount
asItemMixedAmount = Maybe MixedAmount
forall a. Maybe a
Nothing
}
bsNew :: UIOpts -> Day -> Journal -> Maybe AccountName -> Screen
bsNew :: UIOpts -> Day -> Journal -> Maybe AccountName -> Screen
bsNew UIOpts
uopts Day
d Journal
j Maybe AccountName
macct = String -> Screen -> Screen
forall a. String -> a -> a
dbgui String
"bsNew" (Screen -> Screen) -> Screen -> Screen
forall a b. (a -> b) -> a -> b
$ AccountsScreenState -> Screen
BS (AccountsScreenState -> Screen) -> AccountsScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
bsUpdate UIOpts
uopts Day
d Journal
j (AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState -> AccountsScreenState
forall a b. (a -> b) -> a -> b
$ Maybe AccountName -> AccountsScreenState
nullass Maybe AccountName
macct
bsUpdate :: UIOpts -> Day -> Journal -> AccountsScreenState -> AccountsScreenState
bsUpdate :: UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
bsUpdate UIOpts
uopts Day
d = String
-> (AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState
-> AccountsScreenState
forall a. String -> a -> a
dbgui String
"bsUpdate" ((AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState -> AccountsScreenState)
-> (Journal -> AccountsScreenState -> AccountsScreenState)
-> Journal
-> AccountsScreenState
-> AccountsScreenState
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
ReportSpec
-> Day
-> CliOpts
-> (ReportOpts -> ReportOpts)
-> Query
-> Journal
-> AccountsScreenState
-> AccountsScreenState
asUpdateHelper ReportSpec
rspec Day
d CliOpts
copts ReportOpts -> ReportOpts
roptsmod Query
extraquery
where
UIOpts{uoCliOpts :: UIOpts -> CliOpts
uoCliOpts=copts :: CliOpts
copts@CliOpts{reportspec_ :: CliOpts -> ReportSpec
reportspec_=ReportSpec
rspec}} = UIOpts
uopts
roptsmod :: ReportOpts -> ReportOpts
roptsmod ReportOpts
ropts = ReportOpts
ropts{balanceaccum_=Historical}
extraquery :: Query
extraquery = [AccountType] -> Query
Type [AccountType
Asset,AccountType
Liability,AccountType
Equity]
csNew :: UIOpts -> Day -> Journal -> Maybe AccountName -> Screen
csNew :: UIOpts -> Day -> Journal -> Maybe AccountName -> Screen
csNew UIOpts
uopts Day
d Journal
j Maybe AccountName
macct = String -> Screen -> Screen
forall a. String -> a -> a
dbgui String
"csNew" (Screen -> Screen) -> Screen -> Screen
forall a b. (a -> b) -> a -> b
$ AccountsScreenState -> Screen
CS (AccountsScreenState -> Screen) -> AccountsScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
csUpdate UIOpts
uopts Day
d Journal
j (AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState -> AccountsScreenState
forall a b. (a -> b) -> a -> b
$ Maybe AccountName -> AccountsScreenState
nullass Maybe AccountName
macct
csUpdate :: UIOpts -> Day -> Journal -> AccountsScreenState -> AccountsScreenState
csUpdate :: UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
csUpdate UIOpts
uopts Day
d = String
-> (AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState
-> AccountsScreenState
forall a. String -> a -> a
dbgui String
"csUpdate" ((AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState -> AccountsScreenState)
-> (Journal -> AccountsScreenState -> AccountsScreenState)
-> Journal
-> AccountsScreenState
-> AccountsScreenState
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
ReportSpec
-> Day
-> CliOpts
-> (ReportOpts -> ReportOpts)
-> Query
-> Journal
-> AccountsScreenState
-> AccountsScreenState
asUpdateHelper ReportSpec
rspec Day
d CliOpts
copts ReportOpts -> ReportOpts
roptsmod Query
extraquery
where
UIOpts{uoCliOpts :: UIOpts -> CliOpts
uoCliOpts=copts :: CliOpts
copts@CliOpts{reportspec_ :: CliOpts -> ReportSpec
reportspec_=ReportSpec
rspec}} = UIOpts
uopts
roptsmod :: ReportOpts -> ReportOpts
roptsmod ReportOpts
ropts = ReportOpts
ropts{balanceaccum_=Historical}
extraquery :: Query
extraquery = [AccountType] -> Query
Type [AccountType
Cash]
isNew :: UIOpts -> Day -> Journal -> Maybe AccountName -> Screen
isNew :: UIOpts -> Day -> Journal -> Maybe AccountName -> Screen
isNew UIOpts
uopts Day
d Journal
j Maybe AccountName
macct = String -> Screen -> Screen
forall a. String -> a -> a
dbgui String
"isNew" (Screen -> Screen) -> Screen -> Screen
forall a b. (a -> b) -> a -> b
$ AccountsScreenState -> Screen
IS (AccountsScreenState -> Screen) -> AccountsScreenState -> Screen
forall a b. (a -> b) -> a -> b
$ UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
isUpdate UIOpts
uopts Day
d Journal
j (AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState -> AccountsScreenState
forall a b. (a -> b) -> a -> b
$ Maybe AccountName -> AccountsScreenState
nullass Maybe AccountName
macct
isUpdate :: UIOpts -> Day -> Journal -> AccountsScreenState -> AccountsScreenState
isUpdate :: UIOpts
-> Day -> Journal -> AccountsScreenState -> AccountsScreenState
isUpdate UIOpts
uopts Day
d = String
-> (AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState
-> AccountsScreenState
forall a. String -> a -> a
dbgui String
"isUpdate" ((AccountsScreenState -> AccountsScreenState)
-> AccountsScreenState -> AccountsScreenState)
-> (Journal -> AccountsScreenState -> AccountsScreenState)
-> Journal
-> AccountsScreenState
-> AccountsScreenState
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
ReportSpec
-> Day
-> CliOpts
-> (ReportOpts -> ReportOpts)
-> Query
-> Journal
-> AccountsScreenState
-> AccountsScreenState
asUpdateHelper ReportSpec
rspec Day
d CliOpts
copts ReportOpts -> ReportOpts
roptsmod Query
extraquery
where
UIOpts{uoCliOpts :: UIOpts -> CliOpts
uoCliOpts=copts :: CliOpts
copts@CliOpts{reportspec_ :: CliOpts -> ReportSpec
reportspec_=ReportSpec
rspec}} = UIOpts
uopts
roptsmod :: ReportOpts -> ReportOpts
roptsmod ReportOpts
ropts = ReportOpts
ropts{balanceaccum_=PerPeriod}
extraquery :: Query
extraquery = [AccountType] -> Query
Type [AccountType
Revenue, AccountType
Expense]
rsNew :: UIOpts -> Day -> Journal -> AccountName -> Bool -> Screen
rsNew :: UIOpts -> Day -> Journal -> AccountName -> Bool -> Screen
rsNew UIOpts
uopts Day
d Journal
j AccountName
acct Bool
forceinclusive =
String -> Screen -> Screen
forall a. String -> a -> a
dbgui String
"rsNew" (Screen -> Screen) -> Screen -> Screen
forall a b. (a -> b) -> a -> b
$
RegisterScreenState -> Screen
RS (RegisterScreenState -> Screen) -> RegisterScreenState -> Screen
forall a b. (a -> b) -> a -> b
$
UIOpts
-> Day -> Journal -> RegisterScreenState -> RegisterScreenState
rsUpdate UIOpts
uopts Day
d Journal
j (RegisterScreenState -> RegisterScreenState)
-> RegisterScreenState -> RegisterScreenState
forall a b. (a -> b) -> a -> b
$
RSS {
_rssAccount :: AccountName
_rssAccount = AccountName -> AccountName -> AccountName
replaceHiddenAccountsNameWith AccountName
"*" AccountName
acct
,_rssForceInclusive :: Bool
_rssForceInclusive = Bool
forceinclusive
,_rssList :: List Name RegisterScreenItem
_rssList = Name
-> Vector RegisterScreenItem -> Int -> List Name RegisterScreenItem
forall (t :: * -> *) n e.
Foldable t =>
n -> t e -> Int -> GenericList n t e
list Name
RegisterList ([RegisterScreenItem] -> Vector RegisterScreenItem
forall a. [a] -> Vector a
V.fromList []) Int
1
}
rsUpdate :: UIOpts -> Day -> Journal -> RegisterScreenState -> RegisterScreenState
rsUpdate :: UIOpts
-> Day -> Journal -> RegisterScreenState -> RegisterScreenState
rsUpdate UIOpts
uopts Day
d Journal
j rss :: RegisterScreenState
rss@RSS{AccountName
_rssAccount :: RegisterScreenState -> AccountName
_rssAccount :: AccountName
_rssAccount, Bool
_rssForceInclusive :: RegisterScreenState -> Bool
_rssForceInclusive :: Bool
_rssForceInclusive, _rssList :: RegisterScreenState -> List Name RegisterScreenItem
_rssList=List Name RegisterScreenItem
oldlist} =
String -> RegisterScreenState -> RegisterScreenState
forall a. String -> a -> a
dbgui String
"rsUpdate"
RegisterScreenState
rss{_rssList=l'}
where
UIOpts{uoCliOpts :: UIOpts -> CliOpts
uoCliOpts=copts :: CliOpts
copts@CliOpts{reportspec_ :: CliOpts -> ReportSpec
reportspec_=rspec :: ReportSpec
rspec@ReportSpec{_rsReportOpts :: ReportSpec -> ReportOpts
_rsReportOpts=ReportOpts
ropts}}} = UIOpts
uopts
inclusive :: Bool
inclusive = ReportOpts -> Bool
tree_ ReportOpts
ropts Bool -> Bool -> Bool
|| Bool
_rssForceInclusive
thisacctq :: Query
thisacctq = Regexp -> Query
Acct (Regexp -> Query) -> Regexp -> Query
forall a b. (a -> b) -> a -> b
$ AccountName -> Regexp
mkregex AccountName
_rssAccount
where
mkregex :: AccountName -> Regexp
mkregex = if Bool
inclusive then AccountName -> Regexp
accountNameToAccountRegex else AccountName -> Regexp
accountNameToAccountOnlyRegex
ropts' :: ReportOpts
ropts' = ReportOpts
ropts {
depth_=Nothing
, show_costs_=True
}
rspec' :: ReportSpec
rspec' =
ReportOpts -> ReportSpec -> Either String ReportSpec
updateReportSpec ReportOpts
ropts' ReportSpec
rspec{_rsDay=d}
Either String ReportSpec
-> (Either String ReportSpec -> ReportSpec) -> ReportSpec
forall a b. a -> (a -> b) -> b
& (String -> ReportSpec)
-> (ReportSpec -> ReportSpec)
-> Either String ReportSpec
-> ReportSpec
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> String -> ReportSpec
forall a. HasCallStack => String -> a
error String
"rsUpdate: adjusting the query for register, should not have failed") ReportSpec -> ReportSpec
forall {a}. a -> a
id
ReportSpec -> (ReportSpec -> ReportSpec) -> ReportSpec
forall a b. a -> (a -> b) -> b
& Maybe DateSpan -> ReportSpec -> ReportSpec
reportSpecSetFutureAndForecast (InputOpts -> Maybe DateSpan
forecast_ (InputOpts -> Maybe DateSpan) -> InputOpts -> Maybe DateSpan
forall a b. (a -> b) -> a -> b
$ CliOpts -> InputOpts
inputopts_ CliOpts
copts)
items :: AccountTransactionsReport
items = Map AccountName AmountStyle
-> AccountTransactionsReport -> AccountTransactionsReport
forall a. HasAmounts a => Map AccountName AmountStyle -> a -> a
styleAmounts Map AccountName AmountStyle
styles (AccountTransactionsReport -> AccountTransactionsReport)
-> AccountTransactionsReport -> AccountTransactionsReport
forall a b. (a -> b) -> a -> b
$ ReportSpec -> Journal -> Query -> AccountTransactionsReport
accountTransactionsReport ReportSpec
rspec' Journal
j Query
thisacctq
where
styles :: Map AccountName AmountStyle
styles = Rounding -> Journal -> Map AccountName AmountStyle
journalCommodityStylesWith Rounding
HardRounding Journal
j
items' :: AccountTransactionsReport
items' =
(if ReportOpts -> Bool
empty_ ReportOpts
ropts then AccountTransactionsReport -> AccountTransactionsReport
forall {a}. a -> a
id else ((Transaction, Transaction, Bool, AccountName, MixedAmount,
MixedAmount)
-> Bool)
-> AccountTransactionsReport -> AccountTransactionsReport
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((Transaction, Transaction, Bool, AccountName, MixedAmount,
MixedAmount)
-> Bool)
-> (Transaction, Transaction, Bool, AccountName, MixedAmount,
MixedAmount)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MixedAmount -> Bool
mixedAmountLooksZero (MixedAmount -> Bool)
-> ((Transaction, Transaction, Bool, AccountName, MixedAmount,
MixedAmount)
-> MixedAmount)
-> (Transaction, Transaction, Bool, AccountName, MixedAmount,
MixedAmount)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Transaction, Transaction, Bool, AccountName, MixedAmount,
MixedAmount)
-> MixedAmount
forall {a} {b} {c} {d} {e} {f}. (a, b, c, d, e, f) -> e
fifth6)) (AccountTransactionsReport -> AccountTransactionsReport)
-> AccountTransactionsReport -> AccountTransactionsReport
forall a b. (a -> b) -> a -> b
$
AccountTransactionsReport -> AccountTransactionsReport
forall a. [a] -> [a]
reverse
AccountTransactionsReport
items
displayitems :: [RegisterScreenItem]
displayitems = ((Transaction, Transaction, Bool, AccountName, MixedAmount,
MixedAmount)
-> RegisterScreenItem)
-> AccountTransactionsReport -> [RegisterScreenItem]
forall a b. (a -> b) -> [a] -> [b]
map (Transaction, Transaction, Bool, AccountName, MixedAmount,
MixedAmount)
-> RegisterScreenItem
forall {b} {c}.
(Transaction, b, c, AccountName, MixedAmount, MixedAmount)
-> RegisterScreenItem
displayitem AccountTransactionsReport
items'
where
displayitem :: (Transaction, b, c, AccountName, MixedAmount, MixedAmount)
-> RegisterScreenItem
displayitem (Transaction
t, b
_, c
_issplit, AccountName
otheracctsstr, MixedAmount
change, MixedAmount
bal) =
RegisterScreenItem{rsItemDate :: AccountName
rsItemDate = Day -> AccountName
showDate (Day -> AccountName) -> Day -> AccountName
forall a b. (a -> b) -> a -> b
$ WhichDate -> Query -> Query -> Transaction -> Day
transactionRegisterDate WhichDate
wd (ReportSpec -> Query
_rsQuery ReportSpec
rspec') Query
thisacctq Transaction
t
,rsItemStatus :: Status
rsItemStatus = Transaction -> Status
tstatus Transaction
t
,rsItemDescription :: AccountName
rsItemDescription = Transaction -> AccountName
tdescription Transaction
t
,rsItemOtherAccounts :: AccountName
rsItemOtherAccounts = AccountName
otheracctsstr
,rsItemChangeAmount :: WideBuilder
rsItemChangeAmount = MixedAmount -> WideBuilder
showamt MixedAmount
change
,rsItemBalanceAmount :: WideBuilder
rsItemBalanceAmount = MixedAmount -> WideBuilder
showamt MixedAmount
bal
,rsItemTransaction :: Transaction
rsItemTransaction = Transaction
t
}
where
showamt :: MixedAmount -> WideBuilder
showamt = AmountFormat -> MixedAmount -> WideBuilder
showMixedAmountB AmountFormat
oneLineNoCostFmt{displayMaxWidth=Just 3}
wd :: WhichDate
wd = ReportOpts -> WhichDate
whichDate ReportOpts
ropts'
blankitems :: [RegisterScreenItem]
blankitems = Int -> RegisterScreenItem -> [RegisterScreenItem]
forall a. Int -> a -> [a]
replicate Int
uiNumBlankItems
RegisterScreenItem{rsItemDate :: AccountName
rsItemDate = AccountName
""
,rsItemStatus :: Status
rsItemStatus = Status
Unmarked
,rsItemDescription :: AccountName
rsItemDescription = AccountName
""
,rsItemOtherAccounts :: AccountName
rsItemOtherAccounts = AccountName
""
,rsItemChangeAmount :: WideBuilder
rsItemChangeAmount = WideBuilder
forall a. Monoid a => a
mempty
,rsItemBalanceAmount :: WideBuilder
rsItemBalanceAmount = WideBuilder
forall a. Monoid a => a
mempty
,rsItemTransaction :: Transaction
rsItemTransaction = Transaction
nulltransaction
}
l :: List Name RegisterScreenItem
l = Name
-> Vector RegisterScreenItem -> Int -> List Name RegisterScreenItem
forall (t :: * -> *) n e.
Foldable t =>
n -> t e -> Int -> GenericList n t e
list Name
RegisterList ([RegisterScreenItem] -> Vector RegisterScreenItem
forall a. [a] -> Vector a
V.fromList ([RegisterScreenItem] -> Vector RegisterScreenItem)
-> [RegisterScreenItem] -> Vector RegisterScreenItem
forall a b. (a -> b) -> a -> b
$ [RegisterScreenItem]
displayitems [RegisterScreenItem]
-> [RegisterScreenItem] -> [RegisterScreenItem]
forall a. [a] -> [a] -> [a]
++ [RegisterScreenItem]
blankitems) Int
1
l' :: List Name RegisterScreenItem
l' = Int -> List Name RegisterScreenItem -> List Name RegisterScreenItem
forall (t :: * -> *) n e.
(Foldable t, Splittable t) =>
Int -> GenericList n t e -> GenericList n t e
listMoveTo Int
newselidx List Name RegisterScreenItem
l
where
endidx :: Int
endidx = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ [RegisterScreenItem] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [RegisterScreenItem]
displayitems Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
newselidx :: Int
newselidx =
case List Name RegisterScreenItem -> Maybe (Int, RegisterScreenItem)
forall (t :: * -> *) e n.
(Splittable t, Traversable t, Semigroup (t e)) =>
GenericList n t e -> Maybe (Int, e)
listSelectedElement List Name RegisterScreenItem
oldlist of
Maybe (Int, RegisterScreenItem)
Nothing -> Int
endidx
Just (Int
_, RegisterScreenItem{rsItemTransaction :: RegisterScreenItem -> Transaction
rsItemTransaction=Transaction{tindex :: Transaction -> Integer
tindex=Integer
prevselidx, tdate :: Transaction -> Day
tdate=Day
prevseld}}) ->
Int -> [Int] -> Int
forall a. a -> [a] -> a
headDef Int
endidx ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ [Maybe Int] -> [Int]
forall a. [Maybe a] -> [a]
catMaybes [
(RegisterScreenItem -> Bool) -> [RegisterScreenItem] -> Maybe Int
forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex ((Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Integer
prevselidx) (Integer -> Bool)
-> (RegisterScreenItem -> Integer) -> RegisterScreenItem -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Integer
tindex (Transaction -> Integer)
-> (RegisterScreenItem -> Transaction)
-> RegisterScreenItem
-> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegisterScreenItem -> Transaction
rsItemTransaction) [RegisterScreenItem]
displayitems
,(RegisterScreenItem -> Bool) -> [RegisterScreenItem] -> Maybe Int
forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex ((Maybe Integer -> Maybe Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Maybe Integer
nearestidbydatethenid) (Maybe Integer -> Bool)
-> (RegisterScreenItem -> Maybe Integer)
-> RegisterScreenItem
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Integer -> Maybe Integer)
-> (RegisterScreenItem -> Integer)
-> RegisterScreenItem
-> Maybe Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Integer
tindex (Transaction -> Integer)
-> (RegisterScreenItem -> Transaction)
-> RegisterScreenItem
-> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegisterScreenItem -> Transaction
rsItemTransaction) [RegisterScreenItem]
displayitems
]
where
nearestidbydatethenid :: Maybe Integer
nearestidbydatethenid = (Integer, Integer, Integer) -> Integer
forall {a} {b} {c}. (a, b, c) -> c
third3 ((Integer, Integer, Integer) -> Integer)
-> Maybe (Integer, Integer, Integer) -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([(Integer, Integer, Integer)] -> Maybe (Integer, Integer, Integer)
forall a. [a] -> Maybe a
headMay ([(Integer, Integer, Integer)]
-> Maybe (Integer, Integer, Integer))
-> [(Integer, Integer, Integer)]
-> Maybe (Integer, Integer, Integer)
forall a b. (a -> b) -> a -> b
$ [(Integer, Integer, Integer)] -> [(Integer, Integer, Integer)]
forall a. Ord a => [a] -> [a]
sort
[(Integer -> Integer
forall a. Num a => a -> a
abs (Integer -> Integer) -> Integer -> Integer
forall a b. (a -> b) -> a -> b
$ Day -> Day -> Integer
diffDays (Transaction -> Day
tdate Transaction
t) Day
prevseld, Integer -> Integer
forall a. Num a => a -> a
abs (Transaction -> Integer
tindex Transaction
t Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
prevselidx), Transaction -> Integer
tindex Transaction
t) | Transaction
t <- [Transaction]
ts])
ts :: [Transaction]
ts = (RegisterScreenItem -> Transaction)
-> [RegisterScreenItem] -> [Transaction]
forall a b. (a -> b) -> [a] -> [b]
map RegisterScreenItem -> Transaction
rsItemTransaction [RegisterScreenItem]
displayitems
tsNew :: AccountName -> [NumberedTransaction] -> NumberedTransaction -> Screen
tsNew :: AccountName
-> [NumberedTransaction] -> NumberedTransaction -> Screen
tsNew AccountName
acct [NumberedTransaction]
nts NumberedTransaction
nt =
String -> Screen -> Screen
forall a. String -> a -> a
dbgui String
"tsNew" (Screen -> Screen) -> Screen -> Screen
forall a b. (a -> b) -> a -> b
$
TransactionScreenState -> Screen
TS TSS{
_tssAccount :: AccountName
_tssAccount = AccountName
acct
,_tssTransactions :: [NumberedTransaction]
_tssTransactions = [NumberedTransaction]
nts
,_tssTransaction :: NumberedTransaction
_tssTransaction = NumberedTransaction
nt
}
tsUpdate :: TransactionScreenState -> TransactionScreenState
tsUpdate :: TransactionScreenState -> TransactionScreenState
tsUpdate = String -> TransactionScreenState -> TransactionScreenState
forall a. String -> a -> a
dbgui String
"tsUpdate"