Skip to content

Commit 78c0049

Browse files
ZfT2buchen
authored andcommitted
Introduce ex-date field for dividend transactions
Issue: #5439 Signed-off-by: XY <xy> [use custom Protobuf type; split commits; rebased to master] Signed-off-by: Andreas Buchen <andreas.buchen@gmail.com>
1 parent 100df94 commit 78c0049

File tree

17 files changed

+1240
-196
lines changed

17 files changed

+1240
-196
lines changed

name.abuchen.portfolio.tests/src/fileversions/ReadingHistoricClientFilesTest.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ public class ReadingHistoricClientFilesTest
2626
public static Collection<Object[]> getFiles()
2727
{
2828
return Arrays.asList(new Object[][] { // NOSONAR
29-
{ "client52", 52 }, { "client53", 53 } });
29+
{ "client52", 52 }, { "client53", 53 }, { "client69", 69 } });
3030
}
3131

32-
3332
private String file;
3433
private int versionOnDisk;
3534

@@ -55,10 +54,16 @@ public void compare() throws IOException
5554
String binaryEncrypted = ClientTestUtilities.toString(binaryEncryptedClient);
5655
assertThat(binaryEncryptedClient.getFileVersionAfterRead(), is(versionOnDisk));
5756

58-
Client xmlEncrpytedClient = ClientFactory.load(find(file + ".xml+pwd.portfolio"), "123456".toCharArray(),
59-
new NullProgressMonitor());
60-
String xmlEncrpyted = ClientTestUtilities.toString(xmlEncrpytedClient);
61-
assertThat(xmlEncrpytedClient.getFileVersionAfterRead(), is(versionOnDisk));
57+
String xmlEncrpyted = null;
58+
if (versionOnDisk < 60)
59+
{
60+
// encrypted files where the content is stored as XML are not
61+
// supported anymore
62+
Client xmlEncrpytedClient = ClientFactory.load(find(file + ".xml+pwd.portfolio"), "123456".toCharArray(),
63+
new NullProgressMonitor());
64+
xmlEncrpyted = ClientTestUtilities.toString(xmlEncrpytedClient);
65+
assertThat(xmlEncrpytedClient.getFileVersionAfterRead(), is(versionOnDisk));
66+
}
6267

6368
if (!xml.equals(binary))
6469
{
@@ -76,7 +81,7 @@ public void compare() throws IOException
7681
is(xml.substring(pos, Math.min(pos + 100, xml.length()))));
7782
}
7883

79-
if (!xml.equals(xmlEncrpyted))
84+
if (xmlEncrpyted != null && !xml.equals(xmlEncrpyted))
8085
{
8186
int pos = ClientTestUtilities.indexOfDifference(xml, xmlEncrpyted);
8287
assertThat("encrypted xml is not identical to xml " + pos,
Binary file not shown.
Binary file not shown.
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
<client>
2+
<version>69</version>
3+
<baseCurrency>EUR</baseCurrency>
4+
<securities>
5+
<security>
6+
<uuid>2bab2728-f3b2-4ca0-8330-825446831ade</uuid>
7+
<name>Commerzbank AG Inhaber-Aktien o.N.</name>
8+
<currencyCode>EUR</currencyCode>
9+
<isin>DE000CBK1001</isin>
10+
<tickerSymbol>CBK.DE</tickerSymbol>
11+
<feed>PP</feed>
12+
<prices/>
13+
<attributes>
14+
<map/>
15+
</attributes>
16+
<events/>
17+
<isRetired>false</isRetired>
18+
<updatedAt>2026-02-04T21:30:37.744832272Z</updatedAt>
19+
</security>
20+
</securities>
21+
<watchlists/>
22+
<accounts>
23+
<account>
24+
<uuid>6908edd0-1bb5-411e-bb4d-678a858eff66</uuid>
25+
<name>dividendExdate</name>
26+
<currencyCode>EUR</currencyCode>
27+
<isRetired>false</isRetired>
28+
<transactions>
29+
<account-transaction>
30+
<uuid>11d2ebf5-a0c5-4de1-b2f6-19a0a701e1f6</uuid>
31+
<date>2019-05-27T00:00</date>
32+
<currencyCode>EUR</currencyCode>
33+
<amount>1007</amount>
34+
<security reference="../../../../../securities/security"/>
35+
<shares>7000000000</shares>
36+
<note>Abrechnungs-Nr. 19200128</note>
37+
<source>2019-05-24_Wertpapierertrag 24.05.2019_DE000CBK1001.pdf</source>
38+
<units>
39+
<unit type="TAX">
40+
<amount currency="EUR" amount="393"/>
41+
</unit>
42+
</units>
43+
<updatedAt>2026-02-10T13:50:10.694859420Z</updatedAt>
44+
<type>DIVIDENDS</type>
45+
<exDate>2019-05-23T00:00</exDate>
46+
</account-transaction>
47+
</transactions>
48+
<attributes>
49+
<map/>
50+
</attributes>
51+
<updatedAt>2026-02-04T22:52:02.886672581Z</updatedAt>
52+
</account>
53+
</accounts>
54+
<portfolios>
55+
<portfolio>
56+
<uuid>404c0fbf-68ab-4925-bdcb-9838e2380317</uuid>
57+
<name>dividendExdate</name>
58+
<isRetired>false</isRetired>
59+
<referenceAccount reference="../../../accounts/account"/>
60+
<transactions/>
61+
<attributes>
62+
<map/>
63+
</attributes>
64+
<updatedAt>2026-02-04T22:51:41.462743232Z</updatedAt>
65+
</portfolio>
66+
</portfolios>
67+
<plans/>
68+
<taxonomies/>
69+
<dashboards/>
70+
<properties/>
71+
<settings>
72+
<bookmarks>
73+
<bookmark>
74+
<label>finance.yahoo.com</label>
75+
<pattern>https://finance.yahoo.com/quote/{tickerSymbol}</pattern>
76+
</bookmark>
77+
<bookmark>
78+
<label>onvista.de</label>
79+
<pattern>https://www.onvista.de/suche.html?SEARCH_VALUE={isin}</pattern>
80+
</bookmark>
81+
<bookmark>
82+
<label>finanzen.net</label>
83+
<pattern>https://www.finanzen.net/suchergebnis.asp?frmAktiensucheTextfeld={isin}</pattern>
84+
</bookmark>
85+
<bookmark>
86+
<label>ariva.de</label>
87+
<pattern>https://www.ariva.de/{isin}</pattern>
88+
</bookmark>
89+
<bookmark>
90+
<label>justetf.com (ETF)</label>
91+
<pattern>https://www.justetf.com/etf-profile.html?isin={isin}</pattern>
92+
</bookmark>
93+
<bookmark>
94+
<label>fondsweb.com</label>
95+
<pattern>https://www.fondsweb.com/{isin}</pattern>
96+
</bookmark>
97+
<bookmark>
98+
<label>morningstar.de</label>
99+
<pattern>https://www.morningstar.de/de/funds/SecuritySearchResults.aspx?type=ALL&amp;search={isin}</pattern>
100+
</bookmark>
101+
<bookmark>
102+
<label>extraETF.com (ETF)</label>
103+
<pattern>https://extraetf.com/etf-profile/{isin}</pattern>
104+
</bookmark>
105+
<bookmark>
106+
<label>alleaktien.de (Aktie)</label>
107+
<pattern>https://www.alleaktien.de/data/{isin}</pattern>
108+
</bookmark>
109+
<bookmark>
110+
<label>comdirect.de (Aktie)</label>
111+
<pattern>https://www.comdirect.de/inf/aktien/{isin}</pattern>
112+
</bookmark>
113+
<bookmark>
114+
<label>comdirect.de (ETF)</label>
115+
<pattern>https://www.comdirect.de/inf/etfs/{isin}</pattern>
116+
</bookmark>
117+
<bookmark>
118+
<label>divvydiary.com</label>
119+
<pattern>https://divvydiary.com/symbols/{isin}</pattern>
120+
</bookmark>
121+
<bookmark>
122+
<label>trackingdifferences.com (ETF)</label>
123+
<pattern>https://www.trackingdifferences.com/ETF/ISIN/{isin}</pattern>
124+
</bookmark>
125+
<bookmark>
126+
<label>tradingview.com</label>
127+
<pattern>https://www.tradingview.com/chart/?symbol=XETR:{tickerSymbolPrefix}</pattern>
128+
</bookmark>
129+
<bookmark>
130+
<label>cnbc.com (Aktie)</label>
131+
<pattern>https://www.cnbc.com/quotes/{tickerSymbolPrefix}</pattern>
132+
</bookmark>
133+
<bookmark>
134+
<label>nasdaq.com (Aktie)</label>
135+
<pattern>https://www.nasdaq.com/market-activity/stocks/{tickerSymbolPrefix}</pattern>
136+
</bookmark>
137+
<bookmark>
138+
<label>aktienfinder.net (Aktie)</label>
139+
<pattern>https://aktienfinder.net/aktien-profil/{isin}</pattern>
140+
</bookmark>
141+
<bookmark>
142+
<label>aktien.guide (Aktie)</label>
143+
<pattern>http://aktien.guide/isin/aktien/{isin}</pattern>
144+
</bookmark>
145+
</bookmarks>
146+
<attributeTypes>
147+
<attribute-type>
148+
<id>logo</id>
149+
<name>Logo</name>
150+
<columnLabel>Logo</columnLabel>
151+
<target>name.abuchen.portfolio.model.Security</target>
152+
<type>java.lang.String</type>
153+
<converterClass>name.abuchen.portfolio.model.AttributeType$ImageConverter</converterClass>
154+
<properties/>
155+
</attribute-type>
156+
<attribute-type>
157+
<id>logo</id>
158+
<name>Logo</name>
159+
<columnLabel>Logo</columnLabel>
160+
<target>name.abuchen.portfolio.model.Account</target>
161+
<type>java.lang.String</type>
162+
<converterClass>name.abuchen.portfolio.model.AttributeType$ImageConverter</converterClass>
163+
<properties/>
164+
</attribute-type>
165+
<attribute-type>
166+
<id>logo</id>
167+
<name>Logo</name>
168+
<columnLabel>Logo</columnLabel>
169+
<target>name.abuchen.portfolio.model.Portfolio</target>
170+
<type>java.lang.String</type>
171+
<converterClass>name.abuchen.portfolio.model.AttributeType$ImageConverter</converterClass>
172+
<properties/>
173+
</attribute-type>
174+
<attribute-type>
175+
<id>logo</id>
176+
<name>Logo</name>
177+
<columnLabel>Logo</columnLabel>
178+
<target>name.abuchen.portfolio.model.InvestmentPlan</target>
179+
<type>java.lang.String</type>
180+
<converterClass>name.abuchen.portfolio.model.AttributeType$ImageConverter</converterClass>
181+
<properties/>
182+
</attribute-type>
183+
<attribute-type>
184+
<id>ter</id>
185+
<name>Gesamtkostenquote (TER)</name>
186+
<columnLabel>TER</columnLabel>
187+
<source>ter</source>
188+
<target>name.abuchen.portfolio.model.Security</target>
189+
<type>java.lang.Double</type>
190+
<converterClass>name.abuchen.portfolio.model.AttributeType$PercentConverter</converterClass>
191+
<properties/>
192+
</attribute-type>
193+
<attribute-type>
194+
<id>aum</id>
195+
<name>Fondsgröße</name>
196+
<columnLabel>Fondsgröße</columnLabel>
197+
<target>name.abuchen.portfolio.model.Security</target>
198+
<type>java.lang.Long</type>
199+
<converterClass>name.abuchen.portfolio.model.AttributeType$AmountPlainConverter</converterClass>
200+
<properties/>
201+
</attribute-type>
202+
<attribute-type>
203+
<id>vendor</id>
204+
<name>Anbieter</name>
205+
<columnLabel>Anbieter</columnLabel>
206+
<source>vendor</source>
207+
<target>name.abuchen.portfolio.model.Security</target>
208+
<type>java.lang.String</type>
209+
<converterClass>name.abuchen.portfolio.model.AttributeType$StringConverter</converterClass>
210+
<properties/>
211+
</attribute-type>
212+
<attribute-type>
213+
<id>acquisitionFee</id>
214+
<name>Kaufgebühr (prozentual)</name>
215+
<columnLabel>Kaufgebühr</columnLabel>
216+
<target>name.abuchen.portfolio.model.Security</target>
217+
<type>java.lang.Double</type>
218+
<converterClass>name.abuchen.portfolio.model.AttributeType$PercentConverter</converterClass>
219+
<properties/>
220+
</attribute-type>
221+
<attribute-type>
222+
<id>managementFee</id>
223+
<name>Verwaltungsgebühr (prozentual)</name>
224+
<columnLabel>Verwaltungsgebühr</columnLabel>
225+
<target>name.abuchen.portfolio.model.Security</target>
226+
<type>java.lang.Double</type>
227+
<converterClass>name.abuchen.portfolio.model.AttributeType$PercentConverter</converterClass>
228+
<properties/>
229+
</attribute-type>
230+
</attributeTypes>
231+
<configurationSets>
232+
<entry>
233+
<string>name.abuchen.portfolio.ui.views.SecuritiesTable</string>
234+
<config-set>
235+
<configurations>
236+
<config>
237+
<uuid>40227a75-8308-4477-896c-3fa920f43367</uuid>
238+
<name>Standard</name>
239+
<data>{&quot;items&quot;:[{&quot;id&quot;:&quot;0&quot;,&quot;sortDirection&quot;:128,&quot;width&quot;:400},{&quot;id&quot;:&quot;note&quot;,&quot;width&quot;:200},{&quot;id&quot;:&quot;1&quot;,&quot;width&quot;:100},{&quot;id&quot;:&quot;2&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;7&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;4&quot;,&quot;width&quot;:60},{&quot;id&quot;:&quot;5&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;changeonpreviousamount&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;9&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;10&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;q-date-first-historic&quot;,&quot;width&quot;:261}]}</data>
240+
</config>
241+
</configurations>
242+
</config-set>
243+
</entry>
244+
<entry>
245+
<string>name.abuchen.portfolio.ui.views.StatementOfAssetsViewer</string>
246+
<config-set>
247+
<configurations>
248+
<config>
249+
<uuid>71873ede-52b7-44fd-9877-1155f6c3e6aa</uuid>
250+
<name>Standard</name>
251+
<data>{&quot;items&quot;:[{&quot;id&quot;:&quot;0&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;1&quot;,&quot;width&quot;:300},{&quot;id&quot;:&quot;2&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;4&quot;,&quot;width&quot;:60},{&quot;id&quot;:&quot;5&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;6&quot;,&quot;width&quot;:80},{&quot;id&quot;:&quot;note&quot;,&quot;width&quot;:821}]}</data>
252+
</config>
253+
</configurations>
254+
</config-set>
255+
</entry>
256+
</configurationSets>
257+
</settings>
258+
</client>

name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/actions/DetectDuplicatesActionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void testDuplicateDetection4AccountTransaction() throws IntrospectionExce
3636
var action = new DetectDuplicatesAction(new Client());
3737

3838
new PropertyChecker<AccountTransaction>(
39-
AccountTransaction.class, "note", "source", "forex", "monetaryAmount", "updatedAt")
39+
AccountTransaction.class, "note", "source", "forex", "monetaryAmount", "exDate", "updatedAt")
4040
.before((name, o, c) -> assertThat(name,
4141
action.process(o, account(c)).getCode(), is(Code.WARNING)))
4242
.after((name, o, c) -> assertThat(name, action.process(o, account(c)).getCode(),

name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/transactions/AccountTransactionModel.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ public void applyChanges()
122122

123123
// preserve the source field from the original transaction
124124
t.setSource(sourceTransaction.getSource());
125+
t.setExDate(sourceTransaction.getExDate());
125126

126127
sourceTransaction = null;
127128
sourceAccount = null;

0 commit comments

Comments
 (0)