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