;lib: refactor, consolidate, add transactionCheckBalanced
This commit is contained in:
parent
ebe021b0c8
commit
e6f9f09b41
@ -339,21 +339,35 @@ transactionPostingBalances t = (sumPostings $ realPostings t
|
|||||||
,sumPostings $ virtualPostings t
|
,sumPostings $ virtualPostings t
|
||||||
,sumPostings $ balancedVirtualPostings t)
|
,sumPostings $ balancedVirtualPostings t)
|
||||||
|
|
||||||
-- | Does this transaction appear balanced when rendered, optionally with the
|
-- | Check that this transaction appears balanced when rendered,
|
||||||
-- given commodity display styles ? More precisely:
|
-- returning an appropriate error message if it is not.
|
||||||
-- after converting amounts to cost using explicit transaction prices if any;
|
-- In more detail: after converting amounts to cost using explicit
|
||||||
-- and summing the real postings, and summing the balanced virtual postings;
|
-- transaction prices if any; and summing the real postings; and
|
||||||
-- and applying the given display styles if any (maybe affecting decimal places);
|
-- summing the balanced virtual postings; and applying the given
|
||||||
-- do both totals appear to be zero when rendered ?
|
-- display styles, if provided (maybe affecting decimal places):
|
||||||
|
-- do both posting totals appear to be zero when rendered ?
|
||||||
|
transactionCheckBalanced :: Maybe (M.Map CommoditySymbol AmountStyle) -> Transaction -> Maybe String
|
||||||
|
transactionCheckBalanced mstyles t
|
||||||
|
| rbalanced && bvbalanced = Nothing
|
||||||
|
| otherwise = Just $ printf "could not balance this transaction (%s%s%s)" rmsg sep bvmsg
|
||||||
|
where
|
||||||
|
(rsum, _, bvsum) = transactionPostingBalances t
|
||||||
|
(rsumcost, bvsumcost) = (costOfMixedAmount rsum, costOfMixedAmount bvsum)
|
||||||
|
(rsumdisplay, bvsumdisplay) = (canonicalise rsumcost, canonicalise bvsumcost)
|
||||||
|
where canonicalise = maybe id canonicaliseMixedAmount mstyles
|
||||||
|
-- for checking balanced, use the display precision
|
||||||
|
(rbalanced, bvbalanced) = (isZeroMixedAmount rsumdisplay, isZeroMixedAmount bvsumdisplay)
|
||||||
|
-- for selecting and generating error messages, use the uncanonicalised full precision
|
||||||
|
-- XXX always correct ?
|
||||||
|
rmsg | isReallyZeroMixedAmount rsumcost = ""
|
||||||
|
| otherwise = "real postings are off by " ++ showMixedAmount rsumcost
|
||||||
|
bvmsg | isReallyZeroMixedAmount bvsumcost = ""
|
||||||
|
| otherwise = "balanced virtual postings are off by " ++ showMixedAmount bvsumcost
|
||||||
|
sep = if not (null rmsg) && not (null bvmsg) then "; " else "" :: String
|
||||||
|
|
||||||
|
-- | Legacy form of transactionCheckBalanced.
|
||||||
isTransactionBalanced :: Maybe (M.Map CommoditySymbol AmountStyle) -> Transaction -> Bool
|
isTransactionBalanced :: Maybe (M.Map CommoditySymbol AmountStyle) -> Transaction -> Bool
|
||||||
isTransactionBalanced styles t =
|
isTransactionBalanced mstyles = (==Nothing) . transactionCheckBalanced mstyles
|
||||||
-- isReallyZeroMixedAmountCost rsum && isReallyZeroMixedAmountCost bvsum
|
|
||||||
isZeroMixedAmount rsum' && isZeroMixedAmount bvsum'
|
|
||||||
where
|
|
||||||
(rsum, _, bvsum) = transactionPostingBalances t
|
|
||||||
rsum' = canonicalise $ costOfMixedAmount rsum
|
|
||||||
bvsum' = canonicalise $ costOfMixedAmount bvsum
|
|
||||||
canonicalise = maybe id canonicaliseMixedAmount styles
|
|
||||||
|
|
||||||
-- | Balance this transaction, ensuring that its postings
|
-- | Balance this transaction, ensuring that its postings
|
||||||
-- (and its balanced virtual postings) sum to 0,
|
-- (and its balanced virtual postings) sum to 0,
|
||||||
@ -384,22 +398,9 @@ balanceTransactionHelper ::
|
|||||||
balanceTransactionHelper mstyles t = do
|
balanceTransactionHelper mstyles t = do
|
||||||
(t', inferredamtsandaccts) <-
|
(t', inferredamtsandaccts) <-
|
||||||
inferBalancingAmount (fromMaybe M.empty mstyles) $ inferBalancingPrices t
|
inferBalancingAmount (fromMaybe M.empty mstyles) $ inferBalancingPrices t
|
||||||
if isTransactionBalanced mstyles t'
|
case transactionCheckBalanced mstyles t' of
|
||||||
then Right (txnTieKnot t', inferredamtsandaccts)
|
Nothing -> Right (txnTieKnot t', inferredamtsandaccts)
|
||||||
else Left $ annotateErrorWithTransaction t' $ nonzerobalanceerror t'
|
Just err -> Left $ annotateErrorWithTransaction t' err
|
||||||
|
|
||||||
where
|
|
||||||
nonzerobalanceerror :: Transaction -> String
|
|
||||||
nonzerobalanceerror tt = printf "could not balance this transaction (%s%s%s)" rmsg sep bvmsg
|
|
||||||
where
|
|
||||||
(rsum, _, bvsum) = transactionPostingBalances tt
|
|
||||||
rmsg | isReallyZeroMixedAmountCost rsum = ""
|
|
||||||
| otherwise = "real postings are off by "
|
|
||||||
++ showMixedAmount (costOfMixedAmount rsum)
|
|
||||||
bvmsg | isReallyZeroMixedAmountCost bvsum = ""
|
|
||||||
| otherwise = "balanced virtual postings are off by "
|
|
||||||
++ showMixedAmount (costOfMixedAmount bvsum)
|
|
||||||
sep = if not (null rmsg) && not (null bvmsg) then "; " else "" :: String
|
|
||||||
|
|
||||||
annotateErrorWithTransaction :: Transaction -> String -> String
|
annotateErrorWithTransaction :: Transaction -> String -> String
|
||||||
annotateErrorWithTransaction t s = intercalate "\n" [showGenericSourcePos $ tsourcepos t, s, showTransaction t]
|
annotateErrorWithTransaction t s = intercalate "\n" [showGenericSourcePos $ tsourcepos t, s, showTransaction t]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user