1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.moneywise.data.basic;
18
19 import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
20 import io.github.tonywasher.joceanus.metis.data.MetisDataEditState;
21 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
22 import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
23 import io.github.tonywasher.joceanus.metis.data.MetisDataState;
24 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
25 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
26 import io.github.tonywasher.joceanus.metis.field.MetisFieldVersionedSet;
27 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCashCategory.MoneyWiseCashCategoryList;
28 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseCashInfo.MoneyWiseCashInfoList;
29 import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee.MoneyWisePayeeList;
30 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAccountInfoClass;
31 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAccountInfoType.MoneyWiseAccountInfoTypeList;
32 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryClass;
33 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
34 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency.MoneyWiseCurrencyList;
35 import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
36 import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
37 import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseLogicException;
38 import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
39 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
40 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
41 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
42 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataMapItem;
43 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
44 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
45 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues.PrometheusInfoItem;
46 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues.PrometheusInfoSetItem;
47 import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
48
49 import java.util.Iterator;
50
51
52
53
54 public class MoneyWiseCash
55 extends MoneyWiseAssetBase
56 implements PrometheusInfoSetItem {
57
58
59
60 public static final String OBJECT_NAME = MoneyWiseBasicDataType.CASH.getItemName();
61
62
63
64
65 public static final String LIST_NAME = MoneyWiseBasicDataType.CASH.getListName();
66
67
68
69
70 private static final MetisFieldVersionedSet<MoneyWiseCash> FIELD_DEFS = MetisFieldVersionedSet.newVersionedFieldSet(MoneyWiseCash.class);
71
72
73
74
75 static {
76 FIELD_DEFS.declareLocalField(PrometheusDataResource.DATAINFOSET_NAME, MoneyWiseCash::getInfoSet);
77 FIELD_DEFS.buildFieldMap(MoneyWiseAccountInfoClass.class, MoneyWiseCash::getFieldValue);
78 }
79
80
81
82
83 private final boolean hasInfoSet;
84
85
86
87
88 private final boolean useInfoSet;
89
90
91
92
93 private final MoneyWiseCashInfoSet theInfoSet;
94
95
96
97
98
99
100
101 protected MoneyWiseCash(final MoneyWiseCashList pList,
102 final MoneyWiseCash pCash) {
103
104 super(pList, pCash);
105
106
107 switch (getList().getStyle()) {
108 case EDIT:
109 theInfoSet = new MoneyWiseCashInfoSet(this, pList.getActInfoTypes(), pList.getCashInfo());
110 theInfoSet.cloneDataInfoSet(pCash.getInfoSet());
111 hasInfoSet = true;
112 useInfoSet = true;
113 break;
114 case CLONE, CORE:
115 theInfoSet = new MoneyWiseCashInfoSet(this, pList.getActInfoTypes(), pList.getCashInfo());
116 hasInfoSet = true;
117 useInfoSet = false;
118 break;
119 default:
120 theInfoSet = null;
121 hasInfoSet = false;
122 useInfoSet = false;
123 break;
124 }
125 }
126
127
128
129
130
131
132
133
134 private MoneyWiseCash(final MoneyWiseCashList pList,
135 final PrometheusDataValues pValues) throws OceanusException {
136
137 super(pList, pValues);
138
139
140 theInfoSet = new MoneyWiseCashInfoSet(this, pList.getActInfoTypes(), pList.getCashInfo());
141 hasInfoSet = true;
142 useInfoSet = false;
143 }
144
145
146
147
148
149
150 public MoneyWiseCash(final MoneyWiseCashList pList) {
151 super(pList);
152
153
154 theInfoSet = new MoneyWiseCashInfoSet(this, pList.getActInfoTypes(), pList.getCashInfo());
155 hasInfoSet = true;
156 useInfoSet = true;
157 }
158
159 @Override
160 public MetisFieldSetDef getDataFieldSet() {
161 return FIELD_DEFS;
162 }
163
164 @Override
165 public boolean includeXmlField(final MetisDataFieldId pField) {
166
167 if (MoneyWiseBasicResource.CATEGORY_NAME.equals(pField)) {
168 return true;
169 }
170 if (MoneyWiseStaticDataType.CURRENCY.equals(pField)) {
171 return true;
172 }
173
174
175 return super.includeXmlField(pField);
176 }
177
178 @Override
179 public Long getExternalId() {
180 return MoneyWiseAssetType.createExternalId(isAutoExpense() ? MoneyWiseAssetType.AUTOEXPENSE : MoneyWiseAssetType.CASH, getIndexedId());
181 }
182
183 @Override
184 public MoneyWiseCashInfoSet getInfoSet() {
185 return theInfoSet;
186 }
187
188
189
190
191
192
193
194 private Object getFieldValue(final MetisDataFieldId pFieldId) {
195 return theInfoSet != null ? theInfoSet.getFieldValue(pFieldId) : null;
196 }
197
198
199
200
201
202
203 public char[] getNotes() {
204 return hasInfoSet
205 ? theInfoSet.getValue(MoneyWiseAccountInfoClass.NOTES, char[].class)
206 : null;
207 }
208
209
210
211
212
213
214 public MoneyWiseTransCategory getAutoExpense() {
215 return hasInfoSet
216 ? theInfoSet.getEventCategory(MoneyWiseAccountInfoClass.AUTOEXPENSE)
217 : null;
218 }
219
220
221
222
223
224
225 public MoneyWisePayee getAutoPayee() {
226 return hasInfoSet
227 ? theInfoSet.getPayee(MoneyWiseAccountInfoClass.AUTOPAYEE)
228 : null;
229 }
230
231 @Override
232 public OceanusMoney getOpeningBalance() {
233 return hasInfoSet
234 ? theInfoSet.getValue(MoneyWiseAccountInfoClass.OPENINGBALANCE, OceanusMoney.class)
235 : null;
236 }
237
238 @Override
239 public MoneyWiseCashCategory getCategory() {
240 return getValues().getValue(MoneyWiseBasicResource.CATEGORY_NAME, MoneyWiseCashCategory.class);
241 }
242
243
244
245
246
247
248 public Integer getCategoryId() {
249 final MoneyWiseCashCategory myCategory = getCategory();
250 return myCategory == null
251 ? null
252 : myCategory.getIndexedId();
253 }
254
255
256
257
258
259
260 public String getCategoryName() {
261 final MoneyWiseCashCategory myCategory = getCategory();
262 return myCategory == null
263 ? null
264 : myCategory.getName();
265 }
266
267
268
269
270
271
272 public MoneyWiseCashCategoryClass getCategoryClass() {
273 final MoneyWiseCashCategory myCategory = getCategory();
274 return myCategory == null
275 ? null
276 : myCategory.getCategoryTypeClass();
277 }
278
279 @Override
280 public boolean isForeign() {
281 final MoneyWiseCurrency myDefault = getDataSet().getReportingCurrency();
282 return !myDefault.equals(getAssetCurrency());
283 }
284
285 @Override
286 public boolean isAutoExpense() {
287 return MoneyWiseCashCategoryClass.AUTOEXPENSE.equals(getCategoryClass());
288 }
289
290 @Override
291 public MoneyWiseAssetType getAssetType() {
292 return isAutoExpense()
293 ? MoneyWiseAssetType.AUTOEXPENSE
294 : MoneyWiseAssetType.CASH;
295 }
296
297 @Override
298 public MoneyWiseCash getBase() {
299 return (MoneyWiseCash) super.getBase();
300 }
301
302 @Override
303 public MoneyWiseCashList getList() {
304 return (MoneyWiseCashList) super.getList();
305 }
306
307 @Override
308 public MetisDataState getState() {
309
310 MetisDataState myState = super.getState();
311
312
313 if ((myState == MetisDataState.CLEAN) && useInfoSet) {
314
315 myState = theInfoSet.getState();
316 }
317
318
319 return myState;
320 }
321
322 @Override
323 public MetisDataEditState getEditState() {
324
325 MetisDataEditState myState = super.getEditState();
326
327
328 if (myState == MetisDataEditState.CLEAN
329 && useInfoSet) {
330
331 myState = theInfoSet.getEditState();
332 }
333
334
335 return myState;
336 }
337
338 @Override
339 public boolean hasHistory() {
340
341 boolean hasHistory = super.hasHistory();
342
343
344 if (!hasHistory && useInfoSet) {
345
346 hasHistory = theInfoSet.hasHistory();
347 }
348
349
350 return hasHistory;
351 }
352
353 @Override
354 public void pushHistory() {
355
356 super.pushHistory();
357
358
359 if (useInfoSet) {
360
361 theInfoSet.pushHistory();
362 }
363 }
364
365 @Override
366 public void popHistory() {
367
368 super.popHistory();
369
370
371 if (useInfoSet) {
372
373 theInfoSet.popHistory();
374 }
375 }
376
377 @Override
378 public boolean checkForHistory() {
379
380 boolean bChanges = super.checkForHistory();
381
382
383 if (useInfoSet) {
384
385 bChanges |= theInfoSet.checkForHistory();
386 }
387
388
389 return bChanges;
390 }
391
392 @Override
393 public MetisDataDifference fieldChanged(final MetisDataFieldId pField) {
394
395 final MoneyWiseAccountInfoClass myClass = MoneyWiseCashInfoSet.getClassForField(pField);
396 if (myClass != null) {
397 return useInfoSet
398 ? theInfoSet.fieldChanged(myClass)
399 : MetisDataDifference.IDENTICAL;
400 }
401
402
403 return super.fieldChanged(pField);
404 }
405
406 @Override
407 public void setDeleted(final boolean bDeleted) {
408
409 if (useInfoSet) {
410 theInfoSet.setDeleted(bDeleted);
411 }
412
413
414 super.setDeleted(bDeleted);
415 }
416
417
418
419
420
421
422 public void setDefaults() throws OceanusException {
423 getList().getValidator().setDefaults(this);
424 }
425
426
427
428
429
430
431 public void autoCorrect() throws OceanusException {
432 getList().getValidator().autoCorrect(this);
433 }
434
435 @Override
436 public int compareValues(final PrometheusDataItem pThat) {
437
438 final MoneyWiseCash myThat = (MoneyWiseCash) pThat;
439 int iDiff = MetisDataDifference.compareObject(getCategory(), myThat.getCategory());
440 if (iDiff == 0) {
441 iDiff = MetisDataDifference.compareObject(getName(), myThat.getName());
442 }
443 return iDiff;
444 }
445
446 @Override
447 public void resolveDataSetLinks() throws OceanusException {
448
449 super.resolveDataSetLinks();
450
451
452 final MoneyWiseDataSet myData = getDataSet();
453 resolveDataLink(MoneyWiseBasicResource.CATEGORY_NAME, myData.getCashCategories());
454 resolveDataLink(MoneyWiseStaticDataType.CURRENCY, myData.getAccountCurrencies());
455 }
456
457 @Override
458 protected void resolveEditSetLinks() throws OceanusException {
459
460 final PrometheusEditSet myEditSet = getList().getEditSet();
461
462
463 if (myEditSet.hasDataType(MoneyWiseBasicDataType.CASHCATEGORY)) {
464 resolveDataLink(MoneyWiseBasicResource.CATEGORY_NAME, myEditSet.getDataList(MoneyWiseBasicDataType.CASHCATEGORY, MoneyWiseCashCategoryList.class));
465 }
466 if (myEditSet.hasDataType(MoneyWiseStaticDataType.CURRENCY)) {
467 resolveDataLink(MoneyWiseStaticDataType.CURRENCY, myEditSet.getDataList(MoneyWiseStaticDataType.CURRENCY, MoneyWiseCurrencyList.class));
468 }
469
470
471 theInfoSet.resolveEditSetLinks(myEditSet);
472 }
473
474
475
476
477
478
479
480 public void setNotes(final char[] pNotes) throws OceanusException {
481 setInfoSetValue(MoneyWiseAccountInfoClass.NOTES, pNotes);
482 }
483
484
485
486
487
488
489
490 public void setAutoExpense(final MoneyWiseTransCategory pCategory) throws OceanusException {
491 setInfoSetValue(MoneyWiseAccountInfoClass.AUTOEXPENSE, pCategory);
492 }
493
494
495
496
497
498
499
500 public void setAutoPayee(final MoneyWisePayee pPayee) throws OceanusException {
501 setInfoSetValue(MoneyWiseAccountInfoClass.AUTOPAYEE, pPayee);
502 }
503
504
505
506
507
508
509
510 public void setOpeningBalance(final OceanusMoney pBalance) throws OceanusException {
511 setInfoSetValue(MoneyWiseAccountInfoClass.OPENINGBALANCE, pBalance);
512 }
513
514
515
516
517
518
519
520
521 private void setInfoSetValue(final MoneyWiseAccountInfoClass pInfoClass,
522 final Object pValue) throws OceanusException {
523
524 if (!hasInfoSet) {
525 throw new MoneyWiseLogicException(ERROR_BADINFOSET);
526 }
527
528
529 theInfoSet.setValue(pInfoClass, pValue);
530 }
531
532 @Override
533 public void touchUnderlyingItems() {
534
535 getCategory().touchItem(this);
536 getAssetCurrency().touchItem(this);
537
538
539 theInfoSet.touchUnderlyingItems();
540 }
541
542 @Override
543 public void touchOnUpdate() {
544
545 theInfoSet.touchOnUpdate();
546 }
547
548
549
550
551
552
553
554 @Override
555 public boolean applyChanges(final PrometheusDataItem pCash) {
556
557 if (!(pCash instanceof MoneyWiseCash myCash)) {
558 return false;
559 }
560
561
562 pushHistory();
563
564
565 applyBasicChanges(myCash);
566
567
568 return checkForHistory();
569 }
570
571 @Override
572 public void adjustMapForItem() {
573 final MoneyWiseCashList myList = getList();
574 final MoneyWiseCashDataMap myMap = myList.getDataMap();
575 myMap.adjustForItem(this);
576 }
577
578 @Override
579 public void removeItem() {
580 theInfoSet.removeItems();
581 super.removeItem();
582 }
583
584
585
586
587 public static class MoneyWiseCashList
588 extends MoneyWiseAssetBaseList<MoneyWiseCash> {
589
590
591
592 private static final MetisFieldSet<MoneyWiseCashList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseCashList.class);
593
594
595
596
597 private MoneyWiseCashInfoList theInfoList;
598
599
600
601
602 private MoneyWiseAccountInfoTypeList theInfoTypeList;
603
604
605
606
607
608
609 public MoneyWiseCashList(final MoneyWiseDataSet pData) {
610 super(pData, MoneyWiseCash.class, MoneyWiseBasicDataType.CASH);
611 }
612
613
614
615
616
617
618 protected MoneyWiseCashList(final MoneyWiseCashList pSource) {
619 super(pSource);
620 }
621
622 @Override
623 public MetisFieldSet<MoneyWiseCashList> getDataFieldSet() {
624 return FIELD_DEFS;
625 }
626
627 @Override
628 public String listName() {
629 return LIST_NAME;
630 }
631
632 @Override
633 public MetisFieldSetDef getItemFields() {
634 return MoneyWiseCash.FIELD_DEFS;
635 }
636
637 @Override
638 protected MoneyWiseCashDataMap getDataMap() {
639 return (MoneyWiseCashDataMap) super.getDataMap();
640 }
641
642
643
644
645
646
647 public MoneyWiseCashInfoList getCashInfo() {
648 if (theInfoList == null) {
649 theInfoList = getDataSet().getCashInfo();
650 }
651 return theInfoList;
652 }
653
654
655
656
657
658
659 public MoneyWiseAccountInfoTypeList getActInfoTypes() {
660 if (theInfoTypeList == null) {
661 theInfoTypeList = getEditSet() == null
662 ? getDataSet().getActInfoTypes()
663 : getEditSet().getDataList(MoneyWiseStaticDataType.ACCOUNTINFOTYPE, MoneyWiseAccountInfoTypeList.class);
664 }
665 return theInfoTypeList;
666 }
667
668 @Override
669 protected MoneyWiseCashList getEmptyList(final PrometheusListStyle pStyle) {
670 final MoneyWiseCashList myList = new MoneyWiseCashList(this);
671 myList.setStyle(pStyle);
672 return myList;
673 }
674
675
676
677
678
679
680
681
682 public MoneyWiseCashList deriveEditList(final PrometheusEditSet pEditSet) throws OceanusException {
683
684 final MoneyWiseCashList myList = getEmptyList(PrometheusListStyle.EDIT);
685 final MoneyWisePayeeList myPayees = pEditSet.getDataList(MoneyWiseBasicDataType.PAYEE, MoneyWisePayeeList.class);
686 myList.ensureMap(myPayees);
687 pEditSet.setEditEntryList(MoneyWiseBasicDataType.CASH, myList);
688 myList.getValidator().setEditSet(pEditSet);
689
690
691 myList.theInfoTypeList = pEditSet.getDataList(MoneyWiseStaticDataType.ACCOUNTINFOTYPE, MoneyWiseAccountInfoTypeList.class);
692
693
694 final MoneyWiseCashInfoList myCashInfo = getCashInfo();
695 myList.theInfoList = myCashInfo.getEmptyList(PrometheusListStyle.EDIT);
696 pEditSet.setEditEntryList(MoneyWiseBasicDataType.CASHINFO, myList.theInfoList);
697
698
699 myList.setEditSet(pEditSet);
700
701
702 final Iterator<MoneyWiseCash> myIterator = iterator();
703 while (myIterator.hasNext()) {
704 final MoneyWiseCash myCurr = myIterator.next();
705
706
707 if (myCurr.isDeleted()) {
708 continue;
709 }
710
711
712 final MoneyWiseCash myCash = new MoneyWiseCash(myList, myCurr);
713 myList.add(myCash);
714 myCash.resolveEditSetLinks();
715
716
717 myCash.adjustMapForItem();
718 }
719
720
721 return myList;
722 }
723
724 @Override
725 public MoneyWiseCash findItemByName(final String pName) {
726
727 return getDataMap().findItemByName(pName);
728 }
729
730 @Override
731 public boolean checkAvailableName(final String pName) {
732
733 return getDataMap().availableName(pName);
734 }
735
736 @Override
737 public boolean validNameCount(final String pName) {
738
739 return getDataMap().validNameCount(pName);
740 }
741
742 @Override
743 public MoneyWiseCash addCopyItem(final PrometheusDataItem pCash) {
744
745 if (!(pCash instanceof MoneyWiseCash)) {
746 throw new UnsupportedOperationException();
747 }
748
749 final MoneyWiseCash myCash = new MoneyWiseCash(this, (MoneyWiseCash) pCash);
750 add(myCash);
751 return myCash;
752 }
753
754 @Override
755 public MoneyWiseCash addNewItem() {
756 final MoneyWiseCash myCash = new MoneyWiseCash(this);
757 add(myCash);
758 return myCash;
759 }
760
761 @Override
762 public MoneyWiseCash addValuesItem(final PrometheusDataValues pValues) throws OceanusException {
763
764 final MoneyWiseCash myCash = new MoneyWiseCash(this, pValues);
765
766
767 if (!isIdUnique(myCash.getIndexedId())) {
768 myCash.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
769 throw new MoneyWiseDataException(myCash, ERROR_VALIDATION);
770 }
771
772
773 add(myCash);
774
775
776 if (pValues.hasInfoItems()) {
777
778 final Iterator<PrometheusInfoItem> myIterator = pValues.infoIterator();
779 while (myIterator.hasNext()) {
780 final PrometheusInfoItem myItem = myIterator.next();
781
782
783 final PrometheusDataValues myValues = myItem.getValues(myCash);
784 theInfoList.addValuesItem(myValues);
785 }
786 }
787
788
789 return myCash;
790 }
791
792
793
794
795
796
797 private void ensureMap(final MoneyWisePayeeList pPayees) {
798 setDataMap(new MoneyWiseCashDataMap(pPayees));
799 }
800
801 @Override
802 protected MoneyWiseCashDataMap allocateDataMap() {
803 return new MoneyWiseCashDataMap(getDataSet().getPayees());
804 }
805
806 @Override
807 public void postProcessOnLoad() throws OceanusException {
808
809 super.resolveDataSetLinks();
810 reSort();
811 }
812 }
813
814
815
816
817 protected static class MoneyWiseCashDataMap
818 implements PrometheusDataMapItem, MetisFieldItem {
819
820
821
822 private static final MetisFieldSet<MoneyWiseCashDataMap> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseCashDataMap.class);
823
824
825
826
827 static {
828 FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.MONEYWISEDATA_MAP_UNDERLYING, MoneyWiseCashDataMap::getUnderlyingMap);
829 }
830
831
832
833
834 private final MoneyWiseAssetDataMap theUnderlyingMap;
835
836
837
838
839
840
841 protected MoneyWiseCashDataMap(final MoneyWisePayeeList pPayees) {
842 theUnderlyingMap = pPayees.getDataMap().getUnderlyingMap();
843 }
844
845 @Override
846 public MetisFieldSet<MoneyWiseCashDataMap> getDataFieldSet() {
847 return FIELD_DEFS;
848 }
849
850 @Override
851 public String formatObject(final OceanusDataFormatter pFormatter) {
852 return FIELD_DEFS.getName();
853 }
854
855
856
857
858
859
860 private MoneyWiseAssetDataMap getUnderlyingMap() {
861 return theUnderlyingMap;
862 }
863
864 @Override
865 public void resetMap() {
866
867 }
868
869 @Override
870 public void adjustForItem(final PrometheusDataItem pItem) {
871
872 theUnderlyingMap.adjustForItem(pItem);
873 }
874
875
876
877
878
879
880
881 public MoneyWiseCash findItemByName(final String pName) {
882 final MoneyWiseAssetBase myAsset = theUnderlyingMap.findAssetByName(pName);
883 return myAsset instanceof MoneyWiseCash myCash
884 ? myCash
885 : null;
886 }
887
888
889
890
891
892
893
894 public boolean validNameCount(final String pName) {
895 return theUnderlyingMap.validNameCount(pName);
896 }
897
898
899
900
901
902
903
904 public boolean availableName(final String pName) {
905 return theUnderlyingMap.availableKey(pName);
906 }
907 }
908 }