more matcher -> query renaming

This commit is contained in:
Simon Michael 2012-05-16 07:37:24 +00:00
parent a7ef0ba8dd
commit a27eb7c29f
15 changed files with 125 additions and 126 deletions

View File

@ -35,8 +35,8 @@ module Hledger.Data.Journal (
journalFilePaths, journalFilePaths,
journalPostings, journalPostings,
-- * Standard account types -- * Standard account types
journalBalanceSheetAccountMatcher, journalBalanceSheetAccountQuery,
journalProfitAndLossAccountMatcher, journalProfitAndLossAccountQuery,
-- * Misc -- * Misc
groupPostings, groupPostings,
matchpats, matchpats,
@ -163,17 +163,17 @@ balanceSheetAccountRegex, profitAndLossAccountRegex :: String
balanceSheetAccountRegex = "^(assets?|liabilit(y|ies)|equity)(:|$)" balanceSheetAccountRegex = "^(assets?|liabilit(y|ies)|equity)(:|$)"
profitAndLossAccountRegex = "^(income|expenses?|profits?|loss(es)?)(:|$)" profitAndLossAccountRegex = "^(income|expenses?|profits?|loss(es)?)(:|$)"
-- | A matcher for Asset, Liability & Equity accounts in this journal. -- | A query for Asset, Liability & Equity accounts in this journal.
-- Cf <http://en.wikipedia.org/wiki/Chart_of_accounts#Balance_Sheet_Accounts>. -- Cf <http://en.wikipedia.org/wiki/Chart_of_accounts#Balance_Sheet_Accounts>.
-- This is currently hard-coded to the case-insensitive regex @^(assets?|liabilit(y|ies)|equity)(:|$)@. -- This is currently hard-coded to the case-insensitive regex @^(assets?|liabilit(y|ies)|equity)(:|$)@.
journalBalanceSheetAccountMatcher :: Journal -> Matcher journalBalanceSheetAccountQuery :: Journal -> Matcher
journalBalanceSheetAccountMatcher _ = MatchAcct balanceSheetAccountRegex journalBalanceSheetAccountQuery _ = MatchAcct balanceSheetAccountRegex
-- | A matcher for Profit & Loss accounts in this journal. -- | A query for Profit & Loss accounts in this journal.
-- Cf <http://en.wikipedia.org/wiki/Chart_of_accounts#Profit_.26_Loss_accounts>. -- Cf <http://en.wikipedia.org/wiki/Chart_of_accounts#Profit_.26_Loss_accounts>.
-- This is currently hard-coded to the case-insensitive regex @^(income|expenses?|profits?|loss(es)?)(:|$)@. -- This is currently hard-coded to the case-insensitive regex @^(income|expenses?|profits?|loss(es)?)(:|$)@.
journalProfitAndLossAccountMatcher :: Journal -> Matcher journalProfitAndLossAccountQuery :: Journal -> Matcher
journalProfitAndLossAccountMatcher _ = MatchAcct profitAndLossAccountRegex journalProfitAndLossAccountQuery _ = MatchAcct profitAndLossAccountRegex
-- Various kinds of filtering on journals. We do it differently depending -- Various kinds of filtering on journals. We do it differently depending
-- on the command. -- on the command.

View File

@ -49,7 +49,7 @@ journalToLedger fs j = nullledger{journal=j',accountnametree=t,accountmap=m}
-- | Filter a journal's transactions as specified, and then process them -- | Filter a journal's transactions as specified, and then process them
-- to derive a ledger containing all balances, the chart of accounts, -- to derive a ledger containing all balances, the chart of accounts,
-- canonicalised commodities etc. -- canonicalised commodities etc.
-- Like journalToLedger but uses the new matchers. -- Like journalToLedger but uses the new queries.
journalToLedger2 :: Matcher -> Journal -> Ledger journalToLedger2 :: Matcher -> Journal -> Ledger
journalToLedger2 m j = nullledger{journal=j',accountnametree=t,accountmap=amap} journalToLedger2 m j = nullledger{journal=j',accountnametree=t,accountmap=amap}
where j' = filterJournalPostings2 m j where j' = filterJournalPostings2 m j

View File

@ -7,13 +7,13 @@ Currently used only by hledger-web.
module Hledger.Data.Query ( module Hledger.Data.Query (
Matcher(..), Matcher(..),
matcherIsNull, queryIsNull,
matcherIsStartDateOnly, queryIsStartDateOnly,
matcherStartDate, queryStartDate,
matchesTransaction, matchesTransaction,
matchesPosting, matchesPosting,
inAccount, inAccount,
inAccountMatcher, inAccountQuery,
tests_Hledger_Data_Query tests_Hledger_Data_Query
) )
where where
@ -42,9 +42,8 @@ import Hledger.Data.Posting
import Hledger.Data.Transaction import Hledger.Data.Transaction
-- import Hledger.Data.TimeLog -- import Hledger.Data.TimeLog
-- | A matcher is a single, or boolean composition of, search criteria, -- | A query is a composition of search criteria, which can be used to
-- which can be used to match postings, transactions, accounts and more. -- match postings, transactions, accounts and more.
-- Currently used by hledger-web, will likely replace FilterSpec at some point.
data Matcher = MatchAny -- ^ always match data Matcher = MatchAny -- ^ always match
| MatchNone -- ^ never match | MatchNone -- ^ never match
| MatchNot Matcher -- ^ negate this match | MatchNot Matcher -- ^ negate this match
@ -77,21 +76,21 @@ inAccount [] = Nothing
inAccount (QueryOptInAcctOnly a:_) = Just (a,False) inAccount (QueryOptInAcctOnly a:_) = Just (a,False)
inAccount (QueryOptInAcct a:_) = Just (a,True) inAccount (QueryOptInAcct a:_) = Just (a,True)
-- | A matcher for the account(s) we are currently focussed on, if any. -- | A query for the account(s) we are currently focussed on, if any.
-- Just looks at the first query option. -- Just looks at the first query option.
inAccountMatcher :: [QueryOpt] -> Maybe Matcher inAccountQuery :: [QueryOpt] -> Maybe Matcher
inAccountMatcher [] = Nothing inAccountQuery [] = Nothing
inAccountMatcher (QueryOptInAcctOnly a:_) = Just $ MatchAcct $ accountNameToAccountOnlyRegex a inAccountQuery (QueryOptInAcctOnly a:_) = Just $ MatchAcct $ accountNameToAccountOnlyRegex a
inAccountMatcher (QueryOptInAcct a:_) = Just $ MatchAcct $ accountNameToAccountRegex a inAccountQuery (QueryOptInAcct a:_) = Just $ MatchAcct $ accountNameToAccountRegex a
-- -- | A matcher restricting the account(s) to be shown in the sidebar, if any. -- -- | A query restricting the account(s) to be shown in the sidebar, if any.
-- -- Just looks at the first query option. -- -- Just looks at the first query option.
-- showAccountMatcher :: [QueryOpt] -> Maybe Matcher -- showAccountMatcher :: [QueryOpt] -> Maybe Matcher
-- showAccountMatcher (QueryOptInAcctSubsOnly a:_) = Just $ MatchAcct True $ accountNameToAccountRegex a -- showAccountMatcher (QueryOptInAcctSubsOnly a:_) = Just $ MatchAcct True $ accountNameToAccountRegex a
-- showAccountMatcher _ = Nothing -- showAccountMatcher _ = Nothing
-- | Convert a query expression containing zero or more space-separated -- | Convert a query expression containing zero or more space-separated
-- terms to a matcher and zero or more query options. A query term is either: -- terms to a query and zero or more query options. A query term is either:
-- --
-- 1. a search criteria, used to match transactions. This is usually a prefixed pattern such as: -- 1. a search criteria, used to match transactions. This is usually a prefixed pattern such as:
-- acct:REGEXP -- acct:REGEXP
@ -109,10 +108,10 @@ parseQuery :: Day -> String -> (Matcher,[QueryOpt])
parseQuery d s = (m,qopts) parseQuery d s = (m,qopts)
where where
terms = words'' prefixes s terms = words'' prefixes s
(matchers, qopts) = partitionEithers $ map (parseMatcher d) terms (queries, qopts) = partitionEithers $ map (parseQueryTerm d) terms
m = case matchers of [] -> MatchAny m = case queries of [] -> MatchAny
(m':[]) -> m' (m':[]) -> m'
ms -> MatchAnd ms ms -> MatchAnd ms
-- | Quote-and-prefix-aware version of words - don't split on spaces which -- | Quote-and-prefix-aware version of words - don't split on spaces which
-- are inside quotes, including quotes which may have one of the specified -- are inside quotes, including quotes which may have one of the specified
@ -135,14 +134,14 @@ words'' prefixes = fromparse . parsewith maybeprefixedquotedphrases -- XXX
pattern = many (noneOf " \n\r\"") pattern = many (noneOf " \n\r\"")
-- -- | Parse the query string as a boolean tree of match patterns. -- -- | Parse the query string as a boolean tree of match patterns.
-- parseMatcher :: String -> Matcher -- parseQueryTerm :: String -> Matcher
-- parseMatcher s = either (const (MatchAny)) id $ runParser matcher () "" $ lexmatcher s -- parseQueryTerm s = either (const (MatchAny)) id $ runParser query () "" $ lexmatcher s
-- lexmatcher :: String -> [String] -- lexmatcher :: String -> [String]
-- lexmatcher s = words' s -- lexmatcher s = words' s
-- matcher :: GenParser String () Matcher -- query :: GenParser String () Matcher
-- matcher = undefined -- query = undefined
-- keep synced with patterns below, excluding "not" -- keep synced with patterns below, excluding "not"
prefixes = map (++":") [ prefixes = map (++":") [
@ -151,34 +150,34 @@ prefixes = map (++":") [
] ]
defaultprefix = "acct" defaultprefix = "acct"
-- | Parse a single query term as either a matcher or a query option. -- | Parse a single query term as either a query or a query option.
parseMatcher :: Day -> String -> Either Matcher QueryOpt parseQueryTerm :: Day -> String -> Either Matcher QueryOpt
parseMatcher _ ('i':'n':'a':'c':'c':'t':'o':'n':'l':'y':':':s) = Right $ QueryOptInAcctOnly s parseQueryTerm _ ('i':'n':'a':'c':'c':'t':'o':'n':'l':'y':':':s) = Right $ QueryOptInAcctOnly s
parseMatcher _ ('i':'n':'a':'c':'c':'t':':':s) = Right $ QueryOptInAcct s parseQueryTerm _ ('i':'n':'a':'c':'c':'t':':':s) = Right $ QueryOptInAcct s
parseMatcher d ('n':'o':'t':':':s) = case parseMatcher d s of parseQueryTerm d ('n':'o':'t':':':s) = case parseQueryTerm d s of
Left m -> Left $ MatchNot m Left m -> Left $ MatchNot m
Right _ -> Left MatchAny -- not:somequeryoption will be ignored Right _ -> Left MatchAny -- not:somequeryoption will be ignored
parseMatcher _ ('d':'e':'s':'c':':':s) = Left $ MatchDesc s parseQueryTerm _ ('d':'e':'s':'c':':':s) = Left $ MatchDesc s
parseMatcher _ ('a':'c':'c':'t':':':s) = Left $ MatchAcct s parseQueryTerm _ ('a':'c':'c':'t':':':s) = Left $ MatchAcct s
parseMatcher d ('d':'a':'t':'e':':':s) = parseQueryTerm d ('d':'a':'t':'e':':':s) =
case parsePeriodExpr d s of Left _ -> Left MatchNone -- XXX should warn case parsePeriodExpr d s of Left _ -> Left MatchNone -- XXX should warn
Right (_,span) -> Left $ MatchDate span Right (_,span) -> Left $ MatchDate span
parseMatcher d ('e':'d':'a':'t':'e':':':s) = parseQueryTerm d ('e':'d':'a':'t':'e':':':s) =
case parsePeriodExpr d s of Left _ -> Left MatchNone -- XXX should warn case parsePeriodExpr d s of Left _ -> Left MatchNone -- XXX should warn
Right (_,span) -> Left $ MatchEDate span Right (_,span) -> Left $ MatchEDate span
parseMatcher _ ('s':'t':'a':'t':'u':'s':':':s) = Left $ MatchStatus $ parseStatus s parseQueryTerm _ ('s':'t':'a':'t':'u':'s':':':s) = Left $ MatchStatus $ parseStatus s
parseMatcher _ ('r':'e':'a':'l':':':s) = Left $ MatchReal $ parseBool s parseQueryTerm _ ('r':'e':'a':'l':':':s) = Left $ MatchReal $ parseBool s
parseMatcher _ ('e':'m':'p':'t':'y':':':s) = Left $ MatchEmpty $ parseBool s parseQueryTerm _ ('e':'m':'p':'t':'y':':':s) = Left $ MatchEmpty $ parseBool s
parseMatcher _ ('d':'e':'p':'t':'h':':':s) = Left $ MatchDepth $ readDef 0 s parseQueryTerm _ ('d':'e':'p':'t':'h':':':s) = Left $ MatchDepth $ readDef 0 s
parseMatcher _ "" = Left $ MatchAny parseQueryTerm _ "" = Left $ MatchAny
parseMatcher d s = parseMatcher d $ defaultprefix++":"++s parseQueryTerm d s = parseQueryTerm d $ defaultprefix++":"++s
-- | Parse the boolean value part of a "status:" matcher, allowing "*" as -- | Parse the boolean value part of a "status:" query, allowing "*" as
-- another way to spell True, similar to the journal file format. -- another way to spell True, similar to the journal file format.
parseStatus :: String -> Bool parseStatus :: String -> Bool
parseStatus s = s `elem` (truestrings ++ ["*"]) parseStatus s = s `elem` (truestrings ++ ["*"])
-- | Parse the boolean value part of a "status:" matcher. A true value can -- | Parse the boolean value part of a "status:" query. A true value can
-- be spelled as "1", "t" or "true". -- be spelled as "1", "t" or "true".
parseBool :: String -> Bool parseBool :: String -> Bool
parseBool s = s `elem` truestrings parseBool s = s `elem` truestrings
@ -186,9 +185,9 @@ parseBool s = s `elem` truestrings
truestrings :: [String] truestrings :: [String]
truestrings = ["1","t","true"] truestrings = ["1","t","true"]
-- -- | Convert a match expression to its inverse. -- -- | Convert a query to its inverse.
-- negateMatcher :: Matcher -> Matcher -- negateQuery :: Matcher -> Matcher
-- negateMatcher = MatchNot -- negateQuery = MatchNot
-- | Does the match expression match this posting ? -- | Does the match expression match this posting ?
matchesPosting :: Matcher -> Posting -> Bool matchesPosting :: Matcher -> Posting -> Bool
@ -240,33 +239,33 @@ matchesAccount (MatchAnd ms) a = all (`matchesAccount` a) ms
matchesAccount (MatchAcct r) a = regexMatchesCI r a matchesAccount (MatchAcct r) a = regexMatchesCI r a
matchesAccount _ _ = False matchesAccount _ _ = False
-- | What start date does this matcher specify, if any ? -- | What start date does this query specify, if any ?
-- If the matcher is an OR expression, returns the earliest of the alternatives. -- If the query is an OR expression, returns the earliest of the alternatives.
-- When the flag is true, look for a starting effective date instead. -- When the flag is true, look for a starting effective date instead.
matcherStartDate :: Bool -> Matcher -> Maybe Day queryStartDate :: Bool -> Matcher -> Maybe Day
matcherStartDate effective (MatchOr ms) = earliestMaybeDate $ map (matcherStartDate effective) ms queryStartDate effective (MatchOr ms) = earliestMaybeDate $ map (queryStartDate effective) ms
matcherStartDate effective (MatchAnd ms) = latestMaybeDate $ map (matcherStartDate effective) ms queryStartDate effective (MatchAnd ms) = latestMaybeDate $ map (queryStartDate effective) ms
matcherStartDate False (MatchDate (DateSpan (Just d) _)) = Just d queryStartDate False (MatchDate (DateSpan (Just d) _)) = Just d
matcherStartDate True (MatchEDate (DateSpan (Just d) _)) = Just d queryStartDate True (MatchEDate (DateSpan (Just d) _)) = Just d
matcherStartDate _ _ = Nothing queryStartDate _ _ = Nothing
-- | Does this matcher specify a start date and nothing else (that would -- | Does this query specify a start date and nothing else (that would
-- filter postings prior to the date) ? -- filter postings prior to the date) ?
-- When the flag is true, look for a starting effective date instead. -- When the flag is true, look for a starting effective date instead.
matcherIsStartDateOnly :: Bool -> Matcher -> Bool queryIsStartDateOnly :: Bool -> Matcher -> Bool
matcherIsStartDateOnly _ MatchAny = False queryIsStartDateOnly _ MatchAny = False
matcherIsStartDateOnly _ MatchNone = False queryIsStartDateOnly _ MatchNone = False
matcherIsStartDateOnly effective (MatchOr ms) = and $ map (matcherIsStartDateOnly effective) ms queryIsStartDateOnly effective (MatchOr ms) = and $ map (queryIsStartDateOnly effective) ms
matcherIsStartDateOnly effective (MatchAnd ms) = and $ map (matcherIsStartDateOnly effective) ms queryIsStartDateOnly effective (MatchAnd ms) = and $ map (queryIsStartDateOnly effective) ms
matcherIsStartDateOnly False (MatchDate (DateSpan (Just _) _)) = True queryIsStartDateOnly False (MatchDate (DateSpan (Just _) _)) = True
matcherIsStartDateOnly True (MatchEDate (DateSpan (Just _) _)) = True queryIsStartDateOnly True (MatchEDate (DateSpan (Just _) _)) = True
matcherIsStartDateOnly _ _ = False queryIsStartDateOnly _ _ = False
-- | Does this matcher match everything ? -- | Does this query match everything ?
matcherIsNull MatchAny = True queryIsNull MatchAny = True
matcherIsNull (MatchAnd []) = True queryIsNull (MatchAnd []) = True
matcherIsNull (MatchNot (MatchOr [])) = True queryIsNull (MatchNot (MatchOr [])) = True
matcherIsNull _ = False queryIsNull _ = False
-- | What is the earliest of these dates, where Nothing is earliest ? -- | What is the earliest of these dates, where Nothing is earliest ?
earliestMaybeDate :: [Maybe Day] -> Maybe Day earliestMaybeDate :: [Maybe Day] -> Maybe Day

View File

@ -20,7 +20,7 @@ module Hledger.Reports (
whichDateFromOpts, whichDateFromOpts,
journalSelectingDateFromOpts, journalSelectingDateFromOpts,
journalSelectingAmountFromOpts, journalSelectingAmountFromOpts,
optsToFilterSpec, filterSpecFromOpts,
-- * Entries report -- * Entries report
EntriesReport, EntriesReport,
EntriesReportItem, EntriesReportItem,
@ -167,8 +167,8 @@ journalSelectingAmountFromOpts opts
| otherwise = id | otherwise = id
-- | Convert application options to the library's generic filter specification. -- | Convert application options to the library's generic filter specification.
optsToFilterSpec :: ReportOpts -> Day -> FilterSpec filterSpecFromOpts :: ReportOpts -> Day -> FilterSpec
optsToFilterSpec opts@ReportOpts{..} d = FilterSpec { filterSpecFromOpts opts@ReportOpts{..} d = FilterSpec {
datespan=dateSpanFromOpts d opts datespan=dateSpanFromOpts d opts
,cleared= clearedValueFromOpts opts ,cleared= clearedValueFromOpts opts
,real=real_ ,real=real_
@ -384,7 +384,7 @@ triBalance (_,_,_,_,_,Mixed a) = case a of [] -> "0"
-- | Select transactions from the whole journal for a transactions report, -- | Select transactions from the whole journal for a transactions report,
-- with no \"current\" account. The end result is similar to -- with no \"current\" account. The end result is similar to
-- "postingsReport" except it uses matchers and transaction-based report -- "postingsReport" except it uses queries and transaction-based report
-- items and the items are most recent first. Used by eg hledger-web's -- items and the items are most recent first. Used by eg hledger-web's
-- journal view. -- journal view.
journalTransactionsReport :: ReportOpts -> Journal -> Matcher -> TransactionsReport journalTransactionsReport :: ReportOpts -> Journal -> Matcher -> TransactionsReport
@ -411,43 +411,43 @@ journalTransactionsReport _ Journal{jtxns=ts} m = (totallabel, items)
-- most recent first. Used by eg hledger-web's account register view. -- most recent first. Used by eg hledger-web's account register view.
-- --
accountTransactionsReport :: ReportOpts -> Journal -> Matcher -> Matcher -> TransactionsReport accountTransactionsReport :: ReportOpts -> Journal -> Matcher -> Matcher -> TransactionsReport
accountTransactionsReport opts j m thisacctmatcher = (label, items) accountTransactionsReport opts j m thisacctquery = (label, items)
where where
-- transactions affecting this account, in date order -- transactions affecting this account, in date order
ts = sortBy (comparing tdate) $ filter (matchesTransaction thisacctmatcher) $ jtxns $ ts = sortBy (comparing tdate) $ filter (matchesTransaction thisacctquery) $ jtxns $
journalSelectingDateFromOpts opts $ journalSelectingAmountFromOpts opts j journalSelectingDateFromOpts opts $ journalSelectingAmountFromOpts opts j
-- starting balance: if we are filtering by a start date and nothing else, -- starting balance: if we are filtering by a start date and nothing else,
-- the sum of postings to this account before that date; otherwise zero. -- the sum of postings to this account before that date; otherwise zero.
(startbal,label) | matcherIsNull m = (nullmixedamt, balancelabel) (startbal,label) | queryIsNull m = (nullmixedamt, balancelabel)
| matcherIsStartDateOnly (effective_ opts) m = (sumPostings priorps, balancelabel) | queryIsStartDateOnly (effective_ opts) m = (sumPostings priorps, balancelabel)
| otherwise = (nullmixedamt, totallabel) | otherwise = (nullmixedamt, totallabel)
where where
priorps = -- ltrace "priorps" $ priorps = -- ltrace "priorps" $
filter (matchesPosting filter (matchesPosting
(-- ltrace "priormatcher" $ (-- ltrace "priormatcher" $
MatchAnd [thisacctmatcher, tostartdatematcher])) MatchAnd [thisacctquery, tostartdatequery]))
$ transactionsPostings ts $ transactionsPostings ts
tostartdatematcher = MatchDate (DateSpan Nothing startdate) tostartdatequery = MatchDate (DateSpan Nothing startdate)
startdate = matcherStartDate (effective_ opts) m startdate = queryStartDate (effective_ opts) m
items = reverse $ accountTransactionsReportItems m (Just thisacctmatcher) startbal negate ts items = reverse $ accountTransactionsReportItems m (Just thisacctquery) startbal negate ts
-- | Generate transactions report items from a list of transactions, -- | Generate transactions report items from a list of transactions,
-- using the provided query and current account matchers, starting balance, -- using the provided query and current account queries, starting balance,
-- sign-setting function and balance-summing function. -- sign-setting function and balance-summing function.
accountTransactionsReportItems :: Matcher -> Maybe Matcher -> MixedAmount -> (MixedAmount -> MixedAmount) -> [Transaction] -> [TransactionsReportItem] accountTransactionsReportItems :: Matcher -> Maybe Matcher -> MixedAmount -> (MixedAmount -> MixedAmount) -> [Transaction] -> [TransactionsReportItem]
accountTransactionsReportItems _ _ _ _ [] = [] accountTransactionsReportItems _ _ _ _ [] = []
accountTransactionsReportItems matcher thisacctmatcher bal signfn (t:ts) = accountTransactionsReportItems query thisacctquery bal signfn (t:ts) =
-- This is used for both accountTransactionsReport and journalTransactionsReport, -- This is used for both accountTransactionsReport and journalTransactionsReport,
-- which makes it a bit overcomplicated -- which makes it a bit overcomplicated
case i of Just i' -> i':is case i of Just i' -> i':is
Nothing -> is Nothing -> is
where where
tmatched@Transaction{tpostings=psmatched} = filterTransactionPostings matcher t tmatched@Transaction{tpostings=psmatched} = filterTransactionPostings query t
(psthisacct,psotheracct) = case thisacctmatcher of Just m -> partition (matchesPosting m) psmatched (psthisacct,psotheracct) = case thisacctquery of Just m -> partition (matchesPosting m) psmatched
Nothing -> ([],psmatched) Nothing -> ([],psmatched)
numotheraccts = length $ nub $ map paccount psotheracct numotheraccts = length $ nub $ map paccount psotheracct
amt = negate $ sum $ map pamount psthisacct amt = negate $ sum $ map pamount psthisacct
acct | isNothing thisacctmatcher = summarisePostings psmatched -- journal register acct | isNothing thisacctquery = summarisePostings psmatched -- journal register
| numotheraccts == 0 = "transfer between " ++ summarisePostingAccounts psthisacct | numotheraccts == 0 = "transfer between " ++ summarisePostingAccounts psthisacct
| otherwise = prefix ++ summarisePostingAccounts psotheracct | otherwise = prefix ++ summarisePostingAccounts psotheracct
where prefix = maybe "" (\b -> if b then "from " else "to ") $ isNegativeMixedAmount amt where prefix = maybe "" (\b -> if b then "from " else "to ") $ isNegativeMixedAmount amt
@ -457,7 +457,7 @@ accountTransactionsReportItems matcher thisacctmatcher bal signfn (t:ts) =
where where
a = signfn amt a = signfn amt
b = bal + a b = bal + a
is = accountTransactionsReportItems matcher thisacctmatcher bal' signfn ts is = accountTransactionsReportItems query thisacctquery bal' signfn ts
-- | Generate a short readable summary of some postings, like -- | Generate a short readable summary of some postings, like
-- "from (negatives) to (positives)". -- "from (negatives) to (positives)".
@ -498,10 +498,10 @@ accountsReport opts filterspec j = accountsReport' opts j (journalToLedger filte
-- | Select accounts, and get their balances at the end of the selected -- | Select accounts, and get their balances at the end of the selected
-- period, and misc. display information, for an accounts report. Like -- period, and misc. display information, for an accounts report. Like
-- "accountsReport" but uses the new matchers. Used by eg hledger-web's -- "accountsReport" but uses the new queries. Used by eg hledger-web's
-- accounts sidebar. -- accounts sidebar.
accountsReport2 :: ReportOpts -> Matcher -> Journal -> AccountsReport accountsReport2 :: ReportOpts -> Matcher -> Journal -> AccountsReport
accountsReport2 opts matcher j = accountsReport' opts j (journalToLedger2 matcher) accountsReport2 opts query j = accountsReport' opts j (journalToLedger2 query)
-- Accounts report helper. -- Accounts report helper.
accountsReport' :: ReportOpts -> Journal -> (Journal -> Ledger) -> AccountsReport accountsReport' :: ReportOpts -> Journal -> (Journal -> Ledger) -> AccountsReport

View File

@ -138,7 +138,7 @@ getRegisterR = do
(a,subs) = fromMaybe ("all accounts",False) $ inAccount qopts (a,subs) = fromMaybe ("all accounts",False) $ inAccount qopts
andsubs = if subs then " (and subaccounts)" else "" andsubs = if subs then " (and subaccounts)" else ""
filter = if filtering then ", filtered" else "" filter = if filtering then ", filtered" else ""
maincontent = registerReportHtml opts vd $ accountTransactionsReport (reportopts_ $ cliopts_ opts) j m $ fromMaybe MatchAny $ inAccountMatcher qopts maincontent = registerReportHtml opts vd $ accountTransactionsReport (reportopts_ $ cliopts_ opts) j m $ fromMaybe MatchAny $ inAccountQuery qopts
defaultLayout $ do defaultLayout $ do
setTitle "hledger-web register" setTitle "hledger-web register"
addHamlet [$hamlet| addHamlet [$hamlet|
@ -163,7 +163,7 @@ getRegisterOnlyR = do
defaultLayout $ do defaultLayout $ do
setTitle "hledger-web register only" setTitle "hledger-web register only"
addHamlet $ addHamlet $
case inAccountMatcher qopts of Just m' -> registerReportHtml opts vd $ accountTransactionsReport (reportopts_ $ cliopts_ opts) j m m' case inAccountQuery qopts of Just m' -> registerReportHtml opts vd $ accountTransactionsReport (reportopts_ $ cliopts_ opts) j m m'
Nothing -> registerReportHtml opts vd $ journalTransactionsReport (reportopts_ $ cliopts_ opts) j m Nothing -> registerReportHtml opts vd $ journalTransactionsReport (reportopts_ $ cliopts_ opts) j m
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -237,7 +237,7 @@ accountsReportAsHtml _ vd@VD{..} (items',total) =
|] |]
where where
l = journalToLedger nullfilterspec j l = journalToLedger nullfilterspec j
inacctmatcher = inAccountMatcher qopts inacctmatcher = inAccountQuery qopts
allaccts = isNothing inacctmatcher allaccts = isNothing inacctmatcher
items = items' -- maybe items' (\m -> filter (matchesAccount m . \(a,_,_,_)->a) items') showacctmatcher items = items' -- maybe items' (\m -> filter (matchesAccount m . \(a,_,_,_)->a) items') showacctmatcher
itemAsHtml :: ViewData -> AccountsReportItem -> HtmlUrl AppRoute itemAsHtml :: ViewData -> AccountsReportItem -> HtmlUrl AppRoute
@ -850,9 +850,9 @@ data ViewData = VD {
,today :: Day -- ^ today's date (for queries containing relative dates) ,today :: Day -- ^ today's date (for queries containing relative dates)
,j :: Journal -- ^ the up-to-date parsed unfiltered journal ,j :: Journal -- ^ the up-to-date parsed unfiltered journal
,q :: String -- ^ the current q parameter, the main query expression ,q :: String -- ^ the current q parameter, the main query expression
,m :: Matcher -- ^ a matcher parsed from the q parameter ,m :: Matcher -- ^ a query parsed from the q parameter
,qopts :: [QueryOpt] -- ^ query options parsed from the q parameter ,qopts :: [QueryOpt] -- ^ query options parsed from the q parameter
,am :: Matcher -- ^ a matcher parsed from the accounts sidebar query expr ("a" parameter) ,am :: Matcher -- ^ a query parsed from the accounts sidebar query expr ("a" parameter)
,aopts :: [QueryOpt] -- ^ query options parsed from the accounts sidebar query expr ,aopts :: [QueryOpt] -- ^ query options parsed from the accounts sidebar query expr
,showpostings :: Bool -- ^ current p parameter, 1 or 0 shows/hides all postings where applicable ,showpostings :: Bool -- ^ current p parameter, 1 or 0 shows/hides all postings where applicable
} }

View File

@ -110,7 +110,7 @@ tests_Hledger_Cli = TestList
let opts `gives` es = do let opts `gives` es = do
j <- samplejournal j <- samplejournal
d <- getCurrentDay d <- getCurrentDay
accountsReportAsText opts (accountsReport opts (optsToFilterSpec opts d) j) `is` es accountsReportAsText opts (accountsReport opts (filterSpecFromOpts opts d) j) `is` es
in TestList in TestList
[ [
"balance report with no args" ~: "balance report with no args" ~:
@ -281,7 +281,7 @@ tests_Hledger_Cli = TestList
let opts = defreportopts{patterns_=["expenses"]} let opts = defreportopts{patterns_=["expenses"]}
j <- samplejournal j <- samplejournal
d <- getCurrentDay d <- getCurrentDay
showTransactions opts (optsToFilterSpec opts d) j `is` unlines showTransactions opts (filterSpecFromOpts opts d) j `is` unlines
["2008/06/03 * eat & shop" ["2008/06/03 * eat & shop"
," expenses:food $1" ," expenses:food $1"
," expenses:supplies $1" ," expenses:supplies $1"
@ -294,7 +294,7 @@ tests_Hledger_Cli = TestList
let opts = defreportopts{depth_=Just 2} let opts = defreportopts{depth_=Just 2}
j <- samplejournal j <- samplejournal
d <- getCurrentDay d <- getCurrentDay
showTransactions opts (optsToFilterSpec opts d) j `is` unlines showTransactions opts (filterSpecFromOpts opts d) j `is` unlines
["2008/01/01 income" ["2008/01/01 income"
," income:salary $-1" ," income:salary $-1"
,"" ,""
@ -323,7 +323,7 @@ tests_Hledger_Cli = TestList
do do
j <- samplejournal j <- samplejournal
let opts = defreportopts let opts = defreportopts
(postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` unlines (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` unlines
["2008/01/01 income assets:bank:checking $1 $1" ["2008/01/01 income assets:bank:checking $1 $1"
," income:salary $-1 0" ," income:salary $-1 0"
,"2008/06/01 gift assets:bank:checking $1 $1" ,"2008/06/01 gift assets:bank:checking $1 $1"
@ -341,7 +341,7 @@ tests_Hledger_Cli = TestList
do do
let opts = defreportopts{cleared_=True} let opts = defreportopts{cleared_=True}
j <- readJournal' sample_journal_str j <- readJournal' sample_journal_str
(postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` unlines (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` unlines
["2008/06/03 eat & shop expenses:food $1 $1" ["2008/06/03 eat & shop expenses:food $1 $1"
," expenses:supplies $1 $2" ," expenses:supplies $1 $2"
," assets:cash $-2 0" ," assets:cash $-2 0"
@ -353,7 +353,7 @@ tests_Hledger_Cli = TestList
do do
let opts = defreportopts{uncleared_=True} let opts = defreportopts{uncleared_=True}
j <- readJournal' sample_journal_str j <- readJournal' sample_journal_str
(postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` unlines (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` unlines
["2008/01/01 income assets:bank:checking $1 $1" ["2008/01/01 income assets:bank:checking $1 $1"
," income:salary $-1 0" ," income:salary $-1 0"
,"2008/06/01 gift assets:bank:checking $1 $1" ,"2008/06/01 gift assets:bank:checking $1 $1"
@ -374,13 +374,13 @@ tests_Hledger_Cli = TestList
," f" ," f"
] ]
let opts = defreportopts let opts = defreportopts
registerdates (postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` ["2008/01/01","2008/02/02"] registerdates (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` ["2008/01/01","2008/02/02"]
,"register report with account pattern" ~: ,"register report with account pattern" ~:
do do
j <- samplejournal j <- samplejournal
let opts = defreportopts{patterns_=["cash"]} let opts = defreportopts{patterns_=["cash"]}
(postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` unlines (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` unlines
["2008/06/03 eat & shop assets:cash $-2 $-2" ["2008/06/03 eat & shop assets:cash $-2 $-2"
] ]
@ -388,7 +388,7 @@ tests_Hledger_Cli = TestList
do do
j <- samplejournal j <- samplejournal
let opts = defreportopts{patterns_=["cAsH"]} let opts = defreportopts{patterns_=["cAsH"]}
(postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` unlines (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` unlines
["2008/06/03 eat & shop assets:cash $-2 $-2" ["2008/06/03 eat & shop assets:cash $-2 $-2"
] ]
@ -396,7 +396,7 @@ tests_Hledger_Cli = TestList
do do
j <- samplejournal j <- samplejournal
let gives displayexpr = let gives displayexpr =
(registerdates (postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is`) (registerdates (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is`)
where opts = defreportopts{display_=Just displayexpr} where opts = defreportopts{display_=Just displayexpr}
"d<[2008/6/2]" `gives` ["2008/01/01","2008/06/01"] "d<[2008/6/2]" `gives` ["2008/01/01","2008/06/01"]
"d<=[2008/6/2]" `gives` ["2008/01/01","2008/06/01","2008/06/02"] "d<=[2008/6/2]" `gives` ["2008/01/01","2008/06/01","2008/06/02"]
@ -409,7 +409,7 @@ tests_Hledger_Cli = TestList
j <- samplejournal j <- samplejournal
let periodexpr `gives` dates = do let periodexpr `gives` dates = do
j' <- samplejournal j' <- samplejournal
registerdates (postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j') `is` dates registerdates (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j') `is` dates
where opts = defreportopts{period_=maybePeriod date1 periodexpr} where opts = defreportopts{period_=maybePeriod date1 periodexpr}
"" `gives` ["2008/01/01","2008/06/01","2008/06/02","2008/06/03","2008/12/31"] "" `gives` ["2008/01/01","2008/06/01","2008/06/02","2008/06/03","2008/12/31"]
"2008" `gives` ["2008/01/01","2008/06/01","2008/06/02","2008/06/03","2008/12/31"] "2008" `gives` ["2008/01/01","2008/06/01","2008/06/02","2008/06/03","2008/12/31"]
@ -418,7 +418,7 @@ tests_Hledger_Cli = TestList
"monthly" `gives` ["2008/01/01","2008/06/01","2008/12/01"] "monthly" `gives` ["2008/01/01","2008/06/01","2008/12/01"]
"quarterly" `gives` ["2008/01/01","2008/04/01","2008/10/01"] "quarterly" `gives` ["2008/01/01","2008/04/01","2008/10/01"]
let opts = defreportopts{period_=maybePeriod date1 "yearly"} let opts = defreportopts{period_=maybePeriod date1 "yearly"}
(postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` unlines (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` unlines
["2008/01/01 - 2008/12/31 assets:bank:saving $1 $1" ["2008/01/01 - 2008/12/31 assets:bank:saving $1 $1"
," assets:cash $-2 $-1" ," assets:cash $-2 $-1"
," expenses:food $1 0" ," expenses:food $1 0"
@ -428,9 +428,9 @@ tests_Hledger_Cli = TestList
," liabilities:debts $1 0" ," liabilities:debts $1 0"
] ]
let opts = defreportopts{period_=maybePeriod date1 "quarterly"} let opts = defreportopts{period_=maybePeriod date1 "quarterly"}
registerdates (postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` ["2008/01/01","2008/04/01","2008/10/01"] registerdates (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` ["2008/01/01","2008/04/01","2008/10/01"]
let opts = defreportopts{period_=maybePeriod date1 "quarterly",empty_=True} let opts = defreportopts{period_=maybePeriod date1 "quarterly",empty_=True}
registerdates (postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` ["2008/01/01","2008/04/01","2008/07/01","2008/10/01"] registerdates (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` ["2008/01/01","2008/04/01","2008/07/01","2008/10/01"]
] ]
@ -438,7 +438,7 @@ tests_Hledger_Cli = TestList
do do
j <- samplejournal j <- samplejournal
let opts = defreportopts{depth_=Just 2} let opts = defreportopts{depth_=Just 2}
(postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` unlines (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` unlines
["2008/01/01 income assets:bank $1 $1" ["2008/01/01 income assets:bank $1 $1"
," income:salary $-1 0" ," income:salary $-1 0"
,"2008/06/01 gift assets:bank $1 $1" ,"2008/06/01 gift assets:bank $1 $1"
@ -460,7 +460,7 @@ tests_Hledger_Cli = TestList
j <- readJournal' j <- readJournal'
"2009/01/01 * медвежья шкура\n расходы:покупки 100\n актив:наличные\n" "2009/01/01 * медвежья шкура\n расходы:покупки 100\n актив:наличные\n"
let opts = defreportopts let opts = defreportopts
accountsReportAsText opts (accountsReport opts (optsToFilterSpec opts date1) j) `is` accountsReportAsText opts (accountsReport opts (filterSpecFromOpts opts date1) j) `is`
[" -100 актив:наличные" [" -100 актив:наличные"
," 100 расходы:покупки" ," 100 расходы:покупки"
,"--------------------" ,"--------------------"
@ -471,7 +471,7 @@ tests_Hledger_Cli = TestList
j <- readJournal' j <- readJournal'
"2009/01/01 * медвежья шкура\n расходы:покупки 100\n актив:наличные\n" "2009/01/01 * медвежья шкура\n расходы:покупки 100\n актив:наличные\n"
let opts = defreportopts let opts = defreportopts
(postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts date1) j) `is` unlines (postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts date1) j) `is` unlines
["2009/01/01 медвежья шкура расходы:покупки 100 100" ["2009/01/01 медвежья шкура расходы:покупки 100 100"
," актив:наличные -100 0"] ," актив:наличные -100 0"]

View File

@ -229,7 +229,7 @@ registerFromString :: String -> IO String
registerFromString s = do registerFromString s = do
d <- getCurrentDay d <- getCurrentDay
j <- readJournal' s j <- readJournal' s
return $ postingsReportAsText opts $ postingsReport opts (optsToFilterSpec opts d) j return $ postingsReportAsText opts $ postingsReport opts (filterSpecFromOpts opts d) j
where opts = defreportopts{empty_=True} where opts = defreportopts{empty_=True}
-- | Return a similarity measure, from 0 to 1, for two strings. -- | Return a similarity measure, from 0 to 1, for two strings.

View File

@ -117,7 +117,7 @@ balance CliOpts{reportopts_=ropts} j = do
d <- getCurrentDay d <- getCurrentDay
let lines = case formatFromOpts ropts of let lines = case formatFromOpts ropts of
Left err -> [err] Left err -> [err]
Right _ -> accountsReportAsText ropts $ accountsReport ropts (optsToFilterSpec ropts d) j Right _ -> accountsReportAsText ropts $ accountsReport ropts (filterSpecFromOpts ropts d) j
putStr $ unlines lines putStr $ unlines lines
-- | Render a balance report as plain text suitable for console output. -- | Render a balance report as plain text suitable for console output.

View File

@ -24,7 +24,7 @@ balancesheet :: CliOpts -> Journal -> IO ()
balancesheet CliOpts{reportopts_=ropts} j = do balancesheet CliOpts{reportopts_=ropts} j = do
let lines = case formatFromOpts ropts of let lines = case formatFromOpts ropts of
Left err -> [err] Left err -> [err]
Right _ -> accountsReportAsText ropts $ accountsReport2 ropts (journalBalanceSheetAccountMatcher j) j Right _ -> accountsReportAsText ropts $ accountsReport2 ropts (journalBalanceSheetAccountQuery j) j
putStr $ unlines lines putStr $ unlines lines
tests_Hledger_Cli_Balancesheet = TestList tests_Hledger_Cli_Balancesheet = TestList

View File

@ -30,8 +30,8 @@ cashflow :: CliOpts -> Journal -> IO ()
cashflow CliOpts{reportopts_=ropts} j = do cashflow CliOpts{reportopts_=ropts} j = do
-- let lines = case formatFromOpts ropts of Left err, Right ... -- let lines = case formatFromOpts ropts of Left err, Right ...
d <- getCurrentDay d <- getCurrentDay
let m = optsToMatcher (withoutBeginDate ropts) d let m = queryFromOpts (withoutBeginDate ropts) d
cashreport@(_,total) = accountsReport2 ropts (MatchAnd [m, journalCashAccountMatcher j]) j cashreport@(_,total) = accountsReport2 ropts (MatchAnd [m, journalCashAccountQuery j]) j
-- operatingreport@(_,operating) = accountsReport2 ropts (MatchAnd [m, journalOperatingAccountMatcher j]) j -- operatingreport@(_,operating) = accountsReport2 ropts (MatchAnd [m, journalOperatingAccountMatcher j]) j
-- investingreport@(_,investing) = accountsReport2 ropts (MatchAnd [m, journalInvestingAccountMatcher j]) j -- investingreport@(_,investing) = accountsReport2 ropts (MatchAnd [m, journalInvestingAccountMatcher j]) j
-- financingreport@(_,financing) = accountsReport2 ropts (MatchAnd [m, journalFinancingAccountMatcher j]) j -- financingreport@(_,financing) = accountsReport2 ropts (MatchAnd [m, journalFinancingAccountMatcher j]) j

View File

@ -25,7 +25,7 @@ barchar = '*'
histogram :: CliOpts -> Journal -> IO () histogram :: CliOpts -> Journal -> IO ()
histogram CliOpts{reportopts_=reportopts_} j = do histogram CliOpts{reportopts_=reportopts_} j = do
d <- getCurrentDay d <- getCurrentDay
putStr $ showHistogram reportopts_ (optsToFilterSpec reportopts_ d) j putStr $ showHistogram reportopts_ (filterSpecFromOpts reportopts_ d) j
showHistogram :: ReportOpts -> FilterSpec -> Journal -> String showHistogram :: ReportOpts -> FilterSpec -> Journal -> String
showHistogram opts filterspec j = concatMap (printDayWith countBar) spanps showHistogram opts filterspec j = concatMap (printDayWith countBar) spanps

View File

@ -24,7 +24,7 @@ incomestatement :: CliOpts -> Journal -> IO ()
incomestatement CliOpts{reportopts_=ropts} j = do incomestatement CliOpts{reportopts_=ropts} j = do
let lines = case formatFromOpts ropts of let lines = case formatFromOpts ropts of
Left err -> [err] Left err -> [err]
Right _ -> accountsReportAsText ropts $ accountsReport2 ropts (journalProfitAndLossAccountMatcher j) j Right _ -> accountsReportAsText ropts $ accountsReport2 ropts (journalProfitAndLossAccountQuery j) j
putStr $ unlines lines putStr $ unlines lines
tests_Hledger_Cli_Incomestatement = TestList tests_Hledger_Cli_Incomestatement = TestList

View File

@ -19,7 +19,7 @@ import Hledger.Cli.Options
print' :: CliOpts -> Journal -> IO () print' :: CliOpts -> Journal -> IO ()
print' CliOpts{reportopts_=ropts} j = do print' CliOpts{reportopts_=ropts} j = do
d <- getCurrentDay d <- getCurrentDay
putStr $ showTransactions ropts (optsToFilterSpec ropts d) j putStr $ showTransactions ropts (filterSpecFromOpts ropts d) j
showTransactions :: ReportOpts -> FilterSpec -> Journal -> String showTransactions :: ReportOpts -> FilterSpec -> Journal -> String
showTransactions opts fspec j = entriesReportAsText opts fspec $ entriesReport opts fspec j showTransactions opts fspec j = entriesReportAsText opts fspec $ entriesReport opts fspec j

View File

@ -26,7 +26,7 @@ import Hledger.Cli.Options
register :: CliOpts -> Journal -> IO () register :: CliOpts -> Journal -> IO ()
register CliOpts{reportopts_=ropts} j = do register CliOpts{reportopts_=ropts} j = do
d <- getCurrentDay d <- getCurrentDay
putStr $ postingsReportAsText ropts $ postingsReport ropts (optsToFilterSpec ropts d) j putStr $ postingsReportAsText ropts $ postingsReport ropts (filterSpecFromOpts ropts d) j
-- | Render a register report as plain text suitable for console output. -- | Render a register report as plain text suitable for console output.
postingsReportAsText :: ReportOpts -> PostingsReport -> String postingsReportAsText :: ReportOpts -> PostingsReport -> String

View File

@ -24,7 +24,7 @@ import Hledger.Utils.UTF8IOCompat (putStr)
stats :: CliOpts -> Journal -> IO () stats :: CliOpts -> Journal -> IO ()
stats CliOpts{reportopts_=reportopts_} j = do stats CliOpts{reportopts_=reportopts_} j = do
d <- getCurrentDay d <- getCurrentDay
let filterspec = optsToFilterSpec reportopts_ d let filterspec = filterSpecFromOpts reportopts_ d
l = journalToLedger filterspec j l = journalToLedger filterspec j
reportspan = (ledgerDateSpan l) `orDatesFrom` (datespan filterspec) reportspan = (ledgerDateSpan l) `orDatesFrom` (datespan filterspec)
intervalspans = splitSpan (intervalFromOpts reportopts_) reportspan intervalspans = splitSpan (intervalFromOpts reportopts_) reportspan