diff --git a/hledger-lib/Hledger/Data/Posting.hs b/hledger-lib/Hledger/Data/Posting.hs index c212fd714..494720c0d 100644 --- a/hledger-lib/Hledger/Data/Posting.hs +++ b/hledger-lib/Hledger/Data/Posting.hs @@ -193,6 +193,7 @@ showPostingLines p = first3 $ postingAsLines False False maxacctwidth maxamtwidt -- if onelineamounts is true, these amounts are shown on one line, -- comma-separated, and the output will not be valid journal syntax. -- Otherwise, they are shown as several similar postings, one per commodity. +-- When the posting has a balance assertion, it is attached to the last of these postings. -- -- The output will appear to be a balanced transaction. -- Amounts' display precisions, which may have been limited by commodity @@ -243,16 +244,11 @@ postingAsLines elideamount onelineamounts acctwidth amtwidth p = , Cell BottomLeft [assertion] , textCell BottomLeft samelinecomment ] - | amt <- shownAmounts] + | (amt,assertion) <- shownAmountsAssertions] render = renderRow def{tableBorders=False, borderSpaces=False} . Group NoLine . map Header pad amt = WideBuilder (TB.fromText $ T.replicate w " ") w <> amt where w = max 12 amtwidth - wbWidth amt -- min. 12 for backwards compatibility - assertion = maybe mempty ((WideBuilder (TB.singleton ' ') 1 <>).showBalanceAssertion) $ pbalanceassertion p - -- pad to the maximum account name width, plus 2 to leave room for status flags, to keep amounts aligned - statusandaccount = lineIndent . fitText (Just $ 2 + acctwidth) Nothing False True $ pstatusandacct p - thisacctwidth = realLength $ pacctstr p - pacctstr p' = showAccountName Nothing (ptype p') (paccount p') pstatusandacct p' = pstatusprefix p' <> pacctstr p' pstatusprefix p' = case pstatus p' of @@ -268,6 +264,17 @@ postingAsLines elideamount onelineamounts acctwidth amtwidth p = | otherwise = showMixedAmountLinesB noColour{displayOneLine=onelineamounts} $ pamount p thisamtwidth = maximumBound 0 $ map wbWidth shownAmounts + -- when there is a balance assertion, show it only on the last posting line + shownAmountsAssertions = zip shownAmounts shownAssertions + where + shownAssertions = replicate (length shownAmounts - 1) mempty ++ [assertion] + where + assertion = maybe mempty ((WideBuilder (TB.singleton ' ') 1 <>).showBalanceAssertion) $ pbalanceassertion p + + -- pad to the maximum account name width, plus 2 to leave room for status flags, to keep amounts aligned + statusandaccount = lineIndent . fitText (Just $ 2 + acctwidth) Nothing False True $ pstatusandacct p + thisacctwidth = realLength $ pacctstr p + (samelinecomment, newlinecomments) = case renderCommentLines (pcomment p) of [] -> ("",[]) c:cs -> (c,cs) diff --git a/hledger/test/journal/balance-assertions.test b/hledger/test/journal/balance-assertions.test index 1ccd34f9d..ec5db6b9d 100755 --- a/hledger/test/journal/balance-assertions.test +++ b/hledger/test/journal/balance-assertions.test @@ -455,3 +455,23 @@ $ hledger -f- print -x (a) -2 ==* 1 >=0 + +# 26. When balance assignment with a cost generates two postings in one commodity, +# the balance assertion appears only on the last, not both. (#1965) +< +2022-01-01 + assets:eur €10 + equity + +2022-01-02 + assets:eur = €1 @ $1 + assets:usd + +$ hledger -f- print -x date:2022-01-02 +2022-01-02 + assets:eur €-10 + assets:eur €1 @ $1 = €1 @ $1 + assets:usd $-1 + assets:usd €10 + +>=