;doc: journal: reorg; rewrite transactions, simple & secondary dates

[ci skip]
This commit is contained in:
Simon Michael 2020-01-29 08:26:00 -08:00
parent c920bd3169
commit 150a74c5a0

View File

@ -26,10 +26,12 @@ ledger journal files as well. It's safe, and encouraged, to run both
hledger and ledger on the same journal file, eg to validate the results hledger and ledger on the same journal file, eg to validate the results
you're getting. you're getting.
You can use hledger without learning any more about this file; You can use hledger without learning any more about this file; just
just use the [add](#add) or [web](#web) commands to create and update it. use the [add](#add) or [web](#web) commands to create and update it.
Many users, though, also edit the journal file directly with a text editor, perhaps assisted by the helper modes for emacs or vim. Many users, though, also edit the journal file directly with a text
editor, perhaps assisted by the helper modes for emacs or vim.
<!--
Here's an example: Here's an example:
```journal ```journal
@ -60,6 +62,7 @@ Here's an example:
liabilities:debts $1 liabilities:debts $1
assets:bank:checking assets:bank:checking
``` ```
-->
Helper modes exist for popular text editors, which make working with Helper modes exist for popular text editors, which make working with
journal files easier. They add colour, formatting, tab completion, and journal files easier. They add colour, formatting, tab completion, and
@ -73,90 +76,90 @@ _man_({{
# FILE FORMAT # FILE FORMAT
}}) }})
Here's a description of each part of the file format
(and hledger's data model).
These are mostly in the order you'll use them, but in some cases
related concepts have been grouped together for easy reference,
or linked before they are introduced,
so feel free to skip over anything that looks unnecessary right now.
## Transactions ## Transactions
Transactions are movements of some quantity of commodities between named accounts. Transactions are the main unit of information in a journal file.
Each transaction is represented by a journal entry beginning with a [simple date](#simple-dates) in column 0. They represent events, typically a movement of some quantity of
This can be followed by any of the following, separated by spaces: commodities between two or more named accounts.
- (optional) a [status](#status) character (empty, `!`, or `*`) Each transaction is recorded as a journal entry, beginning with a
- (optional) a transaction code (any short number or text, enclosed in parentheses) [simple date](#simple-dates) in column 0. This can be followed by any
- (optional) a transaction description (any remaining text until end of line or a semicolon) of the following optional fields, separated by spaces:
- (optional) a transaction comment (any remaining text following a semicolon until end of line)
Then comes zero or more (but usually at least 2) indented lines representing... - a [status](#status) character (empty, `!`, or `*`)
- a code (any short number or text, enclosed in parentheses)
- a description (any remaining text until end of line or a semicolon)
- a comment (any remaining text following a semicolon until end of line,
and any following indented lines beginning with a semicolon)
- 0 or more indented *posting* lines, describing what was transferred
and the accounts involved.
## Postings Here's a simple journal file containing one transaction:
```journal
2008/01/01 income
assets:bank:checking $1
income:salary $-1
```
A posting is an addition of some amount to, or removal of some amount from, an account.
Each posting line begins with at least one space or tab (2 or 4 spaces is common), followed by:
- (optional) a [status](#status) character (empty, `!`, or `*`), followed by a space
- (required) an [account name](#account-names) (any text, optionally containing **single spaces**, until end of line or a double space)
- (optional) **two or more spaces** or tabs followed by an [amount](#amounts).
Positive amounts are being added to the account, negative amounts are being removed.
The amounts within a transaction must always sum up to zero.
As a convenience, one amount may be left blank; it will be inferred so as to balance the transaction.
Be sure to note the unusual two-space delimiter between account name and amount.
This makes it easy to write account names containing spaces.
But if you accidentally leave only one space (or tab) before the amount, the amount will be considered part of the account name.
## Dates ## Dates
### Simple dates ### Simple dates
Within a journal file, transaction dates use Y/M/D (or Y-M-D or Y.M.D) Dates in the journal file use *simple dates* format:
Leading zeros are optional. `YYYY-MM-DD` or `YYYY/MM/DD` or `YYYY.MM.DD`, with leading zeros optional.
The year may be omitted, in which case it will be inferred from the context - the current transaction, the default year set with a The year may be omitted, in which case it will be inferred from the context:
[default year directive](#default-year), or the current date when the command is run. the current transaction, the default year set with a [default year directive](#default-year),
Some examples: `2010/01/31`, `1/31`, `2010-01-31`, `2010.1.31`. or the current date when the command is run.
Some examples: `2010-01-31`, `2010/01/31`, `2010.1.31`, `1/31`.
(The UI also accepts simple dates, as well as the more flexible [smart
dates](hledger.html#smart-dates) documented in the hledger manual.)
### Secondary dates ### Secondary dates
Real-life transactions sometimes involve more than one date - eg the date Real-life transactions sometimes involve more than one date - eg the date
you write a cheque, and the date it clears in your bank. When you want to you write a cheque, and the date it clears in your bank. When you want to
model this, eg for more accurate balances, you can specify individual model this, eg for more accurate balances, you can specify individual
[posting dates](#posting-dates), which I recommend. Or, you can use the [posting dates](#posting-dates).
secondary dates (aka auxiliary/effective dates) feature, supported for compatibility
with Ledger.
A secondary date can be written after the primary date, separated by Or, you can use the older *secondary date* feature.
an equals sign. The primary date, on the left, is used by default; the (Ledger calls it auxiliary date or effective date.)
secondary date, on the right, is used when the `--date2` flag is But I would recommend avoiding this feature; posting dates are almost
specified (`--aux-date` or `--effective` also work). always clearer and simpler. We support it mainly for compatibility.
<!-- (Secondary dates require you to remember to use them consistently in -->
<!-- your journal, and to choose them or not for each report.) -->
A secondary date is written after the primary date, following an
equals sign. The primary date's year will be used if the year is
omitted. When running reports, the primary (left) date is used by
default, but with the `--date2` flag (or `--aux-date` or
`--effective`), the secondary (right) date will be used instead.
The meaning of secondary dates is up to you, but it's best to follow a The meaning of secondary dates is up to you, but it's best to follow a
consistent rule. Eg write the bank's clearing date as primary, and consistent rule. Eg "primary = the bank's clearing date, secondary =
when needed, the date the transaction was initiated as secondary. date the transaction was initiated, if different", as shown here:
Here's an example. Note that a secondary date will use the year of the
primary date if unspecified.
```journal ```journal
2010/2/23=2/19 movie ticket 2010/2/23=2/19 movie ticket
expenses:cinema $10 expenses:cinema $10
assets:checking assets:checking
``` ```
```shell ```shell
$ hledger register checking $ hledger register checking
2010-02-23 movie ticket assets:checking $-10 $-10 2010-02-23 movie ticket assets:checking $-10 $-10
``` ```
```shell ```shell
$ hledger register checking --date2 $ hledger register checking --date2
2010-02-19 movie ticket assets:checking $-10 $-10 2010-02-19 movie ticket assets:checking $-10 $-10
``` ```
Secondary dates require some effort; you must use them consistently in
your journal entries and remember whether to use or not use the
`--date2` flag for your reports. They are included in hledger for
Ledger compatibility, but posting dates are a more powerful and less
confusing alternative.
### Posting dates ### Posting dates
You can give individual postings a different date from their parent You can give individual postings a different date from their parent
@ -248,6 +251,141 @@ into separate fields for payee/payer name on the left (up to the first `|`) and
field on the right (after the first `|`). This may be worthwhile if you need to do more precise field on the right (after the first `|`). This may be worthwhile if you need to do more precise
[querying](hledger.html#queries) and [pivoting](hledger.html#pivoting) by payee or by note. [querying](hledger.html#queries) and [pivoting](hledger.html#pivoting) by payee or by note.
## Comments
Lines in the journal beginning with a semicolon (`;`) or hash (`#`) or
star (`*`) are comments, and will be ignored. (Star comments cause
org-mode nodes to be ignored, allowing emacs users to fold and navigate
their journals with org-mode or orgstruct-mode.)
You can attach comments to a transaction by writing them after the
description and/or indented on the following lines (before the
postings). Similarly, you can attach comments to an individual
posting by writing them after the amount and/or indented on the
following lines.
Transaction and posting comments must begin with a semicolon (`;`).
Some examples:
```journal
# a file comment
; also a file comment
comment
This is a multiline file comment,
which continues until a line
where the "end comment" string
appears on its own (or end of file).
end comment
2012/5/14 something ; a transaction comment
; the transaction comment, continued
posting1 1 ; a comment for posting 1
posting2
; a comment for posting 2
; another comment line for posting 2
; a file comment (because not indented)
```
You can also comment larger regions of a file using [`comment` and `end comment` directives](#comment-blocks).
## Tags
Tags are a way to add extra labels or labelled data to postings and transactions,
which you can then [search](hledger.html#queries) or [pivot](hledger.html#pivoting) on.
A simple tag is a word (which may contain hyphens) followed by a full colon,
written inside a transaction or posting [comment](#comments) line:
```journal
2017/1/16 bought groceries ; sometag:
```
Tags can have a value, which is the text after the colon, up to the next comma or end of line, with leading/trailing whitespace removed:
```journal
expenses:food $10 ; a-posting-tag: the tag value
```
Note this means hledger's tag values can not contain commas or newlines.
Ending at commas means you can write multiple short tags on one line, comma separated:
```journal
assets:checking ; a comment containing tag1:, tag2: some value ...
```
Here,
- "`a comment containing `" is just comment text, not a tag
- "`tag1`" is a tag with no value
- "`tag2`" is another tag, whose value is "`some value ...`"
Tags in a transaction comment affect the transaction and all of its postings,
while tags in a posting comment affect only that posting.
For example, the following transaction has three tags (`A`, `TAG2`, `third-tag`)
and the posting has four (those plus `posting-tag`):
```journal
1/1 a transaction ; A:, TAG2:
; third-tag: a third transaction tag, <- with a value
(a) $1 ; posting-tag:
```
Tags are like Ledger's
[metadata](http://ledger-cli.org/3.0/doc/ledger3.html#Metadata)
feature, except hledger's tag values are simple strings.
## Postings
A posting is an addition of some amount to, or removal of some amount from, an account.
Each posting line begins with at least one space or tab (2 or 4 spaces is common), followed by:
- (optional) a [status](#status) character (empty, `!`, or `*`), followed by a space
- (required) an [account name](#account-names) (any text, optionally containing **single spaces**, until end of line or a double space)
- (optional) **two or more spaces** or tabs followed by an [amount](#amounts).
Positive amounts are being added to the account, negative amounts are being removed.
The amounts within a transaction must always sum up to zero.
As a convenience, one amount may be left blank; it will be inferred so as to balance the transaction.
Be sure to note the unusual two-space delimiter between account name and amount.
This makes it easy to write account names containing spaces.
But if you accidentally leave only one space (or tab) before the amount, the amount will be considered part of the account name.
### Virtual Postings
A posting with a parenthesised account name is called a *virtual posting*
or *unbalanced posting*, which means it is exempt from the usual rule
that a transaction's postings must balance add up to zero.
This is not part of double entry accounting, so you might choose to
avoid this feature. Or you can use it sparingly for certain special
cases where it can be convenient. Eg, you could set opening balances
without using a balancing equity account:
```journal
1/1 opening balances
(assets:checking) $1000
(assets:savings) $2000
```
A posting with a bracketed account name is called a *balanced virtual
posting*. The balanced virtual postings in a transaction must add up
to zero (separately from other postings). Eg:
```journal
1/1 buy food with cash, update budget envelope subaccounts, & something else
assets:cash $-10 ; <- these balance
expenses:food $7 ; <-
expenses:food $3 ; <-
[assets:checking:budget:food] $-10 ; <- and these balance
[assets:checking:available] $10 ; <-
(something:else) $5 ; <- not required to balance
```
Ordinary non-parenthesised, non-bracketed postings are called *real postings*.
You can exclude virtual postings from reports with the `-R/--real`
flag or `real:1` query.
## Account names ## Account names
Account names typically have several parts separated by a full colon, from Account names typically have several parts separated by a full colon, from
@ -357,41 +495,73 @@ or when an amountless posting is balanced using a price's commodity,
or when -V is used.) If you find this causing problems, use a or when -V is used.) If you find this causing problems, use a
commodity directive to set the display format. commodity directive to set the display format.
## Virtual Postings ## Transaction prices
A posting with a parenthesised account name is called a *virtual posting* Within a transaction, you can note an amount's price in another commodity.
or *unbalanced posting*, which means it is exempt from the usual rule This can be used to document the cost (in a purchase) or selling price (in a sale).
that a transaction's postings must balance (add up to zero). For example, transaction prices are useful to record purchases of a foreign currency.
Note transaction prices are fixed at the time of the transaction, and do not change over time.
See also [market prices](#market-prices), which represent prevailing exchange rates on a certain date.
This is not part of double entry accounting, so you might choose to There are several ways to record a transaction price:
avoid this feature. Or you can use it sparingly for certain special
cases where it can be convenient. Eg, you could set opening balances
without using a balancing equity account:
```journal 1. Write the price per unit, as `@ UNITPRICE` after the amount:
1/1 opening balances
(assets:checking) $1000 ```journal
(assets:savings) $2000 2009/1/1
assets:euros €100 @ $1.35 ; one hundred euros purchased at $1.35 each
assets:dollars ; balancing amount is -$135.00
```
2. Write the total price, as `@@ TOTALPRICE` after the amount:
```journal
2009/1/1
assets:euros €100 @@ $135 ; one hundred euros purchased at $135 for the lot
assets:dollars
```
3. Specify amounts for all postings, using exactly two commodities,
and let hledger infer the price that balances the transaction:
```journal
2009/1/1
assets:euros €100 ; one hundred euros purchased
assets:dollars $-135 ; for $135
```
(Ledger users: Ledger uses a different [syntax](http://ledger-cli.org/3.0/doc/ledger3.html#Fixing-Lot-Prices)
for fixed prices, `{=UNITPRICE}`, which hledger currently ignores).
Use the [`-B/--cost`](hledger.html#reporting-options) flag to convert
amounts to their transaction price's commodity, if any.
(mnemonic: "B" is from "cost Basis", as in Ledger).
Eg here is how -B affects the balance report for the example above:
```shell
$ hledger bal -N --flat
$-135 assets:dollars
€100 assets:euros
$ hledger bal -N --flat -B
$-135 assets:dollars
$135 assets:euros # <- the euros' cost
``` ```
A posting with a bracketed account name is called a *balanced virtual Note -B is sensitive to the order of postings when a transaction price is inferred:
posting*. The balanced virtual postings in a transaction must add up the inferred price will be in the commodity of the last amount.
to zero (separately from other postings). Eg: So if example 3's postings are reversed, while the transaction
is equivalent, -B shows something different:
```journal ```journal
1/1 buy food with cash, update budget envelope subaccounts, & something else 2009/1/1
assets:cash $-10 ; <- these balance assets:dollars $-135 ; 135 dollars sold
expenses:food $7 ; <- assets:euros €100 ; for 100 euros
expenses:food $3 ; <- ```
[assets:checking:budget:food] $-10 ; <- and these balance ```shell
[assets:checking:available] $10 ; <- $ hledger bal -N --flat -B
(something:else) $5 ; <- not required to balance €-100 assets:dollars # <- the dollars' selling price
€100 assets:euros
``` ```
Ordinary non-parenthesised, non-bracketed postings are called *real postings*.
You can exclude virtual postings from reports with the `-R/--real`
flag or `real:1` query.
## Balance Assertions ## Balance Assertions
@ -585,156 +755,6 @@ $ hledger print --explicit
(a) $1 @ €2 = $1 @ €2 (a) $1 @ €2 = $1 @ €2
``` ```
## Transaction prices
Within a transaction, you can note an amount's price in another commodity.
This can be used to document the cost (in a purchase) or selling price (in a sale).
For example, transaction prices are useful to record purchases of a foreign currency.
Note transaction prices are fixed at the time of the transaction, and do not change over time.
See also [market prices](#market-prices), which represent prevailing exchange rates on a certain date.
There are several ways to record a transaction price:
1. Write the price per unit, as `@ UNITPRICE` after the amount:
```journal
2009/1/1
assets:euros €100 @ $1.35 ; one hundred euros purchased at $1.35 each
assets:dollars ; balancing amount is -$135.00
```
2. Write the total price, as `@@ TOTALPRICE` after the amount:
```journal
2009/1/1
assets:euros €100 @@ $135 ; one hundred euros purchased at $135 for the lot
assets:dollars
```
3. Specify amounts for all postings, using exactly two commodities,
and let hledger infer the price that balances the transaction:
```journal
2009/1/1
assets:euros €100 ; one hundred euros purchased
assets:dollars $-135 ; for $135
```
(Ledger users: Ledger uses a different [syntax](http://ledger-cli.org/3.0/doc/ledger3.html#Fixing-Lot-Prices)
for fixed prices, `{=UNITPRICE}`, which hledger currently ignores).
Use the [`-B/--cost`](hledger.html#reporting-options) flag to convert
amounts to their transaction price's commodity, if any.
(mnemonic: "B" is from "cost Basis", as in Ledger).
Eg here is how -B affects the balance report for the example above:
```shell
$ hledger bal -N --flat
$-135 assets:dollars
€100 assets:euros
$ hledger bal -N --flat -B
$-135 assets:dollars
$135 assets:euros # <- the euros' cost
```
Note -B is sensitive to the order of postings when a transaction price is inferred:
the inferred price will be in the commodity of the last amount.
So if example 3's postings are reversed, while the transaction
is equivalent, -B shows something different:
```journal
2009/1/1
assets:dollars $-135 ; 135 dollars sold
assets:euros €100 ; for 100 euros
```
```shell
$ hledger bal -N --flat -B
€-100 assets:dollars # <- the dollars' selling price
€100 assets:euros
```
## Comments
Lines in the journal beginning with a semicolon (`;`) or hash (`#`) or
star (`*`) are comments, and will be ignored. (Star comments cause
org-mode nodes to be ignored, allowing emacs users to fold and navigate
their journals with org-mode or orgstruct-mode.)
You can attach comments to a transaction by writing them after the
description and/or indented on the following lines (before the
postings). Similarly, you can attach comments to an individual
posting by writing them after the amount and/or indented on the
following lines.
Transaction and posting comments must begin with a semicolon (`;`).
Some examples:
```journal
# a file comment
; also a file comment
comment
This is a multiline file comment,
which continues until a line
where the "end comment" string
appears on its own (or end of file).
end comment
2012/5/14 something ; a transaction comment
; the transaction comment, continued
posting1 1 ; a comment for posting 1
posting2
; a comment for posting 2
; another comment line for posting 2
; a file comment (because not indented)
```
You can also comment larger regions of a file using [`comment` and `end comment` directives](#comment-blocks).
## Tags
Tags are a way to add extra labels or labelled data to postings and transactions,
which you can then [search](hledger.html#queries) or [pivot](hledger.html#pivoting) on.
A simple tag is a word (which may contain hyphens) followed by a full colon,
written inside a transaction or posting [comment](#comments) line:
```journal
2017/1/16 bought groceries ; sometag:
```
Tags can have a value, which is the text after the colon, up to the next comma or end of line, with leading/trailing whitespace removed:
```journal
expenses:food $10 ; a-posting-tag: the tag value
```
Note this means hledger's tag values can not contain commas or newlines.
Ending at commas means you can write multiple short tags on one line, comma separated:
```journal
assets:checking ; a comment containing tag1:, tag2: some value ...
```
Here,
- "`a comment containing `" is just comment text, not a tag
- "`tag1`" is a tag with no value
- "`tag2`" is another tag, whose value is "`some value ...`"
Tags in a transaction comment affect the transaction and all of its postings,
while tags in a posting comment affect only that posting.
For example, the following transaction has three tags (`A`, `TAG2`, `third-tag`)
and the posting has four (those plus `posting-tag`):
```journal
1/1 a transaction ; A:, TAG2:
; third-tag: a third transaction tag, <- with a value
(a) $1 ; posting-tag:
```
Tags are like Ledger's
[metadata](http://ledger-cli.org/3.0/doc/ledger3.html#Metadata)
feature, except hledger's tag values are simple strings.
## Directives ## Directives
A directive is a line in the journal beginning with a special keyword, A directive is a line in the journal beginning with a special keyword,