close: add the --interleaved flag; refactor a little
Interleaved equity postings make troubleshooting easier.
This commit is contained in:
parent
a5ff9d6a63
commit
1e9f30bafc
@ -27,14 +27,18 @@ closemode = hledgerCommandMode
|
|||||||
,flagNone ["opening"] (setboolopt "opening") "show just opening transaction"
|
,flagNone ["opening"] (setboolopt "opening") "show just opening transaction"
|
||||||
,flagReq ["close-to"] (\s opts -> Right $ setopt "close-to" s opts) "ACCT" ("account to transfer closing balances to (default: "++defclosingacct++")")
|
,flagReq ["close-to"] (\s opts -> Right $ setopt "close-to" s opts) "ACCT" ("account to transfer closing balances to (default: "++defclosingacct++")")
|
||||||
,flagReq ["open-from"] (\s opts -> Right $ setopt "open-from" s opts) "ACCT" ("account to transfer opening balances from (default: "++defopeningacct++")")
|
,flagReq ["open-from"] (\s opts -> Right $ setopt "open-from" s opts) "ACCT" ("account to transfer opening balances from (default: "++defopeningacct++")")
|
||||||
|
,flagNone ["interleaved"] (setboolopt "interleaved") "keep equity and non-equity postings adjacent"
|
||||||
]
|
]
|
||||||
[generalflagsgroup1]
|
[generalflagsgroup1]
|
||||||
hiddenflags
|
hiddenflags
|
||||||
([], Just $ argsFlag "[QUERY]")
|
([], Just $ argsFlag "[QUERY]")
|
||||||
|
|
||||||
|
-- debugger, beware: close is incredibly devious. simple rules combine to make a horrid maze.
|
||||||
close CliOpts{rawopts_=rawopts, reportopts_=ropts} j = do
|
close CliOpts{rawopts_=rawopts, reportopts_=ropts} j = do
|
||||||
today <- getCurrentDay
|
today <- getCurrentDay
|
||||||
let
|
let
|
||||||
|
-- interleave equity postings next to the corresponding closing posting, or put them all at the end ?
|
||||||
|
interleaved = boolopt "interleaved" rawopts
|
||||||
(opening, closing) =
|
(opening, closing) =
|
||||||
case (boolopt "opening" rawopts, boolopt "closing" rawopts) of
|
case (boolopt "opening" rawopts, boolopt "closing" rawopts) of
|
||||||
(False, False) -> (True, True) -- by default show both opening and closing
|
(False, False) -> (True, True) -- by default show both opening and closing
|
||||||
@ -46,51 +50,78 @@ close CliOpts{rawopts_=rawopts, reportopts_=ropts} j = do
|
|||||||
openingdate = fromMaybe today $ queryEndDate False q
|
openingdate = fromMaybe today $ queryEndDate False q
|
||||||
closingdate = addDays (-1) openingdate
|
closingdate = addDays (-1) openingdate
|
||||||
(acctbals,_) = balanceReportFromMultiBalanceReport ropts_ q j
|
(acctbals,_) = balanceReportFromMultiBalanceReport ropts_ q j
|
||||||
balancingamt = negate $ sum $ map (\(_,_,_,b) -> normaliseMixedAmount b) acctbals
|
balancingamt = sum $ map (\(_,_,_,b) -> normaliseMixedAmount b) acctbals
|
||||||
|
|
||||||
-- since balance assertion amounts are required to be exact, the
|
-- since balance assertion amounts are required to be exact, the
|
||||||
-- amounts in opening/closing transactions should be too (#941, #1137)
|
-- amounts in opening/closing transactions should be too (#941, #1137)
|
||||||
setprec = setFullPrecision
|
setprec = setFullPrecision
|
||||||
-- balance assertion amounts will be unpriced (#824)
|
closingps = concat
|
||||||
-- only the last posting in each commodity will have a balance assertion (#1035)
|
[[posting{paccount = a
|
||||||
closingps = [posting{paccount = a
|
,pamount = mixed [setprec $ negate b]
|
||||||
,pamount = mixed [setprec $ negate b]
|
-- after each commodity's last posting, assert 0 balance (#1035)
|
||||||
,pbalanceassertion = if islast then Just nullassertion{baamount=setprec b{aquantity=0, aprice=Nothing}} else Nothing
|
-- balance assertion amounts are unpriced (#824)
|
||||||
}
|
,pbalanceassertion =
|
||||||
| (a,_,_,mb) <- acctbals
|
if islast
|
||||||
-- the balances in each commodity, and for each transaction price
|
then Just nullassertion{baamount=setprec b{aquantity=0, aprice=Nothing}}
|
||||||
, let bs = amounts $ normaliseMixedAmount mb
|
else Nothing
|
||||||
-- mark the last balance in each commodity
|
}
|
||||||
, let bs' = concat [reverse $ zip (reverse bs) (True : repeat False)
|
] ++
|
||||||
| bs <- groupBy ((==) `on` acommodity) bs]
|
if interleaved then
|
||||||
, (b, islast) <- bs'
|
-- a corresponding posting transferring the above balance to equity
|
||||||
|
[posting{paccount = closingacct
|
||||||
|
,pamount = Mixed [b]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
else []
|
||||||
|
| (a,_,_,mb) <- acctbals
|
||||||
|
-- the balances in each commodity, and for each transaction price
|
||||||
|
, let bs = amounts $ normaliseMixedAmount mb
|
||||||
|
-- mark the last balance in each commodity
|
||||||
|
, let bs' = concat [reverse $ zip (reverse bs) (True : repeat False)
|
||||||
|
| bs <- groupBy ((==) `on` acommodity) bs]
|
||||||
|
, (b, islast) <- bs'
|
||||||
]
|
]
|
||||||
-- The balancing posting to equity. Allow this one to have a multicommodity amount,
|
|
||||||
-- and don't try to assert its balance.
|
|
||||||
++
|
++
|
||||||
|
if interleaved then []
|
||||||
|
else
|
||||||
|
-- a final posting transferring all the balances to equity
|
||||||
|
-- (print will show it as multiple single-commodity postings)
|
||||||
[posting{paccount = closingacct
|
[posting{paccount = closingacct
|
||||||
,pamount = negate balancingamt
|
,pamount = balancingamt
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
openingps = [posting{paccount = a
|
openingps = concat
|
||||||
|
[[posting{paccount = a
|
||||||
,pamount = mixed [setprec b]
|
,pamount = mixed [setprec b]
|
||||||
,pbalanceassertion = case mcommoditysum of
|
,pbalanceassertion = case mcommoditysum of
|
||||||
Just s -> Just nullassertion{baamount=setprec s{aprice=Nothing}}
|
Just s -> Just nullassertion{baamount=setprec s{aprice=Nothing}}
|
||||||
Nothing -> Nothing
|
Nothing -> Nothing
|
||||||
}
|
}
|
||||||
| (a,_,_,mb) <- acctbals
|
] ++
|
||||||
-- the balances in each commodity, and for each transaction price
|
if interleaved then
|
||||||
, let bs = amounts $ normaliseMixedAmount mb
|
-- a corresponding posting transferring the above balance from equity
|
||||||
-- mark the last balance in each commodity, with the unpriced sum in that commodity
|
[posting{paccount = openingacct
|
||||||
, let bs' = concat [reverse $ zip (reverse bs) (Just commoditysum : repeat Nothing)
|
,pamount = Mixed [negate b]
|
||||||
| bs <- groupBy ((==) `on` acommodity) bs
|
}
|
||||||
, let commoditysum = (sum bs)]
|
]
|
||||||
, (b, mcommoditysum) <- bs'
|
else []
|
||||||
|
| (a,_,_,mb) <- acctbals
|
||||||
|
-- the balances in each commodity, and for each transaction price
|
||||||
|
, let bs = amounts $ normaliseMixedAmount mb
|
||||||
|
-- mark the last balance in each commodity, with the unpriced sum in that commodity
|
||||||
|
, let bs' = concat [reverse $ zip (reverse bs) (Just commoditysum : repeat Nothing)
|
||||||
|
| bs <- groupBy ((==) `on` acommodity) bs
|
||||||
|
, let commoditysum = (sum bs)]
|
||||||
|
, (b, mcommoditysum) <- bs'
|
||||||
]
|
]
|
||||||
++
|
++
|
||||||
|
if interleaved then []
|
||||||
|
else
|
||||||
|
-- a final posting transferring all the balances from equity
|
||||||
|
-- (print will show it as multiple single-commodity postings)
|
||||||
[posting{paccount = openingacct
|
[posting{paccount = openingacct
|
||||||
,pamount = balancingamt
|
,pamount = negate balancingamt
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,9 @@ or you can customise these with the `--close-to` and `--open-from` options.
|
|||||||
You can choose to print just one of the transactions by using the
|
You can choose to print just one of the transactions by using the
|
||||||
`--opening` or `--closing` flag.
|
`--opening` or `--closing` flag.
|
||||||
|
|
||||||
|
The equity postings appear at the end of the transaction by default;
|
||||||
|
with `--interleaved`, they appear beside their corresponding closing postings.
|
||||||
|
|
||||||
If you split your journal files by time (eg yearly), you will
|
If you split your journal files by time (eg yearly), you will
|
||||||
typically run this command at the end of the year, and save the
|
typically run this command at the end of the year, and save the
|
||||||
closing transaction as last entry of the old file, and the opening
|
closing transaction as last entry of the old file, and the opening
|
||||||
|
|||||||
@ -237,3 +237,33 @@ $ hledger -f- close -p 2016 assets liabilities
|
|||||||
|
|
||||||
>=0
|
>=0
|
||||||
|
|
||||||
|
# 9. With --interleaved, balanced posting pairs are adjacent.
|
||||||
|
# (And balances with the same cost are not necessarily combined into
|
||||||
|
# a single posting. Eg the 5734 EUR above is 5733 EUR and 1 EUR below.)
|
||||||
|
$ hledger -f- close -p 2016 assets liabilities --interleaved
|
||||||
|
2016-12-31 closing balances
|
||||||
|
assets:bank -5,733.00 EUR = 0.00 EUR
|
||||||
|
equity:closing balances 5,733.00 EUR
|
||||||
|
liabilities:employer $-10,000.00
|
||||||
|
equity:closing balances $10,000.00
|
||||||
|
liabilities:employer $5,000.00 @ 0.93 EUR
|
||||||
|
equity:closing balances $-5,000.00 @ 0.93 EUR
|
||||||
|
liabilities:employer $5,000.00 @ 0.95 EUR = $0.00
|
||||||
|
equity:closing balances $-5,000.00 @ 0.95 EUR
|
||||||
|
liabilities:employer -1.00 EUR = 0.00 EUR
|
||||||
|
equity:closing balances 1.00 EUR
|
||||||
|
|
||||||
|
2017-01-01 opening balances
|
||||||
|
assets:bank 5,733.00 EUR = 5,733.00 EUR
|
||||||
|
equity:opening balances -5,733.00 EUR
|
||||||
|
liabilities:employer $10,000.00
|
||||||
|
equity:opening balances $-10,000.00
|
||||||
|
liabilities:employer $-5,000.00 @ 0.93 EUR
|
||||||
|
equity:opening balances $5,000.00 @ 0.93 EUR
|
||||||
|
liabilities:employer $-5,000.00 @ 0.95 EUR = $0.00
|
||||||
|
equity:opening balances $5,000.00 @ 0.95 EUR
|
||||||
|
liabilities:employer 1.00 EUR = 1.00 EUR
|
||||||
|
equity:opening balances -1.00 EUR
|
||||||
|
|
||||||
|
>=0
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user