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