mirror of
https://github.com/simonmichael/hledger.git
synced 2024-09-20 02:37:12 +03:00
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
|
||||
|
||||
-- | 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
|
||||
-- declared as Asset by account directives, or otherwise for
|
||||
-- accounts with names matched by the case-insensitive regular expression
|
||||
@ -369,12 +346,43 @@ journalProfitAndLossAccountQuery j = Or [journalRevenueAccountQuery j
|
||||
,journalExpenseAccountQuery j
|
||||
]
|
||||
|
||||
-- | A query for Cash (-equivalent) accounts in this journal (ie,
|
||||
-- accounts which appear on the cashflow statement.) This is currently
|
||||
-- hard-coded to be all the Asset accounts except for those with names
|
||||
-- containing the case-insensitive regular expression @(receivable|:A/R|:fixed)@.
|
||||
-- | A query for "Cash" (liquid asset) accounts in this journal (ie,
|
||||
-- accounts which appear on the cashflow statement.) This is the
|
||||
-- accounts declared to be Cash type, or if none of these are
|
||||
-- declared, the Asset accounts whose names do not contain the
|
||||
-- case-insensitive regular expression @(investment|receivable|:A/R|:fixed)@.
|
||||
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
|
||||
-- on the command.
|
||||
|
@ -121,6 +121,7 @@ data AccountType =
|
||||
| Equity
|
||||
| Revenue
|
||||
| Expense
|
||||
| Cash -- ^ a subtype of Asset - liquid assets to show in cashflow report
|
||||
deriving (Show,Eq,Ord,Data,Generic)
|
||||
|
||||
instance NFData AccountType
|
||||
|
@ -380,10 +380,12 @@ parseAccountTypeCode s =
|
||||
"r" -> Right Revenue
|
||||
"expense" -> Right Expense
|
||||
"x" -> Right Expense
|
||||
"cash" -> Right Cash
|
||||
"c" -> Right Cash
|
||||
_ -> Left err
|
||||
where
|
||||
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.
|
||||
addAccountDeclaration :: (AccountName,Text,[Tag]) -> JournalParser m ()
|
||||
|
@ -1087,37 +1087,88 @@ account ACCTNAME [ACCTTYPE] [;COMMENT]
|
||||
|
||||
#### Account types
|
||||
|
||||
hledger recognises five types (or classes) of account: Asset, Liability, Equity, Revenue, Expense.
|
||||
This is used by a few accounting-aware reports such as [balancesheet][], [incomestatement][] and [cashflow][].
|
||||
hledger recognises five main types of account,
|
||||
corresponding to the account classes in the [accounting equation][]:
|
||||
|
||||
[balancesheet]: hledger.html#balancesheet
|
||||
[cashflow]: hledger.html#cashflow
|
||||
[incomestatement]: hledger.html#incomestatement
|
||||
`Asset`, `Liability`, `Equity`, `Revenue`, `Expense`.
|
||||
|
||||
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
|
||||
|
||||
If you name your top-level accounts with some variation of
|
||||
`assets`, `liabilities`/`debts`, `equity`, `revenues`/`income`, or `expenses`,
|
||||
their types are detected automatically.
|
||||
If you happen to use common english top-level account names, you may
|
||||
not need to declare account types, as they will be detected
|
||||
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
|
||||
account assets ; type:Asset
|
||||
account liabilities ; type:Liability
|
||||
account equity ; type:Equity
|
||||
account revenues ; type:Revenue
|
||||
account expenses ; type:Expense
|
||||
account liabilities ; type:Equity
|
||||
|
||||
2020-01-01
|
||||
assets 1
|
||||
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
|
||||
account assets A
|
||||
account liabilities L
|
||||
@ -1126,18 +1177,15 @@ account revenues R
|
||||
account expenses X
|
||||
```
|
||||
|
||||
##### Overriding auto-detected types
|
||||
|
||||
If you ever override the types of those auto-detected english account names mentioned above,
|
||||
you might need to help the reports a bit. Eg:
|
||||
```journal
|
||||
; make "liabilities" not have the liability type - who knows why
|
||||
account liabilities ; type:E
|
||||
[balancesheet]: hledger.html#balancesheet
|
||||
[balancesheetequity]: hledger.html#balancesheetequity
|
||||
[cashflow]: hledger.html#cashflow
|
||||
[incomestatement]: hledger.html#incomestatement
|
||||
[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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user