From c1c28aea3fe0d2d5904c166be65d56b782b7c444 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sat, 15 Jul 2023 16:21:00 -1000 Subject: [PATCH] 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 --- hledger-lib/Hledger/Data/Transaction.hs | 3 +- hledger/hledger.m4.md | 7 ++--- hledger/test/journal/costs.test | 39 ++++++++++++------------- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/hledger-lib/Hledger/Data/Transaction.hs b/hledger-lib/Hledger/Data/Transaction.hs index 111f24eb8..cbad985d8 100644 --- a/hledger-lib/Hledger/Data/Transaction.hs +++ b/hledger-lib/Hledger/Data/Transaction.hs @@ -375,7 +375,8 @@ transactionInferCostsFromEquity dryrun acctTypes t = first (annotateErrorWithTra 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:" - 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 -- index or its posting amount. diff --git a/hledger/hledger.m4.md b/hledger/hledger.m4.md index 0a395f375..2f392c256 100644 --- a/hledger/hledger.m4.md +++ b/hledger/hledger.m4.md @@ -4938,6 +4938,7 @@ The forecast period ends on: - otherwise: 180 days (~6 months) from today. ## Forecast troubleshooting + When --forecast is not doing what you expect, one of these tips should help: - 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). - # Cost reporting 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. 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)). @@ -5158,8 +5157,8 @@ It will infer costs only in transactions with: - Two non-equity postings, in different commodities. 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. - (Perhaps over-exactly, as this is currently not limited by display precision - see #2051.) +- Two postings to equity conversion accounts, next to one another, which balance the two non-equity postings. + This balancing is checked to the same precision (number of decimal places) used in the conversion posting's amount. Equity conversion accounts are: - any accounts declared with account type `V`/`Conversion`, or their subaccounts diff --git a/hledger/test/journal/costs.test b/hledger/test/journal/costs.test index e9f9ffa8a..4cd6cea19 100644 --- a/hledger/test/journal/costs.test +++ b/hledger/test/journal/costs.test @@ -605,23 +605,22 @@ $ hledger -f- print --infer-costs >=0 -# # when the *cost-basis* balance has exactly two commodities, both cost-less, -# # infer a balancing cost for the first one in terms of the second. -# hledger -f - print -# <<< -# 2011/01/01 -# expenses:foreign currency €100 -# assets $-135.00 -# misc $3.1 @ 2 bob -# misc $-3.1 @ 2 bob -# misc £1 @@ 2 shekels -# misc £-1 @@ 2 shekels -# >>> -# 2011/01/01 -# expenses:foreign currency €100 @ $1.35 -# assets €-100 @ $1.35 -# misc $3.1 @ 2 bob -# misc $-3.1 @ 2 bob -# misc £1 @@ 2 shekels -# misc £-1 @@ 2 shekels -# +# 41. Matching costful postings and conversion postings is done at the precision +# of the conversion posting, tolerating smaller decimal differences (#2041). +# 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. +< +2023/05/17 * Transfer + Assets:BOG:Personal -84.01 USD @ 2.495 GEL + Equity:Conversion 84.01 USD + Equity:Conversion -209.60 GEL + Assets:BOG:Personal 209.60 GEL + +$ hledger -f- print +2023-05-17 * Transfer + Assets:BOG:Personal -84.01 USD @ 2.495 GEL + Equity:Conversion 84.01 USD + Equity:Conversion -209.60 GEL + Assets:BOG:Personal 209.60 GEL + +>=