web: an "a" parameter specifies a query expression for filtering the accounts sidebar
Useful for ui experiments, at least
This commit is contained in:
parent
d343614690
commit
8d0b42e1d5
@ -20,6 +20,7 @@ import Hledger.Data.Account (nullacct)
|
|||||||
import Hledger.Data.AccountName
|
import Hledger.Data.AccountName
|
||||||
import Hledger.Data.Journal
|
import Hledger.Data.Journal
|
||||||
import Hledger.Data.Posting
|
import Hledger.Data.Posting
|
||||||
|
import Hledger.Data.Matching
|
||||||
|
|
||||||
|
|
||||||
instance Show Ledger where
|
instance Show Ledger where
|
||||||
@ -45,6 +46,15 @@ journalToLedger fs j = nullledger{journal=j',accountnametree=t,accountmap=m}
|
|||||||
where j' = filterJournalPostings fs{depth=Nothing} j
|
where j' = filterJournalPostings fs{depth=Nothing} j
|
||||||
(t, m) = journalAccountInfo j'
|
(t, m) = journalAccountInfo j'
|
||||||
|
|
||||||
|
-- | Filter a journal's transactions as specified, and then process them
|
||||||
|
-- to derive a ledger containing all balances, the chart of accounts,
|
||||||
|
-- canonicalised commodities etc.
|
||||||
|
-- Like journalToLedger but uses the new matchers.
|
||||||
|
journalToLedger2 :: Matcher -> Journal -> Ledger
|
||||||
|
journalToLedger2 m j = nullledger{journal=j',accountnametree=t,accountmap=amap}
|
||||||
|
where j' = filterJournalPostings2 m j
|
||||||
|
(t, amap) = journalAccountInfo j'
|
||||||
|
|
||||||
-- | List a ledger's account names.
|
-- | List a ledger's account names.
|
||||||
ledgerAccountNames :: Ledger -> [AccountName]
|
ledgerAccountNames :: Ledger -> [AccountName]
|
||||||
ledgerAccountNames = drop 1 . flatten . accountnametree
|
ledgerAccountNames = drop 1 . flatten . accountnametree
|
||||||
|
|||||||
@ -48,8 +48,8 @@ getRootR = redirect RedirectTemporary defaultroute where defaultroute = Register
|
|||||||
-- | The main journal view, with accounts sidebar.
|
-- | The main journal view, with accounts sidebar.
|
||||||
getJournalR :: Handler RepHtml
|
getJournalR :: Handler RepHtml
|
||||||
getJournalR = do
|
getJournalR = do
|
||||||
vd@VD{opts=opts,m=m,j=j} <- getViewData
|
vd@VD{opts=opts,m=m,am=am,j=j} <- getViewData
|
||||||
let sidecontent = balanceReportAsHtml opts vd{q=""} $ balanceReport opts nullfilterspec j
|
let sidecontent = balanceReportAsHtml opts vd $ balanceReport2 opts am j
|
||||||
maincontent = journalReportAsHtml opts vd $ journalReport opts nullfilterspec $ filterJournalTransactions2 m j
|
maincontent = journalReportAsHtml opts vd $ journalReport opts nullfilterspec $ filterJournalTransactions2 m j
|
||||||
defaultLayout $ do
|
defaultLayout $ do
|
||||||
setTitle "hledger-web journal"
|
setTitle "hledger-web journal"
|
||||||
@ -61,8 +61,8 @@ postJournalR = handlePost
|
|||||||
-- | The main register view, with accounts sidebar.
|
-- | The main register view, with accounts sidebar.
|
||||||
getRegisterR :: Handler RepHtml
|
getRegisterR :: Handler RepHtml
|
||||||
getRegisterR = do
|
getRegisterR = do
|
||||||
vd@VD{opts=opts,qopts=qopts,m=m,j=j} <- getViewData
|
vd@VD{opts=opts,qopts=qopts,m=m,am=am,j=j} <- getViewData
|
||||||
let sidecontent = balanceReportAsHtml opts vd{q=""} $ balanceReport opts nullfilterspec j
|
let sidecontent = balanceReportAsHtml opts vd $ balanceReport2 opts am j
|
||||||
maincontent =
|
maincontent =
|
||||||
case inAccountMatcher qopts of Just m' -> accountRegisterReportAsHtml opts vd $ accountRegisterReport opts j m m'
|
case inAccountMatcher qopts of Just m' -> accountRegisterReportAsHtml opts vd $ accountRegisterReport opts j m m'
|
||||||
Nothing -> accountRegisterReportAsHtml opts vd $ journalRegisterReport opts j m
|
Nothing -> accountRegisterReportAsHtml opts vd $ journalRegisterReport opts j m
|
||||||
@ -102,11 +102,11 @@ postRegisterOnlyR = handlePost
|
|||||||
-- specifies json, returns the chart of accounts as json.
|
-- specifies json, returns the chart of accounts as json.
|
||||||
getAccountsR :: Handler RepHtmlJson
|
getAccountsR :: Handler RepHtmlJson
|
||||||
getAccountsR = do
|
getAccountsR = do
|
||||||
vd@VD{opts=opts,m=m,j=j} <- getViewData
|
vd@VD{opts=opts,m=m,am=am,j=j} <- getViewData
|
||||||
let j' = filterJournalPostings2 m j
|
let j' = filterJournalPostings2 m j
|
||||||
html = do
|
html = do
|
||||||
setTitle "hledger-web accounts"
|
setTitle "hledger-web accounts"
|
||||||
addHamlet $ balanceReportAsHtml opts vd $ balanceReport opts nullfilterspec j'
|
addHamlet $ balanceReportAsHtml opts vd $ balanceReport2 opts am j'
|
||||||
json = jsonMap [("accounts", toJSON $ journalAccountNames j')]
|
json = jsonMap [("accounts", toJSON $ journalAccountNames j')]
|
||||||
defaultLayoutJson html json
|
defaultLayoutJson html json
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ accountUrl r a = (r, [("q",pack $ accountQuery a)])
|
|||||||
|
|
||||||
-- | Render a balance report as HTML.
|
-- | Render a balance report as HTML.
|
||||||
balanceReportAsHtml :: [Opt] -> ViewData -> BalanceReport -> Hamlet AppRoute
|
balanceReportAsHtml :: [Opt] -> ViewData -> BalanceReport -> Hamlet AppRoute
|
||||||
balanceReportAsHtml _ vd@VD{here=here,q=q,m=m,qopts=qopts,j=j} (items',total) = $(Settings.hamletFile "balancereport")
|
balanceReportAsHtml _ vd@VD{here=here,m=m,qopts=qopts,j=j} (items',total) = $(Settings.hamletFile "balancereport")
|
||||||
where
|
where
|
||||||
l = journalToLedger nullfilterspec j
|
l = journalToLedger nullfilterspec j
|
||||||
inacctmatcher = inAccountMatcher qopts
|
inacctmatcher = inAccountMatcher qopts
|
||||||
@ -421,8 +421,10 @@ data ViewData = VD {
|
|||||||
opts :: [Opt] -- ^ command-line options at startup
|
opts :: [Opt] -- ^ command-line options at startup
|
||||||
,q :: String -- ^ current q parameter, the query expression
|
,q :: String -- ^ current q parameter, the query expression
|
||||||
,p :: Bool -- ^ current p parameter, 1 or 0 shows/hides all postings, default is based on query
|
,p :: Bool -- ^ current p parameter, 1 or 0 shows/hides all postings, default is based on query
|
||||||
,m :: Matcher -- ^ a matcher parsed from the query expr
|
,m :: Matcher -- ^ a matcher parsed from the main query expr ("q" parameter)
|
||||||
,qopts :: [QueryOpt] -- ^ query options parsed from the query expr
|
,qopts :: [QueryOpt] -- ^ query options parsed from the main query expr
|
||||||
|
,am :: Matcher -- ^ a matcher parsed from the accounts sidebar query expr ("a" parameter)
|
||||||
|
,aopts :: [QueryOpt] -- ^ query options parsed from the accounts sidebar query expr
|
||||||
,j :: Journal -- ^ the up-to-date parsed unfiltered journal
|
,j :: Journal -- ^ the up-to-date parsed unfiltered journal
|
||||||
,today :: Day -- ^ the current day
|
,today :: Day -- ^ the current day
|
||||||
,here :: AppRoute -- ^ the current route
|
,here :: AppRoute -- ^ the current route
|
||||||
@ -436,6 +438,8 @@ mkvd = VD {
|
|||||||
,p = False
|
,p = False
|
||||||
,m = MatchAny
|
,m = MatchAny
|
||||||
,qopts = []
|
,qopts = []
|
||||||
|
,am = MatchAny
|
||||||
|
,aopts = []
|
||||||
,j = nulljournal
|
,j = nulljournal
|
||||||
,today = ModifiedJulianDay 0
|
,today = ModifiedJulianDay 0
|
||||||
,here = RootR
|
,here = RootR
|
||||||
@ -452,12 +456,14 @@ getViewData = do
|
|||||||
Just here' <- getCurrentRoute
|
Just here' <- getCurrentRoute
|
||||||
today <- liftIO getCurrentDay
|
today <- liftIO getCurrentDay
|
||||||
q <- getParameter "q"
|
q <- getParameter "q"
|
||||||
let (m,qopts) = parseQuery today q
|
let (querymatcher,queryopts) = parseQuery today q
|
||||||
|
a <- getParameter "a"
|
||||||
|
let (acctsmatcher,acctsopts) = parseQuery today a
|
||||||
p <- getParameter "p"
|
p <- getParameter "p"
|
||||||
let p' | p == "1" = True
|
let p' | p == "1" = True
|
||||||
| p == "0" = False
|
| p == "0" = False
|
||||||
| otherwise = isNothing $ inAccountMatcher qopts
|
| otherwise = isNothing $ inAccountMatcher queryopts
|
||||||
return mkvd{opts=opts, q=q, p=p', m=m, qopts=qopts, j=j, today=today, here=here', msg=msg}
|
return mkvd{opts=opts, q=q, p=p', m=querymatcher, qopts=queryopts, am=acctsmatcher, aopts=acctsopts, j=j, today=today, here=here', msg=msg}
|
||||||
where
|
where
|
||||||
-- | Update our copy of the journal if the file changed. If there is an
|
-- | Update our copy of the journal if the file changed. If there is an
|
||||||
-- error while reloading, keep the old one and return the error, and set a
|
-- error while reloading, keep the old one and return the error, and set a
|
||||||
|
|||||||
@ -100,6 +100,7 @@ module Hledger.Cli.Balance (
|
|||||||
,BalanceReportItem
|
,BalanceReportItem
|
||||||
,balance
|
,balance
|
||||||
,balanceReport
|
,balanceReport
|
||||||
|
,balanceReport2
|
||||||
,balanceReportAsText
|
,balanceReportAsText
|
||||||
,tests_Hledger_Cli_Balance
|
,tests_Hledger_Cli_Balance
|
||||||
-- ,tests_Balance
|
-- ,tests_Balance
|
||||||
@ -221,6 +222,34 @@ balanceReport opts filterspec j = (items, total)
|
|||||||
| otherwise = abalance acct
|
| otherwise = abalance acct
|
||||||
where acct = ledgerAccount l a
|
where acct = ledgerAccount l a
|
||||||
|
|
||||||
|
-- | Get a balance report with the specified options for this
|
||||||
|
-- journal. Like balanceReport but uses the new matchers.
|
||||||
|
balanceReport2 :: [Opt] -> Matcher -> Journal -> BalanceReport
|
||||||
|
balanceReport2 opts m j = (items, total)
|
||||||
|
where
|
||||||
|
items = map mkitem interestingaccts
|
||||||
|
interestingaccts | NoElide `elem` opts = acctnames
|
||||||
|
| otherwise = filter (isInteresting opts l) acctnames
|
||||||
|
acctnames = sort $ tail $ flatten $ treemap aname accttree
|
||||||
|
accttree = ledgerAccountTree (fromMaybe 99999 $ depthFromOpts opts) l
|
||||||
|
total = sum $ map abalance $ ledgerTopAccounts l
|
||||||
|
l = journalToLedger2 m j'
|
||||||
|
j' = journalSelectingDateFromOpts opts $ journalSelectingAmountFromOpts opts j
|
||||||
|
-- | Get data for one balance report line item.
|
||||||
|
mkitem :: AccountName -> BalanceReportItem
|
||||||
|
mkitem a = (a, adisplay, indent, abal)
|
||||||
|
where
|
||||||
|
adisplay | Flat `elem` opts = a
|
||||||
|
| otherwise = accountNameFromComponents $ reverse (map accountLeafName ps) ++ [accountLeafName a]
|
||||||
|
where ps = takeWhile boring parents where boring = not . (`elem` interestingparents)
|
||||||
|
indent | Flat `elem` opts = 0
|
||||||
|
| otherwise = length interestingparents
|
||||||
|
interestingparents = filter (`elem` interestingaccts) parents
|
||||||
|
parents = parentAccountNames a
|
||||||
|
abal | Flat `elem` opts = exclusiveBalance acct
|
||||||
|
| otherwise = abalance acct
|
||||||
|
where acct = ledgerAccount l a
|
||||||
|
|
||||||
exclusiveBalance :: Account -> MixedAmount
|
exclusiveBalance :: Account -> MixedAmount
|
||||||
exclusiveBalance = sumPostings . apostings
|
exclusiveBalance = sumPostings . apostings
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user