;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