Fix 'Wrong Currency conversion rate in Reports'
ClosedPublic

Authored by habacker on Nov 6 2017, 11:37 AM.

Details

Summary

Fix 'Wrong Currency conversion rate in Reports'

The root cause is that the conversion of reports value to the base
currency is done on grid entry date and not on transaction date.
The price on grid entry date may differ from the price on the transaction
date and results in unexpected sums.

BUG:385857
FIXED-IN:4.8.2

Test Plan
  • generated with appended test case

Diff Detail

Repository
R261 KMyMoney
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
habacker created this revision.Nov 6 2017, 11:37 AM
habacker edited the summary of this revision. (Show Details)Nov 6 2017, 12:29 PM
habacker updated this revision to Diff 21958.Nov 6 2017, 12:33 PM
  • fix commit message and doc wording
wojnilowicz requested changes to this revision.Nov 6 2017, 2:02 PM
wojnilowicz added a subscriber: wojnilowicz.
wojnilowicz added inline comments.
kmymoney/reports/pivottable.cpp
397–398

Is this used at all after your change? :)

kmymoney/reports/pivottable.h
151

Is there a case, in which conversion rate on grid entry date is important to use? I mean it seems like obvious bug that we're referring to entry date and not transaction date, as the second is essential for transaction and the first can be months away from the second.
In that case we shouldn't add another "if" but change the default behavior.

300

You're not using return value anywhere, so what do you need it for?

This revision now requires changes to proceed.Nov 6 2017, 2:02 PM
habacker updated this revision to Diff 22004.Nov 6 2017, 9:56 PM
  • make new approach the default way to convert grid values to base currency Using report grid entry date to convert values to base curreny does not make any sense
  • apply new approach to pivotabletest
habacker marked 2 inline comments as done.Nov 6 2017, 10:03 PM
habacker marked an inline comment as done.
wojnilowicz added inline comments.Nov 7 2017, 2:11 PM
kmymoney/reports/pivottable.cpp
963

I think that function is needed too because we need two approaches:

  1. convert every transaction (this function)
  2. convert only sum of transactions (the function you've written)

According to what you've written, the only problem with this function is that it takes entry date instead of transaction date for conversion rates.

habacker added inline comments.Nov 8 2017, 7:38 AM
kmymoney/reports/pivottable.cpp
963

This happens in the the pivotable class:

  1. Fetch related transactions

2,. Add relates split values, bugdet values and so on to the current grid entry. The current grid entry has a date derived from report settings e.g. for yearly report it is Jan 30, Feb 28, Mar 31. [1]

  1. After collecting the values convert the grid entry values based on the grid entry date, which may differ from the transaction date

After topic 2. the original transaction date is lost and only a sum based on the current grid entry date is available. I don't see how convertToBaseCurrency() could be able to convert a sum based on different single values without having each single value and without the transaction date of each single value. From my observation the conversion need to be done for each transaction before adding to the grid at topic 2., which is implemented in this patch.

wojnilowicz added inline comments.Nov 8 2017, 1:57 PM
kmymoney/reports/pivottable.cpp
963

What I see is that current convertToBaseCurrency has many loops and you want to replace that function with the one without loops, which I think is wrong. If we loose transaction date then that's bad, so maybe we should convert currency when transaction date is available.
I think your patch, in current form, may fix one issue and introduce another one, so it's not good neither.

habacker added inline comments.Nov 9 2017, 8:31 AM
kmymoney/reports/pivottable.cpp
963

... with the one without loops ...

If you display the patch with "show all content" or apply this patch to git master (I hope it fits) and take a look at the context, you will see that this function is called inside the loops adding data to grid before values are added to the report grid by calling assignCell(). [1]

If we loose transaction date then that's bad, so maybe we should convert currency when transaction date is available.

Which is only available in the loops mentioned at [1] and why the conversion is done there.

I think your patch, in current form, may fix one issue and introduce another one,

You are refering to that the conversion has been moved up in init() inside the initial loops and that the following calls may also need also conversions ? Or do you refering to something else ?

//
// Get forecast data
//
if (m_config_f.isIncludingForecast())
  calculateForecast();

//
//Insert Price data
//
if (m_config_f.isIncludingPrice())
  fillBasePriceUnit(ePrice);

//
//Insert Average Price data
//
if (m_config_f.isIncludingAveragePrice()) {
  fillBasePriceUnit(eActual);
  calculateMovingAverage();
}

//
// Collapse columns to match column type
//


if (m_config_f.columnPitch() > 1)
  collapseColumns();

//
// Calculate the running sums
// (for running sum reports only)
//

if (m_config_f.isRunningSum())
  calculateRunningSums();

//
// Calculate Moving Average
//
if (m_config_f.isIncludingMovingAverage())
  calculateMovingAverage();

//
// Calculate Budget Difference
//

if (m_config_f.isIncludingBudgetActuals())
  calculateBudgetDiff();

//
// Convert all values to the deep currency
//

convertToDeepCurrency();
wojnilowicz accepted this revision as: wojnilowicz.Nov 9 2017, 2:00 PM
wojnilowicz added inline comments.
kmymoney/reports/pivottable.cpp
963

Now I see it, sorry for introducing confusion. If it works for you, then it's OK for me.

This revision was automatically updated to reflect the committed changes.