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.date.OceanusDate;
21 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateFormatter;
22 import io.github.tonywasher.joceanus.oceanus.date.OceanusDateRange;
23 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
24 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRatio;
25 import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
26 import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
27 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
28 import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataList;
29 import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
30 import io.github.tonywasher.joceanus.metis.field.MetisFieldItem;
31 import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
32 import io.github.tonywasher.joceanus.metis.field.MetisFieldVersionedSet;
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.MoneyWiseStaticResource;
36 import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
37 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataInstanceMap;
38 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
39 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataList;
40 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataMapItem;
41 import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
42
43 import java.util.ArrayList;
44 import java.util.Currency;
45 import java.util.HashMap;
46 import java.util.Iterator;
47 import java.util.List;
48 import java.util.ListIterator;
49 import java.util.Map;
50
51
52
53
54 public class MoneyWiseExchangeRate
55 extends PrometheusDataItem {
56
57
58
59 public static final String OBJECT_NAME = MoneyWiseBasicDataType.EXCHANGERATE.getItemName();
60
61
62
63
64 public static final String LIST_NAME = MoneyWiseBasicDataType.EXCHANGERATE.getListName();
65
66
67
68
69 private static final MetisFieldVersionedSet<MoneyWiseExchangeRate> FIELD_DEFS = MetisFieldVersionedSet.newVersionedFieldSet(MoneyWiseExchangeRate.class);
70
71
72
73
74 static {
75 FIELD_DEFS.declareDateField(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE);
76 FIELD_DEFS.declareLinkField(MoneyWiseBasicResource.XCHGRATE_FROM);
77 FIELD_DEFS.declareLinkField(MoneyWiseBasicResource.XCHGRATE_TO);
78 FIELD_DEFS.declareRatioField(MoneyWiseBasicResource.XCHGRATE_RATE);
79 }
80
81
82
83
84 public static final String ERROR_CIRCLE = MoneyWiseBasicResource.XCHGRATE_ERROR_CIRCLE.getValue();
85
86
87
88
89 public static final String ERROR_DEF = MoneyWiseBasicResource.XCHGRATE_ERROR_DEFAULT.getValue();
90
91
92
93
94
95
96
97 protected MoneyWiseExchangeRate(final MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate> pList,
98 final MoneyWiseExchangeRate pRate) {
99
100 super(pList, pRate);
101 }
102
103
104
105
106
107
108 public MoneyWiseExchangeRate(final MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate> pList) {
109 super(pList, 0);
110 }
111
112
113
114
115
116
117
118
119 private MoneyWiseExchangeRate(final MoneyWiseExchangeRateList pList,
120 final PrometheusDataValues pValues) throws OceanusException {
121
122 super(pList, pValues);
123
124
125 final OceanusDataFormatter myFormatter = getDataSet().getDataFormatter();
126
127
128 try {
129
130 Object myValue = pValues.getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE);
131 if (myValue instanceof OceanusDate d) {
132 setValueDate(d);
133 } else if (myValue instanceof String s) {
134 final OceanusDateFormatter myParser = myFormatter.getDateFormatter();
135 setValueDate(myParser.parseDate(s));
136 }
137
138
139 myValue = pValues.getValue(MoneyWiseBasicResource.XCHGRATE_FROM);
140 if (myValue instanceof Integer i) {
141 setValueFromCurrency(i);
142 } else if (myValue instanceof String s) {
143 setValueFromCurrency(s);
144 }
145
146
147 myValue = pValues.getValue(MoneyWiseBasicResource.XCHGRATE_TO);
148 if (myValue instanceof Integer i) {
149 setValueToCurrency(i);
150 } else if (myValue instanceof String s) {
151 setValueToCurrency(s);
152 }
153
154
155 myValue = pValues.getValue(MoneyWiseBasicResource.XCHGRATE_RATE);
156 if (myValue instanceof OceanusRatio r) {
157 setValueExchangeRate(r);
158 } else if (myValue instanceof String myString) {
159 setValueExchangeRate(myString);
160 setValueExchangeRate(myFormatter.parseValue(myString, OceanusRatio.class));
161 }
162
163
164 } catch (IllegalArgumentException e) {
165
166 throw new MoneyWiseDataException(this, ERROR_CREATEITEM, e);
167 }
168 }
169
170
171
172
173
174
175 public MoneyWiseExchangeRate(final MoneyWiseExchangeRateList pList) {
176 super(pList, 0);
177 }
178
179 @Override
180 public MetisFieldSetDef getDataFieldSet() {
181 return FIELD_DEFS;
182 }
183
184 @Override
185 public String formatObject(final OceanusDataFormatter pFormatter) {
186 return toString();
187 }
188
189 @Override
190 public String toString() {
191
192 final OceanusDataFormatter myFormatter = getDataSet().getDataFormatter();
193
194
195 final StringBuilder myBuilder = new StringBuilder();
196 myBuilder.append(myFormatter.formatObject(getDate()));
197 myBuilder.append(" ");
198 myBuilder.append(myFormatter.formatObject(getFromCurrency().getCurrency().getCurrencyCode()));
199 myBuilder.append(": ");
200 myBuilder.append(myFormatter.formatObject(getToCurrency().getCurrency().getCurrencyCode()));
201 myBuilder.append('=');
202 myBuilder.append(myFormatter.formatObject(getExchangeRate()));
203 return myBuilder.toString();
204 }
205
206 @Override
207 public boolean includeXmlField(final MetisDataFieldId pField) {
208
209 if (MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE.equals(pField)) {
210 return true;
211 }
212 if (MoneyWiseBasicResource.XCHGRATE_FROM.equals(pField)) {
213 return true;
214 }
215 if (MoneyWiseBasicResource.XCHGRATE_TO.equals(pField)) {
216 return true;
217 }
218 if (MoneyWiseBasicResource.XCHGRATE_RATE.equals(pField)) {
219 return true;
220 }
221
222
223 return super.includeXmlField(pField);
224 }
225
226
227
228
229
230
231 public OceanusDate getDate() {
232 return getValues().getValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE, OceanusDate.class);
233 }
234
235
236
237
238
239
240 public MoneyWiseCurrency getFromCurrency() {
241 return getValues().getValue(MoneyWiseBasicResource.XCHGRATE_FROM, MoneyWiseCurrency.class);
242 }
243
244
245
246
247
248
249 public Integer getFromCurrencyId() {
250 final MoneyWiseCurrency myCurr = getFromCurrency();
251 return myCurr == null
252 ? null
253 : myCurr.getIndexedId();
254 }
255
256
257
258
259
260
261 public String getFromCurrencyName() {
262 final MoneyWiseCurrency myCurr = getFromCurrency();
263 return myCurr == null
264 ? null
265 : myCurr.getName();
266 }
267
268
269
270
271
272
273 public MoneyWiseCurrency getToCurrency() {
274 return getValues().getValue(MoneyWiseBasicResource.XCHGRATE_TO, MoneyWiseCurrency.class);
275 }
276
277
278
279
280
281
282 public Integer getToCurrencyId() {
283 final MoneyWiseCurrency myCurr = getToCurrency();
284 return myCurr == null
285 ? null
286 : myCurr.getIndexedId();
287 }
288
289
290
291
292
293
294 public String getToCurrencyName() {
295 final MoneyWiseCurrency myCurr = getToCurrency();
296 return myCurr == null
297 ? null
298 : myCurr.getName();
299 }
300
301
302
303
304
305
306 public OceanusRatio getExchangeRate() {
307 return getValues().getValue(MoneyWiseBasicResource.XCHGRATE_RATE, OceanusRatio.class);
308 }
309
310
311
312
313
314
315 public OceanusRatio getInverseRate() {
316 final OceanusRatio myRate = getExchangeRate();
317 return myRate == null
318 ? null
319 : myRate.getInverseRatio();
320 }
321
322
323
324
325
326
327 private void setValueDate(final OceanusDate pValue) {
328 getValues().setUncheckedValue(MoneyWiseBasicResource.MONEYWISEDATA_FIELD_DATE, pValue);
329 }
330
331
332
333
334
335
336 private void setValueFromCurrency(final MoneyWiseCurrency pValue) {
337 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_FROM, pValue);
338 }
339
340
341
342
343
344
345 private void setValueFromCurrency(final Integer pValue) {
346 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_FROM, pValue);
347 }
348
349
350
351
352
353
354 private void setValueFromCurrency(final String pValue) {
355 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_FROM, pValue);
356 }
357
358
359
360
361
362
363 private void setValueToCurrency(final MoneyWiseCurrency pValue) {
364 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_TO, pValue);
365 }
366
367
368
369
370
371
372 private void setValueToCurrency(final Integer pValue) {
373 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_TO, pValue);
374 }
375
376
377
378
379
380
381 private void setValueToCurrency(final String pValue) {
382 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_TO, pValue);
383 }
384
385
386
387
388
389
390 protected void setValueExchangeRate(final OceanusRatio pValue) {
391 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_RATE, pValue);
392 }
393
394
395
396
397
398
399 private void setValueExchangeRate(final String pValue) {
400 getValues().setUncheckedValue(MoneyWiseBasicResource.XCHGRATE_RATE, pValue);
401 }
402
403 @Override
404 public MoneyWiseDataSet getDataSet() {
405 return (MoneyWiseDataSet) super.getDataSet();
406 }
407
408 @Override
409 public MoneyWiseExchangeRate getBase() {
410 return (MoneyWiseExchangeRate) super.getBase();
411 }
412
413 @Override
414 @SuppressWarnings("unchecked")
415 public MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate> getList() {
416 return (MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate>) super.getList();
417 }
418
419 @Override
420 public int compareValues(final PrometheusDataItem pThat) {
421
422 final MoneyWiseExchangeRate myThat = (MoneyWiseExchangeRate) pThat;
423
424
425 int iDiff = MetisDataDifference.compareObject(getDate(), myThat.getDate());
426 if (iDiff != 0) {
427
428 return -iDiff;
429 }
430
431
432 iDiff = MetisDataDifference.compareObject(getFromCurrency(), myThat.getFromCurrency());
433 if (iDiff != 0) {
434 return iDiff;
435 }
436
437
438 return getToCurrency().compareTo(myThat.getToCurrency());
439 }
440
441 @Override
442 public void resolveDataSetLinks() throws OceanusException {
443
444 super.resolveDataSetLinks();
445
446
447 final MoneyWiseDataSet myData = getDataSet();
448 final MoneyWiseCurrencyList myCurrencies = myData.getAccountCurrencies();
449 resolveDataLink(MoneyWiseBasicResource.XCHGRATE_FROM, myCurrencies);
450 resolveDataLink(MoneyWiseBasicResource.XCHGRATE_TO, myCurrencies);
451 }
452
453
454
455
456
457
458 public void setDate(final OceanusDate pDate) {
459 setValueDate(pDate);
460 }
461
462
463
464
465
466
467 public void setFromCurrency(final MoneyWiseCurrency pCurrency) {
468 setValueFromCurrency(pCurrency);
469 }
470
471
472
473
474
475
476 public void setToCurrency(final MoneyWiseCurrency pCurrency) {
477 setValueToCurrency(pCurrency);
478 }
479
480
481
482
483
484
485 public void setExchangeRate(final OceanusRatio pRate) {
486 setValueExchangeRate(pRate);
487 }
488
489 @Override
490 public void touchUnderlyingItems() {
491
492 getFromCurrency().touchItem(this);
493 getToCurrency().touchItem(this);
494 }
495
496
497
498
499
500
501
502 @Override
503 public boolean applyChanges(final PrometheusDataItem pRate) {
504
505 if (!(pRate instanceof MoneyWiseExchangeRate)) {
506 return false;
507 }
508 final MoneyWiseExchangeRate myRate = (MoneyWiseExchangeRate) pRate;
509
510
511 pushHistory();
512
513
514 if (!MetisDataDifference.isEqual(getDate(), myRate.getDate())) {
515 setValueDate(myRate.getDate());
516 }
517
518
519 if (!MetisDataDifference.isEqual(getFromCurrency(), myRate.getFromCurrency())) {
520 setValueFromCurrency(myRate.getFromCurrency());
521 }
522
523
524 if (!MetisDataDifference.isEqual(getToCurrency(), myRate.getToCurrency())) {
525 setValueToCurrency(myRate.getToCurrency());
526 }
527
528
529 if (!MetisDataDifference.isEqual(getExchangeRate(), myRate.getExchangeRate())) {
530 setValueExchangeRate(myRate.getExchangeRate());
531 }
532
533
534 return checkForHistory();
535 }
536
537 @Override
538 public void adjustMapForItem() {
539 final MoneyWiseExchangeRateBaseList<? extends MoneyWiseExchangeRate> myList = getList();
540 final MoneyWiseExchangeRateDataMap myMap = myList.getDataMap();
541 myMap.adjustForItem(this);
542 }
543
544
545
546
547
548
549 public abstract static class MoneyWiseExchangeRateBaseList<T extends MoneyWiseExchangeRate>
550 extends PrometheusDataList<T> {
551
552
553
554 static {
555 MetisFieldSet.newFieldSet(MoneyWiseExchangeRateBaseList.class);
556 }
557
558
559
560
561
562
563
564
565 protected MoneyWiseExchangeRateBaseList(final MoneyWiseDataSet pData,
566 final Class<T> pClass,
567 final MoneyWiseBasicDataType pItemType) {
568
569 super(pClass, pData, pItemType, PrometheusListStyle.CORE);
570 }
571
572
573
574
575
576
577 protected MoneyWiseExchangeRateBaseList(final MoneyWiseExchangeRateBaseList<T> pSource) {
578
579 super(pSource);
580 }
581
582 @Override
583 public MoneyWiseExchangeRateDataMap getDataMap() {
584 return (MoneyWiseExchangeRateDataMap) super.getDataMap();
585 }
586
587 @Override
588 protected MoneyWiseExchangeRateDataMap allocateDataMap() {
589 return new MoneyWiseExchangeRateDataMap();
590 }
591 }
592
593
594
595
596 public static class MoneyWiseExchangeRateList
597 extends MoneyWiseExchangeRateBaseList<MoneyWiseExchangeRate> {
598
599
600
601 private static final MetisFieldSet<MoneyWiseExchangeRateList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseExchangeRateList.class);
602
603
604
605
606 static {
607 FIELD_DEFS.declareLocalField(MoneyWiseStaticResource.CURRENCY_REPORTING, MoneyWiseExchangeRateList::getReportingCurrency);
608 }
609
610
611
612
613 private MoneyWiseCurrency theReporting;
614
615
616
617
618
619
620 protected MoneyWiseExchangeRateList(final MoneyWiseDataSet pData) {
621 super(pData, MoneyWiseExchangeRate.class, MoneyWiseBasicDataType.EXCHANGERATE);
622 }
623
624
625
626
627
628
629 protected MoneyWiseExchangeRateList(final MoneyWiseExchangeRateList pSource) {
630 super(pSource);
631 }
632
633 @Override
634 public MetisFieldSet<MoneyWiseExchangeRateList> getDataFieldSet() {
635 return FIELD_DEFS;
636 }
637
638
639
640
641
642
643 public MoneyWiseCurrency getReportingCurrency() {
644 return theReporting;
645 }
646
647 @Override
648 public String listName() {
649 return LIST_NAME;
650 }
651
652 @Override
653 public MetisFieldSetDef getItemFields() {
654 return MoneyWiseExchangeRate.FIELD_DEFS;
655 }
656
657 @Override
658 public MoneyWiseDataSet getDataSet() {
659 return (MoneyWiseDataSet) super.getDataSet();
660 }
661
662 @Override
663 protected MoneyWiseExchangeRateList getEmptyList(final PrometheusListStyle pStyle) {
664 final MoneyWiseExchangeRateList myList = new MoneyWiseExchangeRateList(this);
665 myList.setStyle(pStyle);
666 return myList;
667 }
668
669
670
671
672
673
674
675 @Override
676 public MoneyWiseExchangeRate addCopyItem(final PrometheusDataItem pRate) {
677
678 if (!(pRate instanceof MoneyWiseExchangeRate)) {
679 throw new UnsupportedOperationException();
680 }
681
682 final MoneyWiseExchangeRate myRate = new MoneyWiseExchangeRate(this, (MoneyWiseExchangeRate) pRate);
683 add(myRate);
684 return myRate;
685 }
686
687
688
689
690
691
692 @Override
693 public MoneyWiseExchangeRate addNewItem() {
694 final MoneyWiseExchangeRate myRate = new MoneyWiseExchangeRate(this);
695 add(myRate);
696 return myRate;
697 }
698
699 @Override
700 public MoneyWiseExchangeRate addValuesItem(final PrometheusDataValues pValues)
701 throws OceanusException {
702
703 final MoneyWiseExchangeRate myRate = new MoneyWiseExchangeRate(this, pValues);
704
705
706 if (!isIdUnique(myRate.getIndexedId())) {
707 myRate.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
708 throw new MoneyWiseDataException(myRate, ERROR_VALIDATION);
709 }
710
711
712 add(myRate);
713
714
715 return myRate;
716 }
717
718
719
720
721
722
723
724
725
726 public OceanusMoney convertCurrency(final OceanusMoney pValue,
727 final MoneyWiseCurrency pCurrency,
728 final OceanusDate pDate) {
729
730 OceanusMoney myValue = pValue;
731 final MoneyWiseCurrencyList myCurrencies = getDataSet().getAccountCurrencies();
732 final Currency myCurrent = pValue.getCurrency();
733 final Currency myReporting = theReporting.getCurrency();
734 final Currency myTarget = pCurrency.getCurrency();
735
736
737 if (myCurrent.equals(myTarget)) {
738 return pValue;
739 }
740
741
742 if (!myCurrent.equals(myReporting)) {
743
744 final OceanusRatio myRate = findRate(myCurrencies.findCurrency(myCurrent), pDate);
745
746
747 myValue = myValue.convertCurrency(myReporting, myRate);
748 }
749
750
751 if (!myReporting.equals(myTarget)) {
752
753 final OceanusRatio myRate = findRate(pCurrency, pDate);
754
755
756 myValue = myValue.convertCurrency(myTarget, myRate);
757 }
758
759
760 return myValue;
761 }
762
763
764
765
766
767
768
769
770 private OceanusRatio findRate(final MoneyWiseCurrency pCurrency,
771 final OceanusDate pDate) {
772
773 return getDataMap().getRateForDate(pCurrency, pDate);
774 }
775
776
777
778
779
780
781 public void setReportingCurrency(final MoneyWiseCurrency pCurrency) {
782
783 final Iterator<MoneyWiseExchangeRate> myIterator = iterator();
784 OceanusRatio myCurrRate = null;
785 OceanusDate myCurrDate = null;
786
787
788 while (myIterator.hasNext()) {
789 final MoneyWiseExchangeRate myCurr = myIterator.next();
790
791
792 final OceanusDate myDate = myCurr.getDate();
793 final MoneyWiseCurrency myTo = myCurr.getToCurrency();
794 final OceanusRatio myRatio = myCurr.getExchangeRate();
795
796
797 if (myCurrDate == null || !myDate.equals(myCurrDate)) {
798
799
800
801
802
803 myCurrRate = findRate(pCurrency, myDate);
804 myCurrDate = myDate;
805 }
806
807
808 myCurr.pushHistory();
809
810
811 if (myTo.equals(pCurrency)) {
812
813 myCurr.setToCurrency(myCurr.getFromCurrency());
814
815
816 myCurr.setExchangeRate(myRatio.getInverseRatio());
817
818
819 } else {
820
821 myCurr.setExchangeRate(new OceanusRatio(myRatio, myCurrRate));
822 }
823
824
825 myCurr.setFromCurrency(pCurrency);
826 }
827
828
829 theReporting = pCurrency;
830 }
831 }
832
833
834
835
836 public static class MoneyWiseExchangeRateDataMap
837 implements PrometheusDataMapItem, MetisFieldItem {
838
839
840
841 @SuppressWarnings("rawtypes")
842 private static final MetisFieldSet<MoneyWiseExchangeRateDataMap> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseExchangeRateDataMap.class);
843
844
845
846
847 static {
848 FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.MONEYWISEDATA_MAP_MAPOFMAPS, MoneyWiseExchangeRateDataMap::getMapOfMaps);
849 FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.XCHGRATE_MAP_MAPOFRATES, MoneyWiseExchangeRateDataMap::getMapOfRates);
850 }
851
852
853
854
855 private final Map<MoneyWiseCurrency, Map<OceanusDate, Integer>> theMapOfMaps;
856
857
858
859
860 private final Map<MoneyWiseCurrency, MoneyWiseRateList> theMapOfRates;
861
862
863
864
865 public MoneyWiseExchangeRateDataMap() {
866
867 theMapOfMaps = new HashMap<>();
868 theMapOfRates = new HashMap<>();
869 }
870
871 @SuppressWarnings("rawtypes")
872 @Override
873 public MetisFieldSet<MoneyWiseExchangeRateDataMap> getDataFieldSet() {
874 return FIELD_DEFS;
875 }
876
877 @Override
878 public String formatObject(final OceanusDataFormatter pFormatter) {
879 return FIELD_DEFS.getName();
880 }
881
882
883
884
885
886
887 private Map<MoneyWiseCurrency, Map<OceanusDate, Integer>> getMapOfMaps() {
888 return theMapOfMaps;
889 }
890
891
892
893
894
895
896 private Map<MoneyWiseCurrency, MoneyWiseRateList> getMapOfRates() {
897 return theMapOfRates;
898 }
899
900 @Override
901 public void resetMap() {
902 theMapOfMaps.clear();
903 theMapOfRates.clear();
904 }
905
906 @Override
907 public void adjustForItem(final PrometheusDataItem pItem) {
908
909 final MoneyWiseExchangeRate myItem = (MoneyWiseExchangeRate) pItem;
910 final MoneyWiseCurrency myCurrency = myItem.getToCurrency();
911 if (myCurrency == null) {
912 return;
913 }
914
915
916 final Map<OceanusDate, Integer> myMap = theMapOfMaps.computeIfAbsent(myCurrency, c -> new HashMap<>());
917
918
919 final OceanusDate myDate = myItem.getDate();
920 final Integer myCount = myMap.get(myDate);
921 if (myCount == null) {
922 myMap.put(myDate, PrometheusDataInstanceMap.ONE);
923 } else {
924 myMap.put(myDate, myCount + 1);
925 }
926
927
928 final MoneyWiseRateList myList = theMapOfRates.computeIfAbsent(myCurrency, MoneyWiseRateList::new);
929
930
931 myList.add(myItem);
932 }
933
934
935
936
937
938
939
940 public boolean validRateCount(final MoneyWiseExchangeRate pItem) {
941
942 final MoneyWiseCurrency myCurrency = pItem.getToCurrency();
943 final OceanusDate myDate = pItem.getDate();
944
945
946 final Map<OceanusDate, Integer> myMap = theMapOfMaps.get(myCurrency);
947 if (myMap != null) {
948 final Integer myResult = myMap.get(myDate);
949 return PrometheusDataInstanceMap.ONE.equals(myResult);
950 }
951 return false;
952 }
953
954
955
956
957
958
959
960
961 public boolean availableDate(final MoneyWiseCurrency pCurrency,
962 final OceanusDate pDate) {
963
964 final Map<OceanusDate, Integer> myMap = theMapOfMaps.get(pCurrency);
965 return myMap == null
966 || myMap.get(pDate) == null;
967 }
968
969
970
971
972
973
974
975
976 public OceanusRatio getRateForDate(final MoneyWiseCurrency pCurrency,
977 final OceanusDate pDate) {
978
979 final MoneyWiseRateList myList = theMapOfRates.get(pCurrency);
980 if (myList != null) {
981
982 final Iterator<MoneyWiseExchangeRate> myIterator = myList.iterator();
983 while (myIterator.hasNext()) {
984 final MoneyWiseExchangeRate myCurr = myIterator.next();
985
986
987 final OceanusDate myDate = myCurr.getDate();
988
989
990 if (myDate.compareTo(pDate) >= 0) {
991 return myCurr.getExchangeRate();
992 }
993 }
994 }
995
996
997 return null;
998 }
999
1000
1001
1002
1003
1004
1005
1006
1007 public OceanusRatio[] getRatesForRange(final MoneyWiseCurrency pCurrency,
1008 final OceanusDateRange pRange) {
1009
1010 OceanusRatio myFirst = OceanusRatio.ONE;
1011 OceanusRatio myLatest = OceanusRatio.ONE;
1012 final OceanusDate myStart = pRange.getStart();
1013
1014
1015 final MoneyWiseRateList myList = theMapOfRates.get(pCurrency);
1016 if (myList != null) {
1017
1018 final ListIterator<MoneyWiseExchangeRate> myIterator = myList.listIterator(myList.size());
1019 while (myIterator.hasPrevious()) {
1020 final MoneyWiseExchangeRate myCurr = myIterator.previous();
1021
1022
1023 final OceanusDate myDate = myCurr.getDate();
1024 final int iComp = pRange.compareToDate(myDate);
1025
1026
1027 if (iComp < 0) {
1028 break;
1029 }
1030
1031
1032 myLatest = myCurr.getExchangeRate();
1033
1034
1035 if (iComp > 0
1036 || myDate.compareTo(myStart) == 0) {
1037 myFirst = myLatest;
1038 }
1039 }
1040 }
1041
1042
1043 return new OceanusRatio[]
1044 {myFirst, myLatest};
1045 }
1046
1047
1048
1049
1050
1051
1052
1053 public ListIterator<MoneyWiseExchangeRate> rateIterator(final MoneyWiseCurrency pCurrency) {
1054
1055 final MoneyWiseRateList myList = theMapOfRates.get(pCurrency);
1056 return myList != null
1057 ? myList.listIterator(myList.size())
1058 : null;
1059 }
1060
1061
1062
1063
1064 private static final class MoneyWiseRateList
1065 implements MetisFieldItem, MetisDataList<MoneyWiseExchangeRate> {
1066
1067
1068
1069 private static final MetisFieldSet<MoneyWiseRateList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseRateList.class);
1070
1071
1072
1073
1074 static {
1075 FIELD_DEFS.declareLocalField(MetisDataResource.LIST_SIZE, MoneyWiseRateList::size);
1076 }
1077
1078
1079
1080
1081 private final List<MoneyWiseExchangeRate> theList;
1082
1083
1084
1085
1086 private final MoneyWiseCurrency theCurrency;
1087
1088
1089
1090
1091
1092
1093 private MoneyWiseRateList(final MoneyWiseCurrency pCurrency) {
1094 theCurrency = pCurrency;
1095 theList = new ArrayList<>();
1096 }
1097
1098 @Override
1099 public MetisFieldSet<MoneyWiseRateList> getDataFieldSet() {
1100 return FIELD_DEFS;
1101 }
1102
1103 @Override
1104 public String formatObject(final OceanusDataFormatter pFormatter) {
1105 return theCurrency.formatObject(pFormatter)
1106 + "("
1107 + size()
1108 + ")";
1109 }
1110
1111 @Override
1112 public String toString() {
1113 return theCurrency.toString()
1114 + "("
1115 + size()
1116 + ")";
1117 }
1118
1119 @Override
1120 public List<MoneyWiseExchangeRate> getUnderlyingList() {
1121 return theList;
1122 }
1123 }
1124 }
1125 }