diff --git a/name.abuchen.portfolio.tests/src/fileversions/ReadingHistoricClientFilesTest.java b/name.abuchen.portfolio.tests/src/fileversions/ReadingHistoricClientFilesTest.java index 146f2467b7..a4218685a2 100644 --- a/name.abuchen.portfolio.tests/src/fileversions/ReadingHistoricClientFilesTest.java +++ b/name.abuchen.portfolio.tests/src/fileversions/ReadingHistoricClientFilesTest.java @@ -26,7 +26,7 @@ public class ReadingHistoricClientFilesTest public static Collection getFiles() { return Arrays.asList(new Object[][] { // NOSONAR - { "client52", 52 }, { "client53", 53 } }); + { "client52", 52 }, { "client53", 53 }, { "client69", 69 } }); } @@ -55,10 +55,15 @@ public void compare() throws IOException String binaryEncrypted = ClientTestUtilities.toString(binaryEncryptedClient); assertThat(binaryEncryptedClient.getFileVersionAfterRead(), is(versionOnDisk)); - Client xmlEncrpytedClient = ClientFactory.load(find(file + ".xml+pwd.portfolio"), "123456".toCharArray(), - new NullProgressMonitor()); - String xmlEncrpyted = ClientTestUtilities.toString(xmlEncrpytedClient); - assertThat(xmlEncrpytedClient.getFileVersionAfterRead(), is(versionOnDisk)); + String xmlEncrpyted = null; + if (versionOnDisk < 60) + { + + Client xmlEncrpytedClient = ClientFactory.load(find(file + ".xml+pwd.portfolio"), "123456".toCharArray(), + new NullProgressMonitor()); + xmlEncrpyted = ClientTestUtilities.toString(xmlEncrpytedClient); + assertThat(xmlEncrpytedClient.getFileVersionAfterRead(), is(versionOnDisk)); + } if (!xml.equals(binary)) { @@ -76,7 +81,7 @@ public void compare() throws IOException is(xml.substring(pos, Math.min(pos + 100, xml.length())))); } - if (!xml.equals(xmlEncrpyted)) + if (xmlEncrpyted != null && !xml.equals(xmlEncrpyted)) { int pos = ClientTestUtilities.indexOfDifference(xml, xmlEncrpyted); assertThat("encrypted xml is not identical to xml " + pos, @@ -85,4 +90,4 @@ public void compare() throws IOException } } -} +} \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/fileversions/client69.binary+pwd.portfolio b/name.abuchen.portfolio.tests/src/fileversions/client69.binary+pwd.portfolio new file mode 100644 index 0000000000..9d1404f17c Binary files /dev/null and b/name.abuchen.portfolio.tests/src/fileversions/client69.binary+pwd.portfolio differ diff --git a/name.abuchen.portfolio.tests/src/fileversions/client69.binary.portfolio b/name.abuchen.portfolio.tests/src/fileversions/client69.binary.portfolio new file mode 100644 index 0000000000..b0a072770d Binary files /dev/null and b/name.abuchen.portfolio.tests/src/fileversions/client69.binary.portfolio differ diff --git a/name.abuchen.portfolio.tests/src/fileversions/client69.xml b/name.abuchen.portfolio.tests/src/fileversions/client69.xml new file mode 100644 index 0000000000..af93a27157 --- /dev/null +++ b/name.abuchen.portfolio.tests/src/fileversions/client69.xml @@ -0,0 +1,258 @@ + + 69 + EUR + + + 2bab2728-f3b2-4ca0-8330-825446831ade + Commerzbank AG Inhaber-Aktien o.N. + EUR + DE000CBK1001 + CBK.DE + PP + + + + + + false + 2026-02-04T21:30:37.744832272Z + + + + + + 6908edd0-1bb5-411e-bb4d-678a858eff66 + dividendExdate + EUR + false + + + 11d2ebf5-a0c5-4de1-b2f6-19a0a701e1f6 + 2019-05-27T00:00 + EUR + 1007 + + 7000000000 + Abrechnungs-Nr. 19200128 + 2019-05-24_Wertpapierertrag 24.05.2019_DE000CBK1001.pdf + + + + + + 2026-02-10T13:50:10.694859420Z + DIVIDENDS + 2019-05-23 + + + + + + 2026-02-04T22:52:02.886672581Z + + + + + 404c0fbf-68ab-4925-bdcb-9838e2380317 + dividendExdate + false + + + + + + 2026-02-04T22:51:41.462743232Z + + + + + + + + + + + https://finance.yahoo.com/quote/{tickerSymbol} + + + + https://www.onvista.de/suche.html?SEARCH_VALUE={isin} + + + + https://www.finanzen.net/suchergebnis.asp?frmAktiensucheTextfeld={isin} + + + + https://www.ariva.de/{isin} + + + + https://www.justetf.com/etf-profile.html?isin={isin} + + + + https://www.fondsweb.com/{isin} + + + + https://www.morningstar.de/de/funds/SecuritySearchResults.aspx?type=ALL&search={isin} + + + + https://extraetf.com/etf-profile/{isin} + + + + https://www.alleaktien.de/data/{isin} + + + + https://www.comdirect.de/inf/aktien/{isin} + + + + https://www.comdirect.de/inf/etfs/{isin} + + + + https://divvydiary.com/symbols/{isin} + + + + https://www.trackingdifferences.com/ETF/ISIN/{isin} + + + + https://www.tradingview.com/chart/?symbol=XETR:{tickerSymbolPrefix} + + + + https://www.cnbc.com/quotes/{tickerSymbolPrefix} + + + + https://www.nasdaq.com/market-activity/stocks/{tickerSymbolPrefix} + + + + https://aktienfinder.net/aktien-profil/{isin} + + + + http://aktien.guide/isin/aktien/{isin} + + + + + logo + Logo + Logo + name.abuchen.portfolio.model.Security + java.lang.String + name.abuchen.portfolio.model.AttributeType$ImageConverter + + + + logo + Logo + Logo + name.abuchen.portfolio.model.Account + java.lang.String + name.abuchen.portfolio.model.AttributeType$ImageConverter + + + + logo + Logo + Logo + name.abuchen.portfolio.model.Portfolio + java.lang.String + name.abuchen.portfolio.model.AttributeType$ImageConverter + + + + logo + Logo + Logo + name.abuchen.portfolio.model.InvestmentPlan + java.lang.String + name.abuchen.portfolio.model.AttributeType$ImageConverter + + + + ter + Gesamtkostenquote (TER) + TER + ter + name.abuchen.portfolio.model.Security + java.lang.Double + name.abuchen.portfolio.model.AttributeType$PercentConverter + + + + aum + Fondsgröße + Fondsgröße + name.abuchen.portfolio.model.Security + java.lang.Long + name.abuchen.portfolio.model.AttributeType$AmountPlainConverter + + + + vendor + Anbieter + Anbieter + vendor + name.abuchen.portfolio.model.Security + java.lang.String + name.abuchen.portfolio.model.AttributeType$StringConverter + + + + acquisitionFee + Kaufgebühr (prozentual) + Kaufgebühr + name.abuchen.portfolio.model.Security + java.lang.Double + name.abuchen.portfolio.model.AttributeType$PercentConverter + + + + managementFee + Verwaltungsgebühr (prozentual) + Verwaltungsgebühr + name.abuchen.portfolio.model.Security + java.lang.Double + name.abuchen.portfolio.model.AttributeType$PercentConverter + + + + + + name.abuchen.portfolio.ui.views.SecuritiesTable + + + + 40227a75-8308-4477-896c-3fa920f43367 + Standard + {"items":[{"id":"0","sortDirection":128,"width":400},{"id":"note","width":200},{"id":"1","width":100},{"id":"2","width":80},{"id":"7","width":80},{"id":"4","width":60},{"id":"5","width":80},{"id":"changeonpreviousamount","width":80},{"id":"9","width":80},{"id":"10","width":80},{"id":"q-date-first-historic","width":261}]} + + + + + + name.abuchen.portfolio.ui.views.StatementOfAssetsViewer + + + + 71873ede-52b7-44fd-9877-1155f6c3e6aa + Standard + {"items":[{"id":"0","width":80},{"id":"1","width":300},{"id":"2","width":80},{"id":"4","width":60},{"id":"5","width":80},{"id":"6","width":80},{"id":"note","width":821}]} + + + + + + + \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/ExtractorMatchers.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/ExtractorMatchers.java index 9115131d23..f69506e0bc 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/ExtractorMatchers.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/ExtractorMatchers.java @@ -396,6 +396,15 @@ public static Matcher hasDate(String dateString) Transaction::getDateTime); } + public static Matcher hasDateEx(String dateString) + { + var expected = LocalDate.parse(dateString); + + return new PropertyMatcher<>("exDate", //$NON-NLS-1$ + expected, // + t -> ((AccountTransaction) t).getDateEx()); + } + public static Matcher hasShares(double value) { // work with BigDecimal to have better assertion failed messages diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/actions/DetectDuplicatesActionTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/actions/DetectDuplicatesActionTest.java index a138f1fd73..bf04f4aab2 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/actions/DetectDuplicatesActionTest.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/actions/DetectDuplicatesActionTest.java @@ -36,7 +36,7 @@ public void testDuplicateDetection4AccountTransaction() throws IntrospectionExce var action = new DetectDuplicatesAction(new Client()); new PropertyChecker( - AccountTransaction.class, "note", "source", "forex", "monetaryAmount", "updatedAt") + AccountTransaction.class, "note", "source", "forex", "monetaryAmount", "dateEx", "updatedAt") .before((name, o, c) -> assertThat(name, action.process(o, account(c)).getCode(), is(Code.WARNING))) .after((name, o, c) -> assertThat(name, action.process(o, account(c)).getCode(), diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/onvista/OnvistaPDFExtractorTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/onvista/OnvistaPDFExtractorTest.java index 0f087b5137..502d7c3249 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/onvista/OnvistaPDFExtractorTest.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/onvista/OnvistaPDFExtractorTest.java @@ -8,6 +8,7 @@ import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasAmount; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasCurrencyCode; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasDate; +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasDateEx; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasFees; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasForexGrossValue; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasGrossValue; @@ -40,6 +41,7 @@ import static org.hamcrest.collection.IsEmptyCollection.empty; import static org.junit.Assert.assertNull; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -2053,6 +2055,7 @@ public void testDividende01() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2016-04-21T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2016-04-21"))); assertThat(transaction.getShares(), is(Values.Share.factorize(50))); assertThat(transaction.getSource(), is("Dividende01.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 77110599")); @@ -2113,6 +2116,7 @@ public void testDividende02() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2016-12-16T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2016-12-14"))); assertThat(transaction.getShares(), is(Values.Share.factorize(1.0545))); assertThat(transaction.getSource(), is("Dividende02.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 55746925 | Ertrag für 2016/17")); @@ -2129,6 +2133,7 @@ public void testDividende02() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2016-12-16T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2016-12-14"))); assertThat(transaction.getShares(), is(Values.Share.factorize(1.2879))); assertThat(transaction.getSource(), is("Dividende02.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 97603916 | Ertrag für 2016/17")); @@ -2145,6 +2150,7 @@ public void testDividende02() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2016-12-16T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2016-12-14"))); assertThat(transaction.getShares(), is(Values.Share.factorize(9.9225))); assertThat(transaction.getSource(), is("Dividende02.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 33071326 | Ertrag für 2016")); @@ -2189,6 +2195,7 @@ public void testDividende03() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2019-07-15T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2019-06-27"))); assertThat(transaction.getShares(), is(Values.Share.factorize(100))); assertThat(transaction.getSource(), is("Dividende03.txt")); assertNull(transaction.getNote()); @@ -2234,6 +2241,7 @@ public void testDividende03WithSecurityInEUR() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2019-07-15T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2019-06-27"))); assertThat(transaction.getShares(), is(Values.Share.factorize(100))); assertThat(transaction.getSource(), is("Dividende03.txt")); assertNull(transaction.getNote()); @@ -2285,6 +2293,7 @@ public void testDividende04() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2019-03-26T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2019-03-22"))); assertThat(transaction.getShares(), is(Values.Share.factorize(6))); assertThat(transaction.getSource(), is("Dividende04.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 29013705")); @@ -2329,6 +2338,7 @@ public void testDividende04WithSecurityInEUR() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2019-03-26T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2019-03-22"))); assertThat(transaction.getShares(), is(Values.Share.factorize(6))); assertThat(transaction.getSource(), is("Dividende04.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 29013705")); @@ -2379,6 +2389,7 @@ public void testDividende05() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2020-02-14T00:00"))); + assertNull(transaction.getDateEx()); assertThat(transaction.getShares(), is(Values.Share.factorize(50))); assertThat(transaction.getSource(), is("Dividende05.txt")); assertNull(transaction.getNote()); @@ -2424,6 +2435,7 @@ public void testDividende06() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2015-03-04T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2015-03-02"))); assertThat(transaction.getShares(), is(Values.Share.factorize(28))); assertThat(transaction.getSource(), is("Dividende06.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 96937413 | Ertrag für 2014")); @@ -2469,6 +2481,7 @@ public void testDividende07() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2016-12-15T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2016-12-15"))); assertThat(transaction.getShares(), is(Values.Share.factorize(5.8192))); assertThat(transaction.getSource(), is("Dividende07.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 14053767 | Ertrag für 2016/17")); @@ -2513,6 +2526,7 @@ public void testDividende08() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2019-02-05T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2019-01-31"))); assertThat(transaction.getShares(), is(Values.Share.factorize(32))); assertThat(transaction.getSource(), is("Dividende08.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 12345 | Ertrag für 2018")); @@ -2557,6 +2571,7 @@ public void testDividende08WithSecurityInEUR() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2019-02-05T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2019-01-31"))); assertThat(transaction.getShares(), is(Values.Share.factorize(32))); assertThat(transaction.getSource(), is("Dividende08.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 12345 | Ertrag für 2018")); @@ -2607,6 +2622,7 @@ public void testDividende09() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2019-09-11T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2019-08-08"))); assertThat(transaction.getShares(), is(Values.Share.factorize(40))); assertThat(transaction.getSource(), is("Dividende09.txt")); assertNull(transaction.getNote()); @@ -2652,6 +2668,7 @@ public void testDividende10() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2020-11-25T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2020-09-29"))); assertThat(transaction.getShares(), is(Values.Share.factorize(46))); assertThat(transaction.getSource(), is("Dividende10.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 11223344")); @@ -2697,6 +2714,7 @@ public void testDividende10WithSecurityInEUR() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2020-11-25T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2020-09-29"))); assertThat(transaction.getShares(), is(Values.Share.factorize(46))); assertThat(transaction.getSource(), is("Dividende10.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 11223344")); @@ -2748,6 +2766,7 @@ public void testDividende11() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2020-11-12T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2020-11-04"))); assertThat(transaction.getShares(), is(Values.Share.factorize(500))); assertThat(transaction.getSource(), is("Dividende11.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 23344420 | Ertrag für 2020")); @@ -2793,6 +2812,7 @@ public void testDividende11WithSecurityInEUR() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2020-11-12T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2020-11-04"))); assertThat(transaction.getShares(), is(Values.Share.factorize(500))); assertThat(transaction.getSource(), is("Dividende11.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 23344420 | Ertrag für 2020")); @@ -2844,6 +2864,7 @@ public void testDividende12() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2010-11-17T00:00"))); + assertNull(transaction.getDateEx()); assertThat(transaction.getShares(), is(Values.Share.factorize(1))); assertThat(transaction.getSource(), is("Dividende12.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 63302459")); @@ -2888,6 +2909,7 @@ public void testDividende13() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2021-09-15T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2021-09-15"))); assertThat(transaction.getShares(), is(Values.Share.factorize(549))); assertThat(transaction.getSource(), is("Dividende13.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 34091609 | Ertrag für 2021/22")); @@ -2933,6 +2955,7 @@ public void testDividende14() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2021-12-17T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2021-12-02"))); assertThat(transaction.getShares(), is(Values.Share.factorize(1000))); assertThat(transaction.getSource(), is("Dividende14.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 59788848")); @@ -2978,6 +3001,7 @@ public void testDividende14WithSecurityInEUR() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2021-12-17T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2021-12-02"))); assertThat(transaction.getShares(), is(Values.Share.factorize(1000))); assertThat(transaction.getSource(), is("Dividende14.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 59788848")); @@ -3029,6 +3053,7 @@ public void testDividende15() assertThat(transaction.getType(), is(AccountTransaction.Type.TAXES)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2017-10-20T00:00"))); + assertThat(transaction.getDateEx(), is(LocalDate.parse("2017-10-06"))); assertThat(transaction.getShares(), is(Values.Share.factorize(0.4512))); assertThat(transaction.getSource(), is("Dividende15.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 12345678 | Ertrag für 2017")); @@ -3073,6 +3098,7 @@ public void testDividende16() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2022-09-30T00:00"))); + assertNull(transaction.getDateEx()); assertThat(transaction.getShares(), is(Values.Share.factorize(15))); assertThat(transaction.getSource(), is("Dividende16.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 42739637 | Kapitalrückzahlung")); @@ -3117,6 +3143,7 @@ public void testDividende16WithSecurityInEUR() assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS)); assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2022-09-30T00:00"))); + assertNull(transaction.getDateEx()); assertThat(transaction.getShares(), is(Values.Share.factorize(15))); assertThat(transaction.getSource(), is("Dividende16.txt")); assertThat(transaction.getNote(), is("Abrechnungs-Nr. 42739637 | Kapitalrückzahlung")); @@ -3160,6 +3187,7 @@ public void testDividende17() // check dividends transaction assertThat(results, hasItem(dividend( // hasDate("2019-09-09"), hasShares(60), // + /* hasDateEx("2021-12-02"), */ hasSource("Dividende17.txt"), // hasNote("Abrechnungs-Nr. 26128781"), // hasAmount("EUR", 7.65), hasGrossValue("EUR", 15.73), // @@ -3194,6 +3222,7 @@ public void testDividende17WithSecurityInEUR() // check dividends transaction assertThat(results, hasItem(dividend( // hasDate("2019-09-09"), hasShares(60), // + hasDateEx("2019-08-30"), hasSource("Dividende17.txt"), hasNote("Abrechnungs-Nr. 26128781"), // hasAmount("EUR", 7.65), hasGrossValue("EUR", 15.73), // hasTaxes("EUR", (39.00 / 9.9148) + 3.93 + 0.22), hasFees("EUR", 0.00), // @@ -3232,8 +3261,9 @@ public void testDividende18() hasCurrencyCode("EUR")))); // check dividends transaction - assertThat(results, hasItem(dividend( // + assertThat(results, hasItem(dividend( hasDate("2015-12-17T00:00"), hasShares(156.729), // + hasDateEx("2015-12-15"), hasSource("Dividende18.txt"), // hasNote("Abrechnungs-Nr. 70187215 | Ertrag für 2014/15"), // hasAmount("EUR", 7.68), hasGrossValue("EUR", 11.84), // @@ -3278,6 +3308,7 @@ public void testDividendeStorno01() assertThat(((Transaction) cancellation.getSubject()).getDateTime(), is(LocalDateTime.parse("2020-05-15T00:00"))); + assertThat(((AccountTransaction) cancellation.getSubject()).getDateEx(), is(LocalDate.parse("2020-04-29"))); assertThat(((Transaction) cancellation.getSubject()).getShares(), is(Values.Share.factorize(46))); assertThat(((Transaction) cancellation.getSubject()).getSource(), is("DividendeStorno01.txt")); assertThat(((Transaction) cancellation.getSubject()).getNote(), is( diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java index dd93499cc8..913de83d16 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java @@ -1096,6 +1096,7 @@ public class Messages extends NLS public static String MsgDialogNotAValidCurrency; public static String MsgDialogNotAValidISIN; public static String MsgEmbeddedBrowserError; + public static String MsgExDateNotAllowed; public static String MsgErrorAccountNotExist; public static String MsgErrorConvertedAmount; public static String MsgErrorConvertToBuySellCurrencyMismatch; diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/transactions/AccountTransactionDialog.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/transactions/AccountTransactionDialog.java index 51db8a654b..60f1f8fc99 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/transactions/AccountTransactionDialog.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/transactions/AccountTransactionDialog.java @@ -50,10 +50,12 @@ import name.abuchen.portfolio.ui.Messages; import name.abuchen.portfolio.ui.UIConstants; import name.abuchen.portfolio.ui.dialogs.transactions.AccountTransactionModel.Properties; +import name.abuchen.portfolio.ui.util.DatePicker; import name.abuchen.portfolio.ui.util.FormDataFactory; import name.abuchen.portfolio.ui.util.LabelOnly; import name.abuchen.portfolio.ui.util.SWTHelper; import name.abuchen.portfolio.ui.util.SecurityNameLabelProvider; +import name.abuchen.portfolio.ui.util.SimpleDateTimeDateSelectionProperty; public class AccountTransactionDialog extends AbstractTransactionDialog // NOSONAR { @@ -121,6 +123,18 @@ protected void createFormElements(Composite editArea) // NOSONAR dateTime.bindTime(Properties.time.name()); dateTime.bindButton(() -> model().getTime(), time -> model().setTime(time)); + Label lblDateEx = null; + DatePicker dateEx = null; + if (model().supportsShares()) + { + lblDateEx = new Label(editArea, SWT.RIGHT); + lblDateEx.setText(Messages.ColumnExDate); + dateEx = new DatePicker(editArea); + IObservableValue targetDate = new SimpleDateTimeDateSelectionProperty().observe(dateEx.getControl()); + IObservableValue modelDate = BeanProperties.value(Properties.dateEx.name()).observe(model); + context.bindValue(targetDate, modelDate); + } + // shares Input shares = new Input(editArea, Messages.ColumnShares); @@ -251,6 +265,11 @@ public void widgetSelected(SelectionEvent e) startingWith(dateTime.date.getControl()).thenRight(dateTime.time).thenRight(dateTime.button, 0); + if (model().supportsShares()) + { + startingWith(dateTime.button).thenRight(lblDateEx).thenRight(dateEx.getControl()); + } + // shares [- amount per share] forms.thenBelow(shares.value).width(amountWidth).label(shares.label).suffix(btnShares) // // fxAmount - exchange rate - amount diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/transactions/AccountTransactionModel.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/transactions/AccountTransactionModel.java index 37d5e24811..cf64ed0da8 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/transactions/AccountTransactionModel.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/transactions/AccountTransactionModel.java @@ -32,7 +32,7 @@ public class AccountTransactionModel extends AbstractModel { public enum Properties { - security, account, date, time, shares, fxGrossAmount, dividendAmount, exchangeRate, inverseExchangeRate, grossAmount, // NOSONAR + security, account, date, dateEx, time, shares, fxGrossAmount, dividendAmount, exchangeRate, inverseExchangeRate, grossAmount, // NOSONAR fxTaxes, taxes, fxFees, fees, total, note, exchangeRateCurrencies, inverseExchangeRateCurrencies, // NOSONAR accountCurrencyCode, securityCurrencyCode, fxCurrencyCode, calculationStatus; // NOSONAR } @@ -41,6 +41,7 @@ public enum Properties private final Client client; private AccountTransaction.Type type; + private LocalDate dateEx; private Account sourceAccount; private AccountTransaction sourceTransaction; @@ -103,6 +104,9 @@ public void applyChanges() if (account == null) throw new UnsupportedOperationException(Messages.MsgMissingAccount); + if (dateEx != null && type != Type.DIVIDENDS) + throw new UnsupportedOperationException(Messages.MsgExDateNotAllowed); + AccountTransaction t; if (sourceTransaction != null && sourceAccount.equals(account)) @@ -125,6 +129,7 @@ public void applyChanges() } t.setDateTime(LocalDateTime.of(date, time)); + t.setDateEx(dateEx); t.setSecurity(!EMPTY_SECURITY.equals(security) ? security : null); t.setShares(supportsShares() ? shares : 0); t.setAmount(total); @@ -177,6 +182,7 @@ public void resetToNewTransaction() setFxTaxes(0); setNote(null); setTime(PresetValues.getTime()); + setDateEx(null); } public boolean supportsShares() @@ -229,6 +235,7 @@ public void presetFromSource(Account account, AccountTransaction transaction) LocalDateTime transactionDate = transaction.getDateTime(); this.date = transactionDate.toLocalDate(); this.time = transactionDate.toLocalTime(); + this.dateEx = transaction.getDateEx(); this.shares = transaction.getShares(); this.total = transaction.getAmount(); @@ -444,6 +451,16 @@ public void setTime(LocalTime time) firePropertyChange(Properties.time.name(), this.time, this.time = time); // NOSONAR } + public LocalDate getDateEx() + { + return dateEx; + } + + public void setDateEx(LocalDate dateEx) + { + firePropertyChange(Properties.dateEx.name(), this.dateEx, this.dateEx = dateEx); // NOSONAR + } + public long getShares() { return shares; diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties index 5dcd417952..edbe04c4e4 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties @@ -2184,6 +2184,8 @@ MsgDialogNotAValidISIN = Invalid ISIN: {0} MsgEmbeddedBrowserError = Unable to create embedded browser to display charts\n\n* Are you running the latest version of your browser?\n* On Linux one has to install the packet ''libwebkitgtk-3.0-0''\n\nThe error message\n "No more handles [Unknown Mozilla path (MOZILLA_FIVE_HOME not set)]"\nindicates that libwebkitgtk has to be installed. On Ubuntu 18.04, run\n sudo apt-get install libwebkitgtk-3.0-0\n\n\nDetails:\n{0} +MsgExDateNotAllowed = Ex-Date is only allowed for dividend transactions. + MsgErrorAccountNotExist = There is no account.\nPlease create a new account. MsgErrorConvertToBuySellCurrencyMismatch = Transaction with currency {0} cannot be booked on account ''{2}'' with the currency {1}. diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties index 494cd89985..cc801c92c6 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties @@ -2177,6 +2177,8 @@ MsgDialogNotAValidISIN = Ung\u00FCltige ISIN: {0} MsgEmbeddedBrowserError = Fehler beim \u00D6ffnen des Web Browsers zur Darstellung der Grafiken\n\n* Aktuellste Version des Browsers installiert?\n* Unter Linux muss das Paket ''libwebkitgtk-3.0-0'' installiert sein.\n\nDer Fehlertext\n "No more handles [Unknown Mozilla path (MOZILLA_FIVE_HOME not set)]"\nhei\u00DFt meistens, dass libwebkitgtk installiert werden muss. Unter Ubuntu 18.04 z. B. mit\n sudo apt-get install libwebkitgtk-3.0-0\n\n\nDetails:\n{0} +MsgExDateNotAllowed = Ex-Datum ist nur für Dividenden-Transaktionen erlaubt. + MsgErrorAccountNotExist = Es ist kein Konto vorhanden.\nBitte erstellen Sie ein Konto. MsgErrorConvertToBuySellCurrencyMismatch = Buchung in der W\u00E4hrung {0} kann nicht auf Konto ''{2}'' mit der W\u00E4hrung {1} gebucht werden. diff --git a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/ClientProtos.java b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/ClientProtos.java index 0b1ebd0c9c..74a2dbafc5 100644 --- a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/ClientProtos.java +++ b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/ClientProtos.java @@ -242,7 +242,7 @@ public static void registerAllExtensions( "xRateToBase\030\006 \001(\0132%.name.abuchen.portfol" + "io.PDecimalValueH\002\210\001\001\")\n\004Type\022\017\n\013GROSS_V" + "ALUE\020\000\022\007\n\003TAX\020\001\022\007\n\003FEE\020\002B\013\n\t_fxAmountB\021\n" + - "\017_fxCurrencyCodeB\017\n\r_fxRateToBase\"\230\007\n\014PT" + + "\017_fxCurrencyCodeB\017\n\r_fxRateToBase\"\270\007\n\014PT" + "ransaction\022\014\n\004uuid\030\001 \001(\t\0227\n\004type\030\002 \001(\0162)" + ".name.abuchen.portfolio.PTransaction.Typ" + "e\022\024\n\007account\030\003 \001(\tH\000\210\001\001\022\026\n\tportfolio\030\004 \001" + @@ -250,101 +250,102 @@ public static void registerAllExtensions( "herPortfolio\030\006 \001(\tH\003\210\001\001\022\026\n\totherUuid\030\007 \001" + "(\tH\004\210\001\001\0227\n\016otherUpdatedAt\030\010 \001(\0132\032.google" + ".protobuf.TimestampH\005\210\001\001\022(\n\004date\030\t \001(\0132\032" + - ".google.protobuf.Timestamp\022\024\n\014currencyCo" + - "de\030\n \001(\t\022\016\n\006amount\030\013 \001(\003\022\023\n\006shares\030\014 \001(\003" + - "H\006\210\001\001\022\021\n\004note\030\r \001(\tH\007\210\001\001\022\025\n\010security\030\016 \001" + - "(\tH\010\210\001\001\0227\n\005units\030\017 \003(\0132(.name.abuchen.po" + - "rtfolio.PTransactionUnit\022-\n\tupdatedAt\030\020 " + - "\001(\0132\032.google.protobuf.Timestamp\022\023\n\006sourc" + - "e\030\021 \001(\tH\t\210\001\001\"\362\001\n\004Type\022\014\n\010PURCHASE\020\000\022\010\n\004S" + - "ALE\020\001\022\024\n\020INBOUND_DELIVERY\020\002\022\025\n\021OUTBOUND_" + - "DELIVERY\020\003\022\025\n\021SECURITY_TRANSFER\020\004\022\021\n\rCAS" + - "H_TRANSFER\020\005\022\013\n\007DEPOSIT\020\006\022\013\n\007REMOVAL\020\007\022\014" + - "\n\010DIVIDEND\020\010\022\014\n\010INTEREST\020\t\022\023\n\017INTEREST_C" + - "HARGE\020\n\022\007\n\003TAX\020\013\022\016\n\nTAX_REFUND\020\014\022\007\n\003FEE\020" + - "\r\022\016\n\nFEE_REFUND\020\016B\n\n\010_accountB\014\n\n_portfo" + - "lioB\017\n\r_otherAccountB\021\n\017_otherPortfolioB" + - "\014\n\n_otherUuidB\021\n\017_otherUpdatedAtB\t\n\007_sha" + - "resB\007\n\005_noteB\013\n\t_securityB\t\n\007_source\"\335\003\n" + - "\017PInvestmentPlan\022\014\n\004name\030\001 \001(\t\022\021\n\004note\030\002" + - " \001(\tH\000\210\001\001\022\025\n\010security\030\003 \001(\tH\001\210\001\001\022\026\n\tport" + - "folio\030\004 \001(\tH\002\210\001\001\022\024\n\007account\030\005 \001(\tH\003\210\001\001\0225" + - "\n\nattributes\030\006 \003(\0132!.name.abuchen.portfo" + - "lio.PKeyValue\022\024\n\014autoGenerate\030\007 \001(\010\022\014\n\004d" + - "ate\030\010 \001(\003\022\020\n\010interval\030\t \001(\005\022\016\n\006amount\030\n " + - "\001(\003\022\014\n\004fees\030\013 \001(\003\022\024\n\014transactions\030\014 \003(\t\022" + - "\r\n\005taxes\030\r \001(\003\022:\n\004type\030\016 \001(\0162,.name.abuc" + - "hen.portfolio.PInvestmentPlan.Type\"H\n\004Ty" + - "pe\022\030\n\024PURCHASE_OR_DELIVERY\020\000\022\013\n\007DEPOSIT\020" + - "\001\022\013\n\007REMOVAL\020\002\022\014\n\010INTEREST\020\003B\007\n\005_noteB\013\n" + - "\t_securityB\014\n\n_portfolioB\n\n\010_account\"\252\004\n" + - "\tPTaxonomy\022\n\n\002id\030\001 \001(\t\022\014\n\004name\030\002 \001(\t\022\023\n\006" + - "source\030\003 \001(\tH\000\210\001\001\022\022\n\ndimensions\030\004 \003(\t\022I\n" + - "\017classifications\030\005 \003(\01320.name.abuchen.po" + - "rtfolio.PTaxonomy.Classification\032v\n\nAssi" + - "gnment\022\031\n\021investmentVehicle\030\001 \001(\t\022\016\n\006wei" + - "ght\030\002 \001(\005\022\014\n\004rank\030\003 \001(\005\022/\n\004data\030\004 \003(\0132!." + - "name.abuchen.portfolio.PKeyValue\032\213\002\n\016Cla" + - "ssification\022\n\n\002id\030\001 \001(\t\022\025\n\010parentId\030\002 \001(" + - "\tH\000\210\001\001\022\014\n\004name\030\003 \001(\t\022\021\n\004note\030\004 \001(\tH\001\210\001\001\022" + - "\r\n\005color\030\005 \001(\t\022\016\n\006weight\030\006 \001(\005\022\014\n\004rank\030\007" + - " \001(\005\022/\n\004data\030\010 \003(\0132!.name.abuchen.portfo" + - "lio.PKeyValue\022A\n\013assignments\030\t \003(\0132,.nam" + - "e.abuchen.portfolio.PTaxonomy.Assignment" + - "B\013\n\t_parentIdB\007\n\005_noteB\t\n\007_source\"\357\003\n\nPD" + - "ashboard\022\014\n\004name\030\001 \001(\t\022L\n\rconfiguration\030" + - "\002 \003(\01325.name.abuchen.portfolio.PDashboar" + - "d.ConfigurationEntry\022:\n\007columns\030\003 \003(\0132)." + - "name.abuchen.portfolio.PDashboard.Column" + - "\022\n\n\002id\030\004 \001(\t\032\260\001\n\006Widget\022\014\n\004type\030\001 \001(\t\022\r\n" + - "\005label\030\002 \001(\t\022S\n\rconfiguration\030\003 \003(\0132<.na" + - "me.abuchen.portfolio.PDashboard.Widget.C" + - "onfigurationEntry\0324\n\022ConfigurationEntry\022" + - "\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\032T\n\006Colum" + - "n\022\016\n\006weight\030\001 \001(\005\022:\n\007widgets\030\002 \003(\0132).nam" + - "e.abuchen.portfolio.PDashboard.Widget\0324\n" + - "\022ConfigurationEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005valu" + - "e\030\002 \001(\t:\0028\001\"+\n\tPBookmark\022\r\n\005label\030\001 \001(\t\022" + - "\017\n\007pattern\030\002 \001(\t\"\307\001\n\016PAttributeType\022\n\n\002i" + - "d\030\001 \001(\t\022\014\n\004name\030\002 \001(\t\022\023\n\013columnLabel\030\003 \001" + - "(\t\022\023\n\006source\030\004 \001(\tH\000\210\001\001\022\016\n\006target\030\005 \001(\t\022" + - "\014\n\004type\030\006 \001(\t\022\026\n\016converterClass\030\007 \001(\t\0220\n" + - "\nproperties\030\010 \001(\0132\034.name.abuchen.portfol" + - "io.PMapB\t\n\007_source\"J\n\021PConfigurationSet\022" + - "\013\n\003key\030\001 \001(\t\022\014\n\004uuid\030\002 \001(\t\022\014\n\004name\030\003 \001(\t" + - "\022\014\n\004data\030\004 \001(\t\"\307\001\n\tPSettings\0224\n\tbookmark" + - "s\030\001 \003(\0132!.name.abuchen.portfolio.PBookma" + - "rk\022>\n\016attributeTypes\030\002 \003(\0132&.name.abuche" + - "n.portfolio.PAttributeType\022D\n\021configurat" + - "ionSets\030\003 \003(\0132).name.abuchen.portfolio.P" + - "ConfigurationSet\"\305\005\n\007PClient\022\017\n\007version\030" + - "\001 \001(\005\0225\n\nsecurities\030\002 \003(\0132!.name.abuchen" + - ".portfolio.PSecurity\0222\n\010accounts\030\003 \003(\0132 " + - ".name.abuchen.portfolio.PAccount\0226\n\nport" + - "folios\030\004 \003(\0132\".name.abuchen.portfolio.PP" + - "ortfolio\022:\n\014transactions\030\005 \003(\0132$.name.ab" + - "uchen.portfolio.PTransaction\0226\n\005plans\030\006 " + - "\003(\0132\'.name.abuchen.portfolio.PInvestment" + - "Plan\0226\n\nwatchlists\030\007 \003(\0132\".name.abuchen." + - "portfolio.PWatchlist\0225\n\ntaxonomies\030\010 \003(\013" + - "2!.name.abuchen.portfolio.PTaxonomy\0226\n\nd" + - "ashboards\030\t \003(\0132\".name.abuchen.portfolio" + - ".PDashboard\022C\n\nproperties\030\n \003(\0132/.name.a" + - "buchen.portfolio.PClient.PropertiesEntry" + - "\0223\n\010settings\030\013 \001(\0132!.name.abuchen.portfo" + - "lio.PSettings\022\024\n\014baseCurrency\030\014 \001(\t\022(\n\ne" + - "xtensions\030c \003(\0132\024.google.protobuf.Any\0321\n" + - "\017PropertiesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002" + - " \001(\t:\0028\001\"S\n\rPExchangeRate\022\014\n\004date\030\001 \001(\003\022" + - "4\n\005value\030\002 \001(\0132%.name.abuchen.portfolio." + - "PDecimalValue\"\203\001\n\027PExchangeRateTimeSerie" + - "s\022\024\n\014baseCurrency\030\001 \001(\t\022\024\n\014termCurrency\030" + - "\002 \001(\t\022<\n\rexchangeRates\030\003 \003(\0132%.name.abuc" + - "hen.portfolio.PExchangeRate\"a\n\010PECBData\022" + - "\024\n\014lastModified\030\001 \001(\003\022?\n\006series\030\002 \003(\0132/." + - "name.abuchen.portfolio.PExchangeRateTime" + - "SeriesB7\n%name.abuchen.portfolio.model.p" + - "roto.v1B\014ClientProtosP\001b\006proto3" + ".google.protobuf.Timestamp\022\023\n\006dateEx\030\022 \001" + + "(\003H\006\210\001\001\022\024\n\014currencyCode\030\n \001(\t\022\016\n\006amount\030" + + "\013 \001(\003\022\023\n\006shares\030\014 \001(\003H\007\210\001\001\022\021\n\004note\030\r \001(\t" + + "H\010\210\001\001\022\025\n\010security\030\016 \001(\tH\t\210\001\001\0227\n\005units\030\017 " + + "\003(\0132(.name.abuchen.portfolio.PTransactio" + + "nUnit\022-\n\tupdatedAt\030\020 \001(\0132\032.google.protob" + + "uf.Timestamp\022\023\n\006source\030\021 \001(\tH\n\210\001\001\"\362\001\n\004Ty" + + "pe\022\014\n\010PURCHASE\020\000\022\010\n\004SALE\020\001\022\024\n\020INBOUND_DE" + + "LIVERY\020\002\022\025\n\021OUTBOUND_DELIVERY\020\003\022\025\n\021SECUR" + + "ITY_TRANSFER\020\004\022\021\n\rCASH_TRANSFER\020\005\022\013\n\007DEP" + + "OSIT\020\006\022\013\n\007REMOVAL\020\007\022\014\n\010DIVIDEND\020\010\022\014\n\010INT" + + "EREST\020\t\022\023\n\017INTEREST_CHARGE\020\n\022\007\n\003TAX\020\013\022\016\n" + + "\nTAX_REFUND\020\014\022\007\n\003FEE\020\r\022\016\n\nFEE_REFUND\020\016B\n" + + "\n\010_accountB\014\n\n_portfolioB\017\n\r_otherAccoun" + + "tB\021\n\017_otherPortfolioB\014\n\n_otherUuidB\021\n\017_o" + + "therUpdatedAtB\t\n\007_dateExB\t\n\007_sharesB\007\n\005_" + + "noteB\013\n\t_securityB\t\n\007_source\"\335\003\n\017PInvest" + + "mentPlan\022\014\n\004name\030\001 \001(\t\022\021\n\004note\030\002 \001(\tH\000\210\001" + + "\001\022\025\n\010security\030\003 \001(\tH\001\210\001\001\022\026\n\tportfolio\030\004 " + + "\001(\tH\002\210\001\001\022\024\n\007account\030\005 \001(\tH\003\210\001\001\0225\n\nattrib" + + "utes\030\006 \003(\0132!.name.abuchen.portfolio.PKey" + + "Value\022\024\n\014autoGenerate\030\007 \001(\010\022\014\n\004date\030\010 \001(" + + "\003\022\020\n\010interval\030\t \001(\005\022\016\n\006amount\030\n \001(\003\022\014\n\004f" + + "ees\030\013 \001(\003\022\024\n\014transactions\030\014 \003(\t\022\r\n\005taxes" + + "\030\r \001(\003\022:\n\004type\030\016 \001(\0162,.name.abuchen.port" + + "folio.PInvestmentPlan.Type\"H\n\004Type\022\030\n\024PU" + + "RCHASE_OR_DELIVERY\020\000\022\013\n\007DEPOSIT\020\001\022\013\n\007REM" + + "OVAL\020\002\022\014\n\010INTEREST\020\003B\007\n\005_noteB\013\n\t_securi" + + "tyB\014\n\n_portfolioB\n\n\010_account\"\252\004\n\tPTaxono" + + "my\022\n\n\002id\030\001 \001(\t\022\014\n\004name\030\002 \001(\t\022\023\n\006source\030\003" + + " \001(\tH\000\210\001\001\022\022\n\ndimensions\030\004 \003(\t\022I\n\017classif" + + "ications\030\005 \003(\01320.name.abuchen.portfolio." + + "PTaxonomy.Classification\032v\n\nAssignment\022\031" + + "\n\021investmentVehicle\030\001 \001(\t\022\016\n\006weight\030\002 \001(" + + "\005\022\014\n\004rank\030\003 \001(\005\022/\n\004data\030\004 \003(\0132!.name.abu" + + "chen.portfolio.PKeyValue\032\213\002\n\016Classificat" + + "ion\022\n\n\002id\030\001 \001(\t\022\025\n\010parentId\030\002 \001(\tH\000\210\001\001\022\014" + + "\n\004name\030\003 \001(\t\022\021\n\004note\030\004 \001(\tH\001\210\001\001\022\r\n\005color" + + "\030\005 \001(\t\022\016\n\006weight\030\006 \001(\005\022\014\n\004rank\030\007 \001(\005\022/\n\004" + + "data\030\010 \003(\0132!.name.abuchen.portfolio.PKey" + + "Value\022A\n\013assignments\030\t \003(\0132,.name.abuche" + + "n.portfolio.PTaxonomy.AssignmentB\013\n\t_par" + + "entIdB\007\n\005_noteB\t\n\007_source\"\357\003\n\nPDashboard" + + "\022\014\n\004name\030\001 \001(\t\022L\n\rconfiguration\030\002 \003(\01325." + + "name.abuchen.portfolio.PDashboard.Config" + + "urationEntry\022:\n\007columns\030\003 \003(\0132).name.abu" + + "chen.portfolio.PDashboard.Column\022\n\n\002id\030\004" + + " \001(\t\032\260\001\n\006Widget\022\014\n\004type\030\001 \001(\t\022\r\n\005label\030\002" + + " \001(\t\022S\n\rconfiguration\030\003 \003(\0132<.name.abuch" + + "en.portfolio.PDashboard.Widget.Configura" + + "tionEntry\0324\n\022ConfigurationEntry\022\013\n\003key\030\001" + + " \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\032T\n\006Column\022\016\n\006wei" + + "ght\030\001 \001(\005\022:\n\007widgets\030\002 \003(\0132).name.abuche" + + "n.portfolio.PDashboard.Widget\0324\n\022Configu" + + "rationEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:" + + "\0028\001\"+\n\tPBookmark\022\r\n\005label\030\001 \001(\t\022\017\n\007patte" + + "rn\030\002 \001(\t\"\307\001\n\016PAttributeType\022\n\n\002id\030\001 \001(\t\022" + + "\014\n\004name\030\002 \001(\t\022\023\n\013columnLabel\030\003 \001(\t\022\023\n\006so" + + "urce\030\004 \001(\tH\000\210\001\001\022\016\n\006target\030\005 \001(\t\022\014\n\004type\030" + + "\006 \001(\t\022\026\n\016converterClass\030\007 \001(\t\0220\n\npropert" + + "ies\030\010 \001(\0132\034.name.abuchen.portfolio.PMapB" + + "\t\n\007_source\"J\n\021PConfigurationSet\022\013\n\003key\030\001" + + " \001(\t\022\014\n\004uuid\030\002 \001(\t\022\014\n\004name\030\003 \001(\t\022\014\n\004data" + + "\030\004 \001(\t\"\307\001\n\tPSettings\0224\n\tbookmarks\030\001 \003(\0132" + + "!.name.abuchen.portfolio.PBookmark\022>\n\016at" + + "tributeTypes\030\002 \003(\0132&.name.abuchen.portfo" + + "lio.PAttributeType\022D\n\021configurationSets\030" + + "\003 \003(\0132).name.abuchen.portfolio.PConfigur" + + "ationSet\"\305\005\n\007PClient\022\017\n\007version\030\001 \001(\005\0225\n" + + "\nsecurities\030\002 \003(\0132!.name.abuchen.portfol" + + "io.PSecurity\0222\n\010accounts\030\003 \003(\0132 .name.ab" + + "uchen.portfolio.PAccount\0226\n\nportfolios\030\004" + + " \003(\0132\".name.abuchen.portfolio.PPortfolio" + + "\022:\n\014transactions\030\005 \003(\0132$.name.abuchen.po" + + "rtfolio.PTransaction\0226\n\005plans\030\006 \003(\0132\'.na" + + "me.abuchen.portfolio.PInvestmentPlan\0226\n\n" + + "watchlists\030\007 \003(\0132\".name.abuchen.portfoli" + + "o.PWatchlist\0225\n\ntaxonomies\030\010 \003(\0132!.name." + + "abuchen.portfolio.PTaxonomy\0226\n\ndashboard" + + "s\030\t \003(\0132\".name.abuchen.portfolio.PDashbo" + + "ard\022C\n\nproperties\030\n \003(\0132/.name.abuchen.p" + + "ortfolio.PClient.PropertiesEntry\0223\n\010sett" + + "ings\030\013 \001(\0132!.name.abuchen.portfolio.PSet" + + "tings\022\024\n\014baseCurrency\030\014 \001(\t\022(\n\nextension" + + "s\030c \003(\0132\024.google.protobuf.Any\0321\n\017Propert" + + "iesEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001" + + "\"S\n\rPExchangeRate\022\014\n\004date\030\001 \001(\003\0224\n\005value" + + "\030\002 \001(\0132%.name.abuchen.portfolio.PDecimal" + + "Value\"\203\001\n\027PExchangeRateTimeSeries\022\024\n\014bas" + + "eCurrency\030\001 \001(\t\022\024\n\014termCurrency\030\002 \001(\t\022<\n" + + "\rexchangeRates\030\003 \003(\0132%.name.abuchen.port" + + "folio.PExchangeRate\"a\n\010PECBData\022\024\n\014lastM" + + "odified\030\001 \001(\003\022?\n\006series\030\002 \003(\0132/.name.abu" + + "chen.portfolio.PExchangeRateTimeSeriesB7" + + "\n%name.abuchen.portfolio.model.proto.v1B" + + "\014ClientProtosP\001b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -430,7 +431,7 @@ public static void registerAllExtensions( internal_static_name_abuchen_portfolio_PTransaction_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_name_abuchen_portfolio_PTransaction_descriptor, - new java.lang.String[] { "Uuid", "Type", "Account", "Portfolio", "OtherAccount", "OtherPortfolio", "OtherUuid", "OtherUpdatedAt", "Date", "CurrencyCode", "Amount", "Shares", "Note", "Security", "Units", "UpdatedAt", "Source", "Account", "Portfolio", "OtherAccount", "OtherPortfolio", "OtherUuid", "OtherUpdatedAt", "Shares", "Note", "Security", "Source", }); + new java.lang.String[] { "Uuid", "Type", "Account", "Portfolio", "OtherAccount", "OtherPortfolio", "OtherUuid", "OtherUpdatedAt", "Date", "DateEx", "CurrencyCode", "Amount", "Shares", "Note", "Security", "Units", "UpdatedAt", "Source", "Account", "Portfolio", "OtherAccount", "OtherPortfolio", "OtherUuid", "OtherUpdatedAt", "DateEx", "Shares", "Note", "Security", "Source", }); internal_static_name_abuchen_portfolio_PInvestmentPlan_descriptor = getDescriptor().getMessageTypes().get(13); internal_static_name_abuchen_portfolio_PInvestmentPlan_fieldAccessorTable = new diff --git a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PTransaction.java b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PTransaction.java index 78b5a1a5aa..fb43a00493 100644 --- a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PTransaction.java +++ b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PTransaction.java @@ -620,6 +620,25 @@ public com.google.protobuf.TimestampOrBuilder getDateOrBuilder() { return date_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : date_; } + public static final int DATEEX_FIELD_NUMBER = 18; + private long dateEx_ = 0L; + /** + * optional int64 dateEx = 18; + * @return Whether the dateEx field is set. + */ + @java.lang.Override + public boolean hasDateEx() { + return ((bitField0_ & 0x00000040) != 0); + } + /** + * optional int64 dateEx = 18; + * @return The dateEx. + */ + @java.lang.Override + public long getDateEx() { + return dateEx_; + } + public static final int CURRENCYCODE_FIELD_NUMBER = 10; @SuppressWarnings("serial") private volatile java.lang.Object currencyCode_ = ""; @@ -678,7 +697,7 @@ public long getAmount() { */ @java.lang.Override public boolean hasShares() { - return ((bitField0_ & 0x00000040) != 0); + return ((bitField0_ & 0x00000080) != 0); } /** * optional int64 shares = 12; @@ -698,7 +717,7 @@ public long getShares() { */ @java.lang.Override public boolean hasNote() { - return ((bitField0_ & 0x00000080) != 0); + return ((bitField0_ & 0x00000100) != 0); } /** * optional string note = 13; @@ -745,7 +764,7 @@ public java.lang.String getNote() { */ @java.lang.Override public boolean hasSecurity() { - return ((bitField0_ & 0x00000100) != 0); + return ((bitField0_ & 0x00000200) != 0); } /** * optional string security = 14; @@ -859,7 +878,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdatedAtOrBuilder() { */ @java.lang.Override public boolean hasSource() { - return ((bitField0_ & 0x00000200) != 0); + return ((bitField0_ & 0x00000400) != 0); } /** * optional string source = 17; @@ -944,13 +963,13 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (amount_ != 0L) { output.writeInt64(11, amount_); } - if (((bitField0_ & 0x00000040) != 0)) { + if (((bitField0_ & 0x00000080) != 0)) { output.writeInt64(12, shares_); } - if (((bitField0_ & 0x00000080) != 0)) { + if (((bitField0_ & 0x00000100) != 0)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 13, note_); } - if (((bitField0_ & 0x00000100) != 0)) { + if (((bitField0_ & 0x00000200) != 0)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 14, security_); } for (int i = 0; i < units_.size(); i++) { @@ -959,9 +978,12 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (updatedAt_ != null) { output.writeMessage(16, getUpdatedAt()); } - if (((bitField0_ & 0x00000200) != 0)) { + if (((bitField0_ & 0x00000400) != 0)) { com.google.protobuf.GeneratedMessageV3.writeString(output, 17, source_); } + if (((bitField0_ & 0x00000040) != 0)) { + output.writeInt64(18, dateEx_); + } getUnknownFields().writeTo(output); } @@ -1008,14 +1030,14 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeInt64Size(11, amount_); } - if (((bitField0_ & 0x00000040) != 0)) { + if (((bitField0_ & 0x00000080) != 0)) { size += com.google.protobuf.CodedOutputStream .computeInt64Size(12, shares_); } - if (((bitField0_ & 0x00000080) != 0)) { + if (((bitField0_ & 0x00000100) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(13, note_); } - if (((bitField0_ & 0x00000100) != 0)) { + if (((bitField0_ & 0x00000200) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(14, security_); } for (int i = 0; i < units_.size(); i++) { @@ -1026,9 +1048,13 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeMessageSize(16, getUpdatedAt()); } - if (((bitField0_ & 0x00000200) != 0)) { + if (((bitField0_ & 0x00000400) != 0)) { size += com.google.protobuf.GeneratedMessageV3.computeStringSize(17, source_); } + if (((bitField0_ & 0x00000040) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(18, dateEx_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -1082,6 +1108,11 @@ public boolean equals(final java.lang.Object obj) { if (!getDate() .equals(other.getDate())) return false; } + if (hasDateEx() != other.hasDateEx()) return false; + if (hasDateEx()) { + if (getDateEx() + != other.getDateEx()) return false; + } if (!getCurrencyCode() .equals(other.getCurrencyCode())) return false; if (getAmount() @@ -1156,6 +1187,11 @@ public int hashCode() { hash = (37 * hash) + DATE_FIELD_NUMBER; hash = (53 * hash) + getDate().hashCode(); } + if (hasDateEx()) { + hash = (37 * hash) + DATEEX_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getDateEx()); + } hash = (37 * hash) + CURRENCYCODE_FIELD_NUMBER; hash = (53 * hash) + getCurrencyCode().hashCode(); hash = (37 * hash) + AMOUNT_FIELD_NUMBER; @@ -1341,6 +1377,7 @@ public Builder clear() { dateBuilder_.dispose(); dateBuilder_ = null; } + dateEx_ = 0L; currencyCode_ = ""; amount_ = 0L; shares_ = 0L; @@ -1352,7 +1389,7 @@ public Builder clear() { units_ = null; unitsBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00004000); + bitField0_ = (bitField0_ & ~0x00008000); updatedAt_ = null; if (updatedAtBuilder_ != null) { updatedAtBuilder_.dispose(); @@ -1393,9 +1430,9 @@ public name.abuchen.portfolio.model.proto.v1.PTransaction buildPartial() { private void buildPartialRepeatedFields(name.abuchen.portfolio.model.proto.v1.PTransaction result) { if (unitsBuilder_ == null) { - if (((bitField0_ & 0x00004000) != 0)) { + if (((bitField0_ & 0x00008000) != 0)) { units_ = java.util.Collections.unmodifiableList(units_); - bitField0_ = (bitField0_ & ~0x00004000); + bitField0_ = (bitField0_ & ~0x00008000); } result.units_ = units_; } else { @@ -1444,31 +1481,35 @@ private void buildPartial0(name.abuchen.portfolio.model.proto.v1.PTransaction re : dateBuilder_.build(); } if (((from_bitField0_ & 0x00000200) != 0)) { - result.currencyCode_ = currencyCode_; + result.dateEx_ = dateEx_; + to_bitField0_ |= 0x00000040; } if (((from_bitField0_ & 0x00000400) != 0)) { - result.amount_ = amount_; + result.currencyCode_ = currencyCode_; } if (((from_bitField0_ & 0x00000800) != 0)) { - result.shares_ = shares_; - to_bitField0_ |= 0x00000040; + result.amount_ = amount_; } if (((from_bitField0_ & 0x00001000) != 0)) { - result.note_ = note_; + result.shares_ = shares_; to_bitField0_ |= 0x00000080; } if (((from_bitField0_ & 0x00002000) != 0)) { - result.security_ = security_; + result.note_ = note_; to_bitField0_ |= 0x00000100; } - if (((from_bitField0_ & 0x00008000) != 0)) { + if (((from_bitField0_ & 0x00004000) != 0)) { + result.security_ = security_; + to_bitField0_ |= 0x00000200; + } + if (((from_bitField0_ & 0x00010000) != 0)) { result.updatedAt_ = updatedAtBuilder_ == null ? updatedAt_ : updatedAtBuilder_.build(); } - if (((from_bitField0_ & 0x00010000) != 0)) { + if (((from_bitField0_ & 0x00020000) != 0)) { result.source_ = source_; - to_bitField0_ |= 0x00000200; + to_bitField0_ |= 0x00000400; } result.bitField0_ |= to_bitField0_; } @@ -1524,9 +1565,12 @@ public Builder mergeFrom(name.abuchen.portfolio.model.proto.v1.PTransaction othe if (other.hasDate()) { mergeDate(other.getDate()); } + if (other.hasDateEx()) { + setDateEx(other.getDateEx()); + } if (!other.getCurrencyCode().isEmpty()) { currencyCode_ = other.currencyCode_; - bitField0_ |= 0x00000200; + bitField0_ |= 0x00000400; onChanged(); } if (other.getAmount() != 0L) { @@ -1537,19 +1581,19 @@ public Builder mergeFrom(name.abuchen.portfolio.model.proto.v1.PTransaction othe } if (other.hasNote()) { note_ = other.note_; - bitField0_ |= 0x00001000; + bitField0_ |= 0x00002000; onChanged(); } if (other.hasSecurity()) { security_ = other.security_; - bitField0_ |= 0x00002000; + bitField0_ |= 0x00004000; onChanged(); } if (unitsBuilder_ == null) { if (!other.units_.isEmpty()) { if (units_.isEmpty()) { units_ = other.units_; - bitField0_ = (bitField0_ & ~0x00004000); + bitField0_ = (bitField0_ & ~0x00008000); } else { ensureUnitsIsMutable(); units_.addAll(other.units_); @@ -1562,7 +1606,7 @@ public Builder mergeFrom(name.abuchen.portfolio.model.proto.v1.PTransaction othe unitsBuilder_.dispose(); unitsBuilder_ = null; units_ = other.units_; - bitField0_ = (bitField0_ & ~0x00004000); + bitField0_ = (bitField0_ & ~0x00008000); unitsBuilder_ = com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? getUnitsFieldBuilder() : null; @@ -1576,7 +1620,7 @@ public Builder mergeFrom(name.abuchen.portfolio.model.proto.v1.PTransaction othe } if (other.hasSource()) { source_ = other.source_; - bitField0_ |= 0x00010000; + bitField0_ |= 0x00020000; onChanged(); } this.mergeUnknownFields(other.getUnknownFields()); @@ -1656,27 +1700,27 @@ public Builder mergeFrom( } // case 74 case 82: { currencyCode_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00000200; + bitField0_ |= 0x00000400; break; } // case 82 case 88: { amount_ = input.readInt64(); - bitField0_ |= 0x00000400; + bitField0_ |= 0x00000800; break; } // case 88 case 96: { shares_ = input.readInt64(); - bitField0_ |= 0x00000800; + bitField0_ |= 0x00001000; break; } // case 96 case 106: { note_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00001000; + bitField0_ |= 0x00002000; break; } // case 106 case 114: { security_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00002000; + bitField0_ |= 0x00004000; break; } // case 114 case 122: { @@ -1696,14 +1740,19 @@ public Builder mergeFrom( input.readMessage( getUpdatedAtFieldBuilder().getBuilder(), extensionRegistry); - bitField0_ |= 0x00008000; + bitField0_ |= 0x00010000; break; } // case 130 case 138: { source_ = input.readStringRequireUtf8(); - bitField0_ |= 0x00010000; + bitField0_ |= 0x00020000; break; } // case 138 + case 144: { + dateEx_ = input.readInt64(); + bitField0_ |= 0x00000200; + break; + } // case 144 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -2479,6 +2528,46 @@ public com.google.protobuf.TimestampOrBuilder getDateOrBuilder() { return dateBuilder_; } + private long dateEx_ ; + /** + * optional int64 dateEx = 18; + * @return Whether the dateEx field is set. + */ + @java.lang.Override + public boolean hasDateEx() { + return ((bitField0_ & 0x00000200) != 0); + } + /** + * optional int64 dateEx = 18; + * @return The dateEx. + */ + @java.lang.Override + public long getDateEx() { + return dateEx_; + } + /** + * optional int64 dateEx = 18; + * @param value The dateEx to set. + * @return This builder for chaining. + */ + public Builder setDateEx(long value) { + + dateEx_ = value; + bitField0_ |= 0x00000200; + onChanged(); + return this; + } + /** + * optional int64 dateEx = 18; + * @return This builder for chaining. + */ + public Builder clearDateEx() { + bitField0_ = (bitField0_ & ~0x00000200); + dateEx_ = 0L; + onChanged(); + return this; + } + private java.lang.Object currencyCode_ = ""; /** * string currencyCode = 10; @@ -2522,7 +2611,7 @@ public Builder setCurrencyCode( java.lang.String value) { if (value == null) { throw new NullPointerException(); } currencyCode_ = value; - bitField0_ |= 0x00000200; + bitField0_ |= 0x00000400; onChanged(); return this; } @@ -2532,7 +2621,7 @@ public Builder setCurrencyCode( */ public Builder clearCurrencyCode() { currencyCode_ = getDefaultInstance().getCurrencyCode(); - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000400); onChanged(); return this; } @@ -2546,7 +2635,7 @@ public Builder setCurrencyCodeBytes( if (value == null) { throw new NullPointerException(); } checkByteStringIsUtf8(value); currencyCode_ = value; - bitField0_ |= 0x00000200; + bitField0_ |= 0x00000400; onChanged(); return this; } @@ -2568,7 +2657,7 @@ public long getAmount() { public Builder setAmount(long value) { amount_ = value; - bitField0_ |= 0x00000400; + bitField0_ |= 0x00000800; onChanged(); return this; } @@ -2577,7 +2666,7 @@ public Builder setAmount(long value) { * @return This builder for chaining. */ public Builder clearAmount() { - bitField0_ = (bitField0_ & ~0x00000400); + bitField0_ = (bitField0_ & ~0x00000800); amount_ = 0L; onChanged(); return this; @@ -2590,7 +2679,7 @@ public Builder clearAmount() { */ @java.lang.Override public boolean hasShares() { - return ((bitField0_ & 0x00000800) != 0); + return ((bitField0_ & 0x00001000) != 0); } /** * optional int64 shares = 12; @@ -2608,7 +2697,7 @@ public long getShares() { public Builder setShares(long value) { shares_ = value; - bitField0_ |= 0x00000800; + bitField0_ |= 0x00001000; onChanged(); return this; } @@ -2617,7 +2706,7 @@ public Builder setShares(long value) { * @return This builder for chaining. */ public Builder clearShares() { - bitField0_ = (bitField0_ & ~0x00000800); + bitField0_ = (bitField0_ & ~0x00001000); shares_ = 0L; onChanged(); return this; @@ -2629,7 +2718,7 @@ public Builder clearShares() { * @return Whether the note field is set. */ public boolean hasNote() { - return ((bitField0_ & 0x00001000) != 0); + return ((bitField0_ & 0x00002000) != 0); } /** * optional string note = 13; @@ -2673,7 +2762,7 @@ public Builder setNote( java.lang.String value) { if (value == null) { throw new NullPointerException(); } note_ = value; - bitField0_ |= 0x00001000; + bitField0_ |= 0x00002000; onChanged(); return this; } @@ -2683,7 +2772,7 @@ public Builder setNote( */ public Builder clearNote() { note_ = getDefaultInstance().getNote(); - bitField0_ = (bitField0_ & ~0x00001000); + bitField0_ = (bitField0_ & ~0x00002000); onChanged(); return this; } @@ -2697,7 +2786,7 @@ public Builder setNoteBytes( if (value == null) { throw new NullPointerException(); } checkByteStringIsUtf8(value); note_ = value; - bitField0_ |= 0x00001000; + bitField0_ |= 0x00002000; onChanged(); return this; } @@ -2708,7 +2797,7 @@ public Builder setNoteBytes( * @return Whether the security field is set. */ public boolean hasSecurity() { - return ((bitField0_ & 0x00002000) != 0); + return ((bitField0_ & 0x00004000) != 0); } /** * optional string security = 14; @@ -2752,7 +2841,7 @@ public Builder setSecurity( java.lang.String value) { if (value == null) { throw new NullPointerException(); } security_ = value; - bitField0_ |= 0x00002000; + bitField0_ |= 0x00004000; onChanged(); return this; } @@ -2762,7 +2851,7 @@ public Builder setSecurity( */ public Builder clearSecurity() { security_ = getDefaultInstance().getSecurity(); - bitField0_ = (bitField0_ & ~0x00002000); + bitField0_ = (bitField0_ & ~0x00004000); onChanged(); return this; } @@ -2776,7 +2865,7 @@ public Builder setSecurityBytes( if (value == null) { throw new NullPointerException(); } checkByteStringIsUtf8(value); security_ = value; - bitField0_ |= 0x00002000; + bitField0_ |= 0x00004000; onChanged(); return this; } @@ -2784,9 +2873,9 @@ public Builder setSecurityBytes( private java.util.List units_ = java.util.Collections.emptyList(); private void ensureUnitsIsMutable() { - if (!((bitField0_ & 0x00004000) != 0)) { + if (!((bitField0_ & 0x00008000) != 0)) { units_ = new java.util.ArrayList(units_); - bitField0_ |= 0x00004000; + bitField0_ |= 0x00008000; } } @@ -2936,7 +3025,7 @@ public Builder addAllUnits( public Builder clearUnits() { if (unitsBuilder_ == null) { units_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00004000); + bitField0_ = (bitField0_ & ~0x00008000); onChanged(); } else { unitsBuilder_.clear(); @@ -3013,7 +3102,7 @@ public name.abuchen.portfolio.model.proto.v1.PTransactionUnit.Builder addUnitsBu unitsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< name.abuchen.portfolio.model.proto.v1.PTransactionUnit, name.abuchen.portfolio.model.proto.v1.PTransactionUnit.Builder, name.abuchen.portfolio.model.proto.v1.PTransactionUnitOrBuilder>( units_, - ((bitField0_ & 0x00004000) != 0), + ((bitField0_ & 0x00008000) != 0), getParentForChildren(), isClean()); units_ = null; @@ -3029,7 +3118,7 @@ public name.abuchen.portfolio.model.proto.v1.PTransactionUnit.Builder addUnitsBu * @return Whether the updatedAt field is set. */ public boolean hasUpdatedAt() { - return ((bitField0_ & 0x00008000) != 0); + return ((bitField0_ & 0x00010000) != 0); } /** * .google.protobuf.Timestamp updatedAt = 16; @@ -3054,7 +3143,7 @@ public Builder setUpdatedAt(com.google.protobuf.Timestamp value) { } else { updatedAtBuilder_.setMessage(value); } - bitField0_ |= 0x00008000; + bitField0_ |= 0x00010000; onChanged(); return this; } @@ -3068,7 +3157,7 @@ public Builder setUpdatedAt( } else { updatedAtBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00008000; + bitField0_ |= 0x00010000; onChanged(); return this; } @@ -3077,7 +3166,7 @@ public Builder setUpdatedAt( */ public Builder mergeUpdatedAt(com.google.protobuf.Timestamp value) { if (updatedAtBuilder_ == null) { - if (((bitField0_ & 0x00008000) != 0) && + if (((bitField0_ & 0x00010000) != 0) && updatedAt_ != null && updatedAt_ != com.google.protobuf.Timestamp.getDefaultInstance()) { getUpdatedAtBuilder().mergeFrom(value); @@ -3087,7 +3176,7 @@ public Builder mergeUpdatedAt(com.google.protobuf.Timestamp value) { } else { updatedAtBuilder_.mergeFrom(value); } - bitField0_ |= 0x00008000; + bitField0_ |= 0x00010000; onChanged(); return this; } @@ -3095,7 +3184,7 @@ public Builder mergeUpdatedAt(com.google.protobuf.Timestamp value) { * .google.protobuf.Timestamp updatedAt = 16; */ public Builder clearUpdatedAt() { - bitField0_ = (bitField0_ & ~0x00008000); + bitField0_ = (bitField0_ & ~0x00010000); updatedAt_ = null; if (updatedAtBuilder_ != null) { updatedAtBuilder_.dispose(); @@ -3108,7 +3197,7 @@ public Builder clearUpdatedAt() { * .google.protobuf.Timestamp updatedAt = 16; */ public com.google.protobuf.Timestamp.Builder getUpdatedAtBuilder() { - bitField0_ |= 0x00008000; + bitField0_ |= 0x00010000; onChanged(); return getUpdatedAtFieldBuilder().getBuilder(); } @@ -3146,7 +3235,7 @@ public com.google.protobuf.TimestampOrBuilder getUpdatedAtOrBuilder() { * @return Whether the source field is set. */ public boolean hasSource() { - return ((bitField0_ & 0x00010000) != 0); + return ((bitField0_ & 0x00020000) != 0); } /** * optional string source = 17; @@ -3190,7 +3279,7 @@ public Builder setSource( java.lang.String value) { if (value == null) { throw new NullPointerException(); } source_ = value; - bitField0_ |= 0x00010000; + bitField0_ |= 0x00020000; onChanged(); return this; } @@ -3200,7 +3289,7 @@ public Builder setSource( */ public Builder clearSource() { source_ = getDefaultInstance().getSource(); - bitField0_ = (bitField0_ & ~0x00010000); + bitField0_ = (bitField0_ & ~0x00020000); onChanged(); return this; } @@ -3214,7 +3303,7 @@ public Builder setSourceBytes( if (value == null) { throw new NullPointerException(); } checkByteStringIsUtf8(value); source_ = value; - bitField0_ |= 0x00010000; + bitField0_ |= 0x00020000; onChanged(); return this; } diff --git a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PTransactionOrBuilder.java b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PTransactionOrBuilder.java index 9873a6b262..24586fcbac 100644 --- a/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PTransactionOrBuilder.java +++ b/name.abuchen.portfolio/protos/name/abuchen/portfolio/model/proto/v1/PTransactionOrBuilder.java @@ -145,6 +145,17 @@ public interface PTransactionOrBuilder extends */ com.google.protobuf.TimestampOrBuilder getDateOrBuilder(); + /** + * optional int64 dateEx = 18; + * @return Whether the dateEx field is set. + */ + boolean hasDateEx(); + /** + * optional int64 dateEx = 18; + * @return The dateEx. + */ + long getDateEx(); + /** * string currencyCode = 10; * @return The currencyCode. diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/OnvistaPDFExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/OnvistaPDFExtractor.java index 2e0d46bd15..ab90b12930 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/OnvistaPDFExtractor.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/OnvistaPDFExtractor.java @@ -566,15 +566,17 @@ private void addDividendeTransaction() // STK 50,000 21.04.2016 21.04.2016 EUR 0,200000 // @formatter:on section -> section // - .attributes("name", "isin", "name1", "currency") // + .attributes("dateEx", "name", "isin", "name1", "currency") // .find("Gattungsbezeichnung ISIN") // .match("^(?.*) (?[A-Z]{2}[A-Z0-9]{9}[0-9])$") // .match("^([\\d]{2}\\.[\\d]{2}\\.[\\d]{2,4} )?(?.*)$") // - .match("^STK [\\.,\\d]+ [\\d]{2}\\.[\\d]{2}\\.[\\d]{2,4} [\\d]{2}\\.[\\d]{2}\\.[\\d]{2,4} (?[A-Z]{3}) [\\.,\\d]+$") // + .match("^STK [\\.,\\d]+ (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2,4}) [\\d]{2}\\.[\\d]{2}\\.[\\d]{2,4} (?[A-Z]{3}) [\\.,\\d]+$") // .assign((t, v) -> { if (!v.get("name1").startsWith("Nominal")) v.put("name", trim(v.get("name")) + " " + trim(v.get("name1"))); + t.setDateEx(asDate(v.get("dateEx")).toLocalDate()); + t.setSecurity(getOrCreateSecurity(v)); }), // @formatter:off diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/AccountTransaction.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/AccountTransaction.java index 0b0083bd36..431ed02169 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/AccountTransaction.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/AccountTransaction.java @@ -1,6 +1,7 @@ package name.abuchen.portfolio.model; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ResourceBundle; @@ -47,6 +48,8 @@ public String toString() private Type type; + private LocalDate dateEx; + public AccountTransaction() { // needed for xstream de-serialization @@ -74,6 +77,17 @@ public void setType(Type type) setUpdatedAt(Instant.now()); } + public LocalDate getDateEx() + { + return dateEx; + } + + public void setDateEx(LocalDate dateEx) + { + this.dateEx = dateEx; + setUpdatedAt(Instant.now()); + } + /** * Returns the gross value, i.e. the value before taxes and fees are * applied. See {@link #getGrossValue()}. diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Client.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Client.java index eba572579e..908876eb7b 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Client.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/Client.java @@ -31,7 +31,7 @@ public interface Properties // NOSONAR String WATCHLISTS = "watchlists"; //$NON-NLS-1$ } - public static final int CURRENT_VERSION = 68; + public static final int CURRENT_VERSION = 69; public static final int VERSION_WITH_CURRENCY_SUPPORT = 29; public static final int VERSION_WITH_UNIQUE_FILTER_KEY = 57; diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ClientFactory.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ClientFactory.java index f511f8c73d..2930ed52e9 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ClientFactory.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ClientFactory.java @@ -945,7 +945,8 @@ else if (flags.contains(SaveFlag.COMPRESSED)) fixLogoAttributeName(client); case 67: // NOSONAR removeSourceAttributeFromTaxonomy(client); - + case 68: // NOSONAR + // added exDate date field client.setVersion(Client.CURRENT_VERSION); break; case Client.CURRENT_VERSION: diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ProtobufWriter.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ProtobufWriter.java index 1cd3a579b2..e2f5b31dc8 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ProtobufWriter.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/ProtobufWriter.java @@ -474,6 +474,8 @@ private void loadTransactions(PClient newClient, Lookup lookup) case DIVIDEND: AccountTransaction dividend = new AccountTransaction(newTransaction.getUuid()); dividend.setType(AccountTransaction.Type.DIVIDENDS); + if (newTransaction.hasDateEx()) + dividend.setDateEx(LocalDate.ofEpochDay(newTransaction.getDateEx())); loadCommonTransaction(newTransaction, dividend, lookup, false); // If the dividend has no instrument, convert it to an @@ -1126,6 +1128,8 @@ private void addTransaction(PClient.Builder newClient, Account account, AccountT break; case DIVIDENDS: newTransaction.setTypeValue(PTransaction.Type.DIVIDEND_VALUE); + if (t.getDateEx() != null) + newTransaction.setDateEx(t.getDateEx().toEpochDay()); break; case FEES: newTransaction.setTypeValue(PTransaction.Type.FEE_VALUE); diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/client.proto b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/client.proto index d8859030cb..dcb6e039e5 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/model/client.proto +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/model/client.proto @@ -172,6 +172,7 @@ message PTransaction { optional google.protobuf.Timestamp otherUpdatedAt = 8; google.protobuf.Timestamp date = 9; + optional int64 dateEx = 18; string currencyCode = 10; int64 amount = 11;