diff --git a/hledger-lib/Hledger/Data/Journal.hs b/hledger-lib/Hledger/Data/Journal.hs index 65eb23f2a..5f5a54dac 100644 --- a/hledger-lib/Hledger/Data/Journal.hs +++ b/hledger-lib/Hledger/Data/Journal.hs @@ -162,16 +162,17 @@ instance Sem.Semigroup Journal where ,jparseparentaccounts = jparseparentaccounts j2 ,jparsealiases = jparsealiases j2 -- ,jparsetransactioncount = jparsetransactioncount j1 + jparsetransactioncount j2 - ,jparsetimeclockentries = jparsetimeclockentries j1 <> jparsetimeclockentries j2 + ,jparsetimeclockentries = jparsetimeclockentries j1 <> jparsetimeclockentries j2 ,jincludefilestack = jincludefilestack j2 - ,jdeclaredaccounts = jdeclaredaccounts j1 <> jdeclaredaccounts j2 + ,jdeclaredaccounts = jdeclaredaccounts j1 <> jdeclaredaccounts j2 + ,jdeclaredaccounttypes = jdeclaredaccounttypes j1 <> jdeclaredaccounttypes j2 ,jcommodities = jcommodities j1 <> jcommodities j2 ,jinferredcommodities = jinferredcommodities j1 <> jinferredcommodities j2 ,jmarketprices = jmarketprices j1 <> jmarketprices j2 ,jtxnmodifiers = jtxnmodifiers j1 <> jtxnmodifiers j2 ,jperiodictxns = jperiodictxns j1 <> jperiodictxns j2 ,jtxns = jtxns j1 <> jtxns j2 - ,jfinalcommentlines = jfinalcommentlines j2 + ,jfinalcommentlines = jfinalcommentlines j2 -- XXX discards j1's ? ,jfiles = jfiles j1 <> jfiles j2 ,jlastreadtime = max (jlastreadtime j1) (jlastreadtime j2) } @@ -193,8 +194,9 @@ nulljournal = Journal { ,jparsetimeclockentries = [] ,jincludefilestack = [] ,jdeclaredaccounts = [] - ,jcommodities = M.fromList [] - ,jinferredcommodities = M.fromList [] + ,jdeclaredaccounttypes = M.empty + ,jcommodities = M.empty + ,jinferredcommodities = M.empty ,jmarketprices = [] ,jtxnmodifiers = [] ,jperiodictxns = [] diff --git a/hledger-lib/Hledger/Data/Types.hs b/hledger-lib/Hledger/Data/Types.hs index 1521ac8da..3414dbf6b 100644 --- a/hledger-lib/Hledger/Data/Types.hs +++ b/hledger-lib/Hledger/Data/Types.hs @@ -113,7 +113,26 @@ instance Default Interval where def = NoInterval instance NFData Interval type AccountName = Text -type AccountCode = Int + +data AccountType = + Asset + | Liability + | Equity + | Revenue + | Expense + deriving (Show,Eq,Ord,Data,Generic) + +instance NFData AccountType + +-- not worth the trouble, letters defined in accountdirectivep for now +--instance Read AccountType +-- where +-- readsPrec _ ('A' : xs) = [(Asset, xs)] +-- readsPrec _ ('L' : xs) = [(Liability, xs)] +-- readsPrec _ ('E' : xs) = [(Equity, xs)] +-- readsPrec _ ('R' : xs) = [(Revenue, xs)] +-- readsPrec _ ('X' : xs) = [(Expense, xs)] +-- readsPrec _ _ = [] data AccountAlias = BasicAlias AccountName AccountName | RegexAlias Regexp Replacement @@ -369,6 +388,7 @@ data Journal = Journal { ,jincludefilestack :: [FilePath] -- principal data ,jdeclaredaccounts :: [AccountName] -- ^ Accounts declared by account directives, in parse order (after journal finalisation) + ,jdeclaredaccounttypes :: M.Map AccountType [AccountName] -- ^ Accounts whose type has been declared in account directives (usually 5 top-level accounts) ,jcommodities :: M.Map CommoditySymbol Commodity -- ^ commodities and formats declared by commodity directives ,jinferredcommodities :: M.Map CommoditySymbol AmountStyle -- ^ commodities and formats inferred from journal amounts TODO misnamed - jusedstyles ,jmarketprices :: [MarketPrice] diff --git a/hledger-lib/Hledger/Read/Common.hs b/hledger-lib/Hledger/Read/Common.hs index b305fa957..2ca8f598f 100644 --- a/hledger-lib/Hledger/Read/Common.hs +++ b/hledger-lib/Hledger/Read/Common.hs @@ -43,6 +43,7 @@ module Hledger.Read.Common ( getDefaultAmountStyle, getAmountStyle, pushDeclaredAccount, + addDeclaredAccountType, pushParentAccount, popParentAccount, getParentAccount, @@ -311,6 +312,10 @@ getAmountStyle commodity = do pushDeclaredAccount :: AccountName -> JournalParser m () pushDeclaredAccount acct = modify' (\j -> j{jdeclaredaccounts = acct : jdeclaredaccounts j}) +addDeclaredAccountType :: AccountName -> AccountType -> JournalParser m () +addDeclaredAccountType acct atype = + modify' (\j -> j{jdeclaredaccounttypes = M.insertWith (++) atype [acct] (jdeclaredaccounttypes j)}) + pushParentAccount :: AccountName -> JournalParser m () pushParentAccount acct = modify' (\j -> j{jparseparentaccounts = acct : jparseparentaccounts j}) diff --git a/hledger-lib/Hledger/Read/JournalReader.hs b/hledger-lib/Hledger/Read/JournalReader.hs index 5057f2f48..75abe6e40 100644 --- a/hledger-lib/Hledger/Read/JournalReader.hs +++ b/hledger-lib/Hledger/Read/JournalReader.hs @@ -69,6 +69,7 @@ import Control.Monad import Control.Monad.Except (ExceptT(..)) import Control.Monad.State.Strict import Data.Bifunctor (first) +import Data.Maybe import qualified Data.Map.Strict as M import Data.Text (Text) import Data.String @@ -257,10 +258,29 @@ accountdirectivep :: JournalParser m () accountdirectivep = do string "account" lift (skipSome spacenonewline) - acct <- modifiedaccountnamep -- account directives can be modified by alias/apply account - _ :: Maybe String <- (optional $ lift $ skipSome spacenonewline >> some digitChar) -- compatibility: ignore account codes supported in 1.9/1.10 + -- the account name, possibly modified by preceding alias or apply account directives + acct <- modifiedaccountnamep + -- and maybe something else after two or more spaces ? + matype :: Maybe AccountType <- lift $ fmap (fromMaybe Nothing) $ optional $ do + skipSome spacenonewline -- at least one more space in addition to the one consumed by modifiedaccountp + choice [ + -- a numeric account code, as supported in 1.9-1.10 ? currently ignored + some digitChar >> return Nothing + -- a letter account type code (ALERX), as added in 1.11 ? + ,char 'A' >> return (Just Asset) + ,char 'L' >> return (Just Liability) + ,char 'E' >> return (Just Equity) + ,char 'R' >> return (Just Revenue) + ,char 'X' >> return (Just Expense) + ] newline + -- Ledger-style indented subdirectives on following lines ? ignore skipMany indentedlinep + + -- update the journal + case matype of + Nothing -> return () + Just atype -> addDeclaredAccountType acct atype pushDeclaredAccount acct indentedlinep :: JournalParser m String