;imp: show a more helpful error for transactions unbalanced by upgrade [#2402]

(and drop the last sentence from the single-commodity unbalanced
transaction error)
This commit is contained in:
Simon Michael 2025-06-12 09:23:43 -10:00
parent 868d535f3f
commit 0d388a6f93
3 changed files with 23 additions and 20 deletions

View File

@ -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

View File

@ -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

View File

@ -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