journal: account types: add Cash, tweak fallback regexp, rewrite docs
This commit is contained in:
		
							parent
							
								
									30f02b0882
								
							
						
					
					
						commit
						fd9171df07
					
				| @ -296,29 +296,6 @@ journalAccountNameTree = accountNameTreeFrom . journalAccountNames | |||||||
| 
 | 
 | ||||||
| -- queries for standard account types | -- queries for standard account types | ||||||
| 
 | 
 | ||||||
| -- | 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. |  | ||||||
|       -- So we do a hacky search by name instead. |  | ||||||
|       And [ |  | ||||||
|          Or $ map (Acct . accountNameToAccountRegex) as |  | ||||||
|         ,Not $ Or $ map (Acct . accountNameToAccountRegex) differentlytypedsubs |  | ||||||
|         ] |  | ||||||
|       where |  | ||||||
|         differentlytypedsubs = concat |  | ||||||
|           [subs | (t,bs) <- M.toList (jdeclaredaccounttypes j) |  | ||||||
|               , t /= atype |  | ||||||
|               , let subs = [b | b <- bs, any (`isAccountNamePrefixOf` b) as] |  | ||||||
|           ] |  | ||||||
| 
 |  | ||||||
| -- | 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 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 | ||||||
| @ -369,12 +346,43 @@ journalProfitAndLossAccountQuery j = Or [journalRevenueAccountQuery j | |||||||
|                                         ,journalExpenseAccountQuery j |                                         ,journalExpenseAccountQuery j | ||||||
|                                         ] |                                         ] | ||||||
| 
 | 
 | ||||||
| -- | A query for Cash (-equivalent) accounts in this journal (ie, | -- | A query for "Cash" (liquid asset) accounts in this journal (ie, | ||||||
| -- accounts which appear on the cashflow statement.)  This is currently | -- accounts which appear on the cashflow statement.) This is the | ||||||
| -- hard-coded to be all the Asset accounts except for those with names | -- accounts declared to be Cash type, or if none of these are | ||||||
| -- containing the case-insensitive regular expression @(receivable|:A/R|:fixed)@. | -- declared, the Asset accounts whose names do not contain the | ||||||
|  | -- case-insensitive regular expression @(investment|receivable|:A/R|:fixed)@. | ||||||
| journalCashAccountQuery  :: Journal -> Query | journalCashAccountQuery  :: Journal -> Query | ||||||
| journalCashAccountQuery j = And [journalAssetAccountQuery j, Not $ Acct "(receivable|:A/R|:fixed)"] | journalCashAccountQuery j = | ||||||
|  |   case M.lookup Cash (jdeclaredaccounttypes j) of | ||||||
|  |     Just _  -> journalAccountTypeQuery Cash notused j | ||||||
|  |       where notused = error' "journalCashAccountQuery: this should not have happened!" | ||||||
|  |     Nothing -> And | ||||||
|  |                [journalAssetAccountQuery j | ||||||
|  |                ,Not $ Acct "(investment|receivable|:A/R|:fixed)" | ||||||
|  |                ] | ||||||
|  | 
 | ||||||
|  | -- | 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. | ||||||
|  |       -- So we do a hacky search by name instead. | ||||||
|  |       And [ | ||||||
|  |          Or $ map (Acct . accountNameToAccountRegex) as | ||||||
|  |         ,Not $ Or $ map (Acct . accountNameToAccountRegex) differentlytypedsubs | ||||||
|  |         ] | ||||||
|  |       where | ||||||
|  |         differentlytypedsubs = concat | ||||||
|  |           [subs | (t,bs) <- M.toList (jdeclaredaccounttypes j) | ||||||
|  |               , t /= atype | ||||||
|  |               , let subs = [b | b <- bs, any (`isAccountNamePrefixOf` b) as] | ||||||
|  |           ] | ||||||
| 
 | 
 | ||||||
| -- Various kinds of filtering on journals. We do it differently depending | -- Various kinds of filtering on journals. We do it differently depending | ||||||
| -- on the command. | -- on the command. | ||||||
|  | |||||||
| @ -121,6 +121,7 @@ data AccountType = | |||||||
|   | Equity |   | Equity | ||||||
|   | Revenue |   | Revenue | ||||||
|   | Expense |   | Expense | ||||||
|  |   | Cash  -- ^ a subtype of Asset - liquid assets to show in cashflow report | ||||||
|   deriving (Show,Eq,Ord,Data,Generic) |   deriving (Show,Eq,Ord,Data,Generic) | ||||||
| 
 | 
 | ||||||
| instance NFData AccountType | instance NFData AccountType | ||||||
|  | |||||||
| @ -380,10 +380,12 @@ parseAccountTypeCode s = | |||||||
|     "r"         -> Right Revenue |     "r"         -> Right Revenue | ||||||
|     "expense"   -> Right Expense |     "expense"   -> Right Expense | ||||||
|     "x"         -> Right Expense |     "x"         -> Right Expense | ||||||
|  |     "cash"      -> Right Cash | ||||||
|  |     "c"         -> Right Cash | ||||||
|     _           -> Left err |     _           -> Left err | ||||||
|   where |   where | ||||||
|     err = "invalid account type code "++T.unpack s++", should be one of " ++ |     err = "invalid account type code "++T.unpack s++", should be one of " ++ | ||||||
|           (intercalate ", " $ ["A","L","E","R","X","ASSET","LIABILITY","EQUITY","REVENUE","EXPENSE"]) |           (intercalate ", " $ ["A","L","E","R","X","C","Asset","Liability","Equity","Revenue","Expense","Cash"]) | ||||||
| 
 | 
 | ||||||
| -- Add an account declaration to the journal, auto-numbering it. | -- Add an account declaration to the journal, auto-numbering it. | ||||||
| addAccountDeclaration :: (AccountName,Text,[Tag]) -> JournalParser m () | addAccountDeclaration :: (AccountName,Text,[Tag]) -> JournalParser m () | ||||||
|  | |||||||
| @ -1087,37 +1087,88 @@ account ACCTNAME  [ACCTTYPE] [;COMMENT] | |||||||
| 
 | 
 | ||||||
| #### Account types | #### Account types | ||||||
| 
 | 
 | ||||||
| hledger recognises five types (or classes) of account: Asset, Liability, Equity, Revenue, Expense. | hledger recognises five main types of account, | ||||||
| This is used by a few accounting-aware reports such as [balancesheet][], [incomestatement][] and [cashflow][]. | corresponding to the account classes in the [accounting equation][]: | ||||||
| 
 | 
 | ||||||
| [balancesheet]: hledger.html#balancesheet | `Asset`, `Liability`, `Equity`, `Revenue`, `Expense`. | ||||||
| [cashflow]: hledger.html#cashflow | 
 | ||||||
| [incomestatement]: hledger.html#incomestatement | These account types are important for controlling which accounts | ||||||
|  | appear in the [balancesheet][], [balancesheetequity][], | ||||||
|  | [incomestatement][] reports (and probably for other things in future). | ||||||
|  | 
 | ||||||
|  | There is also the `Cash` type, which is a subtype of `Asset`, | ||||||
|  | and which causes accounts to appear in the [cashflow][] report. | ||||||
|  | ("Cash" here means [liquid assets][CCE], eg typically bank balances | ||||||
|  | but not investments or receivables.) | ||||||
|  | 
 | ||||||
|  | ##### Declaring account types | ||||||
|  | 
 | ||||||
|  | Generally, to make these reports work you should declare your | ||||||
|  | top-level accounts and their types,  | ||||||
|  | using [account directives](#declaring-accounts)  | ||||||
|  | with `type:` [tags](journal.html#tags). | ||||||
|  | 
 | ||||||
|  | The tag's value should be one of: | ||||||
|  | `Asset`, `Liability`, `Equity`, `Revenue`, `Expense`, `Cash`, | ||||||
|  | `A`, `L`, `E`, `R`, `X`, `C` (all case insensitive). | ||||||
|  | The type is inherited by all subaccounts except where they override it. | ||||||
|  | Here's a complete example: | ||||||
|  | 
 | ||||||
|  | ```journal | ||||||
|  | account assets       ; type: Asset | ||||||
|  | account assets:bank  ; type: Cash | ||||||
|  | account assets:cash  ; type: Cash | ||||||
|  | account liabilities  ; type: Liability | ||||||
|  | account equity       ; type: Equity | ||||||
|  | account revenues     ; type: Revenue | ||||||
|  | account expenses     ; type: Expense | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| ##### Auto-detected account types | ##### Auto-detected account types | ||||||
| 
 | 
 | ||||||
| If you name your top-level accounts with some variation of | If you happen to use common english top-level account names, you may | ||||||
| `assets`, `liabilities`/`debts`, `equity`, `revenues`/`income`, or `expenses`, | not need to declare account types, as they will be detected | ||||||
| their types are detected automatically. | automatically using the following rules: | ||||||
| 
 | 
 | ||||||
| ##### Account types declared with tags | | If name matches [regular expression][]: | account type is: | ||||||
|  | |-----------------------------------------|----------------- | ||||||
|  | | `^assets?(:|$)`                         | `Asset` | ||||||
|  | | `^(debts?|liabilit(y|ies))(:|$)`        | `Liability` | ||||||
|  | | `^equity(:|$)`                          | `Equity` | ||||||
|  | | `^(income|revenue)s?(:|$)`              | `Revenue` | ||||||
|  | | `^expenses?(:|$)`                       | `Expense` | ||||||
|  | 
 | ||||||
|  | | If account type is `Asset` and name does not contain regular expression: | account type is: | ||||||
|  | |--------------------------------------------------------------------------|----------------- | ||||||
|  | | `(investment|receivable|:A/R|:fixed)`                                    | `Cash` | ||||||
|  | 
 | ||||||
|  | Even so, explicit declarations may be a good idea, for clarity and | ||||||
|  | predictability.  | ||||||
|  | 
 | ||||||
|  | ##### Interference from auto-detected account types | ||||||
|  | 
 | ||||||
|  | If you assign any account type, it's a good idea to assign all of | ||||||
|  | them, to prevent any confusion from mixing declared and auto-detected | ||||||
|  | types. Although it's unlikely to happen in real life, here's an | ||||||
|  | example: with the following journal, `balancesheetequity` shows | ||||||
|  | "liabilities" in both Liabilities and Equity sections. Declaring another | ||||||
|  | account as `type:Liability` would fix it: | ||||||
| 
 | 
 | ||||||
| More generally, you can declare an account's type with an account directive, |  | ||||||
| by writing a `type:` [tag](journal.html#tags) in a comment, followed by one of the words |  | ||||||
| `Asset`, `Liability`, `Equity`, `Revenue`, `Expense`, |  | ||||||
| or one of the letters `ALERX` (case insensitive): |  | ||||||
| ```journal | ```journal | ||||||
| account assets       ; type:Asset | account liabilities  ; type:Equity | ||||||
| account liabilities  ; type:Liability | 
 | ||||||
| account equity       ; type:Equity | 2020-01-01 | ||||||
| account revenues     ; type:Revenue |   assets        1 | ||||||
| account expenses     ; type:Expense |   liabilities   1 | ||||||
|  |   equity       -2 | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ##### Account types declared with account type codes | ##### Old account type syntax | ||||||
|  | 
 | ||||||
|  | In some hledger journals you might instead see this old syntax (the | ||||||
|  | letters ALERX, separated from the account name by two or more spaces); | ||||||
|  | this is deprecated and may be removed soon: | ||||||
| 
 | 
 | ||||||
| Or, you can write one of those letters separated from the account name by two or more spaces, |  | ||||||
| but this should probably be considered deprecated as of hledger 1.13: |  | ||||||
| ```journal | ```journal | ||||||
| account assets       A | account assets       A | ||||||
| account liabilities  L | account liabilities  L | ||||||
| @ -1126,18 +1177,15 @@ account revenues     R | |||||||
| account expenses     X | account expenses     X | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ##### Overriding auto-detected types |  | ||||||
| 
 | 
 | ||||||
| If you ever override the types of those auto-detected english account names mentioned above, | [balancesheet]: hledger.html#balancesheet | ||||||
| you might need to help the reports a bit. Eg: | [balancesheetequity]: hledger.html#balancesheetequity | ||||||
| ```journal | [cashflow]: hledger.html#cashflow | ||||||
| ; make "liabilities" not have the liability type - who knows why | [incomestatement]: hledger.html#incomestatement | ||||||
| account liabilities  ; type:E | [CCE]: https://en.wikipedia.org/wiki/Cash_and_cash_equivalents | ||||||
|  | [regular expression]: hledger.html#regular-expressions | ||||||
|  | [account equation]: https://en.wikipedia.org/wiki/Accounting_equation | ||||||
| 
 | 
 | ||||||
| ; we need to ensure some other account has the liability type, |  | ||||||
| ; otherwise balancesheet would still show "liabilities" under Liabilities |  | ||||||
| account -            ; type:L |  | ||||||
| ``` |  | ||||||
| 
 | 
 | ||||||
| #### Account display order | #### Account display order | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user