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.metis.data.MetisDataDifference;
20  import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
21  import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
22  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
23  import io.github.tonywasher.joceanus.metis.field.MetisFieldVersionedSet;
24  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAssetCategory;
25  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryClass;
26  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryType;
27  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryType.MoneyWiseCashCategoryTypeList;
28  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
29  import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
30  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
31  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
32  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataResource;
33  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataSet;
34  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataValues;
35  import io.github.tonywasher.joceanus.prometheus.data.PrometheusListStyle;
36  import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataItem;
37  import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
38  
39  import java.util.Iterator;
40  
41  /**
42   * Cash Category class.
43   */
44  public final class MoneyWiseCashCategory
45          extends MoneyWiseCategoryBase
46          implements MoneyWiseAssetCategory {
47      /**
48       * Object name.
49       */
50      public static final String OBJECT_NAME = MoneyWiseBasicDataType.CASHCATEGORY.getItemName();
51  
52      /**
53       * List name.
54       */
55      public static final String LIST_NAME = MoneyWiseBasicDataType.CASHCATEGORY.getListName();
56  
57      /**
58       * Local Report fields.
59       */
60      private static final MetisFieldVersionedSet<MoneyWiseCashCategory> FIELD_DEFS = MetisFieldVersionedSet.newVersionedFieldSet(MoneyWiseCashCategory.class);
61  
62      /*
63       * FieldIds.
64       */
65      static {
66          FIELD_DEFS.declareLinkField(MoneyWiseStaticDataType.CASHTYPE);
67      }
68  
69      /**
70       * Copy Constructor.
71       *
72       * @param pList     the list
73       * @param pCategory The Category to copy
74       */
75      MoneyWiseCashCategory(final MoneyWiseCashCategoryList pList,
76                            final MoneyWiseCashCategory pCategory) {
77          /* Set standard values */
78          super(pList, pCategory);
79      }
80  
81      /**
82       * Values constructor.
83       *
84       * @param pList   the List to add to
85       * @param pValues the values constructor
86       * @throws OceanusException on error
87       */
88      private MoneyWiseCashCategory(final MoneyWiseCashCategoryList pList,
89                                    final PrometheusDataValues pValues) throws OceanusException {
90          /* Initialise the item */
91          super(pList, pValues);
92  
93          /* Store the Category Type */
94          final Object myValue = pValues.getValue(MoneyWiseStaticDataType.CASHTYPE);
95          if (myValue instanceof Integer i) {
96              setValueType(i);
97          } else if (myValue instanceof String s) {
98              setValueType(s);
99          }
100     }
101 
102     /**
103      * Edit Constructor.
104      *
105      * @param pList the list
106      */
107     public MoneyWiseCashCategory(final MoneyWiseCashCategoryList pList) {
108         super(pList);
109     }
110 
111     @Override
112     public MetisFieldSetDef getDataFieldSet() {
113         return FIELD_DEFS;
114     }
115 
116     @Override
117     public boolean includeXmlField(final MetisDataFieldId pField) {
118         /* Determine whether fields should be included */
119         if (MoneyWiseStaticDataType.CASHTYPE.equals(pField)) {
120             return true;
121         }
122 
123         /* Pass call on */
124         return super.includeXmlField(pField);
125     }
126 
127     @Override
128     public MoneyWiseCashCategoryType getCategoryType() {
129         return getValues().getValue(MoneyWiseStaticDataType.CASHTYPE, MoneyWiseCashCategoryType.class);
130     }
131 
132     @Override
133     public MoneyWiseCashCategoryClass getCategoryTypeClass() {
134         final MoneyWiseCashCategoryType myType = getCategoryType();
135         return myType == null
136                 ? null
137                 : myType.getCashClass();
138     }
139 
140     @Override
141     public MoneyWiseCashCategory getParentCategory() {
142         return getValues().getValue(PrometheusDataResource.DATAGROUP_PARENT, MoneyWiseCashCategory.class);
143     }
144 
145     /**
146      * Set category type value.
147      *
148      * @param pValue the value
149      */
150     private void setValueType(final MoneyWiseCashCategoryType pValue) {
151         getValues().setUncheckedValue(MoneyWiseStaticDataType.CASHTYPE, pValue);
152     }
153 
154     /**
155      * Set category type id.
156      *
157      * @param pValue the value
158      */
159     private void setValueType(final Integer pValue) {
160         getValues().setUncheckedValue(MoneyWiseStaticDataType.CASHTYPE, pValue);
161     }
162 
163     /**
164      * Set category type name.
165      *
166      * @param pValue the value
167      */
168     private void setValueType(final String pValue) {
169         getValues().setUncheckedValue(MoneyWiseStaticDataType.CASHTYPE, pValue);
170     }
171 
172     /**
173      * Is this cash category the required class.
174      *
175      * @param pClass the required category class.
176      * @return true/false
177      */
178     public boolean isCategoryClass(final MoneyWiseCashCategoryClass pClass) {
179         /* Check for match */
180         return getCategoryTypeClass() == pClass;
181     }
182 
183     @Override
184     public MoneyWiseCashCategoryList getList() {
185         return (MoneyWiseCashCategoryList) super.getList();
186     }
187 
188     /**
189      * Set defaults.
190      *
191      * @param pParent the parent
192      * @throws OceanusException on error
193      */
194     public void setDefaults(final MoneyWiseCashCategory pParent) throws OceanusException {
195         getList().getValidator().setDefaults(pParent, this);
196     }
197 
198     @Override
199     public void resolveDataSetLinks() throws OceanusException {
200         /* Update the underlying details */
201         super.resolveDataSetLinks();
202 
203         /* Resolve category type and parent */
204         resolveDataLink(MoneyWiseStaticDataType.CASHTYPE, MoneyWiseStaticDataType.CASHTYPE);
205     }
206 
207     @Override
208     protected void resolveEditSetLinks() throws OceanusException {
209         /* Resolve parent within list */
210         resolveDataLink(PrometheusDataResource.DATAGROUP_PARENT, getList());
211 
212         /* Resolve StaticType if required */
213         final PrometheusEditSet myEditSet = getList().getEditSet();
214         if (myEditSet.hasDataType(MoneyWiseStaticDataType.CASHTYPE)) {
215             resolveDataLink(MoneyWiseStaticDataType.CASHTYPE, myEditSet.getDataList(MoneyWiseStaticDataType.CASHTYPE, MoneyWiseCashCategoryTypeList.class));
216         }
217     }
218 
219     @Override
220     public void setCategoryType(final PrometheusStaticDataItem pType) {
221         setValueType((MoneyWiseCashCategoryType) pType);
222     }
223 
224     /**
225      * Update base category from an edited category.
226      *
227      * @param pCategory the edited category
228      * @return whether changes have been made
229      */
230     @Override
231     public boolean applyChanges(final PrometheusDataItem pCategory) {
232         /* Can only update from a cash category */
233         if (!(pCategory instanceof MoneyWiseCashCategory myCategory)) {
234             return false;
235         }
236 
237         /* Store the current detail into history */
238         pushHistory();
239 
240         /* Apply basic changes */
241         applyBasicChanges(myCategory);
242 
243         /* Update the category type if required */
244         if (!MetisDataDifference.isEqual(getCategoryType(), myCategory.getCategoryType())) {
245             setValueType(myCategory.getCategoryType());
246         }
247 
248         /* Check for changes */
249         return checkForHistory();
250     }
251 
252     /**
253      * The Cash Category List class.
254      */
255     public static class MoneyWiseCashCategoryList
256             extends MoneyWiseCategoryBaseList<MoneyWiseCashCategory> {
257         /**
258          * Report fields.
259          */
260         private static final MetisFieldSet<MoneyWiseCashCategoryList> FIELD_DEFS = MetisFieldSet.newFieldSet(MoneyWiseCashCategoryList.class);
261 
262         /**
263          * The EditSet.
264          */
265         private PrometheusEditSet theEditSet;
266 
267         /**
268          * Construct an empty CORE Category list.
269          *
270          * @param pData the DataSet for the list
271          */
272         protected MoneyWiseCashCategoryList(final PrometheusDataSet pData) {
273             super(pData, MoneyWiseCashCategory.class, MoneyWiseBasicDataType.CASHCATEGORY);
274         }
275 
276         /**
277          * Constructor for a cloned List.
278          *
279          * @param pSource the source List
280          */
281         protected MoneyWiseCashCategoryList(final MoneyWiseCashCategoryList pSource) {
282             super(pSource);
283         }
284 
285         @Override
286         public MetisFieldSet<MoneyWiseCashCategoryList> getDataFieldSet() {
287             return FIELD_DEFS;
288         }
289 
290         @Override
291         public String listName() {
292             return LIST_NAME;
293         }
294 
295         @Override
296         public MetisFieldSetDef getItemFields() {
297             return MoneyWiseCashCategory.FIELD_DEFS;
298         }
299 
300         /**
301          * Obtain editSet.
302          *
303          * @return the editSet
304          */
305         public PrometheusEditSet getEditSet() {
306             return theEditSet;
307         }
308 
309         @Override
310         protected MoneyWiseCashCategoryList getEmptyList(final PrometheusListStyle pStyle) {
311             final MoneyWiseCashCategoryList myList = new MoneyWiseCashCategoryList(this);
312             myList.setStyle(pStyle);
313             return myList;
314         }
315 
316         /**
317          * Derive Edit list.
318          *
319          * @param pEditSet the editSet
320          * @return the edit list
321          * @throws OceanusException on error
322          */
323         public MoneyWiseCashCategoryList deriveEditList(final PrometheusEditSet pEditSet) throws OceanusException {
324             /* Build an empty List */
325             final MoneyWiseCashCategoryList myList = getEmptyList(PrometheusListStyle.EDIT);
326             myList.ensureMap();
327             pEditSet.setEditEntryList(MoneyWiseBasicDataType.CASHCATEGORY, myList);
328             myList.getValidator().setEditSet(pEditSet);
329 
330             /* Store the editSet */
331             myList.theEditSet = pEditSet;
332 
333             /* Loop through the categories */
334             final Iterator<MoneyWiseCashCategory> myIterator = iterator();
335             while (myIterator.hasNext()) {
336                 final MoneyWiseCashCategory myCurr = myIterator.next();
337 
338                 /* Ignore deleted events */
339                 if (myCurr.isDeleted()) {
340                     continue;
341                 }
342 
343                 /* Build the new linked cash category and add it to the list */
344                 final MoneyWiseCashCategory myCategory = new MoneyWiseCashCategory(myList, myCurr);
345                 myList.add(myCategory);
346                 myCategory.resolveEditSetLinks();
347 
348                 /* Adjust the map */
349                 myCategory.adjustMapForItem();
350             }
351 
352             /* Return the list */
353             return myList;
354         }
355 
356         /**
357          * Add a new item to the core list.
358          *
359          * @param pCategory item
360          * @return the newly added item
361          */
362         @Override
363         public MoneyWiseCashCategory addCopyItem(final PrometheusDataItem pCategory) {
364             /* Can only clone a CashCategory */
365             if (!(pCategory instanceof MoneyWiseCashCategory)) {
366                 throw new UnsupportedOperationException();
367             }
368 
369             final MoneyWiseCashCategory myCategory = new MoneyWiseCashCategory(this, (MoneyWiseCashCategory) pCategory);
370             add(myCategory);
371             return myCategory;
372         }
373 
374         /**
375          * Add a new item to the edit list.
376          *
377          * @return the new item
378          */
379         @Override
380         public MoneyWiseCashCategory addNewItem() {
381             final MoneyWiseCashCategory myCategory = new MoneyWiseCashCategory(this);
382             add(myCategory);
383             return myCategory;
384         }
385 
386         @Override
387         public MoneyWiseCashCategory addValuesItem(final PrometheusDataValues pValues) throws OceanusException {
388             /* Create the category */
389             final MoneyWiseCashCategory myCategory = new MoneyWiseCashCategory(this, pValues);
390 
391             /* Check that this CategoryId has not been previously added */
392             if (!isIdUnique(myCategory.getIndexedId())) {
393                 myCategory.addError(ERROR_DUPLICATE, MetisDataResource.DATA_ID);
394                 throw new MoneyWiseDataException(myCategory, ERROR_VALIDATION);
395             }
396 
397             /* Add to the list */
398             add(myCategory);
399 
400             /* Return it */
401             return myCategory;
402         }
403     }
404 }