;journal: account types: fix detection of Cash as an Asset, add tests
This commit is contained in:
parent
6a772fb94e
commit
e4f8b80d3b
@ -297,39 +297,52 @@ journalAccountNameTree = accountNameTreeFrom . journalAccountNames
|
|||||||
-- queries for standard account types
|
-- queries for standard account types
|
||||||
|
|
||||||
-- | A query for accounts in this journal which have been
|
-- | A query for accounts in this journal which have been
|
||||||
-- declared as Asset by account directives, or otherwise for
|
-- declared as Asset (or Cash, a subtype of Asset) by account directives,
|
||||||
-- accounts with names matched by the case-insensitive regular expression
|
-- or otherwise for accounts with names matched by the case-insensitive
|
||||||
-- @^assets?(:|$)@.
|
-- regular expression @^assets?(:|$)@.
|
||||||
journalAssetAccountQuery :: Journal -> Query
|
journalAssetAccountQuery :: Journal -> Query
|
||||||
journalAssetAccountQuery = journalAccountTypeQuery Asset "^assets?(:|$)"
|
journalAssetAccountQuery j = journalAccountTypeQuery [Asset,Cash] "^assets?(:|$)" j
|
||||||
|
|
||||||
|
-- | A query for "Cash" (liquid asset) accounts in this journal, ie accounts
|
||||||
|
-- declared as Cash by account directives, or otherwise with names matched by the
|
||||||
|
-- case-insensitive regular expression @^assets?(:|$)@. and not including
|
||||||
|
-- the case-insensitive regular expression @(investment|receivable|:A/R|:fixed)@.
|
||||||
|
journalCashAccountQuery :: Journal -> Query
|
||||||
|
journalCashAccountQuery j =
|
||||||
|
case M.lookup Cash (jdeclaredaccounttypes j) of
|
||||||
|
Just _ -> journalAccountTypeQuery [Cash] notused j
|
||||||
|
where notused = error' "journalCashAccountQuery: this should not have happened!" -- XXX ugly
|
||||||
|
Nothing -> And [journalAssetAccountQuery j
|
||||||
|
,Not $ Acct "(investment|receivable|:A/R|:fixed)"
|
||||||
|
]
|
||||||
|
|
||||||
-- | A query for accounts in this journal which have been
|
-- | A query for accounts in this journal which have been
|
||||||
-- declared as Liability by account directives, or otherwise for
|
-- declared as Liability by account directives, or otherwise for
|
||||||
-- accounts with names matched by the case-insensitive regular expression
|
-- accounts with names matched by the case-insensitive regular expression
|
||||||
-- @^(debts?|liabilit(y|ies))(:|$)@.
|
-- @^(debts?|liabilit(y|ies))(:|$)@.
|
||||||
journalLiabilityAccountQuery :: Journal -> Query
|
journalLiabilityAccountQuery :: Journal -> Query
|
||||||
journalLiabilityAccountQuery = journalAccountTypeQuery Liability "^(debts?|liabilit(y|ies))(:|$)"
|
journalLiabilityAccountQuery = journalAccountTypeQuery [Liability] "^(debts?|liabilit(y|ies))(:|$)"
|
||||||
|
|
||||||
-- | A query for accounts in this journal which have been
|
-- | A query for accounts in this journal which have been
|
||||||
-- declared as Equity by account directives, or otherwise for
|
-- declared as Equity by account directives, or otherwise for
|
||||||
-- accounts with names matched by the case-insensitive regular expression
|
-- accounts with names matched by the case-insensitive regular expression
|
||||||
-- @^equity(:|$)@.
|
-- @^equity(:|$)@.
|
||||||
journalEquityAccountQuery :: Journal -> Query
|
journalEquityAccountQuery :: Journal -> Query
|
||||||
journalEquityAccountQuery = journalAccountTypeQuery Equity "^equity(:|$)"
|
journalEquityAccountQuery = journalAccountTypeQuery [Equity] "^equity(:|$)"
|
||||||
|
|
||||||
-- | A query for accounts in this journal which have been
|
-- | A query for accounts in this journal which have been
|
||||||
-- declared as Revenue by account directives, or otherwise for
|
-- declared as Revenue by account directives, or otherwise for
|
||||||
-- accounts with names matched by the case-insensitive regular expression
|
-- accounts with names matched by the case-insensitive regular expression
|
||||||
-- @^(income|revenue)s?(:|$)@.
|
-- @^(income|revenue)s?(:|$)@.
|
||||||
journalRevenueAccountQuery :: Journal -> Query
|
journalRevenueAccountQuery :: Journal -> Query
|
||||||
journalRevenueAccountQuery = journalAccountTypeQuery Revenue "^(income|revenue)s?(:|$)"
|
journalRevenueAccountQuery = journalAccountTypeQuery [Revenue] "^(income|revenue)s?(:|$)"
|
||||||
|
|
||||||
-- | A query for accounts in this journal which have been
|
-- | A query for accounts in this journal which have been
|
||||||
-- declared as Expense by account directives, or otherwise for
|
-- declared as Expense by account directives, or otherwise for
|
||||||
-- accounts with names matched by the case-insensitive regular expression
|
-- accounts with names matched by the case-insensitive regular expression
|
||||||
-- @^expenses?(:|$)@.
|
-- @^expenses?(:|$)@.
|
||||||
journalExpenseAccountQuery :: Journal -> Query
|
journalExpenseAccountQuery :: Journal -> Query
|
||||||
journalExpenseAccountQuery = journalAccountTypeQuery Expense "^expenses?(:|$)"
|
journalExpenseAccountQuery = journalAccountTypeQuery [Expense] "^expenses?(:|$)"
|
||||||
|
|
||||||
-- | A query for Asset, Liability & Equity accounts in this journal.
|
-- | A query for Asset, Liability & Equity accounts in this journal.
|
||||||
-- Cf <http://en.wikipedia.org/wiki/Chart_of_accounts#Balance_Sheet_Accounts>.
|
-- Cf <http://en.wikipedia.org/wiki/Chart_of_accounts#Balance_Sheet_Accounts>.
|
||||||
@ -346,31 +359,21 @@ journalProfitAndLossAccountQuery j = Or [journalRevenueAccountQuery j
|
|||||||
,journalExpenseAccountQuery j
|
,journalExpenseAccountQuery j
|
||||||
]
|
]
|
||||||
|
|
||||||
-- | A query for "Cash" (liquid asset) accounts in this journal (ie,
|
-- | Get a query for accounts of the specified types (Asset, Liability..) in this journal.
|
||||||
-- accounts which appear on the cashflow statement.) This is the
|
-- The query will match all accounts which were declared as one of
|
||||||
-- accounts declared to be Cash type, or if none of these are
|
-- these types by account directives, plus all their subaccounts which
|
||||||
-- declared, the Asset accounts whose names do not contain the
|
-- have not been declared as some other type.
|
||||||
-- case-insensitive regular expression @(investment|receivable|:A/R|:fixed)@.
|
-- Or if no accounts were declared with these types, the query will
|
||||||
journalCashAccountQuery :: Journal -> Query
|
-- instead match accounts with names matched by the provided
|
||||||
journalCashAccountQuery j =
|
-- case-insensitive regular expression.
|
||||||
case M.lookup Cash (jdeclaredaccounttypes j) of
|
journalAccountTypeQuery :: [AccountType] -> Regexp -> Journal -> Query
|
||||||
Just _ -> journalAccountTypeQuery Cash notused j
|
journalAccountTypeQuery atypes fallbackregex Journal{jdeclaredaccounttypes} =
|
||||||
where notused = error' "journalCashAccountQuery: this should not have happened!"
|
let
|
||||||
Nothing -> And
|
declaredacctsoftype :: [AccountName] =
|
||||||
[journalAssetAccountQuery j
|
concat $ catMaybes [M.lookup t jdeclaredaccounttypes | t <- atypes]
|
||||||
,Not $ Acct "(investment|receivable|:A/R|:fixed)"
|
in case declaredacctsoftype of
|
||||||
]
|
[] -> Acct fallbackregex
|
||||||
|
as ->
|
||||||
-- | Get a query for accounts of a certain type (Asset, Liability..) in this journal.
|
|
||||||
-- The query will match all accounts which were declared as that type by account directives,
|
|
||||||
-- plus all their subaccounts which have not been declared as a different type.
|
|
||||||
-- If no accounts were declared as this type, the query will instead match accounts
|
|
||||||
-- with names matched by the provided case-insensitive regular expression.
|
|
||||||
journalAccountTypeQuery :: AccountType -> Regexp -> Journal -> Query
|
|
||||||
journalAccountTypeQuery atype fallbackregex j =
|
|
||||||
case M.lookup atype (jdeclaredaccounttypes j) of
|
|
||||||
Nothing -> Acct fallbackregex
|
|
||||||
Just as ->
|
|
||||||
-- XXX Query isn't able to match account type since that requires extra info from the journal.
|
-- XXX Query isn't able to match account type since that requires extra info from the journal.
|
||||||
-- So we do a hacky search by name instead.
|
-- So we do a hacky search by name instead.
|
||||||
And [
|
And [
|
||||||
@ -379,8 +382,8 @@ journalAccountTypeQuery atype fallbackregex j =
|
|||||||
]
|
]
|
||||||
where
|
where
|
||||||
differentlytypedsubs = concat
|
differentlytypedsubs = concat
|
||||||
[subs | (t,bs) <- M.toList (jdeclaredaccounttypes j)
|
[subs | (t,bs) <- M.toList jdeclaredaccounttypes
|
||||||
, t /= atype
|
, not $ t `elem` atypes
|
||||||
, let subs = [b | b <- bs, any (`isAccountNamePrefixOf` b) as]
|
, let subs = [b | b <- bs, any (`isAccountNamePrefixOf` b) as]
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1407,11 +1410,18 @@ tests_Journal = tests "Journal" [
|
|||||||
journalAccountNamesMatching q = filter (q `matchesAccount`) . journalAccountNames
|
journalAccountNamesMatching q = filter (q `matchesAccount`) . journalAccountNames
|
||||||
namesfrom qfunc = journalAccountNamesMatching (qfunc j) j
|
namesfrom qfunc = journalAccountNamesMatching (qfunc j) j
|
||||||
in [
|
in [
|
||||||
test "assets" $ assertEqual "" (namesfrom journalAssetAccountQuery) ["assets","assets:bank","assets:bank:checking","assets:bank:saving","assets:cash"]
|
test "assets" $ assertEqual "" ["assets","assets:bank","assets:bank:checking","assets:bank:saving","assets:cash"]
|
||||||
,test "liabilities" $ assertEqual "" (namesfrom journalLiabilityAccountQuery) ["liabilities","liabilities:debts"]
|
(namesfrom journalAssetAccountQuery)
|
||||||
,test "equity" $ assertEqual "" (namesfrom journalEquityAccountQuery) []
|
,test "cash" $ assertEqual "" ["assets","assets:bank","assets:bank:checking","assets:bank:saving","assets:cash"]
|
||||||
,test "income" $ assertEqual "" (namesfrom journalRevenueAccountQuery) ["income","income:gifts","income:salary"]
|
(namesfrom journalCashAccountQuery)
|
||||||
,test "expenses" $ assertEqual "" (namesfrom journalExpenseAccountQuery) ["expenses","expenses:food","expenses:supplies"]
|
,test "liabilities" $ assertEqual "" ["liabilities","liabilities:debts"]
|
||||||
|
(namesfrom journalLiabilityAccountQuery)
|
||||||
|
,test "equity" $ assertEqual "" []
|
||||||
|
(namesfrom journalEquityAccountQuery)
|
||||||
|
,test "income" $ assertEqual "" ["income","income:gifts","income:salary"]
|
||||||
|
(namesfrom journalRevenueAccountQuery)
|
||||||
|
,test "expenses" $ assertEqual "" ["expenses","expenses:food","expenses:supplies"]
|
||||||
|
(namesfrom journalExpenseAccountQuery)
|
||||||
]
|
]
|
||||||
|
|
||||||
,tests "journalBalanceTransactions" [
|
,tests "journalBalanceTransactions" [
|
||||||
|
|||||||
74
tests/journal/account-types.test
Normal file
74
tests/journal/account-types.test
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
; # Here some accounts with type Asset and Cash are declared and
|
||||||
|
; # Liability, Equity, Revenue and Expense accounts are inferred.
|
||||||
|
; <
|
||||||
|
; account assets ; type:Asset
|
||||||
|
; account assets:cash ; type:Cash
|
||||||
|
; account liabilities
|
||||||
|
|
||||||
|
; 2020-01-01
|
||||||
|
; assets 1
|
||||||
|
; assets:cash 1
|
||||||
|
; liabilities -1
|
||||||
|
; revenues 1
|
||||||
|
; expenses -1
|
||||||
|
; equity
|
||||||
|
|
||||||
|
; # 1. bse reports the balance sheet accounts in the proper section.
|
||||||
|
; # A Cash account is also an Asset.
|
||||||
|
; $ hledger -f- bse
|
||||||
|
; Balance Sheet With Equity 2020-01-01
|
||||||
|
|
||||||
|
; || 2020-01-01
|
||||||
|
; =============++============
|
||||||
|
; Assets ||
|
||||||
|
; -------------++------------
|
||||||
|
; assets || 1
|
||||||
|
; assets:cash || 1
|
||||||
|
; -------------++------------
|
||||||
|
; || 2
|
||||||
|
; =============++============
|
||||||
|
; Liabilities ||
|
||||||
|
; -------------++------------
|
||||||
|
; liabilities || 1
|
||||||
|
; -------------++------------
|
||||||
|
; || 1
|
||||||
|
; =============++============
|
||||||
|
; Equity ||
|
||||||
|
; -------------++------------
|
||||||
|
; equity || 1
|
||||||
|
; -------------++------------
|
||||||
|
; || 1
|
||||||
|
; =============++============
|
||||||
|
; Net: || 0
|
||||||
|
|
||||||
|
; # 2. cashflow reports the Cash account.
|
||||||
|
; $ hledger -f- cf
|
||||||
|
; Cashflow Statement 2020-01-01
|
||||||
|
|
||||||
|
; || 2020-01-01
|
||||||
|
; =============++============
|
||||||
|
; Cash flows ||
|
||||||
|
; -------------++------------
|
||||||
|
; assets:cash || 1
|
||||||
|
; -------------++------------
|
||||||
|
; || 1
|
||||||
|
|
||||||
|
; # 3. is reports the income statement accounts in the proper section.
|
||||||
|
; $ hledger -f- is
|
||||||
|
; Income Statement 2020-01-01
|
||||||
|
|
||||||
|
; || 2020-01-01
|
||||||
|
; ==========++============
|
||||||
|
; Revenues ||
|
||||||
|
; ----------++------------
|
||||||
|
; revenues || 1
|
||||||
|
; ----------++------------
|
||||||
|
; || 1
|
||||||
|
; ==========++============
|
||||||
|
; Expenses ||
|
||||||
|
; ----------++------------
|
||||||
|
; expenses || 1
|
||||||
|
; ----------++------------
|
||||||
|
; || 1
|
||||||
|
; ==========++============
|
||||||
|
; Net: || 0
|
||||||
Loading…
Reference in New Issue
Block a user