diff --git a/hledger-lib/Hledger/Data/Account.hs b/hledger-lib/Hledger/Data/Account.hs index 8910d2500..ca362533f 100644 --- a/hledger-lib/Hledger/Data/Account.hs +++ b/hledger-lib/Hledger/Data/Account.hs @@ -210,15 +210,9 @@ sortAccountTreeByAmount normalsign a -- | Add extra info for this account derived from the Journal's -- account directives, if any (comment, tags, declaration order..). --- Currently only sets declaration order. --- Expects that this account is among the Journal's jdeclaredaccounts --- (otherwise sets declaration order to 0). accountSetDeclarationInfo :: Journal -> Account -> Account -accountSetDeclarationInfo j a@Account{..} = - a{adeclarationinfo=Just nullaccountdeclarationinfo{ - adideclarationorder = fromMaybe 0 $ findIndex (==aname) (jdeclaredaccounts j) - } - } +accountSetDeclarationInfo j a@Account{..} = + a{ adeclarationinfo=lookup aname $ jdeclaredaccounts j } -- | Sort account names by the order in which they were declared in -- the journal, at each level of the account tree (ie within each diff --git a/hledger-lib/Hledger/Data/Journal.hs b/hledger-lib/Hledger/Data/Journal.hs index 294febc57..0f73786c5 100644 --- a/hledger-lib/Hledger/Data/Journal.hs +++ b/hledger-lib/Hledger/Data/Journal.hs @@ -264,7 +264,7 @@ journalAccountNamesImplied = expandAccountNames . journalAccountNamesUsed -- | Sorted unique account names declared by account directives in this journal. journalAccountNamesDeclared :: Journal -> [AccountName] -journalAccountNamesDeclared = nub . sort . jdeclaredaccounts +journalAccountNamesDeclared = nub . sort . map fst . jdeclaredaccounts -- | Sorted unique account names declared by account directives or posted to -- by transactions in this journal. diff --git a/hledger-lib/Hledger/Data/Types.hs b/hledger-lib/Hledger/Data/Types.hs index 7355bc857..5a868ce09 100644 --- a/hledger-lib/Hledger/Data/Types.hs +++ b/hledger-lib/Hledger/Data/Types.hs @@ -410,7 +410,7 @@ data Journal = Journal { ,jparsetimeclockentries :: [TimeclockEntry] -- ^ timeclock sessions which have not been clocked out ,jincludefilestack :: [FilePath] -- principal data - ,jdeclaredaccounts :: [AccountName] -- ^ Accounts declared by account directives, in parse order (after journal finalisation) + ,jdeclaredaccounts :: [(AccountName,AccountDeclarationInfo)] -- ^ 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 @@ -444,8 +444,11 @@ type StorageFormat = String data AccountDeclarationInfo = AccountDeclarationInfo { adicomment :: Text -- ^ any comment lines following an account directive for this account ,aditags :: [Tag] -- ^ tags extracted from the account comment, if any - ,adideclarationorder :: Int -- ^ the relative position of this account's account directive, if any. Normally a natural number. -} deriving (Data) + ,adideclarationorder :: Int -- ^ the order in which this account was declared, + -- relative to other account declarations, during parsing (1..) +} deriving (Eq,Data,Generic) + +instance NFData AccountDeclarationInfo nullaccountdeclarationinfo = AccountDeclarationInfo { adicomment = "" diff --git a/hledger-lib/Hledger/Read/Common.hs b/hledger-lib/Hledger/Read/Common.hs index 164bbcb77..c8a128ca6 100644 --- a/hledger-lib/Hledger/Read/Common.hs +++ b/hledger-lib/Hledger/Read/Common.hs @@ -42,7 +42,6 @@ module Hledger.Read.Common ( getDefaultCommodityAndStyle, getDefaultAmountStyle, getAmountStyle, - pushDeclaredAccount, addDeclaredAccountType, pushParentAccount, popParentAccount, @@ -362,9 +361,6 @@ getAmountStyle commodity = do let effectiveStyle = listToMaybe $ catMaybes [specificStyle, defaultStyle] return effectiveStyle -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)}) diff --git a/hledger-lib/Hledger/Read/JournalReader.hs b/hledger-lib/Hledger/Read/JournalReader.hs index 9fdcab5ee..b3d20aec1 100644 --- a/hledger-lib/Hledger/Read/JournalReader.hs +++ b/hledger-lib/Hledger/Read/JournalReader.hs @@ -253,13 +253,15 @@ orRethrowIOError io msg = do Right res -> pure res Left errMsg -> fail errMsg +-- Parse an account directive, adding its info to the journal's +-- list of account declarations. accountdirectivep :: JournalParser m () accountdirectivep = do string "account" lift (skipSome spacenonewline) -- the account name, possibly modified by preceding alias or apply account directives acct <- modifiedaccountnamep - -- and maybe something else after two or more spaces ? + -- maybe an account type code after two or more spaces matype :: Maybe AccountType <- lift $ fmap (fromMaybe Nothing) $ optional $ try $ do skipSome spacenonewline -- at least one more space in addition to the one consumed by modifiedaccountp choice [ @@ -270,16 +272,30 @@ accountdirectivep = do ,char 'R' >> return (Just Revenue) ,char 'X' >> return (Just Expense) ] - -- and maybe a comment on this and/or following lines ? (ignore for now) - (_cmt, _tags) <- lift transactioncommentp - -- and maybe Ledger-style subdirectives ? (ignore) + -- maybe a comment, on this and/or following lines + (cmt, tags) <- lift transactioncommentp + -- maybe Ledger-style subdirectives (ignored) skipMany indentedlinep -- update the journal + addAccountDeclaration (acct, cmt, tags) case matype of Nothing -> return () Just atype -> addDeclaredAccountType acct atype - pushDeclaredAccount acct + +-- Add an account declaration to the journal, auto-numbering it. +addAccountDeclaration :: (AccountName,Text,[Tag]) -> JournalParser m () +addAccountDeclaration (a,cmt,tags) = + modify' (\j -> + let + decls = jdeclaredaccounts j + d = (a, nullaccountdeclarationinfo{ + adicomment = cmt + ,aditags = tags + ,adideclarationorder = length decls + 1 + }) + in + j{jdeclaredaccounts = d:decls}) indentedlinep :: JournalParser m String indentedlinep = lift (skipSome spacenonewline) >> (rstrip <$> lift restofline) diff --git a/hledger/Hledger/Cli/Commands/Accounts.hs b/hledger/Hledger/Cli/Commands/Accounts.hs index 61087b5a4..2ff78eebc 100644 --- a/hledger/Hledger/Cli/Commands/Accounts.hs +++ b/hledger/Hledger/Cli/Commands/Accounts.hs @@ -74,7 +74,7 @@ accounts CliOpts{rawopts_=rawopts, reportopts_=ropts} j = do -- just the acct: part of the query will be reapplied later, after clipping acctq = dbg1 "acctq" $ filterQuery queryIsAcct q depth = dbg1 "depth" $ queryDepth $ filterQuery queryIsDepth q - matcheddeclaredaccts = dbg1 "matcheddeclaredaccts" $ filter (matchesAccount nodepthq) $ jdeclaredaccounts j + matcheddeclaredaccts = dbg1 "matcheddeclaredaccts" $ filter (matchesAccount nodepthq) $ map fst $ jdeclaredaccounts j matchedusedaccts = dbg5 "matchedusedaccts" $ map paccount $ journalPostings $ filterJournalPostings nodepthq j accts = dbg5 "accts to show" $ -- no need to nub/sort, accountTree will if | declared && not used -> matcheddeclaredaccts