1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets;
18
19 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataList;
20 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
21 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem.MetisFieldTableItem;
22 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
23 import io.github.tonywasher.joceanus.metis.list.MetisListIndexed;
24 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisInterfaces.MoneyWiseXAnalysisBucketRegister;
25 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisTaxBasisAccountBucket.MoneyWiseXAnalysisTaxBasisAccountBucketList;
26 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.values.MoneyWiseXAnalysisTaxBasisAttr;
27 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransAsset;
28 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransaction;
29 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
30 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
31 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTaxBasis;
32 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTaxBasis.MoneyWiseTaxBasisList;
33 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTaxClass;
34 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseChargeableGainSlice.MoneyWiseChargeableGainSliceList;
35 import io.github.tonywasher.joceanus.moneywise.tax.MoneyWiseTaxSource;
36 import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
37 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
38 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
39 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
40 import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
41
42 import java.util.Comparator;
43 import java.util.Currency;
44 import java.util.Iterator;
45 import java.util.List;
46
47
48
49
50 public class MoneyWiseXAnalysisTaxBasisBucket
51 extends MoneyWiseXAnalysisTaxBasisBaseBucket
52 implements MetisFieldTableItem, MoneyWiseXAnalysisBucketRegister {
53
54
55
56 private static final MetisFieldSet<MoneyWiseXAnalysisTaxBasisBucket> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseXAnalysisTaxBasisBucket.class);
57
58
59
60
61 static {
62 FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.TAXBASIS_ACCOUNTLIST, MoneyWiseXAnalysisTaxBasisBucket::getAccounts);
63 }
64
65
66
67
68 private final boolean hasAccounts;
69
70
71
72
73 private final MoneyWiseXAnalysisTaxBasisAccountBucketList theAccounts;
74
75
76
77
78
79
80
81 MoneyWiseXAnalysisTaxBasisBucket(final MoneyWiseXAnalysisHolder pAnalysis,
82 final MoneyWiseTaxBasis pTaxBasis) {
83
84 super(pAnalysis, pTaxBasis);
85
86
87 hasAccounts = pTaxBasis != null
88 && pTaxBasis.getTaxClass().analyseAccounts();
89 theAccounts = hasAccounts
90 ? new MoneyWiseXAnalysisTaxBasisAccountBucketList(pAnalysis, pTaxBasis)
91 : null;
92 }
93
94
95
96
97
98
99
100
101 MoneyWiseXAnalysisTaxBasisBucket(final MoneyWiseXAnalysisHolder pAnalysis,
102 final MoneyWiseXAnalysisTaxBasisBucket pBase,
103 final OceanusDate pDate) {
104
105 super(pAnalysis, pBase, pDate);
106
107
108 hasAccounts = pBase.hasAccounts();
109 theAccounts = hasAccounts
110 ? new MoneyWiseXAnalysisTaxBasisAccountBucketList(pAnalysis, getTaxBasis(), pBase.getAccounts(), pDate)
111 : null;
112 }
113
114
115
116
117
118
119
120
121 MoneyWiseXAnalysisTaxBasisBucket(final MoneyWiseXAnalysisHolder pAnalysis,
122 final MoneyWiseXAnalysisTaxBasisBucket pBase,
123 final OceanusDateRange pRange) {
124
125 super(pAnalysis, pBase, pRange);
126
127
128 hasAccounts = pBase.hasAccounts();
129 theAccounts = hasAccounts
130 ? new MoneyWiseXAnalysisTaxBasisAccountBucketList(pAnalysis, getTaxBasis(), pBase.getAccounts(), pRange)
131 : null;
132 }
133
134 @Override
135 public MetisFieldSet<? extends MoneyWiseXAnalysisTaxBasisBucket> getDataFieldSet() {
136 return FIELD_DEFS;
137 }
138
139 @Override
140 public String formatObject(final OceanusDataFormatter pFormatter) {
141 return toString();
142 }
143
144
145
146
147
148
149 public boolean hasAccounts() {
150 return hasAccounts;
151 }
152
153
154
155
156
157
158 private MoneyWiseXAnalysisTaxBasisAccountBucketList getAccounts() {
159 return theAccounts;
160 }
161
162
163
164
165
166
167 public Iterator<MoneyWiseXAnalysisTaxBasisAccountBucket> accountIterator() {
168 return hasAccounts
169 ? theAccounts.iterator()
170 : null;
171 }
172
173
174
175
176
177
178
179 public MoneyWiseXAnalysisTaxBasisAccountBucket findAccountBucket(final MoneyWiseTransAsset pAccount) {
180 return hasAccounts
181 ? theAccounts.findBucket(pAccount)
182 : null;
183 }
184
185 @Override
186 MoneyWiseXAnalysisTaxBasisBaseBucket adjustAccountValue(final MoneyWiseTransAsset pAccount,
187 final OceanusMoney pValue,
188 final MoneyWiseXTaxBasisAdjust pAdjust) {
189
190 return hasAccounts && pAccount != null
191 ? theAccounts.adjustValue(pAccount, pValue, pAdjust)
192 : null;
193 }
194
195
196
197
198 public static class MoneyWiseXAnalysisTaxBasisBucketList
199 implements MetisFieldItem, MoneyWiseTaxSource, MetisDataList<MoneyWiseXAnalysisTaxBasisBucket> {
200
201
202
203 private static final MetisFieldSet<MoneyWiseXAnalysisTaxBasisBucketList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseXAnalysisTaxBasisBucketList.class);
204
205
206
207
208 static {
209 FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.ANALYSIS_NAME, MoneyWiseXAnalysisTaxBasisBucketList::getAnalysis);
210 FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.ANALYSIS_CHARGES, MoneyWiseXAnalysisTaxBasisBucketList::getGainSlices);
211 FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.ANALYSIS_TOTALS, MoneyWiseXAnalysisTaxBasisBucketList::getTotals);
212 }
213
214
215
216
217 private final MoneyWiseXAnalysisHolder theAnalysis;
218
219
220
221
222 private final MetisListIndexed<MoneyWiseXAnalysisTaxBasisBucket> theList;
223
224
225
226
227 private final PrometheusEditSet theEditSet;
228
229
230
231
232 private final MoneyWiseChargeableGainSliceList theCharges;
233
234
235
236
237 private final MoneyWiseXAnalysisTaxBasisBucket theTotals;
238
239
240
241
242
243
244
245 private MoneyWiseXAnalysisTaxBasisBucketList(final MoneyWiseXAnalysisHolder pAnalysis,
246 final MoneyWiseChargeableGainSliceList pGains) {
247 theAnalysis = pAnalysis;
248 theEditSet = theAnalysis.getEditSet();
249 theCharges = pGains;
250 theTotals = allocateTotalsBucket();
251 theList = new MetisListIndexed<>();
252 theList.setComparator(Comparator.comparing(MoneyWiseXAnalysisTaxBasisBucket::getTaxBasis));
253 }
254
255
256
257
258
259
260 protected MoneyWiseXAnalysisTaxBasisBucketList(final MoneyWiseXAnalysisHolder pAnalysis) {
261 this(pAnalysis, new MoneyWiseChargeableGainSliceList());
262 }
263
264
265
266
267
268
269
270
271 protected MoneyWiseXAnalysisTaxBasisBucketList(final MoneyWiseXAnalysisHolder pAnalysis,
272 final MoneyWiseXAnalysisTaxBasisBucketList pBase,
273 final OceanusDate pDate) {
274
275 this(pAnalysis, new MoneyWiseChargeableGainSliceList(pBase.getGainSlices(), pAnalysis.getDateRange()));
276
277
278 final Iterator<MoneyWiseXAnalysisTaxBasisBucket> myIterator = pBase.iterator();
279 while (myIterator.hasNext()) {
280 final MoneyWiseXAnalysisTaxBasisBucket myCurr = myIterator.next();
281
282
283 final MoneyWiseXAnalysisTaxBasisBucket myBucket = new MoneyWiseXAnalysisTaxBasisBucket(pAnalysis, myCurr, pDate);
284
285
286 if (!myBucket.isIdle()) {
287
288 theList.add(myBucket);
289 }
290 }
291 }
292
293
294
295
296
297
298
299
300 protected MoneyWiseXAnalysisTaxBasisBucketList(final MoneyWiseXAnalysisHolder pAnalysis,
301 final MoneyWiseXAnalysisTaxBasisBucketList pBase,
302 final OceanusDateRange pRange) {
303
304 this(pAnalysis, new MoneyWiseChargeableGainSliceList(pBase.getGainSlices(), pAnalysis.getDateRange()));
305
306
307 final Iterator<MoneyWiseXAnalysisTaxBasisBucket> myIterator = pBase.iterator();
308 while (myIterator.hasNext()) {
309 final MoneyWiseXAnalysisTaxBasisBucket myCurr = myIterator.next();
310
311
312 final MoneyWiseXAnalysisTaxBasisBucket myBucket = new MoneyWiseXAnalysisTaxBasisBucket(pAnalysis, myCurr, pRange);
313
314
315 if (!myBucket.isIdle()) {
316
317 myBucket.adjustToBase();
318 theList.add(myBucket);
319 }
320 }
321 }
322
323 @Override
324 public MetisFieldSet<MoneyWiseXAnalysisTaxBasisBucketList> getDataFieldSet() {
325 return FIELD_DEFS;
326 }
327
328 @Override
329 public List<MoneyWiseXAnalysisTaxBasisBucket> getUnderlyingList() {
330 return theList.getUnderlyingList();
331 }
332
333 @Override
334 public String formatObject(final OceanusDataFormatter pFormatter) {
335 return getDataFieldSet().getName();
336 }
337
338
339
340
341
342
343 protected MoneyWiseXAnalysisHolder getAnalysis() {
344 return theAnalysis;
345 }
346
347
348
349
350
351
352
353 public MoneyWiseXAnalysisTaxBasisBucket findItemById(final Integer pId) {
354
355 return theList.getItemById(pId);
356 }
357
358 @Override
359 public MoneyWiseChargeableGainSliceList getGainSlices() {
360 return theCharges;
361 }
362
363
364
365
366
367
368 public MoneyWiseXAnalysisTaxBasisBucket getTotals() {
369 return theTotals;
370 }
371
372
373
374
375
376
377 private MoneyWiseXAnalysisTaxBasisBucket allocateTotalsBucket() {
378
379 return new MoneyWiseXAnalysisTaxBasisBucket(theAnalysis, null);
380 }
381
382
383
384
385
386
387
388 public MoneyWiseXAnalysisTaxBasisBucket getBucket(final MoneyWiseTaxClass pClass) {
389
390 final MoneyWiseTaxBasis myBasis = theEditSet.getDataList(MoneyWiseStaticDataType.TAXBASIS, MoneyWiseTaxBasisList.class).findItemByClass(pClass);
391 MoneyWiseXAnalysisTaxBasisBucket myItem = findItemById(myBasis.getIndexedId());
392
393
394 if (myItem == null) {
395
396 myItem = new MoneyWiseXAnalysisTaxBasisBucket(theAnalysis, myBasis);
397
398
399 theList.add(myItem);
400 }
401
402
403 return myItem;
404 }
405
406
407
408
409
410
411
412 public MoneyWiseXAnalysisTaxBasisBaseBucket getMatchingBasis(final MoneyWiseXAnalysisTaxBasisBaseBucket pTaxBasis) {
413
414 MoneyWiseXAnalysisTaxBasisBaseBucket myBasis = findItemById(pTaxBasis.getTaxBasis().getIndexedId());
415 if (myBasis == null) {
416 myBasis = new MoneyWiseXAnalysisTaxBasisBucket(theAnalysis, pTaxBasis.getTaxBasis());
417 }
418
419
420 if (pTaxBasis instanceof MoneyWiseXAnalysisTaxBasisAccountBucket myBucket) {
421
422 final MoneyWiseTransAsset myAsset = myBucket.getAccount();
423 MoneyWiseXAnalysisTaxBasisAccountBucket myAccountBucket =
424 ((MoneyWiseXAnalysisTaxBasisBucket) myBasis).findAccountBucket(myAsset);
425
426
427 if (myAccountBucket == null) {
428
429 myAccountBucket = new MoneyWiseXAnalysisTaxBasisAccountBucket(theAnalysis, myBasis.getTaxBasis(), myAsset);
430 }
431
432
433 myBasis = myAccountBucket;
434 }
435
436
437 return myBasis;
438 }
439
440
441
442
443
444
445 public MoneyWiseXAnalysisTaxBasisBucket getDefaultBasis() {
446
447 return isEmpty()
448 ? null
449 : theList.getUnderlyingList().getFirst();
450 }
451
452
453
454
455
456
457
458
459
460 public void recordChargeableGain(final MoneyWiseTransaction pTrans,
461 final OceanusMoney pGain,
462 final OceanusMoney pSlice,
463 final Integer pYears) {
464
465 theCharges.addTransaction(pTrans, pGain, pSlice, pYears);
466 }
467
468
469
470
471 public void produceTotals() {
472
473 final Iterator<MoneyWiseXAnalysisTaxBasisBucket> myIterator = iterator();
474 while (myIterator.hasNext()) {
475 final MoneyWiseXAnalysisTaxBasisBucket myBucket = myIterator.next();
476
477
478 if (myBucket.isIdle()) {
479 myIterator.remove();
480 continue;
481 }
482
483
484 if (myBucket.hasAccounts()) {
485 myBucket.getAccounts().sortBuckets();
486 }
487
488
489 theTotals.addValues(myBucket);
490 }
491
492
493 theList.sortList();
494 }
495
496 @Override
497 public OceanusMoney getAmountForTaxBasis(final MoneyWiseTaxClass pBasis) {
498
499 final MoneyWiseXAnalysisTaxBasisBucket myItem = findItemById(pBasis.getClassId());
500
501
502 if (myItem == null) {
503 final MoneyWiseCurrency myAssetCurrency = theAnalysis.getCurrency();
504 final Currency myCurrency = myAssetCurrency == null
505 ? OceanusMoney.getDefaultCurrency()
506 : myAssetCurrency.getCurrency();
507 return new OceanusMoney(myCurrency);
508 }
509
510 return myItem.getMoneyValue(MoneyWiseXAnalysisTaxBasisAttr.GROSS);
511 }
512 }
513 }