Skip to content

Commit

Permalink
Ignore fixing of gross value unit if there is no suitable
Browse files Browse the repository at this point in the history
  • Loading branch information
buchen committed May 31, 2022
1 parent 8b1c294 commit 3f854b2
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package name.abuchen.portfolio.model;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

import java.math.BigDecimal;

import org.junit.Test;

import name.abuchen.portfolio.model.Transaction.Unit;
import name.abuchen.portfolio.money.CurrencyUnit;
import name.abuchen.portfolio.money.Money;
import name.abuchen.portfolio.money.Values;

public class TransactionTest
{

@Test
public void testUnitValidityCheckWithSmallValues()
{
Transaction.Unit unit = new Transaction.Unit(Unit.Type.TAX,
Money.of(CurrencyUnit.EUR, Values.Amount.factorize(4.33)),
Money.of("JPY", Values.Amount.factorize(0.03)), //$NON-NLS-1$
BigDecimal.valueOf(131.53));

assertThat(unit.getAmount().getAmount(), is(Values.Amount.factorize(4.33)));
}

@Test(expected = IllegalArgumentException.class)
public void testUnitRoundingCheck()
{
new Transaction.Unit(Unit.Type.TAX,
Money.of(CurrencyUnit.EUR, Values.Amount.factorize(4.33)),
Money.of("JPY", Values.Amount.factorize(0.01)), //$NON-NLS-1$
BigDecimal.valueOf(131.53));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1396,13 +1396,13 @@ private static void addKeyToTaxonomyClassifications(Client client)
private static void copyClassificationKeys(Classification from, Classification to)
{
to.setKey(from.getKey());

Map<String, Classification> fromChildren = from.getChildren().stream()
.collect(Collectors.toMap(Classification::getName, Function.identity(), (r,l) -> null));
.collect(Collectors.toMap(Classification::getName, Function.identity(), (r, l) -> null));

Map<String, Classification> toChildren = to.getChildren().stream()
.collect(Collectors.toMap(Classification::getName, Function.identity(), (r,l) -> null));
.collect(Collectors.toMap(Classification::getName, Function.identity(), (r, l) -> null));

for (Map.Entry<String, Classification> entry : fromChildren.entrySet())
{
String key = entry.getKey();
Expand Down Expand Up @@ -1453,14 +1453,24 @@ private static void fixGrossValueUnit(Transaction tx)
// recalculate the unit to fix the gross value
}

Money updatedGrossValue = Money.of(grossValueUnit.getForex().getCurrencyCode(),
BigDecimal.valueOf(calculatedGrossValue.getAmount())
.divide(grossValueUnit.getExchangeRate(), Values.MC)
.setScale(0, RoundingMode.HALF_EVEN).longValue());
try
{
Money updatedGrossValue = Money.of(grossValueUnit.getForex().getCurrencyCode(),
BigDecimal.valueOf(calculatedGrossValue.getAmount())
.divide(grossValueUnit.getExchangeRate(), Values.MC)
.setScale(0, RoundingMode.HALF_EVEN).longValue());

tx.removeUnit(grossValueUnit);
tx.addUnit(new Unit(Unit.Type.GROSS_VALUE, calculatedGrossValue, updatedGrossValue,
grossValueUnit.getExchangeRate()));
tx.removeUnit(grossValueUnit);
tx.addUnit(new Unit(Unit.Type.GROSS_VALUE, calculatedGrossValue, updatedGrossValue,
grossValueUnit.getExchangeRate()));
}
catch (IllegalArgumentException e)
{
// ignore in case we are still running into rounding differences
// (for example: 4,33 EUR / 131,53 = 0,03 JPY but 0,03 JPY * 131,53
// = 3,95 EUR) because otherwise the user cannot open the file at
// all (and manually fix the issue)
}
}

@SuppressWarnings("nls")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.MessageFormat;
import java.time.Instant;
import java.time.LocalDateTime;
Expand Down Expand Up @@ -91,9 +92,29 @@ private Unit(Type type, Money amount, Money forex, BigDecimal exchangeRate, bool
}

if (amount.getAmount() < lower || amount.getAmount() > upper)
throw new IllegalArgumentException(MessageFormat.format(Messages.MsgErrorIllegalForexUnit,
type.toString(), Values.Money.format(forex), exchangeRate,
Values.Money.format(amount)));
{
// do the reverse check b/c small currency amounts might not
// allow for a better exchange rate

upper = BigDecimal.valueOf(amount.getAmount() + 1).divide(exchangeRate, Values.MC)
.setScale(0, RoundingMode.HALF_EVEN).longValue();
lower = BigDecimal.valueOf(amount.getAmount() - 1).divide(exchangeRate, Values.MC)
.setScale(0, RoundingMode.HALF_EVEN).longValue();

if (lower > upper)
{
long temp = lower;
lower = upper;
upper = temp;
}

if (forex.getAmount() < lower || forex.getAmount() > upper)
{
throw new IllegalArgumentException(MessageFormat.format(Messages.MsgErrorIllegalForexUnit,
type.toString(), Values.Money.format(forex), exchangeRate,
Values.Money.format(amount)));
}
}
}
}

Expand Down

0 comments on commit 3f854b2

Please sign in to comment.