diff --git a/hledger-lib/Hledger/Reports/BudgetReport.hs b/hledger-lib/Hledger/Reports/BudgetReport.hs index 29b9220a0..66e8af052 100644 --- a/hledger-lib/Hledger/Reports/BudgetReport.hs +++ b/hledger-lib/Hledger/Reports/BudgetReport.hs @@ -258,17 +258,19 @@ budgetReportAsText ropts budgetr = ++ tableAsText ropts showcell (budgetReportAsTable ropts budgetr) where + -- XXX lay out actual, percentage and/or goal in the single table cell for now, should probably use separate cells showcell :: (Maybe Change, Maybe BudgetGoal) -> String showcell (mactual, mbudget) = actualstr ++ " " ++ budgetstr where actualwidth = 7 percentwidth = 4 budgetwidth = 5 - actualstr = printf ("%"++show actualwidth++"s") (maybe "0" showamt mactual) - budgetstr = case (mactual, mbudget) of - (_, Nothing) -> replicate (percentwidth + 7 + budgetwidth) ' ' - (mactual, Just budget) -> - case percentage mactual budget of + actual = fromMaybe 0 mactual + actualstr = printf ("%"++show actualwidth++"s") (showamt actual) + budgetstr = case mbudget of + Nothing -> replicate (percentwidth + 7 + budgetwidth) ' ' + Just budget -> + case percentage actual budget of Just pct -> printf ("[%"++show percentwidth++"s%% of %"++show budgetwidth++"s]") (show $ roundTo 0 pct) (showbudgetamt budget) @@ -276,18 +278,19 @@ budgetReportAsText ropts budgetr = printf ("["++replicate (percentwidth+5) ' '++"%"++show budgetwidth++"s]") (showbudgetamt budget) - percentage :: Maybe Change -> BudgetGoal -> Maybe Percentage - percentage Nothing _ = Nothing - percentage (Just actual) budget = - -- percentage of budget consumed is always computed in the cost basis + -- | Calculate the percentage of actual change to budget goal to show, if any. + -- Both amounts are converted to cost, if possible, before comparing. + -- A percentage will not be shown if: + -- - actual or goal are not the same, single, commodity + -- - the goal is zero + percentage :: Change -> BudgetGoal -> Maybe Percentage + percentage actual budget = case (toCost actual, toCost budget) of - (Mixed [a1], Mixed [a2]) - | isReallyZeroAmount a1 -> Just 0 -- if there are no postings, we consumed 0% of budget - | acommodity a1 == acommodity a2 && aquantity a2 /= 0 -> - Just $ 100 * aquantity a1 / aquantity a2 - _ -> Nothing - where - toCost = normaliseMixedAmount . costOfMixedAmount + (Mixed [a], Mixed [b]) | (acommodity a == acommodity b || isZeroAmount a) && not (isZeroAmount b) + -> Just $ 100 * aquantity a / aquantity b + _ -> Nothing + where + toCost = normaliseMixedAmount . costOfMixedAmount showamt :: MixedAmount -> String showamt | color_ ropts = cshowMixedAmountOneLineWithoutPrice diff --git a/tests/budget/budget.test b/tests/budget/budget.test index 0ee1997d5..30ebce1b1 100644 --- a/tests/budget/budget.test +++ b/tests/budget/budget.test @@ -41,7 +41,7 @@ Budget performance in 2016/12/01-2016/12/03: expenses:food || $10 [ 100% of $10] $9 [ 90% of $10] $11 [ 110% of $10] expenses:leisure || 0 [ 0% of $15] $5 [ 33% of $15] 0 [ 0% of $15] -----------------------++------------------------------------------------------------------------------ - || 0 [ 0% of 0] 0 [ 0% of 0] 0 [ 0% of 0] + || 0 [ 0] 0 [ 0] 0 [ 0] # 2. --show-unbudgeted $ hledger bal -D -b 2016-12-01 -e 2016-12-04 -f - --budget --show-unbudgeted @@ -55,7 +55,7 @@ Budget performance in 2016/12/01-2016/12/03: expenses:leisure || 0 [ 0% of $15] $5 [ 33% of $15] 0 [ 0% of $15] expenses:movies || 0 0 $25 ------------------++------------------------------------------------------------------------------ - || 0 [ 0% of 0] 0 [ 0% of 0] 0 [ 0% of 0] + || 0 [ 0] 0 [ 0] 0 [ 0] # 3. Test that budget works with mix of commodities < @@ -102,8 +102,7 @@ Budget performance in 2016/12/01-2016/12/03: expenses:food || £10 [ 150% of $10] 20 CAD [ 210% of $10] $11 [ 110% of $10] expenses:leisure || 0 [ 0% of $15] $5 [ 33% of $15] 0 [ 0% of $15] -----------------------++------------------------------------------------------------------------------------- - || $-15, £10 [ 0% of 0] $-21, 20 CAD [ 0% of 0] 0 [ 0% of 0] -# TODO zero totals ^ + || $-15, £10 [ 0] $-21, 20 CAD [ 0] 0 [ 0] < ~ daily @@ -142,8 +141,8 @@ Budget performance in 2018/01/01-2018/01/03: || 2018/01/01 2018/01/02 2018/01/03 ===++============================================================================== a || 1 [ 10% of 10] 0 [ 0% of 10] 1 [ 10% of 10] - b || 1 [ 1% of 100] 0 [ 0% of 0] 1 [ 0] - c || 1 [ 0% of 1000] 0 [ 0% of 0] 1 [ 0] + b || 1 [ 1% of 100] 0 [ 0] 1 [ 0] + c || 1 [ 0% of 1000] 0 [ 0] 1 [ 0] ---++------------------------------------------------------------------------------ || 3 [ 0% of 1110] 0 [ 0% of 10] 3 [ 30% of 10] @@ -247,9 +246,9 @@ Budget performance in 2018/01/01-2018/01/02: || 2018/01/01 2018/01/02 ===++==================================================== - a || 0 [ 1] 0 [ 1] + a || 0 [ 0% of 1] 0 [ 0% of 1] ---++---------------------------------------------------- - || 0 [ 1] 0 [ 1] + || 0 [ 0% of 1] 0 [ 0% of 1] # 11. With -E, zeroes are shown $ hledger -f- bal --budget -D date:2018/1/1-2018/1/3 -E