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.OceanusDate;
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 MoneyWiseReportPortfolioView
48 extends MetisReportBase<MoneyWiseAnalysis, MoneyWiseAnalysisFilter<?, ?>> {
49
50
51
52 private static final OceanusLogger LOGGER = OceanusLogManager.getLogger(MoneyWiseReportPortfolioView.class);
53
54
55
56
57 private static final String TEXT_TITLE = MoneyWiseReportResource.PORTFOLIO_TITLE.getValue();
58
59
60
61
62 private static final String TEXT_COST = MoneyWiseAnalysisValuesResource.SECURITYATTR_RESIDUALCOST.getValue();
63
64
65
66
67 private static final String TEXT_ADJUST = MoneyWiseAnalysisValuesResource.SECURITYATTR_GROWTHADJUST.getValue();
68
69
70
71
72 private static final String TEXT_VALUE = MoneyWiseAnalysisValuesResource.ACCOUNTATTR_VALUATION.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_DIVIDEND = MoneyWiseAnalysisValuesResource.SECURITYATTR_DIVIDEND.getValue();
83
84
85
86
87 private final MetisReportHTMLBuilder theBuilder;
88
89
90
91
92 private final OceanusDataFormatter theFormatter;
93
94
95
96
97
98
99 protected MoneyWiseReportPortfolioView(final MetisReportManager<MoneyWiseAnalysisFilter<?, ?>> pManager) {
100
101 theBuilder = pManager.getBuilder();
102 theFormatter = theBuilder.getDataFormatter();
103 }
104
105 @Override
106 public Document createReport(final MoneyWiseAnalysis pAnalysis) {
107
108 final MoneyWiseAnalysisPortfolioBucketList myPortfolios = pAnalysis.getPortfolios();
109
110
111 final MoneyWiseAnalysisPortfolioBucket myTotals = myPortfolios.getTotals();
112 final OceanusDate myDate = pAnalysis.getDateRange().getEnd();
113
114
115 final Element myBody = theBuilder.startReport();
116 theBuilder.makeTitle(myBody, TEXT_TITLE, theFormatter.formatObject(myDate));
117
118
119 final MetisHTMLTable myTable = theBuilder.startTable(myBody);
120 theBuilder.startHdrRow(myTable);
121 theBuilder.makeTitleCell(myTable);
122 theBuilder.makeTitleCell(myTable, TEXT_VALUE);
123 theBuilder.makeTitleCell(myTable, TEXT_COST);
124 theBuilder.makeTitleCell(myTable, TEXT_GAINS);
125 theBuilder.makeTitleCell(myTable, TEXT_DIVIDEND);
126 theBuilder.makeTitleCell(myTable, TEXT_ADJUST);
127 theBuilder.makeTitleCell(myTable, MoneyWiseReportBuilder.TEXT_PROFIT);
128
129
130 final Iterator<MoneyWiseAnalysisPortfolioBucket> myIterator = myPortfolios.iterator();
131 while (myIterator.hasNext()) {
132 final MoneyWiseAnalysisPortfolioBucket myBucket = myIterator.next();
133
134
135 final String myName = myBucket.getName();
136
137
138 final MoneyWiseAnalysisSecurityValues myValues = myBucket.getValues();
139
140
141 theBuilder.startRow(myTable);
142 theBuilder.makeDelayLinkCell(myTable, myName);
143
144
145 theBuilder.makeValueCell(myTable, myBucket.getNonCashValue(false));
146 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST));
147 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
148 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.DIVIDEND));
149 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST));
150 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.PROFIT));
151 checkPortfolioProfit(myBucket);
152
153
154 setDelayedTable(myName, myTable, myBucket);
155 }
156
157
158 final MoneyWiseAnalysisSecurityValues myValues = myTotals.getValues();
159
160
161 theBuilder.startTotalRow(myTable);
162 theBuilder.makeTitleCell(myTable, MoneyWiseReportBuilder.TEXT_TOTAL);
163 theBuilder.makeTotalCell(myTable, myTotals.getNonCashValue(false));
164 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST));
165 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
166 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.DIVIDEND));
167 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST));
168 theBuilder.makeTotalCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.PROFIT));
169 checkPortfolioProfit(myTotals);
170
171
172 return theBuilder.getDocument();
173 }
174
175 @Override
176 public MetisHTMLTable createDelayedTable(final DelayedTable pTable) {
177
178 final Object mySource = pTable.getSource();
179 if (mySource instanceof MoneyWiseAnalysisPortfolioBucket mySourceBucket) {
180 return createDelayedPortfolio(pTable.getParent(), mySourceBucket);
181 }
182
183
184 return null;
185 }
186
187
188
189
190
191
192
193
194 private MetisHTMLTable createDelayedPortfolio(final MetisHTMLTable pParent,
195 final MoneyWiseAnalysisPortfolioBucket pSource) {
196
197 final MoneyWiseAnalysisSecurityBucketList mySecurities = pSource.getSecurities();
198
199
200 final MetisHTMLTable myTable = theBuilder.createEmbeddedTable(pParent);
201
202
203 final Iterator<MoneyWiseAnalysisSecurityBucket> myIterator = mySecurities.iterator();
204 while (myIterator.hasNext()) {
205 final MoneyWiseAnalysisSecurityBucket myBucket = myIterator.next();
206
207
208 final String myName = myBucket.getSecurityName();
209 String myFullName = myBucket.getDecoratedName();
210 myFullName = myFullName.replace(':', '-');
211
212
213 final MoneyWiseAnalysisSecurityValues myValues = myBucket.getValues();
214
215
216 theBuilder.startRow(myTable);
217 theBuilder.makeFilterLinkCell(myTable, myFullName, myName);
218 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION));
219 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST));
220 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
221 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.DIVIDEND));
222 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST));
223 theBuilder.makeValueCell(myTable, myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.PROFIT));
224 checkSecurityProfit(myBucket);
225
226
227 setFilterForId(myFullName, myBucket);
228 }
229
230
231 return myTable;
232 }
233
234
235
236
237
238
239 private static void checkPortfolioProfit(final MoneyWiseAnalysisPortfolioBucket pBucket) {
240 final MoneyWiseAnalysisSecurityValues myValues = pBucket.getValues();
241 final OceanusMoney myCalcProfit = pBucket.getNonCashValue(false);
242 myCalcProfit.subtractAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST));
243 myCalcProfit.addAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
244 myCalcProfit.addAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.DIVIDEND));
245 myCalcProfit.addAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST));
246 final OceanusMoney myProfit = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.PROFIT);
247 if (!myProfit.equals(myCalcProfit)) {
248 LOGGER.error("Incorrect profit calculation for portfolio <%s>", pBucket.getName());
249 }
250 }
251
252
253
254
255
256
257 private static void checkSecurityProfit(final MoneyWiseAnalysisSecurityBucket pBucket) {
258 final MoneyWiseAnalysisSecurityValues myValues = pBucket.getValues();
259 final OceanusMoney myCalcProfit = new OceanusMoney(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.VALUATION));
260 myCalcProfit.subtractAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.RESIDUALCOST));
261 myCalcProfit.addAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.REALISEDGAINS));
262 myCalcProfit.addAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.DIVIDEND));
263 myCalcProfit.addAmount(myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.GROWTHADJUST));
264 final OceanusMoney myProfit = myValues.getMoneyValue(MoneyWiseAnalysisSecurityAttr.PROFIT);
265 if (!myProfit.equals(myCalcProfit)) {
266 LOGGER.error("Incorrect profit calculation for security <%s>", pBucket.getDecoratedName());
267 }
268 }
269
270 @Override
271 public MoneyWiseAnalysisSecurityFilter processFilter(final Object pSource) {
272
273 if (pSource instanceof MoneyWiseAnalysisSecurityBucket mySource) {
274
275 return new MoneyWiseAnalysisSecurityFilter(mySource);
276 }
277 return null;
278 }
279 }