View Javadoc
1   /*
2    * MoneyWise: Finance Application
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
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.decimal.OceanusMoney;
22  import io.github.tonywasher.joceanus.oceanus.format.OceanusDataFormatter;
23  import io.github.tonywasher.joceanus.metis.data.MetisDataDifference;
24  import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
25  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
26  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDataValidator.MoneyWiseDataValidatorAccount;
27  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTax.MoneyWiseTaxCredit;
28  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseTransaction.MoneyWiseTransactionList;
29  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAssetCategory;
30  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
31  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
32  import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
33  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataInstanceMap;
34  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
35  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataList.PrometheusListStyle;
36  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
37  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
38  import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedDataItem;
39  import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedFieldSet;
40  import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedPair;
41  import io.github.tonywasher.joceanus.prometheus.data.PrometheusEncryptedValues;
42  import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
43  
44  import java.util.Currency;
45  import java.util.Iterator;
46  
47  /**
48   * Class representing an account that can be part of a transaction.
49   */
50  public abstract class MoneyWiseAssetBase
51          extends PrometheusEncryptedDataItem
52          implements MoneyWiseTransAsset {
53      /**
54       * Report fields.
55       */
56      private static final PrometheusEncryptedFieldSet<MoneyWiseAssetBase> FIELD_DEFS = PrometheusEncryptedFieldSet.newEncryptedFieldSet(MoneyWiseAssetBase.class);
57  
58      /*
59       * FieldIds.
60       */
61      static {
62          FIELD_DEFS.declareEncryptedStringField(PrometheusDataResource.DATAITEM_FIELD_NAME, NAMELEN);
63          FIELD_DEFS.declareEncryptedStringField(PrometheusDataResource.DATAITEM_FIELD_DESC, DESCLEN);
64          FIELD_DEFS.declareLinkField(MoneyWiseBasicResource.CATEGORY_NAME);
65          FIELD_DEFS.declareLinkField(MoneyWiseBasicResource.ASSET_PARENT);
66          FIELD_DEFS.declareLinkField(MoneyWiseStaticDataType.CURRENCY);
67          FIELD_DEFS.declareBooleanField(MoneyWiseBasicResource.ASSET_CLOSED);
68          FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.ASSET_CLOSEDATE, MoneyWiseAssetBase::getCloseDate);
69          FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.ASSET_FIRSTEVENT, MoneyWiseAssetBase::getEarliest);
70          FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.ASSET_LASTEVENT, MoneyWiseAssetBase::getLatest);
71          FIELD_DEFS.declareLocalField(MoneyWiseBasicResource.ASSET_RELEVANT, MoneyWiseAssetBase::isRelevant);
72      }
73  
74      /**
75       * Bad InfoSet Error Text.
76       */
77      protected static final String ERROR_BADINFOSET = PrometheusDataResource.DATAINFOSET_ERROR_BADSET.getValue();
78  
79      /**
80       * Close Date.
81       */
82      private OceanusDate theCloseDate;
83  
84      /**
85       * Earliest Transaction.
86       */
87      private MoneyWiseTransaction theEarliest;
88  
89      /**
90       * Latest Transaction.
91       */
92      private MoneyWiseTransaction theLatest;
93  
94      /**
95       * Is this relevant?
96       */
97      private boolean isRelevant;
98  
99      /**
100      * Copy Constructor.
101      *
102      * @param pList  the list
103      * @param pAsset The Asset to copy
104      */
105     protected MoneyWiseAssetBase(final MoneyWiseAssetBaseList<?> pList,
106                                  final MoneyWiseAssetBase pAsset) {
107         /* Set standard values */
108         super(pList, pAsset);
109 
110         /* If we are creating an edit copy from core */
111         final PrometheusListStyle myBaseStyle = pAsset.getList().getStyle();
112         if (pList.getStyle() == PrometheusListStyle.EDIT
113                 && myBaseStyle == PrometheusListStyle.CORE) {
114             /* Update underlying flags */
115             theCloseDate = pAsset.getCloseDate();
116             theEarliest = pAsset.getEarliest();
117             theLatest = pAsset.getLatest();
118             isRelevant = pAsset.isRelevant();
119         }
120     }
121 
122     /**
123      * Values constructor.
124      *
125      * @param pList   the List to add to
126      * @param pValues the values constructor
127      * @throws OceanusException on error
128      */
129     protected MoneyWiseAssetBase(final MoneyWiseAssetBaseList<?> pList,
130                                  final PrometheusDataValues pValues) throws OceanusException {
131         /* Initialise the item */
132         super(pList, pValues);
133 
134         /* Access formatter */
135         final OceanusDataFormatter myFormatter = getDataSet().getDataFormatter();
136 
137         /* Protect against exceptions */
138         try {
139             /* Store the name */
140             Object myValue = pValues.getValue(PrometheusDataResource.DATAITEM_FIELD_NAME);
141             if (myValue instanceof String s) {
142                 setValueName(s);
143             } else if (myValue instanceof byte[] ba) {
144                 setValueName(ba);
145             }
146 
147             /* Store the Description */
148             myValue = pValues.getValue(PrometheusDataResource.DATAITEM_FIELD_DESC);
149             if (myValue instanceof String s) {
150                 setValueDesc(s);
151             } else if (myValue instanceof byte[] ba) {
152                 setValueDesc(ba);
153             }
154 
155             /* Store the Category */
156             myValue = pValues.getValue(MoneyWiseBasicResource.CATEGORY_NAME);
157             if (myValue instanceof Integer i) {
158                 setValueCategory(i);
159             } else if (myValue instanceof String s) {
160                 setValueCategory(s);
161             }
162 
163             /* Store the Parent */
164             myValue = pValues.getValue(MoneyWiseBasicResource.ASSET_PARENT);
165             if (myValue instanceof Integer i) {
166                 setValueParent(i);
167             } else if (myValue instanceof String s) {
168                 setValueParent(s);
169             }
170 
171             /* Store the Currency */
172             myValue = pValues.getValue(MoneyWiseStaticDataType.CURRENCY);
173             if (myValue instanceof Integer i) {
174                 setValueCurrency(i);
175             } else if (myValue instanceof String s) {
176                 setValueCurrency(s);
177             } else if (myValue instanceof MoneyWiseCurrency c) {
178                 setValueCurrency(c);
179             }
180 
181             /* Store the closed flag */
182             myValue = pValues.getValue(MoneyWiseBasicResource.ASSET_CLOSED);
183             if (myValue instanceof Boolean b) {
184                 setValueClosed(b);
185             } else if (myValue instanceof String s) {
186                 setValueClosed(myFormatter.parseValue(s, Boolean.class));
187             }
188 
189             /* Catch Exceptions */
190         } catch (OceanusException e) {
191             /* Pass on exception */
192             throw new MoneyWiseDataException(this, ERROR_CREATEITEM, e);
193         }
194     }
195 
196     /**
197      * Edit Constructor.
198      *
199      * @param pList the list
200      */
201     protected MoneyWiseAssetBase(final MoneyWiseAssetBaseList<?> pList) {
202         super(pList, 0);
203         setNextDataKeySet();
204     }
205 
206     @Override
207     public String formatObject(final OceanusDataFormatter pFormatter) {
208         return toString();
209     }
210 
211     @Override
212     public String toString() {
213         return getName();
214     }
215 
216     @Override
217     public boolean includeXmlField(final MetisDataFieldId pField) {
218         /* Determine whether fields should be included */
219         if (PrometheusDataResource.DATAITEM_FIELD_NAME.equals(pField)) {
220             return true;
221         }
222         if (PrometheusDataResource.DATAITEM_FIELD_DESC.equals(pField)) {
223             return getDesc() != null;
224         }
225         if (MoneyWiseBasicResource.ASSET_CLOSED.equals(pField)) {
226             return isClosed();
227         }
228 
229         /* Pass call on */
230         return super.includeXmlField(pField);
231     }
232 
233     /**
234      * Obtain Category.
235      *
236      * @return the category
237      */
238     public abstract MoneyWiseAssetCategory getCategory();
239 
240     @Override
241     public MoneyWisePayee getParent() {
242         return getValues().getValue(MoneyWiseBasicResource.ASSET_PARENT, MoneyWisePayee.class);
243     }
244 
245     /**
246      * Obtain ParentId.
247      *
248      * @return the parentId
249      */
250     public Integer getParentId() {
251         final MoneyWisePayee myParent = getParent();
252         return myParent == null
253                 ? null
254                 : myParent.getIndexedId();
255     }
256 
257     /**
258      * Obtain ParentName.
259      *
260      * @return the parentName
261      */
262     public String getParentName() {
263         final MoneyWisePayee myParent = getParent();
264         return myParent == null
265                 ? null
266                 : myParent.getName();
267     }
268 
269     @Override
270     public MoneyWiseCurrency getAssetCurrency() {
271         return getValues().getValue(MoneyWiseStaticDataType.CURRENCY, MoneyWiseCurrency.class);
272     }
273 
274     /**
275      * Obtain CurrencyId.
276      *
277      * @return the currencyId
278      */
279     public Integer getAssetCurrencyId() {
280         final MoneyWiseCurrency myCurrency = getAssetCurrency();
281         return myCurrency == null ? null : myCurrency.getIndexedId();
282     }
283 
284     /**
285      * Obtain CurrencyName.
286      *
287      * @return the currencyName
288      */
289     public String getAssetCurrencyName() {
290         final MoneyWiseCurrency myCurrency = getAssetCurrency();
291         return myCurrency == null ? null : myCurrency.getName();
292     }
293 
294     @Override
295     public Currency getCurrency() {
296         MoneyWiseCurrency myCurrency = getAssetCurrency();
297         myCurrency = myCurrency == null
298                 ? getDataSet().getReportingCurrency()
299                 : myCurrency;
300         return myCurrency == null ? null : myCurrency.getCurrency();
301     }
302 
303     /**
304      * Obtain Opening Balance.
305      *
306      * @return the Opening balance
307      */
308     public OceanusMoney getOpeningBalance() {
309         return null;
310     }
311 
312     @Override
313     public boolean isTaxFree() {
314         return false;
315     }
316 
317     @Override
318     public boolean isGross() {
319         return false;
320     }
321 
322     @Override
323     public boolean isForeign() {
324         return false;
325     }
326 
327     /**
328      * Get the close Date of the account.
329      *
330      * @return the closeDate
331      */
332     public OceanusDate getCloseDate() {
333         return theCloseDate;
334     }
335 
336     /**
337      * Obtain Earliest transaction.
338      *
339      * @return the event
340      */
341     public MoneyWiseTransaction getEarliest() {
342         return theEarliest;
343     }
344 
345     /**
346      * Obtain Latest Transaction.
347      *
348      * @return the event
349      */
350     public MoneyWiseTransaction getLatest() {
351         return theLatest;
352     }
353 
354     /**
355      * Is the account relevant (i.e. non-closeable)?
356      *
357      * @return true/false
358      */
359     public boolean isRelevant() {
360         return isRelevant;
361     }
362 
363     @Override
364     public boolean isAutoExpense() {
365         return false;
366     }
367 
368     @Override
369     public boolean isShares() {
370         return false;
371     }
372 
373     @Override
374     public boolean isCapital() {
375         return false;
376     }
377 
378     @Override
379     public boolean isHidden() {
380         return false;
381     }
382 
383     @Override
384     public MoneyWiseAssetType getAssetType() {
385         switch ((MoneyWiseBasicDataType) getItemType()) {
386             case DEPOSIT:
387                 return MoneyWiseAssetType.DEPOSIT;
388             case CASH:
389                 return MoneyWiseAssetType.CASH;
390             case LOAN:
391                 return MoneyWiseAssetType.LOAN;
392             case PORTFOLIO:
393                 return MoneyWiseAssetType.PORTFOLIO;
394             case SECURITY:
395                 return MoneyWiseAssetType.SECURITY;
396             case PAYEE:
397                 return MoneyWiseAssetType.PAYEE;
398             default:
399                 throw new IllegalStateException();
400         }
401     }
402 
403     @Override
404     public String getName() {
405         return getValues().getValue(PrometheusDataResource.DATAITEM_FIELD_NAME, String.class);
406     }
407 
408     /**
409      * Obtain Encrypted name.
410      *
411      * @return the bytes
412      */
413     public byte[] getNameBytes() {
414         return getValues().getEncryptedBytes(PrometheusDataResource.DATAITEM_FIELD_NAME);
415     }
416 
417     /**
418      * Obtain Encrypted Name Field.
419      *
420      * @return the Field
421      */
422     private PrometheusEncryptedPair getNameField() {
423         return getValues().getEncryptedPair(PrometheusDataResource.DATAITEM_FIELD_NAME);
424     }
425 
426     /**
427      * Obtain Description.
428      *
429      * @return the description
430      */
431     public String getDesc() {
432         return getValues().getValue(PrometheusDataResource.DATAITEM_FIELD_DESC, String.class);
433     }
434 
435     /**
436      * Obtain Encrypted description.
437      *
438      * @return the bytes
439      */
440     public byte[] getDescBytes() {
441         return getValues().getEncryptedBytes(PrometheusDataResource.DATAITEM_FIELD_DESC);
442     }
443 
444     /**
445      * Obtain Encrypted Description Field.
446      *
447      * @return the Field
448      */
449     private PrometheusEncryptedPair getDescField() {
450         return getValues().getEncryptedPair(PrometheusDataResource.DATAITEM_FIELD_DESC);
451     }
452 
453     @Override
454     public Boolean isClosed() {
455         return getValues().getValue(MoneyWiseBasicResource.ASSET_CLOSED, Boolean.class);
456     }
457 
458     @Override
459     public boolean isDisabled() {
460         return isClosed();
461     }
462 
463     /**
464      * Set name value.
465      *
466      * @param pValue the value
467      * @throws OceanusException on error
468      */
469     private void setValueName(final String pValue) throws OceanusException {
470         setEncryptedValue(PrometheusDataResource.DATAITEM_FIELD_NAME, pValue);
471     }
472 
473     /**
474      * Set name value.
475      *
476      * @param pBytes the value
477      * @throws OceanusException on error
478      */
479     private void setValueName(final byte[] pBytes) throws OceanusException {
480         setEncryptedValue(PrometheusDataResource.DATAITEM_FIELD_NAME, pBytes, String.class);
481     }
482 
483     /**
484      * Set name value.
485      *
486      * @param pValue the value
487      */
488     private void setValueName(final PrometheusEncryptedPair pValue) {
489         getValues().setUncheckedValue(PrometheusDataResource.DATAITEM_FIELD_NAME, pValue);
490     }
491 
492     /**
493      * Set description value.
494      *
495      * @param pValue the value
496      * @throws OceanusException on error
497      */
498     private void setValueDesc(final String pValue) throws OceanusException {
499         setEncryptedValue(PrometheusDataResource.DATAITEM_FIELD_DESC, pValue);
500     }
501 
502     /**
503      * Set description value.
504      *
505      * @param pBytes the value
506      * @throws OceanusException on error
507      */
508     private void setValueDesc(final byte[] pBytes) throws OceanusException {
509         setEncryptedValue(PrometheusDataResource.DATAITEM_FIELD_DESC, pBytes, String.class);
510     }
511 
512     /**
513      * Set description value.
514      *
515      * @param pValue the value
516      */
517     private void setValueDesc(final PrometheusEncryptedPair pValue) {
518         getValues().setUncheckedValue(PrometheusDataResource.DATAITEM_FIELD_DESC, pValue);
519     }
520 
521     /**
522      * Set category value.
523      *
524      * @param pValue the value
525      */
526     private void setValueCategory(final MoneyWiseAssetCategory pValue) {
527         getValues().setUncheckedValue(MoneyWiseBasicResource.CATEGORY_NAME, pValue);
528     }
529 
530     /**
531      * Set category id.
532      *
533      * @param pValue the value
534      */
535     private void setValueCategory(final Integer pValue) {
536         getValues().setUncheckedValue(MoneyWiseBasicResource.CATEGORY_NAME, pValue);
537     }
538 
539     /**
540      * Set category name.
541      *
542      * @param pValue the value
543      */
544     private void setValueCategory(final String pValue) {
545         getValues().setUncheckedValue(MoneyWiseBasicResource.CATEGORY_NAME, pValue);
546     }
547 
548     /**
549      * Set parent value.
550      *
551      * @param pValue the value
552      */
553     private void setValueParent(final MoneyWisePayee pValue) {
554         getValues().setUncheckedValue(MoneyWiseBasicResource.ASSET_PARENT, pValue);
555     }
556 
557     /**
558      * Set parent id.
559      *
560      * @param pValue the value
561      */
562     private void setValueParent(final Integer pValue) {
563         getValues().setUncheckedValue(MoneyWiseBasicResource.ASSET_PARENT, pValue);
564     }
565 
566     /**
567      * Set parent name.
568      *
569      * @param pValue the value
570      */
571     private void setValueParent(final String pValue) {
572         getValues().setUncheckedValue(MoneyWiseBasicResource.ASSET_PARENT, pValue);
573     }
574 
575     /**
576      * Set currency value.
577      *
578      * @param pValue the value
579      */
580     private void setValueCurrency(final MoneyWiseCurrency pValue) {
581         getValues().setUncheckedValue(MoneyWiseStaticDataType.CURRENCY, pValue);
582     }
583 
584     /**
585      * Set currency id.
586      *
587      * @param pValue the value
588      */
589     private void setValueCurrency(final Integer pValue) {
590         getValues().setUncheckedValue(MoneyWiseStaticDataType.CURRENCY, pValue);
591     }
592 
593     /**
594      * Set currency name.
595      *
596      * @param pValue the value
597      */
598     private void setValueCurrency(final String pValue) {
599         getValues().setUncheckedValue(MoneyWiseStaticDataType.CURRENCY, pValue);
600     }
601 
602     /**
603      * Set closed indication.
604      *
605      * @param pValue the value
606      */
607     private void setValueClosed(final Boolean pValue) {
608         getValues().setUncheckedValue(MoneyWiseBasicResource.ASSET_CLOSED, pValue);
609     }
610 
611     @Override
612     public MoneyWiseDataSet getDataSet() {
613         return (MoneyWiseDataSet) super.getDataSet();
614     }
615 
616     @Override
617     public MoneyWiseAssetBaseList<?> getList() {
618         return (MoneyWiseAssetBaseList<?>) super.getList();
619     }
620 
621     @Override
622     public boolean isLocked() {
623         return isClosed();
624     }
625 
626     /**
627      * Set relevant.
628      */
629     public void setRelevant() {
630         isRelevant = true;
631     }
632 
633     /**
634      * Obtain detailed category.
635      *
636      * @param pCategory current category
637      * @param pYear     the taxYear
638      * @return detailed category
639      */
640     public MoneyWiseTransCategory getDetailedCategory(final MoneyWiseTransCategory pCategory,
641                                                       final MoneyWiseTaxCredit pYear) {
642         /* return the unchanged category */
643         return pCategory;
644     }
645 
646     /**
647      * Adjust closed date.
648      *
649      * @throws OceanusException on error
650      */
651     public void adjustClosed() throws OceanusException {
652         /* Access latest activity date */
653         theCloseDate = theLatest == null ? null : theLatest.getDate();
654     }
655 
656     @Override
657     public void clearActive() {
658         /* Reset flags */
659         theCloseDate = null;
660         theEarliest = null;
661         theLatest = null;
662         isRelevant = false;
663 
664         /* Pass call onwards */
665         super.clearActive();
666     }
667 
668     @Override
669     public void touchItem(final PrometheusDataItem pSource) {
670         /* If we are being touched by a transaction */
671         if (pSource instanceof MoneyWiseTransaction myTrans) {
672             /* Record the transaction */
673             if (theEarliest == null) {
674                 theEarliest = myTrans;
675             }
676             theLatest = myTrans;
677 
678             /* if this transaction is not reconciled */
679             if (!myTrans.isReconciled()) {
680                 /* Mark account as relevant */
681                 setRelevant();
682             }
683 
684             /* Touch parent if it exists */
685             final MoneyWiseAssetBase myParent = getParent();
686             if (myParent != null) {
687                 myParent.touchItem(pSource);
688             }
689         }
690 
691         /* If we are being touched by an asset */
692         if (pSource instanceof MoneyWiseAssetBase myAsset) {
693             /* Mark as relevant if child is open */
694             if (!myAsset.isClosed()) {
695                 setRelevant();
696             }
697         }
698 
699         /* Pass call onwards */
700         super.touchItem(pSource);
701     }
702 
703     @Override
704     public void resolveDataSetLinks() throws OceanusException {
705         /* Update the Encryption details */
706         super.resolveDataSetLinks();
707 
708         /* Resolve data links */
709         final PrometheusEncryptedValues myValues = getValues();
710 
711         /* Adjust Closed */
712         final Object myClosed = myValues.getValue(MoneyWiseBasicResource.ASSET_CLOSED);
713         if (myClosed == null) {
714             setValueClosed(Boolean.FALSE);
715         }
716     }
717 
718     /**
719      * resolve EditSet links.
720      *
721      * @throws OceanusException on error
722      */
723     protected abstract void resolveEditSetLinks() throws OceanusException;
724 
725     /**
726      * Resolve late edit Set links.
727      *
728      * @throws OceanusException on error
729      */
730     public void resolveLateEditSetLinks() throws OceanusException {
731         /* Access the editSet */
732         final PrometheusEditSet myEditSet = getList().getEditSet();
733 
734         /* Resolve First/LastEvent if required */
735         final MoneyWiseTransactionList myTransList = myEditSet.getDataList(MoneyWiseBasicDataType.TRANSACTION, MoneyWiseTransactionList.class);
736         if (theEarliest != null) {
737             theEarliest = myTransList.findItemById(theEarliest.getIndexedId());
738         }
739         if (theLatest != null) {
740             theLatest = myTransList.findItemById(theLatest.getIndexedId());
741         }
742     }
743 
744     /**
745      * Set a new name.
746      *
747      * @param pName the new name
748      * @throws OceanusException on error
749      */
750     public void setName(final String pName) throws OceanusException {
751         setValueName(pName);
752     }
753 
754     /**
755      * Set a new description.
756      *
757      * @param pDesc the description
758      * @throws OceanusException on error
759      */
760     public void setDescription(final String pDesc) throws OceanusException {
761         setValueDesc(pDesc);
762     }
763 
764     /**
765      * Set a new category.
766      *
767      * @param pCategory the new category
768      */
769     public void setCategory(final MoneyWiseAssetCategory pCategory) {
770         setValueCategory(pCategory);
771     }
772 
773     /**
774      * Set a new currency.
775      *
776      * @param pCurrency the new currency
777      */
778     public void setAssetCurrency(final MoneyWiseCurrency pCurrency) {
779         setValueCurrency(pCurrency);
780     }
781 
782     /**
783      * Set a new parent.
784      *
785      * @param pParent the parent
786      */
787     public void setParent(final MoneyWisePayee pParent) {
788         setValueParent(pParent);
789     }
790 
791     /**
792      * Set a new closed indication.
793      *
794      * @param isClosed the new closed indication
795      */
796     public void setClosed(final Boolean isClosed) {
797         setValueClosed(isClosed);
798     }
799 
800     /**
801      * Update base asset from an edited asset.
802      *
803      * @param pAsset the edited asset
804      */
805     protected void applyBasicChanges(final MoneyWiseAssetBase pAsset) {
806         /* Update the name if required */
807         if (!MetisDataDifference.isEqual(getName(), pAsset.getName())) {
808             setValueName(pAsset.getNameField());
809         }
810 
811         /* Update the description if required */
812         if (!MetisDataDifference.isEqual(getDesc(), pAsset.getDesc())) {
813             setValueDesc(pAsset.getDescField());
814         }
815 
816         /* Update the category if required */
817         if (!MetisDataDifference.isEqual(getCategory(), pAsset.getCategory())) {
818             setValueCategory(pAsset.getCategory());
819         }
820 
821         /* Update the parent if required */
822         if (!MetisDataDifference.isEqual(getParent(), pAsset.getParent())) {
823             setValueParent(pAsset.getParent());
824         }
825 
826         /* Update the currency if required */
827         if (!MetisDataDifference.isEqual(getAssetCurrency(), pAsset.getAssetCurrency())) {
828             setValueCurrency(pAsset.getAssetCurrency());
829         }
830 
831         /* Update the closed indication if required */
832         if (!MetisDataDifference.isEqual(isClosed(), pAsset.isClosed())) {
833             setValueClosed(pAsset.isClosed());
834         }
835     }
836 
837     /**
838      * The Asset List class.
839      *
840      * @param <T> the dataType
841      */
842     public abstract static class MoneyWiseAssetBaseList<T extends MoneyWiseAssetBase>
843             extends PrometheusEncryptedList<T> {
844         /*
845          * Report fields.
846          */
847         static {
848             MetisFieldSet.newFieldSet(MoneyWiseAssetBaseList.class);
849         }
850 
851         /**
852          * The EditSet.
853          */
854         private PrometheusEditSet theEditSet;
855 
856         /**
857          * Construct an empty CORE list.
858          *
859          * @param pData     the DataSet for the list
860          * @param pClass    the class of the item
861          * @param pItemType the item type
862          */
863         protected MoneyWiseAssetBaseList(final MoneyWiseDataSet pData,
864                                          final Class<T> pClass,
865                                          final MoneyWiseBasicDataType pItemType) {
866             super(pClass, pData, pItemType, PrometheusListStyle.CORE);
867         }
868 
869         /**
870          * Constructor for a cloned List.
871          *
872          * @param pSource the source List
873          */
874         protected MoneyWiseAssetBaseList(final MoneyWiseAssetBaseList<T> pSource) {
875             super(pSource);
876         }
877 
878         @Override
879         public MoneyWiseDataSet getDataSet() {
880             return (MoneyWiseDataSet) super.getDataSet();
881         }
882 
883         @Override
884         @SuppressWarnings("unchecked")
885         public MoneyWiseDataValidatorAccount<T> getValidator() {
886             return (MoneyWiseDataValidatorAccount<T>) super.getValidator();
887         }
888 
889         /**
890          * Obtain editSet.
891          *
892          * @return the editSet
893          */
894         public PrometheusEditSet getEditSet() {
895             return theEditSet;
896         }
897 
898         /**
899          * Set editSet.
900          *
901          * @param pEditSet the editSet
902          */
903         protected void setEditSet(final PrometheusEditSet pEditSet) {
904             theEditSet = pEditSet;
905         }
906 
907         @Override
908         public abstract T findItemByName(String pName);
909 
910         /**
911          * Check whether a name is available for use.
912          *
913          * @param pName Name of item
914          * @return true/false
915          */
916         public abstract boolean checkAvailableName(String pName);
917 
918         /**
919          * Check whether a name is validly used.
920          *
921          * @param pName Name of item
922          * @return true/false
923          */
924         public abstract boolean validNameCount(String pName);
925 
926         @Override
927         public void postProcessOnLoad() throws OceanusException {
928             /* Resolve links and sort the data */
929             super.resolveDataSetLinks();
930             reSort();
931 
932             /* Map the data */
933             mapData();
934         }
935 
936         /**
937          * Resolve late edit Set links.
938          *
939          * @throws OceanusException on error
940          */
941         public void resolveLateEditSetLinks() throws OceanusException {
942             final Iterator<T> myIterator = iterator();
943             while (myIterator.hasNext()) {
944                 final T myItem = myIterator.next();
945                 myItem.resolveLateEditSetLinks();
946             }
947         }
948     }
949 
950     /**
951      * The dataMap class.
952      */
953     protected static class MoneyWiseAssetDataMap
954             extends PrometheusDataInstanceMap<MoneyWiseAssetBase, String> {
955         @Override
956         public void adjustForItem(final PrometheusDataItem pItem) {
957             /* Access item */
958             final MoneyWiseAssetBase myItem = (MoneyWiseAssetBase) pItem;
959 
960             /* Adjust name count */
961             adjustForItem(myItem, myItem.getName());
962         }
963 
964         /**
965          * find item by name.
966          *
967          * @param pName the name to look up
968          * @return the matching item
969          */
970         public MoneyWiseAssetBase findAssetByName(final String pName) {
971             return findItemByKey(pName);
972         }
973 
974         /**
975          * Check validity of name.
976          *
977          * @param pName the name to look up
978          * @return true/false
979          */
980         public boolean validNameCount(final String pName) {
981             return validKeyCount(pName);
982         }
983     }
984 }