Skip to content

Commit

Permalink
imp:close: add tags, with optional custom value, for easier matching/…
Browse files Browse the repository at this point in the history
…exclusion [#2151]

They are `balances:` for assertion transactions,
`retain:` for retained earnings transactions,
and `start` for opening/closing transactions.

And some --help cleanups.
  • Loading branch information
simonmichael committed Jan 21, 2024
1 parent 29ac554 commit c2ce1c2
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 35 deletions.
6 changes: 5 additions & 1 deletion hledger-lib/Hledger/Data/JournalChecks.hs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,11 @@ journalCheckTags j = do
-- | Tag names which have special significance to hledger.
builtinTags = [
"type" -- declares an account's type
,"t" -- generated by timedot letters notation
,"t" -- declares the (user defined, single letter) type of a 15m unit of time parsed from timedot format
-- generated by close
,"balances" -- balance assertions transaction
,"retain" -- retain earnings transaction
,"start" -- opening balances, closing balances or balance assignment transaction
-- optionally generated on periodic transactions and auto postings
,"generated-transaction"
,"generated-posting"
Expand Down
46 changes: 33 additions & 13 deletions hledger/Hledger/Cli/Commands/Close.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,25 @@ import Hledger
import Hledger.Cli.CliOptions
import Safe (lastDef, readMay)

defretaindesc = "retain earnings"
defclosedesc = "closing balances"
defopendesc = "opening balances"
defretainacct = "equity:retained earnings"
defretaindesc = "retain earnings"

defcloseacct = "equity:opening/closing balances"
defretainacct = "equity:retained earnings"

closemode = hledgerCommandMode
$(embedFileRelative "Hledger/Cli/Commands/Close.txt")
[flagNone ["close"] (setboolopt "close") "show a closing transaction (default)"
,flagNone ["open"] (setboolopt "open") "show an opening transaction"
,flagNone ["migrate"] (setboolopt "migrate") "show both closing and opening transactions"
,flagNone ["assert"] (setboolopt "assert") "show closing balance assertions"
,flagNone ["assign"] (setboolopt "assign") "show opening balance assignments (an alternative to closing/opening transactions)"
,flagNone ["retain"] (setboolopt "retain") "show a retain earnings transaction (for RX accounts)"
[flagOpt "" ["migrate"] (\s opts -> Right $ setopt "migrate" s opts) "NEW" ("show closing and opening transactions,"
<> " for Asset and Liability accounts by default,"
<> " tagged for easy matching,"
<> " with NEW (eg a new year) as tag value."
)
,flagOpt "" ["close"] (\s opts -> Right $ setopt "close" s opts) "NEW" "(default) show a closing transaction"
,flagOpt "" ["open"] (\s opts -> Right $ setopt "open" s opts) "NEW" "show an opening transaction"
,flagOpt "" ["assign"] (\s opts -> Right $ setopt "assign" s opts) "NEW" "show opening balance assignments"
,flagOpt "" ["assert"] (\s opts -> Right $ setopt "assert" s opts) "NEW" "show closing balance assertions"
,flagOpt "" ["retain"] (\s opts -> Right $ setopt "retain" s opts) "NEW" "show a retain earnings transaction, for Revenue and Expense accounts by default"
,flagNone ["explicit","x"] (setboolopt "explicit") "show all amounts explicitly"
,flagNone ["show-costs"] (setboolopt "show-costs") "show amounts with different costs separately"
,flagNone ["interleaved"] (setboolopt "interleaved") "show source and destination postings together"
Expand All @@ -52,10 +57,11 @@ closemode = hledgerCommandMode
,flagReq ["open-from"] (\s opts -> Right $ setopt "open-acct" s opts) "ACCT" "old spelling of --open-acct"
]
)
([], Just $ argsFlag "[--close | --open | --migrate | --retain] [ACCTQUERY]")
([], Just $ argsFlag "[--migrate|--close|--open|--assign|--assert|--retain] [ACCTQUERY]")

-- | The close command's mode. Really a subcommand.
data CloseMode = Migrate | Close | Open | Assert | Assign | Retain deriving (Eq,Show,Read,Enum)
-- | The close command's mode (subcommand).
-- The code depends on these spellings.
data CloseMode = Migrate | Close | Open | Assign | Assert | Retain deriving (Eq,Show,Read)

-- | Pick the rightmost flag spelled like a CloseMode (--migrate, --close, --open, etc), or default to Close.
closeModeFromRawOpts :: RawOpts -> CloseMode
Expand All @@ -71,6 +77,16 @@ close copts@CliOpts{rawopts_=rawopts, reportspec_=rspec0} j = do
closeacct = T.pack $ fromMaybe defcloseacct_ $ maybestringopt "close-acct" rawopts
openacct = maybe closeacct T.pack $ maybestringopt "open-acct" rawopts

-- For easy matching and exclusion, a recognisable tag is added to all generated transactions,
-- with the mode flag's argument if any (NEW, eg a new year number) as its argument.
comment = T.pack $ if
| mode_ == Assert -> "balances:" <> flagval
| mode_ == Retain -> "retain:" <> flagval
| otherwise -> "start:" <> flagval
where
flagval = fromMaybe "" $ maybestringopt modeflag rawopts
where modeflag = lowercase $ show mode_

ropts = (_rsReportOpts rspec0){balanceaccum_=Historical, accountlistmode_=ALFlat}
rspec1 = setDefaultConversionOp NoConversionOp rspec0{_rsReportOpts=ropts}

Expand Down Expand Up @@ -112,7 +128,9 @@ close copts@CliOpts{rawopts_=rawopts, reportspec_=rspec0} j = do
-- the closing (balance-asserting or balance-zeroing) transaction
mclosetxn
| mode_ `notElem` [Migrate, Close, Assert, Retain] = Nothing
| otherwise = Just nulltransaction{tdate=closedate, tdescription=closedesc, tpostings=closeps}
| otherwise = Just nulltransaction{
tdate=closedate, tdescription=closedesc, tcomment=comment, tpostings=closeps
}
where
closedesc = T.pack $ fromMaybe defclosedesc_ $ maybestringopt "close-desc" rawopts
where defclosedesc_ = if mode_ == Retain then defretaindesc else defclosedesc
Expand Down Expand Up @@ -169,7 +187,9 @@ close copts@CliOpts{rawopts_=rawopts, reportspec_=rspec0} j = do
-- the opening (balance-assigning or balance-unzeroing) transaction
mopentxn
| mode_ `notElem` [Migrate, Open, Assign] = Nothing
| otherwise = Just nulltransaction{tdate=opendate, tdescription=opendesc, tpostings=openps}
| otherwise = Just nulltransaction{
tdate=opendate, tdescription=opendesc, tcomment=comment, tpostings=openps
}
where
opendesc = T.pack $ fromMaybe defopendesc $ maybestringopt "open-desc" rawopts
openps
Expand Down
17 changes: 11 additions & 6 deletions hledger/Hledger/Cli/Commands/Close.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ You can append or copy these to your journal file(s) when you are happy with how

_FLAGS

<!-- related: -->

`close` currently has six modes, selected by a single mode flag:

### close --migrate
Expand All @@ -21,7 +19,7 @@ and an opposite "opening balances" transaction that restores them again.
The balancing account will be `equity:opening/closing balances` (or another specified by `--close-acct` or `--open-acct`).

This is useful when migrating balances to a new journal file at the start of a new year.
Essentially, you run `hledger close --migrate -e NEWYEAR`
Essentially, you run `hledger close --migrate=NEWYEAR -e NEWYEAR`
and then copy the closing transaction to the end of the old file
and the opening transaction to the start of the new file.
The opening transaction sets correct starting balances in the new file when it is used alone,
Expand All @@ -34,6 +32,11 @@ Eg if you want to include equity, you can add `assets liabilities equity` or [`t
(The balancing account is always excluded.)
Revenues and expenses usually are not migrated to a new file directly; see `--retain` below.

The generated transactions will have a `start:` tag, with its value set to
`--migrate`'s `NEW` argument if any, for easier matching or exclusion.
It's a good idea to provide a `NEW` argument, unique to the new file; the new year number is most often used.
The other modes behave similarly.

### close --close

This prints just the closing balances transaction of `--migrate`.
Expand All @@ -47,8 +50,8 @@ It is similar to [Ledger's equity command](https://ledger-cli.org/doc/ledger3.ht

### close --assert

This prints a "closing balances" transaction that just declares [balance assertions](#balance-assertions)
for the current balances without changing them.
This prints a "closing balances" transaction (with `balances:` tag),
that just declares [balance assertions](#balance-assertions) for the current balances without changing them.
It could be useful as documention and to guard against changes.

### close --assign
Expand All @@ -64,7 +67,8 @@ So `--migrate` is generally the best way to set to set balances in new files, [f
### close --retain

This is like `--close` with different defaults:
it prints a "retain earnings" transaction that transfers revenue and expense balances to `equity:retained earnings`.
it prints a "retain earnings" transaction (with `retain:` tag),
that transfers revenue and expense balances to `equity:retained earnings`.

This is a different kind of closing, called "retaining earnings" or "closing the books";
it is traditionally performed by businesses at the end of each accounting period,
Expand All @@ -81,6 +85,7 @@ In all modes, the following things can be overridden:
- the accounts to be closed/opened, with account query arguments
- the balancing account, with `--close-acct=ACCT` and/or `--open-acct=ACCT`
- the transaction descriptions, with `--close-desc=DESC` and `--open-desc=DESC`
- the transaction's tag value, with a `--MODE=NEW` option argument
- the closing/opening dates, with `-e OPENDATE`

By default, the closing date is yesterday, or the journal's end date, whichever is later;
Expand Down
3 changes: 3 additions & 0 deletions hledger/hledger.m4.md
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,9 @@ followed by a colon may work.
The following tag names are generated by hledger or have special significance to hledger,
so you may want to avoid using them yourself:

- `balances` -- a balance assertions transaction generated by close
- `retain` -- a retain earnings transaction generated by close
- `start` -- a opening balances, closing balances or balance assignment transaction generated by close
- `generated-transaction` -- a transaction generated by --forecast
- `generated-posting` -- a posting generated by --auto
- `modified` -- a transaction which has had postings added by --auto
Expand Down
30 changes: 15 additions & 15 deletions hledger/test/close.test
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

# ** 1. By default, closes ALE accounts, on the last day of the report period.
$ hledger close -f- -e 2017
2016-12-31 closing balances
2016-12-31 closing balances ; start:
assets:bank $-80 = $0
assets:cash $-10 = $0
liabilities $-25 = $0
Expand All @@ -30,7 +30,7 @@ $ hledger close -f- -e 2017

# ** 2. With --close, likewise.
$ hledger close -f- -e 2017 --close
2016-12-31 closing balances
2016-12-31 closing balances ; start:
assets:bank $-80 = $0
assets:cash $-10 = $0
liabilities $-25 = $0
Expand All @@ -40,21 +40,21 @@ $ hledger close -f- -e 2017 --close

# ** 3. With --retain, closes RX accounts.
$ hledger close -f- -e 2017 --retain
2016-12-31 retain earnings
2016-12-31 retain earnings ; retain:
expenses:sweets $-5 = $0
equity:retained earnings

>=0

# ** 4. With --migrate, opens and closes ALE.
$ hledger close -f- -p 2016 --migrate
2016-12-31 closing balances
2016-12-31 closing balances ; start:
assets:bank $-80 = $0
assets:cash $-10 = $0
liabilities $-25 = $0
equity:opening/closing balances

2017-01-01 opening balances
2017-01-01 opening balances ; start:
assets:bank $80 = $80
assets:cash $10 = $10
liabilities $25 = $25
Expand All @@ -64,7 +64,7 @@ $ hledger close -f- -p 2016 --migrate

# ** 5. With --open, opens ALE.
$ hledger close -f- -p 2016 --open
2017-01-01 opening balances
2017-01-01 opening balances ; start:
assets:bank $80 = $80
assets:cash $10 = $10
liabilities $25 = $25
Expand All @@ -74,7 +74,7 @@ $ hledger close -f- -p 2016 --open

# ** 6. -x makes all amounts explicit.
$ hledger close -f- -p 2016 -x
2016-12-31 closing balances
2016-12-31 closing balances ; start:
assets:bank $-80 = $0
assets:cash $-10 = $0
liabilities $-25 = $0
Expand All @@ -90,7 +90,7 @@ $ hledger close -f- -p 2016 -x
equity

$ hledger -f- close assets -p 2019 -x
2019-12-31 closing balances
2019-12-31 closing balances ; start:
assets -2A = 0A
equity:opening/closing balances 2A

Expand All @@ -100,7 +100,7 @@ $ hledger -f- close assets -p 2019 -x
# Only the last posting in each commodity gets a balance assertion (#1035).
# Balance assertion amounts do not have a price.
$ hledger -f- close assets -p 2019 --show-costs -x
2019-12-31 closing balances
2019-12-31 closing balances ; start:
assets -1A @ 1B
assets -1A @ 1C = 0A
equity:opening/closing balances 1A @ 1B
Expand All @@ -119,15 +119,15 @@ $ hledger -f- close assets -p 2019 --show-costs -x
(assets) 1A @ 2B

$ hledger -f- close assets -p 2019 -x
2019-12-31 closing balances
2019-12-31 closing balances ; start:
assets -2A = 0A
equity:opening/closing balances 2A

>=0

# ** 10. The same with costs preserved.
$ hledger -f- close assets -p 2019 --show-costs -x
2019-12-31 closing balances
2019-12-31 closing balances ; start:
assets -1A @ 1B
assets -1A @ 2B = 0A
equity:opening/closing balances 1A @ 1B
Expand Down Expand Up @@ -160,7 +160,7 @@ $ hledger -f- close assets -p 2019 --show-costs -x
liabilities:employer

$ hledger -f- close -p 2016 assets liabilities --show-costs -x
2016-12-31 closing balances
2016-12-31 closing balances ; start:
assets:bank -5,733.00 EUR = 0.00 EUR
liabilities:employer $-10,000.00
liabilities:employer $5,000.00 @ 0.93 EUR
Expand All @@ -177,7 +177,7 @@ $ hledger -f- close -p 2016 assets liabilities --show-costs -x
# (And balances with the same cost are not necessarily combined into
# a single posting. Eg the 5734 EUR above is 5733 EUR and 1 EUR below.)
$ hledger -f- close -p 2016 assets liabilities --interleaved --show-costs -x
2016-12-31 closing balances
2016-12-31 closing balances ; start:
assets:bank -5,733.00 EUR = 0.00 EUR
equity:opening/closing balances 5,733.00 EUR
liabilities:employer $-10,000.00
Expand Down Expand Up @@ -206,7 +206,7 @@ commodity AAA 0.00000000
expenses:banking $0.1280810

$ hledger -f- close -p 2019 assets --show-costs -x
2019-12-31 closing balances
2019-12-31 closing balances ; start:
assets:aaa AAA -510 = AAA 0
assets:usd $-49.50
assets:usd $49.3900010 @ AAA 10.3528243 = $0.0000000
Expand All @@ -218,7 +218,7 @@ $ hledger -f- close -p 2019 assets --show-costs -x

# ** 14. The same, without costs and with --interleaved.
$ hledger -f- close -p 2019 assets --interleaved -x
2019-12-31 closing balances
2019-12-31 closing balances ; start:
assets:aaa AAA -510 = AAA 0
equity:opening/closing balances AAA 510
assets:usd $-0.1099990 = $0.0000000
Expand Down

0 comments on commit c2ce1c2

Please sign in to comment.