;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 $ balancedVirtualPostings t) | ||||
| 
 | ||||
| -- | Does this transaction appear balanced when rendered, optionally with the | ||||
| -- given commodity display styles ? More precisely: | ||||
| -- after converting amounts to cost using explicit transaction prices if any; | ||||
| -- and summing the real postings, and summing the balanced virtual postings; | ||||
| -- and applying the given display styles if any (maybe affecting decimal places); | ||||
| -- do both totals appear to be zero when rendered ? | ||||
| -- | Check that this transaction appears balanced when rendered, | ||||
| -- returning an appropriate error message if it is not. | ||||
| -- In more detail: after converting amounts to cost using explicit | ||||
| -- transaction prices if any; and summing the real postings; and | ||||
| -- summing the balanced virtual postings; and applying the given | ||||
| -- 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 styles t = | ||||
|     -- 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 | ||||
| isTransactionBalanced mstyles = (==Nothing) . transactionCheckBalanced mstyles | ||||
| 
 | ||||
| -- | Balance this transaction, ensuring that its postings | ||||
| -- (and its balanced virtual postings) sum to 0, | ||||
| @ -384,22 +398,9 @@ balanceTransactionHelper :: | ||||
| balanceTransactionHelper mstyles t = do | ||||
|   (t', inferredamtsandaccts) <- | ||||
|     inferBalancingAmount (fromMaybe M.empty mstyles) $ inferBalancingPrices t | ||||
|   if isTransactionBalanced mstyles t' | ||||
|   then Right (txnTieKnot t', inferredamtsandaccts) | ||||
|   else Left $ annotateErrorWithTransaction t' $ nonzerobalanceerror t' | ||||
| 
 | ||||
|   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 | ||||
|   case transactionCheckBalanced mstyles t' of | ||||
|     Nothing  -> Right (txnTieKnot t', inferredamtsandaccts) | ||||
|     Just err -> Left $ annotateErrorWithTransaction t' err | ||||
| 
 | ||||
| annotateErrorWithTransaction :: Transaction -> String -> String | ||||
| annotateErrorWithTransaction t s = intercalate "\n" [showGenericSourcePos $ tsourcepos t, s, showTransaction t] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user