Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simpler conversion account with --infer-equity #2262

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions hledger-lib/Hledger/Data/Journal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@ module Hledger.Data.Journal (
journalAccountTypes,
journalAddAccountTypes,
journalPostingsAddAccountTags,
defaultConversionAccount,
-- journalPrices,
journalConversionAccount,
journalConversionAccounts,
-- * Misc
canonicalStyleFrom,

nulljournal,
journalConcat,
journalNumberTransactions,
Expand Down
21 changes: 17 additions & 4 deletions hledger-lib/Hledger/Data/JournalChecks.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ journalCheckAccounts :: Journal -> Either String ()
journalCheckAccounts j = mapM_ checkacct (journalPostings j)
where
checkacct p@Posting{paccount=a}
| a `elem` journalAccountNamesDeclared j = Right ()
| a `elem` declaredaccounts = Right ()
| otherwise = Left $ printf (unlines [
"%s:%d:"
,"%s"
Expand All @@ -67,11 +67,24 @@ journalCheckAccounts j = mapM_ checkacct (journalPostings j)
,"Consider adding an account directive. Examples:"
,""
,"account %s"
,"account %s ; type:A ; (L,E,R,X,C,V)"
]) f l ex (show a) a a
]) f l ex (show a) a
where
declaredaccounts = journalAccountNamesDeclared j <> builtinAccounts
(f,l,_mcols,ex) = makePostingAccountErrorExcerpt p

-- | Hard coded account names in hledger, which need not be declared for `hledger check accounts`.
-- Keep synced with check-accounts.test, hledger manual.
builtinAccounts = [
defaultConversionAccount -- equity:conversion, the account used by --infer-equity by default
]
-- The following accounts names are also special, in that they are recognised as conversion equity accounts
-- by transactionInferCostsFromEquity; but these are not auto-declared for hledger check accounts.
-- equity:trade
-- equity:trades
-- equity:trading
-- and any subaccounts of these or defaultConversionAccount.


-- | Check all balance assertions in the journal and return an error message if any of them fail.
-- (Technically, this also tries to balance the journal and can return balancing failure errors;
-- ensure the journal is already balanced (with journalBalanceTransactions) to avoid this.)
Expand Down Expand Up @@ -215,7 +228,7 @@ journalCheckTags j = do
,"tag %s"
])

-- | Tag names which have special significance to hledger.
-- | Tag names which have special significance to hledger, and need not be declared for `hledger check tags`.
-- Keep synced with check-tags.test and hledger manual > Special tags.
builtinTags = [
"date" -- overrides a posting's date
Expand Down
11 changes: 3 additions & 8 deletions hledger-lib/Hledger/Data/Posting.hs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ import Data.Foldable (asum)
import Data.Function ((&))
import qualified Data.Map as M
import Data.Maybe (fromMaybe, isJust, mapMaybe)
import Data.List (sort, union)
import Data.List (union)
#if !MIN_VERSION_base(4,20,0)
import Data.List (foldl')
#endif
Expand Down Expand Up @@ -475,17 +475,15 @@ postingAddInferredEquityPostings verbosetags equityAcct p
| otherwise = p{ ptags = ("_cost-matched","") : ptags p }
conversionPostings amt = case acost amt of
Nothing -> []
Just _ -> [ cp{ paccount = accountPrefix <> amtCommodity
Just _ -> [ cp{ paccount = equityAcct
, pamount = mixedAmount . negate $ amountStripCost amt
}
, cp{ paccount = accountPrefix <> costCommodity
, cp{ paccount = equityAcct
, pamount = mixedAmount cost
}
]
where
cost = amountCost amt
amtCommodity = commodity amt
costCommodity = commodity cost
cp = p{ pcomment = pcomment p & (if verbosetags then (`commentAddTag` ("generated-posting","conversion")) else id)
, ptags =
("_conversion-matched","") : -- implementation-specific internal tag, not for users
Expand All @@ -494,9 +492,6 @@ postingAddInferredEquityPostings verbosetags equityAcct p
, pbalanceassertion = Nothing
, poriginal = Nothing
}
accountPrefix = mconcat [ equityAcct, ":", T.intercalate "-" $ sort [amtCommodity, costCommodity], ":"]
-- Take the commodity of an amount and collapse consecutive spaces to a single space
commodity = T.unwords . filter (not . T.null) . T.words . acommodity

-- | Make a market price equivalent to this posting's amount's unit
-- price, if any.
Expand Down
25 changes: 11 additions & 14 deletions hledger/hledger.m4.md
Original file line number Diff line number Diff line change
Expand Up @@ -714,9 +714,7 @@ hledger will try adjust your account names, if needed, to
[Beancount account names](https://beancount.github.io/docs/beancount_language_syntax.html#accounts),
by capitalising, replacing unsupported characters with `-`, and
prepending `B` to parts which don't begin with a letter or digit.
(It's possible for this to convert distinct hledger account names to the same beancount name.
Eg, hledger's automatic equity conversion accounts can have currency symbols in their name,
so `equity:conversion:$-€` becomes `equity:conversion:B---`.)
(It's possible for this to convert distinct hledger account names to the same beancount name.)

In addition, you must ensure that the top level account names are `Assets`, `Liabilities`, `Equity`, `Income`, and `Expenses`,
which Beancount requires.
Expand Down Expand Up @@ -1980,7 +1978,8 @@ Some notes:
- The account directive's scope is "whole file and below" (see [directives](#directives)). This means it affects all of the current file, and any files it includes, but not parent or sibling files. The position of account directives within the file does not matter, though it's usual to put them at the top.
- Accounts can only be declared in `journal` files, but will affect [included](#include-directive) files of all types.
- It's currently not possible to declare "all possible subaccounts" with a wildcard; every account posted to must be declared.
- If you use the [--infer-equity](#inferring-equity-conversion-postings) flag, you will also need declarations for the account names it generates.
- The account [--infer-equity](#inferring-equity-conversion-postings) uses by default - equity:conversion - need not be declared.
(If you configure a different conversion account, that will need to be declared.)

### Account display order

Expand Down Expand Up @@ -2049,7 +2048,8 @@ account expenses ; type: X
account assets:bank ; type: C
account assets:cash ; type: C

account equity:conversion ; type: V
; if you want to override the conversion account name, which is equity:conversion by default:
;account equity:exchange ; type: V
```

[five main account types]: https://en.wikipedia.org/wiki/Chart_of_accounts#Types_of_accounts
Expand Down Expand Up @@ -5709,15 +5709,12 @@ $ hledger print --infer-equity
2022-01-01
assets:dollars $-135
assets:euros €100 @ $1.35
equity:conversion:$-€:€ €-100
equity:conversion:$-€:$ $135.00
equity:conversion €-100
equity:conversion $135.00
```

The equity account names will be "equity:conversion:A-B:A" and "equity:conversion:A-B:B"
where A is the alphabetically first commodity symbol.
You can customise the "equity:conversion" part by declaring an account with the `V`/`Conversion` [account type](#account-types).

Note you will need to add [account declarations](#account-error-checking) for these to your journal, if you use `check accounts` or `check --strict`.
`--infer-equity` will use the "equity:conversion" account by default (and you don't have to declare this account for `check accounts` or `check --strict`).
If you declare some other account with the `V`/`Conversion` [account type](#account-types), it will use that instead.

## Combining costs and equity conversion postings

Expand Down Expand Up @@ -5762,9 +5759,9 @@ It will infer costs only in transactions with:
Equity conversion accounts are:

- any accounts declared with account type `V`/`Conversion`, or their subaccounts
- otherwise, accounts named `equity:conversion`, `equity:trade`, or `equity:trading`, or their subaccounts.
- otherwise, accounts named `equity:conversion`, `equity:trade`, `equity:trades`, `equity:trading`, or any subaccounts of these.

And multiple such four-posting groups can coexist within a single transaction.
Multiple such four-posting groups can coexist within a single transaction.
When `--infer-costs` fails, it does not infer a cost in that transaction, and does not raise an error (ie, it infers costs where it can).

Reading variant 5 journal entries, combining cost notation and equity postings, has all the same requirements.
Expand Down
24 changes: 24 additions & 0 deletions hledger/test/check-accounts.test
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,27 @@ $ hledger -f- --auto check accounts
$ hledger -f- --auto --strict bal
>2 /account "b" has not been declared/
>=1

# ** 7. The default equity:conversion account used by --infer-equity does not need to be declared for check accounts.
<
account a
account b

2024-01-01
a 1A
b -1B

$ hledger -f- check accounts --infer-equity

# ** 8. It does not need to be declared, even without --infer-equity, and even if a different conversion account is declared. (For simplicity.)
<
account a
account b
account equity ; type:V

2024-01-01
a 1A
b -1B
equity:conversion 0

$ hledger -f- check accounts
1 change: 0 additions & 1 deletion hledger/test/errors/accounts.test
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ account "a" has not been declared.
Consider adding an account directive. Examples:

account a
account a ; type:A ; \(L,E,R,X,C,V\)

/
>>>= 1
12 changes: 6 additions & 6 deletions hledger/test/journal/costs.test
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ $ hledger -f- print --explicit --cost
$ hledger -f- print --infer-equity --verbose-tags
2011-01-01
expenses:foreign currency €100 @ $1.35
equity:conversion:$-€:€ €-100 ; generated-posting: conversion
equity:conversion:$-€:$ $135.00 ; generated-posting: conversion
equity:conversion €-100 ; generated-posting: conversion
equity:conversion $135.00 ; generated-posting: conversion
assets $-135.00

>=0
Expand Down Expand Up @@ -142,8 +142,8 @@ $ hledger -f - balance --value=cost,XXX
$ hledger -f - balance --infer-equity
10£ a
-16$ b
16$ equity:conversion:$-£:$
-10£ equity:conversion:$-£:£
16$
-10£ equity:conversion
--------------------
0
>=0
Expand Down Expand Up @@ -366,8 +366,8 @@ account equity:trades ; type:V
$ hledger -f- print --infer-equity
2011-01-01
expenses:foreign currency €100 @ $1.35
equity:trades:$-€:€ €-100
equity:trades:$-€:$ $135.00
equity:trades €-100
equity:trades $135.00
assets

>=0
Expand Down