diff --git a/hledger-lib/Hledger/Reports.hs b/hledger-lib/Hledger/Reports.hs index 25b416d2e..59d690826 100644 --- a/hledger-lib/Hledger/Reports.hs +++ b/hledger-lib/Hledger/Reports.hs @@ -34,7 +34,8 @@ module Hledger.Reports ( TransactionsReport, TransactionsReportItem, triDate, - triBalance, + triSimpleBalance, + transactionsReportByCommodity, journalTransactionsReport, accountTransactionsReport, -- * Accounts report @@ -435,8 +436,38 @@ type TransactionsReportItem = (Transaction -- the corresponding transaction ) triDate (t,_,_,_,_,_) = tdate t -triBalance (_,_,_,_,_,Mixed a) = case a of [] -> "0" - (Amount{aquantity=q}):_ -> show q +triAmount (_,_,_,_,a,_) = a +triSimpleBalance (_,_,_,_,_,Mixed a) = case a of [] -> "0" + (Amount{aquantity=q}):_ -> show q + +-- Split a transactions report whose items may involve several commodities, +-- into one or more single-commodity transactions reports. +transactionsReportByCommodity :: TransactionsReport -> [TransactionsReport] +transactionsReportByCommodity tr = + [filterTransactionsReportByCommodity c tr | c <- transactionsReportCommodities tr] + where + transactionsReportCommodities (_,items) = + nub $ sort $ map acommodity $ concatMap (amounts . triAmount) items + +-- Remove transaction report items and item amount components that +-- don't involve the specified commodity. Other item fields like the +-- running balance and the transaction are left unchanged. +filterTransactionsReportByCommodity :: Commodity -> TransactionsReport -> TransactionsReport +filterTransactionsReportByCommodity c (label,items) = + (label, fixTransactionsReportItemBalances $ concat [filterTransactionsReportItemByCommodity c i | i <- items]) + where + filterTransactionsReportItemByCommodity c (t,t2,s,o,Mixed as,bal) + | c `elem` cs = [item'] + | otherwise = [] + where + cs = map acommodity as + item' = (t,t2,s,o,Mixed as',bal) + as' = filter ((==c).acommodity) as + fixTransactionsReportItemBalances is = reverse $ go nullmixedamt $ reverse is + where + go _ [] = [] + go bal ((t,t2,s,o,amt,_):is) = (t,t2,s,o,amt,bal'):go bal' is + where bal' = bal + amt -- | Select transactions from the whole journal for a transactions report, -- with no \"current\" account. The end result is similar to diff --git a/hledger-web/Handler/Common.hs b/hledger-web/Handler/Common.hs index 6b34c4c1c..492911f51 100644 --- a/hledger-web/Handler/Common.hs +++ b/hledger-web/Handler/Common.hs @@ -423,8 +423,8 @@ $forall p' <- tpostings t -- Generate html for an account register, including a balance chart and transaction list. registerReportHtml :: WebOpts -> ViewData -> TransactionsReport -> HtmlUrl AppRoute -registerReportHtml opts vd r@(_,items) = [hamlet| - ^{registerChartHtml items} +registerReportHtml opts vd r = [hamlet| + ^{registerChartHtml $ map snd $ transactionsReportByCommodity r} ^{registerItemsHtml opts vd r} |] @@ -486,8 +486,8 @@ $forall p' <- tpostings t -- Data.Foldable.Foldable t1 => -- t1 (Transaction, t2, t3, t4, t5, MixedAmount) -- -> t -> Text.Blaze.Internal.HtmlM () -registerChartHtml :: [TransactionsReportItem] -> HtmlUrl AppRoute -registerChartHtml items = +registerChartHtml :: [[TransactionsReportItem]] -> HtmlUrl AppRoute +registerChartHtml itemss = -- have to make sure plot is not called when our container (maincontent) -- is hidden, eg with add form toggled [hamlet| @@ -499,10 +499,11 @@ registerChartHtml items = if (chartdiv.is(':visible')) \$.plot(chartdiv, [ - [ - $forall i <- items - [#{dayToJsTimestamp $ triDate i}, #{triBalance i}], - ] + $forall items <- itemss + [ + $forall i <- items + [#{dayToJsTimestamp $ triDate i}, #{triSimpleBalance i}], + ], ], { xaxis: {