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.oceanus.date.OceanusDate;
20 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
21 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusDecimal;
22 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
23 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
24 import io.github.tonywasher.joceanus.metis.data.MetisDataFieldValue;
25 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
26 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataList;
27 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
28 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem.MetisFieldTableItem;
29 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
30 import io.github.tonywasher.joceanus.metis.list.MetisListIndexed;
31 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.base.MoneyWiseXAnalysisEvent;
32 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.base.MoneyWiseXAnalysisHistory;
33 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.buckets.MoneyWiseXAnalysisInterfaces.MoneyWiseXAnalysisBucketRegister;
34 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.values.MoneyWiseXAnalysisPayeeAttr;
35 import io.github.tonywasher.joceanus.moneywise.atlas.data.analysis.values.MoneyWiseXAnalysisPayeeValues;
36 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseAssetBase;
37 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
38 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee;
39 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee.MoneyWisePayeeList;
40 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
41 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWisePayeeClass;
42 import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
43
44 import java.util.Currency;
45 import java.util.Iterator;
46 import java.util.List;
47
48
49
50
51 public final class MoneyWiseXAnalysisPayeeBucket
52 implements MetisFieldTableItem, MoneyWiseXAnalysisBucketRegister {
53
54
55
56 private static final MetisFieldSet<MoneyWiseXAnalysisPayeeBucket> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseXAnalysisPayeeBucket.class);
57
58
59
60
61 static {
62 FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.ANALYSIS_NAME, MoneyWiseXAnalysisPayeeBucket::getAnalysis);
63 FIELD_DEFS.declareLocalField(MoneyWiseBasicDataType.PAYEE, MoneyWiseXAnalysisPayeeBucket::getPayee);
64 FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.BUCKET_BASEVALUES, MoneyWiseXAnalysisPayeeBucket::getBaseValues);
65 FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.BUCKET_HISTORY, MoneyWiseXAnalysisPayeeBucket::getHistoryMap);
66 FIELD_DEFS.declareLocalFieldsForEnum(MoneyWiseXAnalysisPayeeAttr.class, MoneyWiseXAnalysisPayeeBucket::getAttributeValue);
67 }
68
69
70
71
72 private static final MetisDataFieldId NAME_TOTALS = MoneyWiseXAnalysisBucketResource.ANALYSIS_TOTALS;
73
74
75
76
77 private final MoneyWiseXAnalysis theAnalysis;
78
79
80
81
82 private final MoneyWisePayee thePayee;
83
84
85
86
87 private final MoneyWiseXAnalysisPayeeValues theValues;
88
89
90
91
92 private final MoneyWiseXAnalysisPayeeValues theBaseValues;
93
94
95
96
97 private final MoneyWiseXAnalysisHistory<MoneyWiseXAnalysisPayeeValues, MoneyWiseXAnalysisPayeeAttr> theHistory;
98
99
100
101
102
103
104
105 private MoneyWiseXAnalysisPayeeBucket(final MoneyWiseXAnalysis pAnalysis,
106 final MoneyWisePayee pPayee) {
107
108 thePayee = pPayee;
109 theAnalysis = pAnalysis;
110
111
112 final MoneyWiseCurrency myDefault = theAnalysis.getCurrency();
113 final Currency myCurrency = myDefault == null
114 ? MoneyWiseXAnalysisAccountBucket.DEFAULT_CURRENCY
115 : myDefault.getCurrency();
116 final MoneyWiseXAnalysisPayeeValues myValues = new MoneyWiseXAnalysisPayeeValues(myCurrency);
117 theHistory = new MoneyWiseXAnalysisHistory<>(myValues);
118
119
120 theValues = theHistory.getValues();
121 theBaseValues = theHistory.getBaseValues();
122 }
123
124
125
126
127
128
129
130
131 private MoneyWiseXAnalysisPayeeBucket(final MoneyWiseXAnalysis pAnalysis,
132 final MoneyWiseXAnalysisPayeeBucket pBase,
133 final OceanusDate pDate) {
134
135 thePayee = pBase.getPayee();
136 theAnalysis = pAnalysis;
137
138
139 theHistory = new MoneyWiseXAnalysisHistory<>(pBase.getHistoryMap(), pDate);
140
141
142 theValues = theHistory.getValues();
143 theBaseValues = theHistory.getBaseValues();
144 }
145
146
147
148
149
150
151
152
153 private MoneyWiseXAnalysisPayeeBucket(final MoneyWiseXAnalysis pAnalysis,
154 final MoneyWiseXAnalysisPayeeBucket pBase,
155 final OceanusDateRange pRange) {
156
157 thePayee = pBase.getPayee();
158 theAnalysis = pAnalysis;
159
160
161 theHistory = new MoneyWiseXAnalysisHistory<>(pBase.getHistoryMap(), pRange);
162
163
164 theValues = theHistory.getValues();
165 theBaseValues = theHistory.getBaseValues();
166 }
167
168 @Override
169 public MetisFieldSet<MoneyWiseXAnalysisPayeeBucket> getDataFieldSet() {
170 return FIELD_DEFS;
171 }
172
173 @Override
174 public String formatObject(final OceanusDataFormatter pFormatter) {
175 return toString();
176 }
177
178 @Override
179 public String toString() {
180 return getName() + " " + theValues;
181 }
182
183
184
185
186
187
188 public String getName() {
189 return thePayee == null
190 ? NAME_TOTALS.getId()
191 : thePayee.getName();
192 }
193
194
195
196
197
198
199 public MoneyWisePayee getPayee() {
200 return thePayee;
201 }
202
203 @Override
204 public Integer getIndexedId() {
205 return thePayee.getIndexedId();
206 }
207
208 @Override
209 public Long getBucketId() {
210 return thePayee.getExternalId();
211 }
212
213
214
215
216
217
218 public boolean isIdle() {
219 return theHistory.isIdle();
220 }
221
222
223
224
225
226
227 MoneyWiseXAnalysis getAnalysis() {
228 return theAnalysis;
229 }
230
231
232
233
234
235
236 public OceanusDateRange getDateRange() {
237 return theAnalysis.getDateRange();
238 }
239
240
241
242
243
244
245 public MoneyWiseXAnalysisPayeeValues getValues() {
246 return theValues;
247 }
248
249
250
251
252
253
254 public MoneyWiseXAnalysisPayeeValues getBaseValues() {
255 return theBaseValues;
256 }
257
258
259
260
261
262
263
264 public MoneyWiseXAnalysisPayeeValues getValuesForEvent(final MoneyWiseXAnalysisEvent pEvent) {
265
266 return theHistory.getValuesForEvent(pEvent);
267 }
268
269
270
271
272
273
274
275 public MoneyWiseXAnalysisPayeeValues getPreviousValuesForEvent(final MoneyWiseXAnalysisEvent pEvent) {
276 return theHistory.getPreviousValuesForEvent(pEvent);
277 }
278
279
280
281
282
283
284
285
286 public OceanusDecimal getDeltaForEvent(final MoneyWiseXAnalysisEvent pEvent,
287 final MoneyWiseXAnalysisPayeeAttr pAttr) {
288
289 return theHistory.getDeltaValue(pEvent, pAttr);
290 }
291
292
293
294
295
296
297 private MoneyWiseXAnalysisHistory<MoneyWiseXAnalysisPayeeValues, MoneyWiseXAnalysisPayeeAttr> getHistoryMap() {
298 return theHistory;
299 }
300
301
302
303
304
305
306
307 void setValue(final MoneyWiseXAnalysisPayeeAttr pAttr,
308 final Object pValue) {
309
310 theValues.setValue(pAttr, pValue);
311 }
312
313
314
315
316
317
318
319 private Object getAttributeValue(final MoneyWiseXAnalysisPayeeAttr pAttr) {
320
321 final Object myValue = getValue(pAttr);
322
323
324 return myValue != null
325 ? myValue
326 : MetisDataFieldValue.SKIP;
327 }
328
329
330
331
332
333
334
335 private Object getValue(final MoneyWiseXAnalysisPayeeAttr pAttr) {
336
337 return theValues.getValue(pAttr);
338 }
339
340
341
342
343
344
345
346 void adjustCounter(final MoneyWiseXAnalysisPayeeAttr pAttr,
347 final OceanusMoney pDelta) {
348 OceanusMoney myValue = theValues.getMoneyValue(pAttr);
349 myValue = new OceanusMoney(myValue);
350 myValue.addAmount(pDelta);
351 setValue(pAttr, myValue);
352 }
353
354 @Override
355 public void registerEvent(final MoneyWiseXAnalysisEvent pEvent) {
356
357 theHistory.registerEvent(pEvent, theValues);
358 }
359
360
361
362
363
364
365 public void addIncome(final OceanusMoney pValue) {
366
367 if (pValue.isNonZero()) {
368 adjustCounter(MoneyWiseXAnalysisPayeeAttr.INCOME, pValue);
369 }
370 }
371
372
373
374
375
376
377 public void subtractIncome(final OceanusMoney pValue) {
378
379 if (pValue.isNonZero()) {
380 final OceanusMoney myIncome = new OceanusMoney(pValue);
381 myIncome.negate();
382 adjustCounter(MoneyWiseXAnalysisPayeeAttr.INCOME, myIncome);
383 }
384 }
385
386
387
388
389
390
391 public void addExpense(final OceanusMoney pValue) {
392
393 if (pValue.isNonZero()) {
394 adjustCounter(MoneyWiseXAnalysisPayeeAttr.EXPENSE, pValue);
395 }
396 }
397
398
399
400
401
402
403 public void subtractExpense(final OceanusMoney pValue) {
404
405 if (pValue.isNonZero()) {
406 final OceanusMoney myExpense = new OceanusMoney(pValue);
407 myExpense.negate();
408 adjustCounter(MoneyWiseXAnalysisPayeeAttr.EXPENSE, myExpense);
409 }
410 }
411
412
413
414
415
416
417 void addValues(final MoneyWiseXAnalysisPayeeBucket pSource) {
418
419 final MoneyWiseXAnalysisPayeeValues mySource = pSource.getValues();
420
421
422 OceanusMoney myValue = theValues.getMoneyValue(MoneyWiseXAnalysisPayeeAttr.INCOME);
423 OceanusMoney mySrcValue = mySource.getMoneyValue(MoneyWiseXAnalysisPayeeAttr.INCOME);
424 myValue.addAmount(mySrcValue);
425
426
427 myValue = theValues.getMoneyValue(MoneyWiseXAnalysisPayeeAttr.EXPENSE);
428 mySrcValue = mySource.getMoneyValue(MoneyWiseXAnalysisPayeeAttr.EXPENSE);
429 myValue.addAmount(mySrcValue);
430 }
431
432
433
434
435 void calculateDelta() {
436
437 theValues.calculateDelta();
438 }
439
440
441
442
443 void adjustToBase() {
444
445 theValues.adjustToBaseValues(theBaseValues);
446 theBaseValues.resetBaseValues();
447 }
448
449
450
451
452 public static final class MoneyWiseXAnalysisPayeeBucketList
453 implements MetisFieldItem, MetisDataList<MoneyWiseXAnalysisPayeeBucket> {
454
455
456
457 private static final MetisFieldSet<MoneyWiseXAnalysisPayeeBucketList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseXAnalysisPayeeBucketList.class);
458
459
460
461
462 static {
463 FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.ANALYSIS_NAME, MoneyWiseXAnalysisPayeeBucketList::getAnalysis);
464 FIELD_DEFS.declareLocalField(MoneyWiseXAnalysisBucketResource.ANALYSIS_TOTALS, MoneyWiseXAnalysisPayeeBucketList::getTotals);
465 }
466
467
468
469
470 private final MoneyWiseXAnalysis theAnalysis;
471
472
473
474
475 private final MetisListIndexed<MoneyWiseXAnalysisPayeeBucket> theList;
476
477
478
479
480 private final PrometheusEditSet theEditSet;
481
482
483
484
485 private final MoneyWiseXAnalysisPayeeBucket theTotals;
486
487
488
489
490
491
492 MoneyWiseXAnalysisPayeeBucketList(final MoneyWiseXAnalysis pAnalysis) {
493
494 theAnalysis = pAnalysis;
495 theEditSet = theAnalysis.getEditSet();
496 theTotals = allocateTotalsBucket();
497 theList = new MetisListIndexed<>();
498 theList.setComparator((l, r) -> l.getPayee().compareTo(r.getPayee()));
499 }
500
501
502
503
504
505
506
507
508 MoneyWiseXAnalysisPayeeBucketList(final MoneyWiseXAnalysis pAnalysis,
509 final MoneyWiseXAnalysisPayeeBucketList pBase,
510 final OceanusDate pDate) {
511
512 this(pAnalysis);
513
514
515 final Iterator<MoneyWiseXAnalysisPayeeBucket> myIterator = pBase.iterator();
516 while (myIterator.hasNext()) {
517 final MoneyWiseXAnalysisPayeeBucket myCurr = myIterator.next();
518
519
520 final MoneyWiseXAnalysisPayeeBucket myBucket = new MoneyWiseXAnalysisPayeeBucket(pAnalysis, myCurr, pDate);
521
522
523 if (!myBucket.isIdle()) {
524
525 theList.add(myBucket);
526 }
527 }
528 }
529
530
531
532
533
534
535
536
537 MoneyWiseXAnalysisPayeeBucketList(final MoneyWiseXAnalysis pAnalysis,
538 final MoneyWiseXAnalysisPayeeBucketList pBase,
539 final OceanusDateRange pRange) {
540
541 this(pAnalysis);
542
543
544 final Iterator<MoneyWiseXAnalysisPayeeBucket> myIterator = pBase.iterator();
545 while (myIterator.hasNext()) {
546 final MoneyWiseXAnalysisPayeeBucket myCurr = myIterator.next();
547
548
549 final MoneyWiseXAnalysisPayeeBucket myBucket = new MoneyWiseXAnalysisPayeeBucket(pAnalysis, myCurr, pRange);
550
551
552 if (!myBucket.isIdle()) {
553
554 myBucket.adjustToBase();
555 theList.add(myBucket);
556 }
557 }
558 }
559
560 @Override
561 public MetisFieldSet<MoneyWiseXAnalysisPayeeBucketList> getDataFieldSet() {
562 return FIELD_DEFS;
563 }
564
565 @Override
566 public List<MoneyWiseXAnalysisPayeeBucket> getUnderlyingList() {
567 return theList.getUnderlyingList();
568 }
569
570 @Override
571 public String formatObject(final OceanusDataFormatter pFormatter) {
572 return getDataFieldSet().getName();
573 }
574
575
576
577
578
579
580
581 public MoneyWiseXAnalysisPayeeBucket findItemById(final Integer pId) {
582
583 return theList.getItemById(pId);
584 }
585
586
587
588
589
590
591 MoneyWiseXAnalysis getAnalysis() {
592 return theAnalysis;
593 }
594
595
596
597
598
599
600 public MoneyWiseXAnalysisPayeeBucket getTotals() {
601 return theTotals;
602 }
603
604
605
606
607
608
609 private MoneyWiseXAnalysisPayeeBucket allocateTotalsBucket() {
610
611 return new MoneyWiseXAnalysisPayeeBucket(theAnalysis, null);
612 }
613
614
615
616
617
618
619
620 public MoneyWiseXAnalysisPayeeBucket getBucket(final MoneyWiseAssetBase pPayee) {
621
622 if (pPayee == null) {
623 return null;
624 }
625
626
627 final MoneyWisePayee myPayee = (MoneyWisePayee) pPayee;
628
629
630 MoneyWiseXAnalysisPayeeBucket myItem = findItemById(myPayee.getIndexedId());
631
632
633 if (myItem == null) {
634
635 myItem = new MoneyWiseXAnalysisPayeeBucket(theAnalysis, myPayee);
636
637
638 theList.add(myItem);
639 }
640
641
642 return myItem;
643 }
644
645
646
647
648
649
650
651 public MoneyWiseXAnalysisPayeeBucket getBucket(final MoneyWisePayeeClass pClass) {
652
653 final MoneyWisePayee myPayee = theEditSet.getDataList(MoneyWiseBasicDataType.PAYEE, MoneyWisePayeeList.class).getSingularClass(pClass);
654
655
656 return getBucket(myPayee);
657 }
658
659
660
661
662
663
664
665 public MoneyWiseXAnalysisPayeeBucket getMatchingPayee(final MoneyWisePayee pPayee) {
666
667 final MoneyWiseXAnalysisPayeeBucket myPayee = findItemById(pPayee.getIndexedId());
668 return myPayee != null
669 ? myPayee
670 : new MoneyWiseXAnalysisPayeeBucket(theAnalysis, pPayee);
671 }
672
673
674
675
676
677
678 public MoneyWiseXAnalysisPayeeBucket getDefaultPayee() {
679
680 return isEmpty()
681 ? null
682 : theList.getUnderlyingList().get(0);
683 }
684
685
686
687
688 public void produceTotals() {
689
690 final Iterator<MoneyWiseXAnalysisPayeeBucket> myIterator = iterator();
691 while (myIterator.hasNext()) {
692 final MoneyWiseXAnalysisPayeeBucket myCurr = myIterator.next();
693
694
695 if (myCurr.isIdle()) {
696 myIterator.remove();
697 continue;
698 }
699
700
701 myCurr.calculateDelta();
702
703
704 theTotals.addValues(myCurr);
705 }
706
707
708 theList.sortList();
709
710
711 if (theTotals != null) {
712 theTotals.calculateDelta();
713 }
714 }
715 }
716 }