imp:journal: match equity conversion postings more tolerantly (fix #2041)

Equity conversion postings and cost amounts were being matched up too
exactly, causing valid entries with redundant conversion postings and
costs to be rejected. Now the amounts are compared with the precision
(number of decimal places) used in the conversion posting's amount.
Eg, here the first posting's 209.60495 GEL cost is recognised as a
match for the third posting's -209.60 GEL, using the latter's two
digit precision:

    2023-01-01
        Assets               -84.01 USD @ 2.495 GEL  ; 209.60495 GEL
        Equity:Conversion     84.01 USD
        Equity:Conversion   -209.60 GEL
        Assets               209.60 GEL
This commit is contained in:
Simon Michael 2023-07-15 16:21:00 -10:00
parent d19690e5bd
commit c1c28aea3f
3 changed files with 24 additions and 25 deletions

View File

@ -375,7 +375,8 @@ transactionInferCostsFromEquity dryrun acctTypes t = first (annotateErrorWithTra
Just Amount{aprice=Just _} -> Left $ annotateWithPostings [p] "Conversion postings must not have a cost:" Just Amount{aprice=Just _} -> Left $ annotateWithPostings [p] "Conversion postings must not have a cost:"
Nothing -> Left $ annotateWithPostings [p] "Conversion postings must have a single-commodity amount:" Nothing -> Left $ annotateWithPostings [p] "Conversion postings must have a single-commodity amount:"
amountMatches a b = acommodity a == acommodity b && aquantity a == aquantity b -- Do these amounts look the same when compared at the first's display precision ?
amountsMatch a b = amountLooksZero $ amountSetPrecision (asprecision $ astyle a) $ a - b
-- Delete a posting from the indexed list of postings based on either its -- Delete a posting from the indexed list of postings based on either its
-- index or its posting amount. -- index or its posting amount.

View File

@ -4938,6 +4938,7 @@ The forecast period ends on:
- otherwise: 180 days (~6 months) from today. - otherwise: 180 days (~6 months) from today.
## Forecast troubleshooting ## Forecast troubleshooting
When --forecast is not doing what you expect, one of these tips should help: When --forecast is not doing what you expect, one of these tips should help:
- Remember to use the `--forecast` option. - Remember to use the `--forecast` option.
@ -4963,7 +4964,6 @@ You can generate budget goals and forecast transactions at the same time, from t
See also: [Budgeting and Forecasting](/budgeting-and-forecasting.html). See also: [Budgeting and Forecasting](/budgeting-and-forecasting.html).
# Cost reporting # Cost reporting
In some transactions - for example a currency conversion, or a purchase or sale of stock - one commodity is exchanged for another. In some transactions - for example a currency conversion, or a purchase or sale of stock - one commodity is exchanged for another.
@ -5144,7 +5144,6 @@ Downsides:
- The precise format of the journal entry becomes more important. - The precise format of the journal entry becomes more important.
If hledger can't detect and match up the cost and equity postings, it will give a transaction balancing error. If hledger can't detect and match up the cost and equity postings, it will give a transaction balancing error.
Amounts with repeating decimals are one of the things that can cause this ([#2051](https://github.com/simonmichael/hledger/issues/2051)).
- The [add](#add) command does not yet accept this kind of entry ([#2056](https://github.com/simonmichael/hledger/issues/2056)). - The [add](#add) command does not yet accept this kind of entry ([#2056](https://github.com/simonmichael/hledger/issues/2056)).
@ -5158,8 +5157,8 @@ It will infer costs only in transactions with:
- Two non-equity postings, in different commodities. - Two non-equity postings, in different commodities.
Their order is significant: the cost will be added to the first of them. Their order is significant: the cost will be added to the first of them.
- Two postings to equity conversion accounts, next to one another, which balance the two non-equity postings exactly. - Two postings to equity conversion accounts, next to one another, which balance the two non-equity postings.
(Perhaps over-exactly, as this is currently not limited by display precision - see #2051.) This balancing is checked to the same precision (number of decimal places) used in the conversion posting's amount.
Equity conversion accounts are: Equity conversion accounts are:
- any accounts declared with account type `V`/`Conversion`, or their subaccounts - any accounts declared with account type `V`/`Conversion`, or their subaccounts

View File

@ -605,23 +605,22 @@ $ hledger -f- print --infer-costs
>=0 >=0
# # when the *cost-basis* balance has exactly two commodities, both cost-less, # 41. Matching costful postings and conversion postings is done at the precision
# # infer a balancing cost for the first one in terms of the second. # of the conversion posting, tolerating smaller decimal differences (#2041).
# hledger -f - print # Here 84.01 * 2.495 GEL is 209.60495 GEL, which is considered to match 209.60 GEL
# <<< # because we use the latter's 2 digit precision.
# 2011/01/01 <
# expenses:foreign currency €100 2023/05/17 * Transfer
# assets $-135.00 Assets:BOG:Personal -84.01 USD @ 2.495 GEL
# misc $3.1 @ 2 bob Equity:Conversion 84.01 USD
# misc $-3.1 @ 2 bob Equity:Conversion -209.60 GEL
# misc £1 @@ 2 shekels Assets:BOG:Personal 209.60 GEL
# misc £-1 @@ 2 shekels
# >>> $ hledger -f- print
# 2011/01/01 2023-05-17 * Transfer
# expenses:foreign currency €100 @ $1.35 Assets:BOG:Personal -84.01 USD @ 2.495 GEL
# assets €-100 @ $1.35 Equity:Conversion 84.01 USD
# misc $3.1 @ 2 bob Equity:Conversion -209.60 GEL
# misc $-3.1 @ 2 bob Assets:BOG:Personal 209.60 GEL
# misc £1 @@ 2 shekels
# misc £-1 @@ 2 shekels >=
#