budget: declaration and (actual) amount sorting for bal --budget
Account declaration-aware sorting is the default throughout hledger now.
This commit is contained in:
parent
f2b4fca9b0
commit
855bd54d19
@ -35,12 +35,15 @@ import Hledger.Utils
|
|||||||
--import Hledger.Read (mamountp')
|
--import Hledger.Read (mamountp')
|
||||||
import Hledger.Reports.ReportOptions
|
import Hledger.Reports.ReportOptions
|
||||||
import Hledger.Reports.ReportTypes
|
import Hledger.Reports.ReportTypes
|
||||||
|
import Hledger.Reports.BalanceReport (sortAccountItemsLike)
|
||||||
import Hledger.Reports.MultiBalanceReports
|
import Hledger.Reports.MultiBalanceReports
|
||||||
|
|
||||||
|
|
||||||
|
-- for reference:
|
||||||
|
--
|
||||||
--type MultiBalanceReportRow = (AccountName, AccountName, Int, [MixedAmount], MixedAmount, MixedAmount)
|
--type MultiBalanceReportRow = (AccountName, AccountName, Int, [MixedAmount], MixedAmount, MixedAmount)
|
||||||
--type MultiBalanceReportTotals = ([MixedAmount], MixedAmount, MixedAmount) -- (Totals list, sum of totals, average of totals)
|
--type MultiBalanceReportTotals = ([MixedAmount], MixedAmount, MixedAmount) -- (Totals list, sum of totals, average of totals)
|
||||||
|
--
|
||||||
--type PeriodicReportRow a =
|
--type PeriodicReportRow a =
|
||||||
-- ( AccountName -- ^ A full account name.
|
-- ( AccountName -- ^ A full account name.
|
||||||
-- , [a] -- ^ The data value for each subperiod.
|
-- , [a] -- ^ The data value for each subperiod.
|
||||||
@ -53,7 +56,9 @@ type BudgetTotal = Total
|
|||||||
type BudgetAverage = Average
|
type BudgetAverage = Average
|
||||||
|
|
||||||
-- | A budget report tracks expected and actual changes per account and subperiod.
|
-- | A budget report tracks expected and actual changes per account and subperiod.
|
||||||
type BudgetReport = PeriodicReport (Maybe Change, Maybe BudgetGoal)
|
type BudgetCell = (Maybe Change, Maybe BudgetGoal)
|
||||||
|
type BudgetReport = PeriodicReport BudgetCell
|
||||||
|
type BudgetReportRow = PeriodicReportRow BudgetCell
|
||||||
|
|
||||||
-- | Calculate budget goals from all periodic transactions,
|
-- | Calculate budget goals from all periodic transactions,
|
||||||
-- actual balance changes from the regular transactions,
|
-- actual balance changes from the regular transactions,
|
||||||
@ -79,8 +84,54 @@ budgetReport ropts assrt showunbudgeted reportspan d j =
|
|||||||
-- it should be safe to replace it with the latter, so they combine well.
|
-- it should be safe to replace it with the latter, so they combine well.
|
||||||
| interval_ ropts == NoInterval = MultiBalanceReport (actualspans, budgetgoalitems, budgetgoaltotals)
|
| interval_ ropts == NoInterval = MultiBalanceReport (actualspans, budgetgoalitems, budgetgoaltotals)
|
||||||
| otherwise = budgetgoalreport
|
| otherwise = budgetgoalreport
|
||||||
|
budgetreport = combineBudgetAndActual budgetgoalreport' actualreport
|
||||||
|
sortedbudgetreport = sortBudgetReport ropts j budgetreport
|
||||||
in
|
in
|
||||||
dbg1 "budgetreport" $ combineBudgetAndActual budgetgoalreport' actualreport
|
dbg1 "sortedbudgetreport" sortedbudgetreport
|
||||||
|
|
||||||
|
-- | Sort a budget report's rows according to options.
|
||||||
|
sortBudgetReport :: ReportOpts -> Journal -> BudgetReport -> BudgetReport
|
||||||
|
sortBudgetReport ropts j (PeriodicReport (ps, rows, trow)) = PeriodicReport (ps, sortedrows, trow)
|
||||||
|
where
|
||||||
|
sortedrows
|
||||||
|
| sort_amount_ ropts && tree_ ropts = sortTreeBURByActualAmount rows
|
||||||
|
| sort_amount_ ropts = sortFlatBURByActualAmount rows
|
||||||
|
| otherwise = sortByAccountDeclaration rows
|
||||||
|
|
||||||
|
-- Sort a tree-mode budget report's rows by total actual amount at each level.
|
||||||
|
sortTreeBURByActualAmount :: [BudgetReportRow] -> [BudgetReportRow]
|
||||||
|
sortTreeBURByActualAmount rows = sortedrows
|
||||||
|
where
|
||||||
|
anamesandrows = [(first6 r, r) | r <- rows]
|
||||||
|
anames = map fst anamesandrows
|
||||||
|
atotals = [(a,tot) | (a,_,_,_,(tot,_),_) <- rows]
|
||||||
|
accounttree = accountTree "root" anames
|
||||||
|
accounttreewithbals = mapAccounts setibalance accounttree
|
||||||
|
where
|
||||||
|
setibalance a = a{aibalance=
|
||||||
|
fromMaybe 0 $ -- when there's no actual amount, assume 0; will mess up with negative amounts ? TODO
|
||||||
|
fromMaybe (error "sortTreeByAmount 1") $ -- should not happen, but it's ugly; TODO
|
||||||
|
lookup (aname a) atotals
|
||||||
|
}
|
||||||
|
sortedaccounttree = sortAccountTreeByAmount (fromMaybe NormallyPositive $ normalbalance_ ropts) accounttreewithbals
|
||||||
|
sortedanames = map aname $ drop 1 $ flattenAccounts sortedaccounttree
|
||||||
|
sortedrows = sortAccountItemsLike sortedanames anamesandrows
|
||||||
|
|
||||||
|
-- Sort a flat-mode budget report's rows by total actual amount.
|
||||||
|
sortFlatBURByActualAmount :: [BudgetReportRow] -> [BudgetReportRow]
|
||||||
|
sortFlatBURByActualAmount = sortBy (maybeflip $ comparing (fst . fifth6))
|
||||||
|
where
|
||||||
|
maybeflip = if normalbalance_ ropts == Just NormallyNegative then id else flip
|
||||||
|
|
||||||
|
-- Sort the report rows by account declaration order then account name.
|
||||||
|
-- <unbudgeted> remains at the top.
|
||||||
|
sortByAccountDeclaration rows = sortedrows
|
||||||
|
where
|
||||||
|
(unbudgetedrow,rows') = partition ((=="<unbudgeted>").first6) rows
|
||||||
|
anamesandrows = [(first6 r, r) | r <- rows']
|
||||||
|
anames = map fst anamesandrows
|
||||||
|
sortedanames = sortAccountNamesByDeclaration j (tree_ ropts) anames
|
||||||
|
sortedrows = unbudgetedrow ++ sortAccountItemsLike sortedanames anamesandrows
|
||||||
|
|
||||||
-- | Use all periodic transactions in the journal to generate
|
-- | Use all periodic transactions in the journal to generate
|
||||||
-- budget transactions in the specified report period.
|
-- budget transactions in the specified report period.
|
||||||
@ -184,41 +235,6 @@ combineBudgetAndActual
|
|||||||
rows :: [PeriodicReportRow (Maybe Change, Maybe BudgetGoal)] =
|
rows :: [PeriodicReportRow (Maybe Change, Maybe BudgetGoal)] =
|
||||||
sortBy (comparing first6) $ rows1 ++ rows2
|
sortBy (comparing first6) $ rows1 ++ rows2
|
||||||
|
|
||||||
-- -- like MultiBalanceReport
|
|
||||||
-- sortedrows
|
|
||||||
-- | sort_amount_ opts && tree_ opts = sortTreeBURByAmount items
|
|
||||||
-- | sort_amount_ opts = sortFlatBURByAmount items
|
|
||||||
-- | otherwise = sortBURByAccountDeclaration items
|
|
||||||
--
|
|
||||||
-- where
|
|
||||||
-- -- Sort the report rows, representing a tree of accounts, by row total at each level.
|
|
||||||
-- sortTreeMBRByAmount rows = sortedrows
|
|
||||||
-- where
|
|
||||||
-- anamesandrows = [(first6 r, r) | r <- rows]
|
|
||||||
-- anames = map fst anamesandrows
|
|
||||||
-- atotals = [(a,tot) | (a,_,_,_,tot,_) <- rows]
|
|
||||||
-- accounttree = accountTree "root" anames
|
|
||||||
-- accounttreewithbals = mapAccounts setibalance accounttree
|
|
||||||
-- where
|
|
||||||
-- -- should not happen, but it's ugly; TODO
|
|
||||||
-- setibalance a = a{aibalance=fromMaybe (error "sortTreeBURByAmount 1") $ lookup (aname a) atotals}
|
|
||||||
-- sortedaccounttree = sortAccountTreeByAmount (fromMaybe NormallyPositive $ normalbalance_ opts) accounttreewithbals
|
|
||||||
-- sortedanames = map aname $ drop 1 $ flattenAccounts sortedaccounttree
|
|
||||||
-- sortedrows = sortAccountItemsLike sortedanames anamesandrows
|
|
||||||
--
|
|
||||||
-- -- Sort the report rows, representing a flat account list, by row total.
|
|
||||||
-- sortFlatBURByAmount = sortBy (maybeflip $ comparing fifth6)
|
|
||||||
-- where
|
|
||||||
-- maybeflip = if normalbalance_ opts == Just NormallyNegative then id else flip
|
|
||||||
--
|
|
||||||
-- -- Sort the report rows by account declaration order then account name.
|
|
||||||
-- sortBURByAccountDeclaration rows = sortedrows
|
|
||||||
-- where
|
|
||||||
-- anamesandrows = [(first6 r, r) | r <- rows]
|
|
||||||
-- anames = map fst anamesandrows
|
|
||||||
-- sortedanames = sortAccountNamesByDeclaration j (tree_ opts) anames
|
|
||||||
-- sortedrows = sortAccountItemsLike sortedanames anamesandrows
|
|
||||||
|
|
||||||
-- TODO: grand total & average shows 0% when there are no actual amounts, inconsistent with other cells
|
-- TODO: grand total & average shows 0% when there are no actual amounts, inconsistent with other cells
|
||||||
totalrow =
|
totalrow =
|
||||||
( ""
|
( ""
|
||||||
|
|||||||
@ -832,7 +832,8 @@ account assets:bank:checking
|
|||||||
|
|
||||||
### Account display order
|
### Account display order
|
||||||
|
|
||||||
Account directives have another purpose: they set the display order of accounts in reports.
|
Account directives have another purpose: they set the order in which accounts are displayed,
|
||||||
|
in hledger reports, hledger-ui accounts screen, hledger-web sidebar etc.
|
||||||
For example, say you have these top-level accounts:
|
For example, say you have these top-level accounts:
|
||||||
```shell
|
```shell
|
||||||
$ accounts -1
|
$ accounts -1
|
||||||
@ -867,13 +868,14 @@ misc
|
|||||||
other
|
other
|
||||||
```
|
```
|
||||||
|
|
||||||
Ie, declared accounts first, in the order they were declared, followed by undeclared accounts in alphabetic order.
|
Ie, declared accounts first, in the order they were declared, followed by any undeclared accounts in alphabetic order.
|
||||||
|
|
||||||
This is supported in most reports organised by account (accounts/balance/bs/bse/cf/is).
|
Note that sorting is done at each level of the account tree (within each group of sibling accounts under the same parent).
|
||||||
It is not yet supported in budget reports (balance --budget) or hledger-web's sidebar.
|
This directive:
|
||||||
|
```journal
|
||||||
Note sorting is done at each level of the account tree (within each group of sibling accounts
|
account other:zoo
|
||||||
under the same parent).
|
```
|
||||||
|
would influence the position of `zoo` among `other`'s subaccounts, but not the position of `other` among the top-level accounts.
|
||||||
|
|
||||||
### Rewriting accounts
|
### Rewriting accounts
|
||||||
|
|
||||||
|
|||||||
@ -250,7 +250,6 @@ module Hledger.Cli.Commands.Balance (
|
|||||||
,tests_Balance
|
,tests_Balance
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad (when)
|
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
--import qualified Data.Map as Map
|
--import qualified Data.Map as Map
|
||||||
@ -313,7 +312,6 @@ balance opts@CliOpts{rawopts_=rawopts,reportopts_=ropts} j = do
|
|||||||
case (budget, interval) of
|
case (budget, interval) of
|
||||||
(True, _) -> do
|
(True, _) -> do
|
||||||
-- single or multicolumn budget report
|
-- single or multicolumn budget report
|
||||||
when (sort_amount_ ropts) $ error' "Sorry, --sort-amount is not yet supported with --budget." -- TODO
|
|
||||||
reportspan <- reportSpan j ropts
|
reportspan <- reportSpan j ropts
|
||||||
let budgetreport = dbg1 "budgetreport" $ budgetReport ropts assrt showunbudgeted reportspan d j
|
let budgetreport = dbg1 "budgetreport" $ budgetReport ropts assrt showunbudgeted reportspan d j
|
||||||
where
|
where
|
||||||
|
|||||||
241
tests/budget/sorting.test
Normal file
241
tests/budget/sorting.test
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
#* budget report sorting
|
||||||
|
# These tests below aren't very thorough, could use more varied amounts
|
||||||
|
# and pathological cases.
|
||||||
|
|
||||||
|
#** Default sort without account declarations
|
||||||
|
# already tested in budget.test, but for completeness:
|
||||||
|
|
||||||
|
<
|
||||||
|
~ daily from 2016/1/1
|
||||||
|
expenses:food $10
|
||||||
|
expenses:leisure $15
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/01
|
||||||
|
expenses:food $10
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/02
|
||||||
|
expenses:food $9
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/03
|
||||||
|
expenses:food $11
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/02
|
||||||
|
expenses:leisure $5
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/03
|
||||||
|
expenses:movies $25
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/03
|
||||||
|
expenses:cab $15
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
$ hledger -f- bal --budget -DTN
|
||||||
|
Budget performance in 2016/12/01-2016/12/03:
|
||||||
|
|
||||||
|
|| 2016/12/01 2016/12/02 2016/12/03 Total
|
||||||
|
==================++========================================================================================================
|
||||||
|
<unbudgeted> || 0 0 $40 $40
|
||||||
|
assets:cash || $-10 [ 40% of $-25] $-14 [ 56% of $-25] $-51 [ 204% of $-25] $-75 [ 100% of $-75]
|
||||||
|
expenses:food || $10 [ 100% of $10] $9 [ 90% of $10] $11 [ 110% of $10] $30 [ 100% of $30]
|
||||||
|
expenses:leisure || 0 [ 0% of $15] $5 [ 33% of $15] 0 [ 0% of $15] $5 [ 11% of $45]
|
||||||
|
|
||||||
|
#** Default sort with account declarations
|
||||||
|
|
||||||
|
<
|
||||||
|
account expenses
|
||||||
|
account expenses:leisure
|
||||||
|
|
||||||
|
~ daily from 2016/1/1
|
||||||
|
expenses:food $10
|
||||||
|
expenses:leisure $15
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/01
|
||||||
|
expenses:food $10
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/02
|
||||||
|
expenses:food $9
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/03
|
||||||
|
expenses:food $11
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/02
|
||||||
|
expenses:leisure $5
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/03
|
||||||
|
expenses:movies $25
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
2016/12/03
|
||||||
|
expenses:cab $15
|
||||||
|
assets:cash
|
||||||
|
|
||||||
|
$ hledger -f- bal --budget -DTN
|
||||||
|
Budget performance in 2016/12/01-2016/12/03:
|
||||||
|
|
||||||
|
|| 2016/12/01 2016/12/02 2016/12/03 Total
|
||||||
|
==================++========================================================================================================
|
||||||
|
<unbudgeted> || 0 0 $40 $40
|
||||||
|
expenses:leisure || 0 [ 0% of $15] $5 [ 33% of $15] 0 [ 0% of $15] $5 [ 11% of $45]
|
||||||
|
expenses:food || $10 [ 100% of $10] $9 [ 90% of $10] $11 [ 110% of $10] $30 [ 100% of $30]
|
||||||
|
assets:cash || $-10 [ 40% of $-25] $-14 [ 56% of $-25] $-51 [ 204% of $-25] $-75 [ 100% of $-75]
|
||||||
|
|
||||||
|
# # 2. --show-unbudgeted
|
||||||
|
# $ hledger bal -D -b 2016-12-01 -e 2016-12-04 -f - --budget --show-unbudgeted
|
||||||
|
# Budget performance in 2016/12/01-2016/12/03:
|
||||||
|
|
||||||
|
# || 2016/12/01 2016/12/02 2016/12/03
|
||||||
|
# ==============================++==============================================================================
|
||||||
|
# <unbudgeted>:expenses:cab || 0 0 $15
|
||||||
|
# <unbudgeted>:expenses:movies || 0 0 $25
|
||||||
|
# assets:cash || $-10 [ 40% of $-25] $-14 [ 56% of $-25] $-51 [ 204% of $-25]
|
||||||
|
# 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] 0 [ 0] 0 [ 0]
|
||||||
|
|
||||||
|
# # 3. Test that budget works with mix of commodities
|
||||||
|
# <
|
||||||
|
# 2016/12/01
|
||||||
|
# expenses:food £10 @@ $15
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/02
|
||||||
|
# expenses:food 10 CAD @ $1
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/02
|
||||||
|
# expenses:food 10 CAD @ $1.1
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/03
|
||||||
|
# expenses:food $11
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/02
|
||||||
|
# expenses:leisure $5
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/03
|
||||||
|
# expenses:movies $25
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/03
|
||||||
|
# expenses:cab $15
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# ~ daily from 2016/1/1
|
||||||
|
# expenses:food $10
|
||||||
|
# expenses:leisure $15
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# $ hledger bal -D -b 2016-12-01 -e 2016-12-04 -f - --budget
|
||||||
|
# Budget performance in 2016/12/01-2016/12/03:
|
||||||
|
|
||||||
|
# || 2016/12/01 2016/12/02 2016/12/03
|
||||||
|
# ==================++=====================================================================================
|
||||||
|
# <unbudgeted> || 0 0 $40
|
||||||
|
# assets:cash || $-15 [ 60% of $-25] $-26 [ 104% of $-25] $-51 [ 204% of $-25]
|
||||||
|
# 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] $-21, 20 CAD [ 0] 0 [ 0]
|
||||||
|
|
||||||
|
#** Sort by actual amount, flat mode.
|
||||||
|
|
||||||
|
$ hledger -f- bal --budget -DTNS
|
||||||
|
Budget performance in 2016/12/01-2016/12/03:
|
||||||
|
|
||||||
|
|| 2016/12/01 2016/12/02 2016/12/03 Total
|
||||||
|
==================++========================================================================================================
|
||||||
|
<unbudgeted> || 0 0 $40 $40
|
||||||
|
expenses:food || $10 [ 100% of $10] $9 [ 90% of $10] $11 [ 110% of $10] $30 [ 100% of $30]
|
||||||
|
expenses:leisure || 0 [ 0% of $15] $5 [ 33% of $15] 0 [ 0% of $15] $5 [ 11% of $45]
|
||||||
|
assets:cash || $-10 [ 40% of $-25] $-14 [ 56% of $-25] $-51 [ 204% of $-25] $-75 [ 100% of $-75]
|
||||||
|
|
||||||
|
#** Sort by actual amount, tree mode.
|
||||||
|
|
||||||
|
$ hledger -f- bal --budget -DTNS --tree
|
||||||
|
Budget performance in 2016/12/01-2016/12/03:
|
||||||
|
|
||||||
|
|| 2016/12/01 2016/12/02 2016/12/03 Total
|
||||||
|
==============++========================================================================================================
|
||||||
|
<unbudgeted> || 0 0 $40 $40
|
||||||
|
expenses || $10 [ 40% of $25] $14 [ 56% of $25] $11 [ 44% of $25] $35 [ 47% of $75]
|
||||||
|
food || $10 [ 100% of $10] $9 [ 90% of $10] $11 [ 110% of $10] $30 [ 100% of $30]
|
||||||
|
leisure || 0 [ 0% of $15] $5 [ 33% of $15] 0 [ 0% of $15] $5 [ 11% of $45]
|
||||||
|
assets || $-10 [ 40% of $-25] $-14 [ 56% of $-25] $-51 [ 204% of $-25] $-75 [ 100% of $-75]
|
||||||
|
cash || $-10 [ 40% of $-25] $-14 [ 56% of $-25] $-51 [ 204% of $-25] $-75 [ 100% of $-75]
|
||||||
|
|
||||||
|
#** other ?
|
||||||
|
# with --show-unbudgeted
|
||||||
|
# $ hledger bal -D -b 2016-12-01 -e 2016-12-04 -f - --budget --show-unbudgeted
|
||||||
|
# Budget performance in 2016/12/01-2016/12/03:
|
||||||
|
|
||||||
|
# || 2016/12/01 2016/12/02 2016/12/03
|
||||||
|
# ==============================++==============================================================================
|
||||||
|
# <unbudgeted>:expenses:cab || 0 0 $15
|
||||||
|
# <unbudgeted>:expenses:movies || 0 0 $25
|
||||||
|
# assets:cash || $-10 [ 40% of $-25] $-14 [ 56% of $-25] $-51 [ 204% of $-25]
|
||||||
|
# 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] 0 [ 0] 0 [ 0]
|
||||||
|
|
||||||
|
# with multiple commodities
|
||||||
|
# <
|
||||||
|
# 2016/12/01
|
||||||
|
# expenses:food £10 @@ $15
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/02
|
||||||
|
# expenses:food 10 CAD @ $1
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/02
|
||||||
|
# expenses:food 10 CAD @ $1.1
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/03
|
||||||
|
# expenses:food $11
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/02
|
||||||
|
# expenses:leisure $5
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/03
|
||||||
|
# expenses:movies $25
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# 2016/12/03
|
||||||
|
# expenses:cab $15
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# ~ daily from 2016/1/1
|
||||||
|
# expenses:food $10
|
||||||
|
# expenses:leisure $15
|
||||||
|
# assets:cash
|
||||||
|
|
||||||
|
# $ hledger bal -D -b 2016-12-01 -e 2016-12-04 -f - --budget
|
||||||
|
# Budget performance in 2016/12/01-2016/12/03:
|
||||||
|
|
||||||
|
# || 2016/12/01 2016/12/02 2016/12/03
|
||||||
|
# ==================++=====================================================================================
|
||||||
|
# <unbudgeted> || 0 0 $40
|
||||||
|
# assets:cash || $-15 [ 60% of $-25] $-26 [ 104% of $-25] $-51 [ 204% of $-25]
|
||||||
|
# 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] $-21, 20 CAD [ 0] 0 [ 0]
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user