From 0d388a6f93cd0824058ca17ec53b67068fa8af3f Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Thu, 12 Jun 2025 09:23:43 -1000 Subject: [PATCH] ;imp: show a more helpful error for transactions unbalanced by upgrade [#2402] (and drop the last sentence from the single-commodity unbalanced transaction error) --- hledger-lib/Hledger/Data/Balancing.hs | 39 +++++++++++++++------------ hledger/test/errors/autobalanced.test | 1 - hledger/test/errors/balanced.test | 3 +-- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/hledger-lib/Hledger/Data/Balancing.hs b/hledger-lib/Hledger/Data/Balancing.hs index 285f3d8a9..b48013b28 100644 --- a/hledger-lib/Hledger/Data/Balancing.hs +++ b/hledger-lib/Hledger/Data/Balancing.hs @@ -104,22 +104,24 @@ transactionCheckBalanced BalancingOpts{commodity_styles_=_mglobalstyles, txn_bal BalancedVirtualPosting -> (l, p:r) VirtualPosting -> (l, r) - -- convert this posting's amount to cost, + -- convert a posting's amount to cost, -- unless it has been marked as a redundant cost (equivalent to some nearby equity conversion postings), -- in which case ignore it. postingBalancingAmount p | costPostingTagName `elem` map fst (ptags p) = mixedAmountStripCosts $ pamount p | otherwise = mixedAmountCost $ pamount p - lookszero = mixedAmountLooksZero . roundforbalancecheck - where - roundforbalancecheck = case txn_balancing_ of - TBPOld -> maybe id styleAmounts _mglobalstyles - TBPExact -> styleAmounts transactionstyles - where - transactionstyles = transactionCommodityStylesWith HardRounding t - -- limitprecisionsto = undefined - -- commoditydirectivestyles = undefined + lookszero = case txn_balancing_ of + TBPOld -> lookszeroatglobaldisplayprecision + TBPExact -> lookszeroatlocaltransactionprecision + + lookszeroatlocaltransactionprecision = mixedAmountLooksZero . styleAmounts (transactionCommodityStylesWith HardRounding t) + lookszeroatglobaldisplayprecision = mixedAmountLooksZero . maybe id styleAmounts _mglobalstyles + + -- check that the sum looks like zero + (rsumcost, bvsumcost) = (foldMap postingBalancingAmount rps, foldMap postingBalancingAmount bvps) + (rsumok, bvsumok) = (lookszero rsumcost, lookszero bvsumcost) + (rsumokold, bvsumokold) = (lookszeroatglobaldisplayprecision rsumcost, lookszeroatglobaldisplayprecision bvsumcost) -- when there's multiple non-zeros, check they do not all have the same sign (rsignsok, bvsignsok) = (signsOk rps, signsOk bvps) @@ -129,10 +131,6 @@ transactionCheckBalanced BalancingOpts{commodity_styles_=_mglobalstyles, txn_bal nonzeros = filter (not.lookszero) $ map postingBalancingAmount ps nonzerosigns = nubSort $ mapMaybe isNegativeMixedAmount nonzeros - -- check that the sum looks like zero - (rsumcost, bvsumcost) = (foldMap postingBalancingAmount rps, foldMap postingBalancingAmount bvps) - (rsumok, bvsumok) = (lookszero rsumcost, lookszero bvsumcost) - -- Generate error messages if any. Show amounts with their original precisions. errs = filter (not.null) [rmsg, bvmsg] where @@ -143,6 +141,7 @@ transactionCheckBalanced BalancingOpts{commodity_styles_=_mglobalstyles, txn_bal (showMixedAmountWith oneLineNoCostFmt{displayCost=True, displayZeroCommodity=True} $ mixedAmountSetFullPrecisionUpTo Nothing $ mixedAmountSetFullPrecision rsumcost) + ++ if rsumokold then "" else oldbalancingmsg bvmsg | bvsumok = "" | not bvsignsok = "The balanced virtual postings all have the same sign. Consider negating some of them." @@ -150,6 +149,14 @@ transactionCheckBalanced BalancingOpts{commodity_styles_=_mglobalstyles, txn_bal (showMixedAmountWith oneLineNoCostFmt{displayCost=True, displayZeroCommodity=True} $ mixedAmountSetFullPrecisionUpTo Nothing $ mixedAmountSetFullPrecision bvsumcost) + ++ if bvsumokold then "" else oldbalancingmsg + oldbalancingmsg = unlines [ + -- ------------------------------------------------------------------------------- + "\nNote, hledger <1.44 accepted this entry because of the global display precision," + ,"but hledger 1.44+ checks more strictly, using the entry's local precision." + ,"You can use --txn-balancing=old to keep it working, or fix it (recommended);" + ,"see 'Transaction balancing' in the hledger manual." + ] -- | Legacy form of transactionCheckBalanced. isTransactionBalanced :: BalancingOpts -> Transaction -> Bool @@ -214,9 +221,7 @@ balanceTransactionHelper bopts t = do [ "Consider adjusting this entry's amounts, adding missing postings," , "or recording conversion price(s) with @, @@ or equity postings." ] - else - [ "Consider adjusting this entry's amounts, or adding missing postings." - ] + else [] transactionCommodities :: Transaction -> S.Set CommoditySymbol transactionCommodities t = mconcat $ map (maCommodities . pamount) $ tpostings t diff --git a/hledger/test/errors/autobalanced.test b/hledger/test/errors/autobalanced.test index 138fbe0fc..67b78363d 100644 --- a/hledger/test/errors/autobalanced.test +++ b/hledger/test/errors/autobalanced.test @@ -5,6 +5,5 @@ $$$ hledger check -f autobalanced.j This transaction is unbalanced. The real postings' sum should be 0 but is: 1 -Consider adjusting this entry's amounts, or adding missing postings. / >>>= 1 diff --git a/hledger/test/errors/balanced.test b/hledger/test/errors/balanced.test index 03bd6c4c2..a325fe5e6 100644 --- a/hledger/test/errors/balanced.test +++ b/hledger/test/errors/balanced.test @@ -6,6 +6,5 @@ $$$ hledger check balanced -f balanced.j This multi-commodity transaction is unbalanced. Automatic commodity conversion is not enabled. -The real postings' sum should be 0 but is: 1 A, -1 B -Consider adjusting this entry's amounts, adding/ +The real postings' sum should be 0 but is: 1 A, -1 B/ >>>= 1