imp:journal: balance transactions with local precisions [#2402]
This commit is contained in:
parent
82ba831822
commit
a9408b8cd5
@ -34,6 +34,7 @@ import Control.Monad.Reader as R (ReaderT, reader, runReaderT, ask, asks)
|
||||
import Control.Monad.ST (ST, runST)
|
||||
import Control.Monad.Trans.Class (lift)
|
||||
import Data.Array.ST (STArray, getElems, newListArray, writeArray)
|
||||
import Data.Bifunctor (second)
|
||||
import Data.Foldable (asum)
|
||||
import Data.Function ((&))
|
||||
import Data.Functor ((<&>), void)
|
||||
@ -49,7 +50,6 @@ import qualified Data.Map as M
|
||||
import Safe (headErr)
|
||||
import Text.Printf (printf)
|
||||
|
||||
import Hledger.Utils
|
||||
import Hledger.Data.Types
|
||||
import Hledger.Data.AccountName (isAccountNamePrefixOf)
|
||||
import Hledger.Data.Amount
|
||||
@ -57,7 +57,7 @@ import Hledger.Data.Journal
|
||||
import Hledger.Data.Posting
|
||||
import Hledger.Data.Transaction
|
||||
import Hledger.Data.Errors
|
||||
import Data.Bifunctor (second)
|
||||
import Hledger.Utils
|
||||
|
||||
|
||||
data BalancingOpts = BalancingOpts
|
||||
@ -92,7 +92,8 @@ defbalancingopts = BalancingOpts
|
||||
-- (using the given display styles if provided)
|
||||
--
|
||||
transactionCheckBalanced :: BalancingOpts -> Transaction -> [String]
|
||||
transactionCheckBalanced BalancingOpts{commodity_styles_} t = errs
|
||||
-- transactionCheckBalanced BalancingOpts{commodity_styles_=_mstyles} t = errs
|
||||
transactionCheckBalanced _ t = errs
|
||||
where
|
||||
-- get real and balanced virtual postings, to be checked separately
|
||||
(rps, bvps) = foldr partitionPosting ([], []) $ tpostings t
|
||||
@ -109,10 +110,9 @@ transactionCheckBalanced BalancingOpts{commodity_styles_} t = errs
|
||||
| costPostingTagName `elem` map fst (ptags p) = mixedAmountStripCosts $ pamount p
|
||||
| otherwise = mixedAmountCost $ pamount p
|
||||
|
||||
-- transaction balancedness is checked at each commodity's display precision
|
||||
lookszero = mixedAmountLooksZero . atdisplayprecision
|
||||
where
|
||||
atdisplayprecision = maybe id styleAmounts $ commodity_styles_
|
||||
lookszero = mixedAmountLooksZero .
|
||||
-- maybe id styleAmounts _mstyles -- when rounded with global/journal precisions
|
||||
styleAmounts (transactionCommodityStylesWith HardRounding t) -- when rounded with transaction's precisions
|
||||
|
||||
-- when there's multiple non-zeros, check they do not all have the same sign
|
||||
(rsignsok, bvsignsok) = (signsOk rps, signsOk bvps)
|
||||
|
||||
@ -33,6 +33,8 @@ module Hledger.Data.Transaction
|
||||
, transactionMapPostings
|
||||
, transactionMapPostingAmounts
|
||||
, transactionAmounts
|
||||
, transactionCommodityStyles
|
||||
, transactionCommodityStylesWith
|
||||
, transactionNegate
|
||||
, partitionAndCheckConversionPostings
|
||||
, transactionAddTags
|
||||
@ -483,6 +485,17 @@ transactionMapPostingAmounts f = transactionMapPostings (postingTransformAmount
|
||||
transactionAmounts :: Transaction -> [MixedAmount]
|
||||
transactionAmounts = map pamount . tpostings
|
||||
|
||||
-- | Get the canonical amount styles inferred from this transaction's amounts.
|
||||
transactionCommodityStyles :: Transaction -> M.Map CommoditySymbol AmountStyle
|
||||
transactionCommodityStyles =
|
||||
either (const mempty) id . -- ignore style problems, commodityStylesFromAmounts doesn't report them currently
|
||||
commodityStylesFromAmounts . concatMap (amountsRaw . pamount) . tpostings
|
||||
|
||||
-- | Like transactionCommodityStyles, but attach a particular rounding strategy to the styles,
|
||||
-- affecting how they will affect display precisions when applied.
|
||||
transactionCommodityStylesWith :: Rounding -> Transaction -> M.Map CommoditySymbol AmountStyle
|
||||
transactionCommodityStylesWith r = amountStylesSetRounding r . transactionCommodityStyles
|
||||
|
||||
-- | Flip the sign of this transaction's posting amounts (and balance assertion amounts).
|
||||
transactionNegate :: Transaction -> Transaction
|
||||
transactionNegate = transactionMapPostings postingNegate
|
||||
|
||||
@ -188,3 +188,16 @@ $ hledger -f - bal -O csv
|
||||
"b","1 JPY"
|
||||
"c","1000 JPY"
|
||||
"Total:","1002 JPY"
|
||||
|
||||
# ** 13. An entry like this, generated by bean-report, did not balance in hledger <=1.43,
|
||||
# because the P amount influenced the commodity's display (and balancing) precision.
|
||||
# From 1.44 transaction balancing uses the transaction's local precisions,
|
||||
# so CNY's precision is 2 and this does balance.
|
||||
<
|
||||
P 2025-01-01 USD 7.147224669603524229074889868 CNY
|
||||
|
||||
2025-01-01
|
||||
a -113.50 USD @ 7.147224669603524229074889868 CNY
|
||||
a 811.21 CNY
|
||||
|
||||
$ hledger -f - check
|
||||
|
||||
Loading…
Reference in New Issue
Block a user