1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.lethe.reports;
18
19 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
20 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
21 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
22 import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogManager;
23 import io.github.tonywasher.joceanus.oceanus.logger.OceanusLogger;
24 import io.github.tonywasher.joceanus.metis.report.MetisReportBase;
25 import io.github.tonywasher.joceanus.metis.report.MetisReportHTMLBuilder;
26 import io.github.tonywasher.joceanus.metis.report.MetisReportHTMLBuilder.MetisHTMLTable;
27 import io.github.tonywasher.joceanus.metis.report.MetisReportManager;
28 import io.github.tonywasher.joceanus.metis.report.MetisReportReferenceManager.DelayedTable;
29 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysis;
30 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPortfolioBucket;
31 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisPortfolioBucket.MoneyWiseAnalysisPortfolioBucketList;
32 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisSecurityBucket;
33 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.data.MoneyWiseAnalysisSecurityBucket.MoneyWiseAnalysisSecurityBucketList;
34 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.values.MoneyWiseAnalysisSecurityAttr;
35 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.values.MoneyWiseAnalysisSecurityValues;
36 import io.github.tonywasher.joceanus.moneywise.lethe.data.analysis.values.MoneyWiseAnalysisValuesResource;
37 import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter;
38 import io.github.tonywasher.joceanus.moneywise.lethe.views.MoneyWiseAnalysisFilter.MoneyWiseAnalysisSecurityFilter;
39 import org.w3c.dom.Document;
40 import org.w3c.dom.Element;
41
42 import java.util.Iterator;
43
44
45
46
47 public class MoneyWiseReportMarketGrowth
48 extends MetisReportBase<MoneyWiseAnalysis, MoneyWiseAnalysisFilter<?, ?>> {
49
50
51
52 private static final OceanusLogger LOGGER = OceanusLogManager.getLogger(MoneyWiseReportMarketGrowth.class);
53
54
55
56
57 private static final String TEXT_TITLE = MoneyWiseReportResource.MARKETGROWTH_TITLE.getValue();
58
59
60
61
62 private static final String TEXT_VALUE = MoneyWiseAnalysisValuesResource.ACCOUNTATTR_VALUATION.getValue();
63
64
65
66
67 private static final String TEXT_INVEST = MoneyWiseAnalysisValuesResource.SECURITYATTR_INVESTED.getValue();
68
69
70
71
72 private static final String TEXT_ADJUST = MoneyWiseAnalysisValuesResource.SECURITYATTR_GROWTHADJUST.getValue();
73
74
75
76
77 private static final String TEXT_GAINS = MoneyWiseAnalysisValuesResource.SECURITYATTR_REALISEDGAINS.getValue();
78
79
80
81
82 private static final String TEXT_BASE = MoneyWiseReportResource.MARKETGROWTH_BASE.getValue();
83
84
85
86
87 private static final String TEXT_GROWTH = MoneyWiseAnalysisValuesResource.SECURITYATTR_MARKETGROWTH.getValue();
88
89
90
91
92 private static final String TEXT_CURRENCY = MoneyWiseAnalysisValuesResource.ACCOUNTATTR_CURRENCYFLUCT.getValue();
93
94
95
96
97 private static final String TEXT_PROFIT = MoneyWiseAnalysisValuesResource.SECURITYATTR_PROFIT.getValue();
98
99
100
101
102 private final MetisReportHTMLBuilder theBuilder;
103
104
105
106
107 private final OceanusDataFormatter theFormatter;
108
109
110
111
112 private boolean hasForeign;
113
114
115
116
117
118
119 protected MoneyWiseReportMarketGrowth(final MetisReportManager<MoneyWiseAnalysisFilter<?, ?>> pManager) {
120
121 theBuilder = pManager.getBuilder();
122 theFormatter = theBuilder.getDataFormatter();
123 }
124
125 @Override
126 public Document createReport(final MoneyWiseAnalysis pAnalysis) {
127
128 final MoneyWiseAnalysisPortfolioBucketList myPortfolios = pAnalysis.getPortfolios();
129 hasForeign = myPortfolios.haveForeignCurrency();
130
131
132 final MoneyWiseAnalysisPortfolioBucket myTotals = myPortfolios.getTotals();
133 final OceanusDateRange myRange = pAnalysis.getDateRange();
134
135
136 final Element myBody = theBuilder.startReport();
137 theBuilder.makeTitle(myBody, TEXT_TITLE, theFormatter.formatObject(myRange));
138
139
140 final MetisHTMLTable myTable = theBuilder.startTable(myBody);
141 theBuilder.startHdrRow(myTable);
142 theBuilder.makeTitleCell(myTable);
143 theBuilder.makeTitleCell(myTable, TEXT_VALUE);
144 theBuilder.makeTitleCell(myTable, TEXT_BASE);
145 theBuilder.makeTitleCell(myTable, TEXT_INVEST);
146 theBuilder.makeTitleCell(myTable, TEXT_ADJUST);
147 theBuilder.makeTitleCell(myTable, TEXT_GAINS);
148 theBuilder.makeTitleCell(myTable, TEXT_GROWTH);
149 if (hasForeign) {
150 theBuilder.makeTitleCell(myTable, TEXT_CURRENCY);
151 }
152 theBuilder.makeTitleCell(myTable, TEXT_PROFIT);
153
154
155 final Iterator<MoneyWiseAnalysisPortfolioBucket> myIterator = myPortfolios.iterator();
156 while (myIterator.hasNext()) {
157 final MoneyWiseAnalysisPortfolioBucket myBucket = myIterator.next();
158
159
160 final String myName = myBucket.getName();
161
162
163 final MoneyWiseAnalysisSecurityValues myValues = myBucket.getValues();
164
165
166 if (myBucket.securityIterator().hasNext()) {
167
168 theBuilder.startRow(myTable);
169 theBuilder.makeDelayLinkCell(myTable, myName);
170 theBuilder.makeTotalCell(myTable, myBucket.getNonCashValue(false));
171 theBuilder.makeTotalCell(myTable, myBucket.getNonCashValue(true));
172 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED));
173 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST));
174 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
175 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETGROWTH));
176 if (hasForeign) {
177 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.CURRENCYFLUCT));
178 }
179 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETPROFIT));
180 checkPortfolioGrowth(myBucket);
181
182
183 setDelayedTable(myName, myTable, myBucket);
184 }
185 }
186
187
188 final MoneyWiseAnalysisSecurityValues myValues = myTotals.getValues();
189
190
191 theBuilder.startTotalRow(myTable);
192 theBuilder.makeTitleCell(myTable, MoneyWiseReportBuilder.TEXT_TOTAL);
193 theBuilder.makeTotalCell(myTable, myTotals.getNonCashValue(false));
194 theBuilder.makeTotalCell(myTable, myTotals.getNonCashValue(true));
195 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED));
196 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST));
197 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
198 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETGROWTH));
199 if (hasForeign) {
200 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.CURRENCYFLUCT));
201 }
202 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETPROFIT));
203 checkPortfolioGrowth(myTotals);
204
205
206 return theBuilder.getDocument();
207 }
208
209 @Override
210 public MetisHTMLTable createDelayedTable(final DelayedTable pTable) {
211
212 final Object mySource = pTable.getSource();
213 if (mySource instanceof MoneyWiseAnalysisPortfolioBucket mySourceBucket) {
214 return createDelayedPortfolio(pTable.getParent(), mySourceBucket);
215 }
216
217
218 return null;
219 }
220
221
222
223
224
225
226
227
228 private MetisHTMLTable createDelayedPortfolio(final MetisHTMLTable pParent,
229 final MoneyWiseAnalysisPortfolioBucket pSource) {
230
231 final MoneyWiseAnalysisSecurityBucketList mySecurities = pSource.getSecurities();
232
233
234 final MetisHTMLTable myTable = theBuilder.createEmbeddedTable(pParent);
235
236
237 final Iterator<MoneyWiseAnalysisSecurityBucket> myIterator = mySecurities.iterator();
238 while (myIterator.hasNext()) {
239 final MoneyWiseAnalysisSecurityBucket myBucket = myIterator.next();
240
241
242 final String myName = myBucket.getSecurityName();
243 String myFullName = myBucket.getDecoratedName();
244 myFullName = myFullName.replace(':', '-');
245
246
247 final MoneyWiseAnalysisSecurityValues myValues = myBucket.getValues();
248 final MoneyWiseAnalysisSecurityValues myBaseValues = myBucket.getBaseValues();
249
250
251 theBuilder.startRow(myTable);
252 theBuilder.makeFilterLinkCell(myTable, myFullName, myName);
253 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION));
254 theBuilder.makeValueCell(myTable, myBaseValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION));
255 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED));
256 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST));
257 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
258 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETGROWTH));
259 if (hasForeign) {
260 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.CURRENCYFLUCT));
261 }
262 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETPROFIT));
263 checkSecurityGrowth(myBucket);
264
265
266 setFilterForId(myFullName, myBucket);
267 }
268
269
270 return myTable;
271 }
272
273
274
275
276
277
278 private static void checkPortfolioGrowth(final MoneyWiseAnalysisPortfolioBucket pBucket) {
279
280 final MoneyWiseAnalysisSecurityValues myValues = pBucket.getValues();
281 final OceanusMoney myAdjust = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST);
282 final OceanusMoney myCalcGrowth = pBucket.getNonCashValue(false);
283 myCalcGrowth.subtractAmount(pBucket.getNonCashValue(true));
284 myCalcGrowth.subtractAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED));
285 myCalcGrowth.addAmount(myAdjust);
286 final OceanusMoney myProfit = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETPROFIT);
287 if (!myProfit.equals(myCalcGrowth)) {
288 LOGGER.error("Incorrect profit calculation for security <%s> of <%s>", pBucket.getName(), myCalcGrowth);
289 }
290
291
292 myCalcGrowth.subtractAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
293 myCalcGrowth.subtractAmount(myAdjust);
294 myCalcGrowth.subtractAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.CURRENCYFLUCT));
295 final OceanusMoney myGrowth = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETGROWTH);
296 if (!myGrowth.equals(myCalcGrowth)) {
297 LOGGER.error("Incorrect growth calculation for portfolio <%s> of <%s>", pBucket.getName(), myCalcGrowth);
298 }
299 }
300
301
302
303
304
305
306 private static void checkSecurityGrowth(final MoneyWiseAnalysisSecurityBucket pBucket) {
307
308 final MoneyWiseAnalysisSecurityValues myValues = pBucket.getValues();
309 final MoneyWiseAnalysisSecurityValues myBaseValues = pBucket.getBaseValues();
310 final OceanusMoney myAdjust = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST);
311 final OceanusMoney myCalcGrowth = new OceanusMoney(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION));
312 myCalcGrowth.subtractAmount(myBaseValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION));
313 myCalcGrowth.subtractAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.INVESTED));
314 myCalcGrowth.addAmount(myAdjust);
315 final OceanusMoney myProfit = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETPROFIT);
316 if (!myProfit.equals(myCalcGrowth)) {
317 LOGGER.error("Incorrect profit calculation for security <%s> of <%s>", pBucket.getDecoratedName(), myCalcGrowth);
318 }
319
320
321 myCalcGrowth.subtractAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
322 myCalcGrowth.subtractAmount(myAdjust);
323 final OceanusMoney myFluct = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.CURRENCYFLUCT);
324 if (myFluct != null) {
325 myCalcGrowth.subtractAmount(myFluct);
326 }
327 final OceanusMoney myGrowth = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.MARKETGROWTH);
328 if (!myGrowth.equals(myCalcGrowth)) {
329 LOGGER.error("Incorrect growth calculation for security <%s> of <%s>", pBucket.getDecoratedName(), myCalcGrowth);
330 }
331 }
332
333 @Override
334 public MoneyWiseAnalysisSecurityFilter processFilter(final Object pSource) {
335
336 if (pSource instanceof MoneyWiseAnalysisSecurityBucket mySource) {
337
338 return new MoneyWiseAnalysisSecurityFilter(mySource);
339 }
340 return null;
341 }
342 }