From da11d74ae6e16867bf3676c0e4eeabbfc5122b5f Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Thu, 17 Oct 2024 12:00:48 -1000 Subject: [PATCH] dev: refactor: clarify journalAccountTypes --- hledger-lib/Hledger/Data/Journal.hs | 34 +++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/hledger-lib/Hledger/Data/Journal.hs b/hledger-lib/Hledger/Data/Journal.hs index 150e3e491..1235384a7 100644 --- a/hledger-lib/Hledger/Data/Journal.hs +++ b/hledger-lib/Hledger/Data/Journal.hs @@ -154,6 +154,7 @@ import System.FilePath (takeFileName) import Data.Ord (comparing) import Hledger.Data.Dates (nulldate) import Data.List (sort) +import Data.Function ((&)) -- import Data.Function ((&)) @@ -576,27 +577,31 @@ journalAccountType Journal{jaccounttypes} = accountNameType jaccounttypes journalAddAccountTypes :: Journal -> Journal journalAddAccountTypes j = j{jaccounttypes = journalAccountTypes j} +-- | An account type inherited from the parent account(s), +-- and whether it was originally declared by an account directive (true) or inferred from an account name (false). +type ParentAccountType = ( AccountType, Bool ) + -- | Build a map of all known account types, explicitly declared -- or inferred from the account's parent or name. journalAccountTypes :: Journal -> M.Map AccountName AccountType journalAccountTypes j = M.fromList [(a,acctType) | (a, Just (acctType,_)) <- flatten t'] where t = accountNameTreeFrom $ journalAccountNames j :: Tree AccountName - -- Map from the top of the account tree down to the leaves, propagating - -- account types downward. Keep track of whether the account is declared - -- (True), in which case the parent account should be preferred, or merely - -- inferred (False), in which case the inferred type should be preferred. - t' = settypes Nothing t :: Tree (AccountName, Maybe (AccountType, Bool)) + -- Map from the top of the account tree down to the leaves, applying any explicitly declared account types, + -- otherwise inferring account types from account names when possible, and propagating account types downward. + -- Declared account types (possibly inherited from parent) are preferred, inferred types are used as a fallback. + t' = setTypeHereAndBelow Nothing t :: Tree (AccountName, Maybe (AccountType, Bool)) where - settypes :: Maybe (AccountType, Bool) -> Tree AccountName -> Tree (AccountName, Maybe (AccountType, Bool)) - settypes mparenttype (Node a subs) = Node (a, mtype) (map (settypes mtype) subs) + declaredtypesbyname = journalDeclaredAccountTypes j & fmap (,True) + setTypeHereAndBelow :: Maybe ParentAccountType -> Tree AccountName -> Tree (AccountName, Maybe ParentAccountType) + setTypeHereAndBelow mparenttype (Node a subs) = Node (a, mnewtype) (map (setTypeHereAndBelow mnewtype) subs) where - mtype = M.lookup a declaredtypes <|> minferred - where - declaredtypes = (,True) <$> journalDeclaredAccountTypes j - minferred = if maybe False snd mparenttype - then mparenttype - else (,False) <$> accountNameInferType a <|> mparenttype + mnewtype = mthisacctdeclaredtype <|> mparentacctdeclaredtype <|> mthisacctinferredtype <|> mparentacctinferredtype + where + mthisacctdeclaredtype = M.lookup a declaredtypesbyname + mparentacctdeclaredtype = if fromMaybe False $ snd <$> mparenttype then mparenttype else Nothing + mparentacctinferredtype = if not $ fromMaybe True $ snd <$> mparenttype then mparenttype else Nothing + mthisacctinferredtype = accountNameInferType a & fmap (,False) -- | Build a map of the account types explicitly declared for each account. journalDeclaredAccountTypes :: Journal -> M.Map AccountName AccountType @@ -616,7 +621,8 @@ journalPostingsAddAccountTags j = journalMapPostings addtags j journalBaseConversionAccount :: Journal -> AccountName journalBaseConversionAccount = headDef defaultBaseConversionAccount . journalConversionAccounts --- | All the accounts declared or inferred as V/Conversion type in this journal. +-- | All the accounts in this journal which are declared or inferred as V/Conversion type. +-- This does not include new account names which might be generated by --infer-equity, currently. journalConversionAccounts :: Journal -> [AccountName] journalConversionAccounts = M.keys . M.filter (==Conversion) . jaccounttypes