diff --git a/moneyjinn-server/src/main/java/org/laladev/moneyjinn/server/controller/impl/EtfController.java b/moneyjinn-server/src/main/java/org/laladev/moneyjinn/server/controller/impl/EtfController.java index a9773e5a..befec9a1 100644 --- a/moneyjinn-server/src/main/java/org/laladev/moneyjinn/server/controller/impl/EtfController.java +++ b/moneyjinn-server/src/main/java/org/laladev/moneyjinn/server/controller/impl/EtfController.java @@ -207,7 +207,8 @@ public ResponseEntity calcEtfSale(@RequestBody final CalcEt .add(etfFlow.getAccumulatedPreliminaryLumpSum()); } openPieces = openPieces.subtract(useablePieces); - originalBuyPrice = originalBuyPrice.add(useablePieces.multiply(etfFlow.getPrice())); + originalBuyPrice = originalBuyPrice + .add(useablePieces.multiply(etfFlow.getPrice()).setScale(2, RoundingMode.HALF_UP)); } overallPreliminaryLumpSum = overallPreliminaryLumpSum.setScale(2, RoundingMode.HALF_UP); if (BigDecimal.ZERO.compareTo(openPieces) != 0) { @@ -216,8 +217,8 @@ public ResponseEntity calcEtfSale(@RequestBody final CalcEt this.throwValidationExceptionIfInvalid(validationResult); } else { - final BigDecimal newBuyPrice = askPrice.multiply(pieces); - final BigDecimal sellPrice = bidPrice.multiply(pieces); + final BigDecimal newBuyPrice = askPrice.multiply(pieces).setScale(2, RoundingMode.HALF_UP); + final BigDecimal sellPrice = bidPrice.multiply(pieces).setScale(2, RoundingMode.HALF_UP); final BigDecimal transactionCosts = request.getTransactionCosts().multiply(BigDecimal.valueOf(2)); final BigDecimal profit = sellPrice.subtract(originalBuyPrice); final BigDecimal chargeable = profit.multiply(TAX_RELEVANT_PERCENTAGE).setScale(2, RoundingMode.UP) diff --git a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/builder/EtfEffectiveFlowTransportBuilder.java b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/builder/EtfEffectiveFlowTransportBuilder.java index dfb0c4c9..0cd0fac9 100644 --- a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/builder/EtfEffectiveFlowTransportBuilder.java +++ b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/builder/EtfEffectiveFlowTransportBuilder.java @@ -8,50 +8,49 @@ import org.laladev.moneyjinn.server.model.EtfEffectiveFlowTransport; public class EtfEffectiveFlowTransportBuilder extends EtfEffectiveFlowTransport { - public static final Long ETF_FLOW_2ID = 2L; - public static final Long ETF_FLOW_4ID = 4L; - public static final Long ETF_FLOW_5ID = 5L; public static final Long ETF_FLOW_6ID = 6L; - public static final Long NEXT_ID = 4L; + public static final Long ETF_FLOW_8ID = 8L; + public static final Long ETF_FLOW_9ID = 9L; + public static final Long ETF_FLOW_11ID = 11L; public static final String ISIN = "ISIN123"; - public EtfEffectiveFlowTransportBuilder forFlow2() { - super.setEtfflowid(ETF_FLOW_2ID); - super.setAmount(new BigDecimal("80.000")); + public EtfEffectiveFlowTransportBuilder forFlow6() { + super.setEtfflowid(ETF_FLOW_6ID); + super.setAmount(new BigDecimal("2.234")); super.setIsin(ISIN); - super.setNanoseconds(320000000); - super.setPrice(new BigDecimal("777.666")); - super.setTimestamp(OffsetDateTime.of(2008, 12, 14, 15, 16, 20, 320000000, ZoneOffset.UTC)); + super.setNanoseconds(999000000); + super.setPrice(new BigDecimal("889.123")); + super.setTimestamp(OffsetDateTime.of(2009, 2, 20, 23, 59, 59, 999000000, ZoneOffset.UTC)); return this; } - public EtfEffectiveFlowTransportBuilder forFlow4() { - super.setEtfflowid(ETF_FLOW_4ID); - super.setAmount(new BigDecimal("1.234")); + public EtfEffectiveFlowTransportBuilder forFlow8() { + super.setEtfflowid(ETF_FLOW_8ID); + super.setAmount(new BigDecimal("81.000")); super.setIsin(ISIN); super.setNanoseconds(320000000); - super.setPrice(new BigDecimal("666.123")); - super.setTimestamp(OffsetDateTime.of(2008, 12, 16, 15, 16, 20, 320000000, ZoneOffset.UTC)); + super.setPrice(new BigDecimal("777.000")); + super.setTimestamp(OffsetDateTime.of(2010, 01, 01, 15, 16, 20, 320000000, ZoneOffset.UTC)); return this; } - public EtfEffectiveFlowTransportBuilder forFlow5() { - super.setEtfflowid(ETF_FLOW_5ID); - super.setAmount(new BigDecimal("5.500")); + public EtfEffectiveFlowTransportBuilder forFlow9() { + super.setEtfflowid(ETF_FLOW_9ID); + super.setAmount(new BigDecimal("80.000")); super.setIsin(ISIN); - super.setNanoseconds(999000000); - super.setPrice(new BigDecimal("789.123")); - super.setTimestamp(OffsetDateTime.of(2009, 1, 31, 23, 59, 59, 999000000, ZoneOffset.UTC)); + super.setNanoseconds(320000000); + super.setPrice(new BigDecimal("777.000")); + super.setTimestamp(OffsetDateTime.of(2010, 02, 02, 15, 16, 20, 320000000, ZoneOffset.UTC)); return this; } - public EtfEffectiveFlowTransportBuilder forFlow6() { - super.setEtfflowid(ETF_FLOW_6ID); - super.setAmount(new BigDecimal("6.500")); + public EtfEffectiveFlowTransportBuilder forFlow11() { + super.setEtfflowid(ETF_FLOW_11ID); + super.setAmount(new BigDecimal("30.000")); super.setIsin(ISIN); - super.setNanoseconds(999000000); - super.setPrice(new BigDecimal("889.123")); - super.setTimestamp(OffsetDateTime.of(2009, 2, 20, 23, 59, 59, 999000000, ZoneOffset.UTC)); + super.setNanoseconds(320000000); + super.setPrice(new BigDecimal("750.000")); + super.setTimestamp(OffsetDateTime.of(2010, 02, 04, 15, 16, 20, 320000000, ZoneOffset.UTC)); return this; } diff --git a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/builder/EtfFlowTransportBuilder.java b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/builder/EtfFlowTransportBuilder.java index d490883e..2501b2df 100644 --- a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/builder/EtfFlowTransportBuilder.java +++ b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/builder/EtfFlowTransportBuilder.java @@ -14,7 +14,12 @@ public class EtfFlowTransportBuilder extends EtfFlowTransport { public static final Long ETF_FLOW_4ID = 4L; public static final Long ETF_FLOW_5ID = 5L; public static final Long ETF_FLOW_6ID = 6L; - public static final Long NEXT_ID = 7L; + public static final Long ETF_FLOW_7ID = 7L; + public static final Long ETF_FLOW_8ID = 8L; + public static final Long ETF_FLOW_9ID = 9L; + public static final Long ETF_FLOW_10ID = 10L; + public static final Long ETF_FLOW_11ID = 11L; + public static final Long NEXT_ID = 12L; public static final String ISIN = "ISIN123"; public EtfFlowTransportBuilder forFlow1() { @@ -77,6 +82,56 @@ public EtfFlowTransportBuilder forFlow6() { return this; } + public EtfFlowTransportBuilder forFlow7() { + super.setEtfflowid(ETF_FLOW_7ID); + super.setAmount(new BigDecimal("-81.000")); + super.setIsin(ISIN); + super.setNanoseconds(320000000); + super.setPrice(new BigDecimal("877.000")); + super.setTimestamp(OffsetDateTime.of(2009, 12, 12, 15, 16, 20, 320000000, ZoneOffset.UTC)); + return this; + } + + public EtfFlowTransportBuilder forFlow8() { + super.setEtfflowid(ETF_FLOW_8ID); + super.setAmount(new BigDecimal("81.000")); + super.setIsin(ISIN); + super.setNanoseconds(320000000); + super.setPrice(new BigDecimal("777.000")); + super.setTimestamp(OffsetDateTime.of(2010, 01, 01, 15, 16, 20, 320000000, ZoneOffset.UTC)); + return this; + } + + public EtfFlowTransportBuilder forFlow9() { + super.setEtfflowid(ETF_FLOW_9ID); + super.setAmount(new BigDecimal("80.000")); + super.setIsin(ISIN); + super.setNanoseconds(320000000); + super.setPrice(new BigDecimal("777.000")); + super.setTimestamp(OffsetDateTime.of(2010, 02, 02, 15, 16, 20, 320000000, ZoneOffset.UTC)); + return this; + } + + public EtfFlowTransportBuilder forFlow10() { + super.setEtfflowid(ETF_FLOW_10ID); + super.setAmount(new BigDecimal("-10.000")); + super.setIsin(ISIN); + super.setNanoseconds(320000000); + super.setPrice(new BigDecimal("760.000")); + super.setTimestamp(OffsetDateTime.of(2010, 02, 03, 15, 16, 20, 320000000, ZoneOffset.UTC)); + return this; + } + + public EtfFlowTransportBuilder forFlow11() { + super.setEtfflowid(ETF_FLOW_11ID); + super.setAmount(new BigDecimal("30.000")); + super.setIsin(ISIN); + super.setNanoseconds(320000000); + super.setPrice(new BigDecimal("750.000")); + super.setTimestamp(OffsetDateTime.of(2010, 02, 04, 15, 16, 20, 320000000, ZoneOffset.UTC)); + return this; + } + public EtfFlowTransportBuilder forNewFlow() { super.setEtfflowid(NEXT_ID); super.setAmount(new BigDecimal("100.432")); diff --git a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/CalcEtfSaleTest.java b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/CalcEtfSaleTest.java index 225cf641..ab562796 100644 --- a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/CalcEtfSaleTest.java +++ b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/CalcEtfSaleTest.java @@ -2,6 +2,7 @@ package org.laladev.moneyjinn.server.controller.etf; import java.math.BigDecimal; +import java.math.RoundingMode; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -15,8 +16,8 @@ class CalcEtfSaleTest extends AbstractWebUserControllerTest { - private final static BigDecimal SETTING_SALE_ASK_PRICE = new BigDecimal("800.000"); - private final static BigDecimal SETTING_SALE_BID_PRICE = new BigDecimal("799.500"); + private final static BigDecimal SETTING_SALE_ASK_PRICE = new BigDecimal("900.000"); + private final static BigDecimal SETTING_SALE_BID_PRICE = new BigDecimal("899.500"); private final static String SETTING_ISIN = EtfTransportBuilder.ISIN; private final static BigDecimal SETTING_SALE_PIECES = new BigDecimal("10"); private final static BigDecimal SETTING_SALE_TRANSACTION_COSTS = new BigDecimal("0.99"); @@ -36,19 +37,7 @@ void test_standardRequest_FullResponseObject() throws Exception { request.setPieces(SETTING_SALE_PIECES); request.setTransactionCosts(SETTING_SALE_TRANSACTION_COSTS); - final CalcEtfSaleResponse expected = new CalcEtfSaleResponse(); - expected.setIsin(SETTING_ISIN); - expected.setOriginalBuyPrice(new BigDecimal("7776.660")); - expected.setSellPrice(new BigDecimal("7995.000")); - expected.setNewBuyPrice(new BigDecimal("8000.000")); - expected.setProfit(new BigDecimal("218.340")); - expected.setChargeable(new BigDecimal("152.84")); - expected.setTransactionCosts(new BigDecimal("1.98")); - expected.setRebuyLosses(new BigDecimal("5.000")); - expected.setOverallCosts(new BigDecimal("6.980")); - expected.setPieces(BigDecimal.TEN); - expected.accumulatedPreliminaryLumpSum(BigDecimal.ZERO.setScale(2)); - + final CalcEtfSaleResponse expected = this.getExpected(); final CalcEtfSaleResponse actual = super.callUsecaseExpect200(request, CalcEtfSaleResponse.class); Assertions.assertEquals(expected, actual); @@ -83,25 +72,34 @@ void test_negativeInput_AbsoluteValuesAreUsed() throws Exception { request.setPieces(SETTING_SALE_PIECES.negate()); request.setTransactionCosts(SETTING_SALE_TRANSACTION_COSTS); - final CalcEtfSaleResponse expected = new CalcEtfSaleResponse(); - expected.setIsin(SETTING_ISIN); - expected.setOriginalBuyPrice(new BigDecimal("7776.660")); - expected.setSellPrice(new BigDecimal("7995.000")); - expected.setNewBuyPrice(new BigDecimal("8000.000")); - expected.setProfit(new BigDecimal("218.340")); - expected.setChargeable(new BigDecimal("152.84")); - expected.setTransactionCosts(new BigDecimal("1.98")); - expected.setRebuyLosses(new BigDecimal("5.000")); - expected.setOverallCosts(new BigDecimal("6.980")); - expected.setPieces(BigDecimal.TEN); - expected.accumulatedPreliminaryLumpSum(BigDecimal.ZERO.setScale(2)); - + final CalcEtfSaleResponse expected = this.getExpected(); final CalcEtfSaleResponse actual = super.callUsecaseExpect200(request, CalcEtfSaleResponse.class); Assertions.assertEquals(expected, actual); } + private CalcEtfSaleResponse getExpected() { + final BigDecimal pieces = BigDecimal.TEN; + final BigDecimal sellPrice = SETTING_SALE_BID_PRICE.multiply(pieces).setScale(2); + final BigDecimal newBuyPrice = SETTING_SALE_ASK_PRICE.multiply(pieces).setScale(2); + final BigDecimal originalBuyPrice = new BigDecimal("8020.482782").setScale(2, RoundingMode.HALF_UP); + + final CalcEtfSaleResponse expected = new CalcEtfSaleResponse(); + expected.setIsin(SETTING_ISIN); + expected.setOriginalBuyPrice(originalBuyPrice); + expected.setSellPrice(sellPrice); + expected.setNewBuyPrice(newBuyPrice); + expected.setProfit(new BigDecimal("974.52")); + expected.setChargeable(new BigDecimal("682.17")); + expected.setTransactionCosts(new BigDecimal("1.98")); + expected.setRebuyLosses(new BigDecimal("5.00")); + expected.setOverallCosts(new BigDecimal("6.98")); + expected.setPieces(pieces); + expected.accumulatedPreliminaryLumpSum(BigDecimal.ZERO.setScale(2)); + return expected; + } + @Test void test_invalidIsinWithPieces_emptyResponse() throws Exception { diff --git a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/ListEtfFlowsTest.java b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/ListEtfFlowsTest.java index ede06293..c9759f03 100644 --- a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/ListEtfFlowsTest.java +++ b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/ListEtfFlowsTest.java @@ -66,6 +66,11 @@ private ListEtfFlowsResponse fillDefaultResponse() { expected.setEtfTransports(etfs); final List allTransports = new ArrayList<>(); + allTransports.add(new EtfFlowTransportBuilder().forFlow11().build()); + allTransports.add(new EtfFlowTransportBuilder().forFlow10().build()); + allTransports.add(new EtfFlowTransportBuilder().forFlow9().build()); + allTransports.add(new EtfFlowTransportBuilder().forFlow8().build()); + allTransports.add(new EtfFlowTransportBuilder().forFlow7().build()); allTransports.add(new EtfFlowTransportBuilder().forFlow6().build()); allTransports.add(new EtfFlowTransportBuilder().forFlow5().build()); allTransports.add(new EtfFlowTransportBuilder().forFlow4().build()); @@ -75,10 +80,10 @@ private ListEtfFlowsResponse fillDefaultResponse() { expected.setEtfFlowTransports(allTransports); final List effectiveTransports = new ArrayList<>(); + effectiveTransports.add(new EtfEffectiveFlowTransportBuilder().forFlow11().build()); + effectiveTransports.add(new EtfEffectiveFlowTransportBuilder().forFlow9().build()); + effectiveTransports.add(new EtfEffectiveFlowTransportBuilder().forFlow8().build()); effectiveTransports.add(new EtfEffectiveFlowTransportBuilder().forFlow6().build()); - effectiveTransports.add(new EtfEffectiveFlowTransportBuilder().forFlow5().build()); - effectiveTransports.add(new EtfEffectiveFlowTransportBuilder().forFlow4().build()); - effectiveTransports.add(new EtfEffectiveFlowTransportBuilder().forFlow2().build()); expected.setEtfEffectiveFlowTransports(effectiveTransports); return expected; } diff --git a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/ListEtfOverviewTest.java b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/ListEtfOverviewTest.java index b251d6ef..a121d1fe 100644 --- a/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/ListEtfOverviewTest.java +++ b/moneyjinn-server/src/test/java/org/laladev/moneyjinn/server/controller/etf/ListEtfOverviewTest.java @@ -9,11 +9,9 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.laladev.moneyjinn.server.builder.EtfEffectiveFlowTransportBuilder; import org.laladev.moneyjinn.server.builder.EtfTransportBuilder; import org.laladev.moneyjinn.server.controller.AbstractWebUserControllerTest; import org.laladev.moneyjinn.server.controller.api.EtfControllerApi; -import org.laladev.moneyjinn.server.model.EtfEffectiveFlowTransport; import org.laladev.moneyjinn.server.model.EtfSummaryTransport; import org.laladev.moneyjinn.server.model.EtfTransport; import org.laladev.moneyjinn.server.model.ListEtfOverviewResponse; @@ -28,15 +26,11 @@ protected void loadMethod() { @Test void test_standardRequest_FullResponseObject() throws Exception { final EtfTransport etf = new EtfTransportBuilder().forEtf1().build(); - final EtfEffectiveFlowTransport flow1 = new EtfEffectiveFlowTransportBuilder().forFlow2().build(); - final EtfEffectiveFlowTransport flow3 = new EtfEffectiveFlowTransportBuilder().forFlow4().build(); - final ListEtfOverviewResponse expected = new ListEtfOverviewResponse(); final EtfSummaryTransport transport = new EtfSummaryTransport(); - final BigDecimal amount = flow1.getAmount().add(flow3.getAmount()); - final BigDecimal spentValue = flow1.getAmount().multiply(flow1.getPrice()) - .add(flow3.getAmount().multiply(flow3.getPrice())); + final BigDecimal amount = new BigDecimal("93.234"); + final BigDecimal spentValue = new BigDecimal("73212.348782"); transport.setIsin(etf.getIsin()); transport.setName(etf.getName()); transport.setChartUrl(etf.getChartUrl()); @@ -45,12 +39,12 @@ void test_standardRequest_FullResponseObject() throws Exception { // latest etfvalues table entry transport.setBuyPrice(new BigDecimal("666.000")); transport.setSellPrice(new BigDecimal("666.543")); - transport.setPricesTimestamp(ZonedDateTime.of(2008, 12, 16, 22, 5, 2, 0, ZoneId.systemDefault()).toInstant() + transport.setPricesTimestamp(ZonedDateTime.of(2012, 01, 16, 22, 5, 2, 0, ZoneId.systemDefault()).toInstant() .atOffset(ZoneOffset.UTC)); expected.setEtfSummaryTransports(Collections.singletonList(transport)); - final ListEtfOverviewResponse actual = super.callUsecaseExpect200(ListEtfOverviewResponse.class, 2008, 12); + final ListEtfOverviewResponse actual = super.callUsecaseExpect200(ListEtfOverviewResponse.class, 2010, 1); Assertions.assertEquals(expected, actual); diff --git a/moneyjinn-server/src/test/resources/testdata.sql b/moneyjinn-server/src/test/resources/testdata.sql index 5ae93834..2b88971e 100644 --- a/moneyjinn-server/src/test/resources/testdata.sql +++ b/moneyjinn-server/src/test/resources/testdata.sql @@ -173,6 +173,11 @@ INSERT INTO etfflows VALUES ( 3, '2008-12-15 15:16:20.320000', 'ISIN123', -50.0 INSERT INTO etfflows VALUES ( 4, '2008-12-16 15:16:20.320000', 'ISIN123', 1.234, 666.123); INSERT INTO etfflows VALUES ( 5, '2009-01-31 23:59:59.999000', 'ISIN123', 5.500, 789.123); INSERT INTO etfflows VALUES ( 6, '2009-02-20 23:59:59.999000', 'ISIN123', 6.500, 889.123); +INSERT INTO etfflows VALUES ( 7, '2009-12-12 15:16:20.320000', 'ISIN123', -81.000, 877.000); +INSERT INTO etfflows VALUES ( 8, '2010-01-01 15:16:20.320000', 'ISIN123', 81.000, 777.000); +INSERT INTO etfflows VALUES ( 9, '2010-02-02 15:16:20.320000', 'ISIN123', 80.000, 777.000); +INSERT INTO etfflows VALUES (10, '2010-02-03 15:16:20.320000', 'ISIN123', -10.000, 760.000); +INSERT INTO etfflows VALUES (11, '2010-02-04 15:16:20.320000', 'ISIN123', 30.000, 750.000); INSERT INTO etfvalues VALUES ( 'ISIN123', '2008-12-14',777.777, 777.000, '2008-12-14 22:05:02'); INSERT INTO etfvalues VALUES ( 'ISIN123', '2008-12-15',878.000, 878.500, '2008-12-15 22:05:02'); -INSERT INTO etfvalues VALUES ( 'ISIN123', '2008-12-16',666.000, 666.543, '2008-12-16 22:05:02'); \ No newline at end of file +INSERT INTO etfvalues VALUES ( 'ISIN123', '2010-01-16',666.000, 666.543, '2012-01-16 22:05:02'); \ No newline at end of file