ref: Refactor journalFinalise to clarify flow.

The only semantic difference is that we now apply
journalApplyCommodityStyles before running journalCheckAccountsDeclared
and journalCheckCommoditiesDeclared.
This commit is contained in:
Stephen Morgan 2021-07-26 15:33:31 +10:00 committed by Simon Michael
parent c537f9426b
commit 04a36d4942

View File

@ -128,7 +128,7 @@ import Prelude ()
import "base-compat-batteries" Prelude.Compat hiding (fail, readFile) import "base-compat-batteries" Prelude.Compat hiding (fail, readFile)
import Control.Applicative.Permutations (runPermutation, toPermutationWithDefault) import Control.Applicative.Permutations (runPermutation, toPermutationWithDefault)
import qualified "base-compat-batteries" Control.Monad.Fail.Compat as Fail (fail) import qualified "base-compat-batteries" Control.Monad.Fail.Compat as Fail (fail)
import Control.Monad.Except (ExceptT(..), runExceptT, throwError) import Control.Monad.Except (ExceptT(..), liftEither, runExceptT, throwError)
import Control.Monad.State.Strict hiding (fail) import Control.Monad.State.Strict hiding (fail)
import Data.Bifunctor (bimap, second) import Data.Bifunctor (bimap, second)
import Data.Char (digitToInt, isDigit, isSpace) import Data.Char (digitToInt, isDigit, isSpace)
@ -329,52 +329,43 @@ parseAndFinaliseJournal' parser iopts f txt = do
-- - infer transaction-implied market prices from transaction prices -- - infer transaction-implied market prices from transaction prices
-- --
journalFinalise :: InputOpts -> FilePath -> Text -> ParsedJournal -> ExceptT String IO Journal journalFinalise :: InputOpts -> FilePath -> Text -> ParsedJournal -> ExceptT String IO Journal
journalFinalise InputOpts{auto_,balancingopts_,strict_} f txt pj = do journalFinalise InputOpts{auto_,balancingopts_,strict_} f txt pj' = do
t <- liftIO getClockTime t <- liftIO getClockTime
d <- liftIO getCurrentDay d <- liftIO getCurrentDay
let pj' = liftEither $ do
pj{jglobalcommoditystyles=fromMaybe M.empty $ commodity_styles_ balancingopts_} -- save any global commodity styles -- Infer and apply canonical styles for each commodity (or throw an error).
-- This affects transaction balancing/assertions/assignments, so needs to be done early.
pj <- journalApplyCommodityStyles $
pj'{jglobalcommoditystyles=fromMaybe M.empty $ commodity_styles_ balancingopts_} -- save any global commodity styles
& journalAddFile (f, txt) -- save the main file's info & journalAddFile (f, txt) -- save the main file's info
& journalSetLastReadTime t -- save the last read time & journalSetLastReadTime t -- save the last read time
& journalReverse -- convert all lists to the order they were parsed & journalReverse -- convert all lists to the order they were parsed
when strict_ $ do
-- If in strict mode, check all postings are to declared accounts -- If in strict mode, check all postings are to declared accounts
case if strict_ then journalCheckAccountsDeclared pj' else Right () of journalCheckAccountsDeclared pj
Left e -> throwError e
Right () ->
-- and using declared commodities -- and using declared commodities
case if strict_ then journalCheckCommoditiesDeclared pj' else Right () of journalCheckCommoditiesDeclared pj
Left e -> throwError e
Right () ->
-- Infer and apply canonical styles for each commodity (or throw an error). -- infer market prices from commodity-exchanging transactions
-- This affects transaction balancing/assertions/assignments, so needs to be done early. journalInferMarketPricesFromTransactions <$>
case journalApplyCommodityStyles pj' of if not auto_ || null (jtxnmodifiers pj)
Left e -> throwError e
Right pj'' -> either throwError return $
pj''
& (if not auto_ || null (jtxnmodifiers pj'')
then then
-- Auto postings are not active. -- Auto postings are not active.
-- Balance all transactions and maybe check balance assertions. -- Balance all transactions and maybe check balance assertions.
journalBalanceTransactions balancingopts_ journalBalanceTransactions balancingopts_ pj
else \j -> do -- Either monad else
-- Auto postings are active. -- Auto postings are active.
-- Balance all transactions without checking balance assertions, -- Balance all transactions without checking balance assertions,
j' <- journalBalanceTransactions balancingopts_{ignore_assertions_=True} j journalBalanceTransactions balancingopts_{ignore_assertions_=True} pj
-- then add the auto postings -- then add the auto postings
-- (Note adding auto postings after balancing means #893b fails; -- (Note adding auto postings after balancing means #893b fails;
-- adding them before balancing probably means #893a, #928, #938 fail.) -- adding them before balancing probably means #893a, #928, #938 fail.)
case journalModifyTransactions d j' of >>= journalModifyTransactions d
Left e -> throwError e
Right j'' -> do
-- then apply commodity styles once more, to style the auto posting amounts. (XXX inefficient ?) -- then apply commodity styles once more, to style the auto posting amounts. (XXX inefficient ?)
j''' <- journalApplyCommodityStyles j'' >>= journalApplyCommodityStyles
-- then check balance assertions. -- then check balance assertions.
journalBalanceTransactions balancingopts_ j''' >>= journalBalanceTransactions balancingopts_
)
& fmap journalInferMarketPricesFromTransactions -- infer market prices from commodity-exchanging transactions
-- | Check that all the journal's transactions have payees declared with -- | Check that all the journal's transactions have payees declared with
-- payee directives, returning an error message otherwise. -- payee directives, returning an error message otherwise.