diff --git a/hledger-lib/Ledger/Transaction.hs b/hledger-lib/Ledger/Transaction.hs index 0f79fc548..3fb098153 100644 --- a/hledger-lib/Ledger/Transaction.hs +++ b/hledger-lib/Ledger/Transaction.hs @@ -126,19 +126,22 @@ isTransactionBalanced t = isReallyZeroMixedAmountCost rsum && isReallyZeroMixedA -- return an error message instead. balanceTransaction :: Transaction -> Either String Transaction balanceTransaction t@Transaction{tpostings=ps} - | length missingamounts' > 1 = Left $ printerr "could not balance this transaction (too many missing amounts)" + | length rwithoutamounts > 1 || length bvwithoutamounts > 1 + = Left $ printerr "could not balance this transaction (too many missing amounts)" | not $ isTransactionBalanced t' = Left $ printerr $ nonzerobalanceerror t' | otherwise = Right t' where - (withamounts, missingamounts) = partition hasAmount $ filter isReal ps - (_, missingamounts') = partition hasAmount ps - t' = t{tpostings=ps'} - ps' | length missingamounts == 1 = map balance ps - | otherwise = ps + rps = filter isReal ps + bvps = filter isBalancedVirtual ps + (rwithamounts, rwithoutamounts) = partition hasAmount rps + (bvwithamounts, bvwithoutamounts) = partition hasAmount bvps + t' = t{tpostings=map balance ps} where - balance p | isReal p && not (hasAmount p) = p{pamount = costOfMixedAmount (-otherstotal)} + balance p | not (hasAmount p) && isReal p + = p{pamount = costOfMixedAmount (-(sum $ map pamount rwithamounts))} + | not (hasAmount p) && isBalancedVirtual p + = p{pamount = costOfMixedAmount (-(sum $ map pamount bvwithamounts))} | otherwise = p - where otherstotal = sum $ map pamount withamounts printerr s = intercalate "\n" [s, showTransactionUnelided t] nonzerobalanceerror :: Transaction -> String diff --git a/tests/amountless-virtual-postings.test b/tests/amountless-virtual-postings.test deleted file mode 100644 index 0559ffd09..000000000 --- a/tests/amountless-virtual-postings.test +++ /dev/null @@ -1,9 +0,0 @@ -# again, complain like ledger, but we could handle this -./hledger -f - print -<<< -2009/1/1 x - a 1 - b - (c) - (d) ->>>2 /too many missing/ diff --git a/tests/missing-real-and-virtual-amt.test b/tests/missing-real-and-virtual-amt.test deleted file mode 100644 index e83127ea1..000000000 --- a/tests/missing-real-and-virtual-amt.test +++ /dev/null @@ -1,9 +0,0 @@ -# could balance this, but complain instead like ledger -./hledger -f - register -<<< -2009/6/24 carwash - equity:draw:personal:transportation:car:carwash $3.50 - assets:cash - [expenses:car] $3.50 - [simon] ->>>2 /too many missing/ diff --git a/tests/virtual.test b/tests/virtual.test index 2dd0efb1f..6c84105cb 100644 --- a/tests/virtual.test +++ b/tests/virtual.test @@ -5,24 +5,44 @@ (virtual) 100 a 1 b +# # 2. balanced virtual postings should be required to balance (themselves) ./hledger -f- <<< 2010/1/1 x - [balanced virtual] 100 + [balanced virtual] 10 a 1 b >>>= !0 +# +# 3. balanced virtual postings should be required to balance (themselves) ./hledger -f- <<< 2010/1/1 x - [balanced virtual] 100 - [balanced virtual] -100 + [balanced virtual] 10 + [balanced virtual] -10 a 1 b -# 3. a virtual posting with implicit amount should be handled correctly +# +# 4. a virtual posting with implicit amount should be handled correctly ./hledger -f- <<< 2010/1/1 x - [a] 1 - [b] + [a] 10 + [b] +# +# 5. real and balanced virtual postings are balanced separately, and multiple blank virtuals are ok +./hledger -f- +<<< +2010/1/1 x + a 1 + b + [e] 10 + [f] + (c) + (d) +>>> + 1 a + -1 b + 10 e + -10 f