diff --git a/hledger/Hledger/Cli/Commands/Close.hs b/hledger/Hledger/Cli/Commands/Close.hs index 7bca787f9..be8ebb6c0 100755 --- a/hledger/Hledger/Cli/Commands/Close.hs +++ b/hledger/Hledger/Cli/Commands/Close.hs @@ -38,93 +38,93 @@ closemode = hledgerCommandMode close CliOpts{rawopts_=rawopts, reportopts_=ropts} j = do today <- getCurrentDay let - -- interleave equity postings next to the corresponding closing posting, or put them all at the end ? - interleaved = boolopt "interleaved" rawopts - (opening, closing) = - case (boolopt "opening" rawopts, boolopt "closing" rawopts) of - (False, False) -> (True, True) -- by default show both opening and closing - (o, c) -> (o, c) - closingacct = T.pack $ fromMaybe defclosingacct $ maybestringopt "close-to" rawopts - openingacct = T.pack $ fromMaybe defopeningacct $ maybestringopt "open-from" rawopts - ropts_ = ropts{balancetype_=HistoricalBalance, accountlistmode_=ALFlat} - q = queryFromOpts today ropts_ - openingdate = fromMaybe today $ queryEndDate False q - closingdate = addDays (-1) openingdate - (acctbals,_) = balanceReportFromMultiBalanceReport ropts_ q j - totalbalancingamt = sum $ map (\(_,_,_,b) -> normaliseMixedAmount b) acctbals + -- interleave equity postings next to the corresponding closing posting, or put them all at the end ? + interleaved = boolopt "interleaved" rawopts + (opening, closing) = + case (boolopt "opening" rawopts, boolopt "closing" rawopts) of + (False, False) -> (True, True) -- by default show both opening and closing + (o, c) -> (o, c) + closingacct = T.pack $ fromMaybe defclosingacct $ maybestringopt "close-to" rawopts + openingacct = T.pack $ fromMaybe defopeningacct $ maybestringopt "open-from" rawopts + ropts_ = ropts{balancetype_=HistoricalBalance, accountlistmode_=ALFlat} + q = queryFromOpts today ropts_ + openingdate = fromMaybe today $ queryEndDate False q + closingdate = addDays (-1) openingdate + (acctbals,_) = balanceReportFromMultiBalanceReport ropts_ q j + totalbalancingamt = sum $ map (\(_,_,_,b) -> normaliseMixedAmount b) acctbals - -- since balance assertion amounts are required to be exact, the - -- amounts in opening/closing transactions should be too (#941, #1137) - setprec = setFullPrecision - closingps = concat - [[posting{paccount = a - ,pamount = mixed [setprec $ negate b] - -- after each commodity's last posting, assert 0 balance (#1035) - -- balance assertion amounts are unpriced (#824) - ,pbalanceassertion = - if islast - then Just nullassertion{baamount=setprec b{aquantity=0, aprice=Nothing}} - else Nothing - } - ] ++ - if interleaved then - -- a corresponding posting transferring the above balance to equity - [posting{paccount = closingacct - ,pamount = Mixed [setprec 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' - ] - ++ - 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 - ,pamount = mapMixedAmount setprec totalbalancingamt - } - ] + -- since balance assertion amounts are required to be exact, the + -- amounts in opening/closing transactions should be too (#941, #1137) + setprec = setFullPrecision + closingps = concat + [[posting{paccount = a + ,pamount = mixed [setprec $ negate b] + -- after each commodity's last posting, assert 0 balance (#1035) + -- balance assertion amounts are unpriced (#824) + ,pbalanceassertion = + if islast + then Just nullassertion{baamount=setprec b{aquantity=0, aprice=Nothing}} + else Nothing + } + ] ++ + if interleaved then + -- a corresponding posting transferring the above balance to equity + [posting{paccount = closingacct + ,pamount = Mixed [setprec 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' + ] + ++ + 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 + ,pamount = mapMixedAmount setprec totalbalancingamt + } + ] - openingps = concat - [[posting{paccount = a - ,pamount = mixed [setprec b] - ,pbalanceassertion = case mcommoditysum of - Just s -> Just nullassertion{baamount=setprec s{aprice=Nothing}} - Nothing -> Nothing - } - ] ++ - if interleaved then - -- a corresponding posting transferring the above balance from equity - [posting{paccount = openingacct - ,pamount = Mixed [setprec $ negate 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, 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 - ,pamount = mapMixedAmount setprec $ negate totalbalancingamt - } - ] + openingps = concat + [[posting{paccount = a + ,pamount = mixed [setprec b] + ,pbalanceassertion = case mcommoditysum of + Just s -> Just nullassertion{baamount=setprec s{aprice=Nothing}} + Nothing -> Nothing + } + ] ++ + if interleaved then + -- a corresponding posting transferring the above balance from equity + [posting{paccount = openingacct + ,pamount = Mixed [setprec $ negate 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, 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 + ,pamount = mapMixedAmount setprec $ negate totalbalancingamt + } + ] when closing $ putStr $ showTransaction (nulltransaction{tdate=closingdate, tdescription="closing balances", tpostings=closingps}) when opening $ putStr $ showTransaction (nulltransaction{tdate=openingdate, tdescription="opening balances", tpostings=openingps})