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.metis.data.MetisDataDifference;
21  import io.github.tonywasher.joceanus.metis.data.MetisDataItem.MetisDataFieldId;
22  import io.github.tonywasher.joceanus.metis.data.MetisDataResource;
23  import io.github.tonywasher.joceanus.metis.field.MetisFieldSet;
24  import io.github.tonywasher.joceanus.metis.field.MetisFieldVersionedSet;
25  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAssetCategory;
26  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryClass;
27  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryType;
28  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryType.MoneyWiseCashCategoryTypeList;
29  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
30  import io.github.tonywasher.joceanus.moneywise.exc.MoneyWiseDataException;
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.PrometheusDataValues;
34  import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataItem;
35  import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
36  
37  import java.util.Iterator;
38  
39  /**
40   * Cash Category class.
41   */
42  public final class MoneyWiseCashCategory
43          extends MoneyWiseCategoryBase
44          implements MoneyWiseAssetCategory {
45      /**
46       * Object name.
47       */
48      public static final String OBJECT_NAME = MoneyWiseBasicDataType.CASHCATEGORY.getItemName();
49  
50      /**
51       * List name.
52       */
53      public static final String LIST_NAME = MoneyWiseBasicDataType.CASHCATEGORY.getListName();
54  
55      /**
56       * Local Report fields.
57       */
58      private static final MetisFieldVersionedSet<MoneyWiseCashCategory> FIELD_DEFS = MetisFieldVersionedSet.newVersionedFieldSet(MoneyWiseCashCategory.class);
59  
60      /*
61       * FieldIds.
62       */
63      static {
64          FIELD_DEFS.declareLinkField(MoneyWiseStaticDataType.CASHTYPE);
65      }
66  
67      /**
68       * Copy Constructor.
69       *
70       * @param pList     the list
71       * @param pCategory The Category to copy
72       */
73      MoneyWiseCashCategory(final MoneyWiseCashCategoryList pList,
74                            final MoneyWiseCashCategory pCategory) {
75          /* Set standard values */
76          super(pList, pCategory);
77      }
78  
79      /**
80       * Values constructor.
81       *
82       * @param pList   the List to add to
83       * @param pValues the values constructor
84       * @throws OceanusException on error
85       */
86      private MoneyWiseCashCategory(final MoneyWiseCashCategoryList pList,
87                                    final PrometheusDataValues pValues) throws OceanusException {
88          /* Initialise the item */
89          super(pList, pValues);
90  
91          /* Store the Category Type */
92          final Object myValue = pValues.getValue(MoneyWiseStaticDataType.CASHTYPE);
93          if (myValue instanceof Integer i) {
94              setValueType(i);
95          } else if (myValue instanceof String s) {
96              setValueType(s);
97          }
98      }
99  
100     /**
101      * Edit Constructor.
102      *
103      * @param pList the list
104      */
105     public MoneyWiseCashCategory(final MoneyWiseCashCategoryList pList) {
106         super(pList);
107     }
108 
109     @Override
110     public MetisFieldSetDef getDataFieldSet() {
111         return FIELD_DEFS;
112     }
113 
114     @Override
115     public boolean includeXmlField(final MetisDataFieldId pField) {
116         /* Determine whether fields should be included */
117         if (MoneyWiseStaticDataType.CASHTYPE.equals(pField)) {
118             return true;
119         }
120 
121         /* Pass call on */
122         return super.includeXmlField(pField);
123     }
124 
125     @Override
126     public MoneyWiseCashCategoryType getCategoryType() {
127         return getValues().getValue(MoneyWiseStaticDataType.CASHTYPE, MoneyWiseCashCategoryType.class);
128     }
129 
130     @Override
131     public MoneyWiseCashCategoryClass getCategoryTypeClass() {
132         final MoneyWiseCashCategoryType myType = getCategoryType();
133         return myType == null
134                 ? null
135                 : myType.getCashClass();
136     }
137 
138     @Override
139     public MoneyWiseCashCategory getParentCategory() {
140         return getValues().getValue(PrometheusDataResource.DATAGROUP_PARENT, MoneyWiseCashCategory.class);
141     }
142 
143     /**
144      * Set category type value.
145      *
146      * @param pValue the value
147      */
148     private void setValueType(final MoneyWiseCashCategoryType pValue) {
149         getValues().setUncheckedValue(MoneyWiseStaticDataType.CASHTYPE, pValue);
150     }
151 
152     /**
153      * Set category type id.
154      *
155      * @param pValue the value
156      */
157     private void setValueType(final Integer pValue) {
158         getValues().setUncheckedValue(MoneyWiseStaticDataType.CASHTYPE, pValue);
159     }
160 
161     /**
162      * Set category type name.
163      *
164      * @param pValue the value
165      */
166     private void setValueType(final String pValue) {
167         getValues().setUncheckedValue(MoneyWiseStaticDataType.CASHTYPE, pValue);
168     }
169 
170     /**
171      * Is this cash category the required class.
172      *
173      * @param pClass the required category class.
174      * @return true/false
175      */
176     public boolean isCategoryClass(final MoneyWiseCashCategoryClass pClass) {
177         /* Check for match */
178         return getCategoryTypeClass() == pClass;
179     }
180 
181     @Override
182     public MoneyWiseCashCategoryList getList() {
183         return (MoneyWiseCashCategoryList) super.getList();
184     }
185 
186     /**
187      * Set defaults.
188      *
189      * @param pParent the parent
190      * @throws OceanusException on error
191      */
192     public void setDefaults(final MoneyWiseCashCategory pParent) throws OceanusException {
193         getList().getValidator().setDefaults(pParent, this);
194     }
195 
196     @Override
197     public void resolveDataSetLinks() throws OceanusException {
198         /* Update the underlying details */
199         super.resolveDataSetLinks();
200 
201         /* Resolve category type and parent */
202         final MoneyWiseDataSet myData = getDataSet();
203         resolveDataLink(MoneyWiseStaticDataType.CASHTYPE, myData.getCashCategoryTypes());
204     }
205 
206     @Override
207     protected void resolveEditSetLinks() throws OceanusException {
208         /* Resolve parent within list */
209         resolveDataLink(PrometheusDataResource.DATAGROUP_PARENT, getList());
210 
211         /* Resolve StaticType if required */
212         final PrometheusEditSet myEditSet = getList().getEditSet();
213         if (myEditSet.hasDataType(MoneyWiseStaticDataType.CASHTYPE)) {
214             resolveDataLink(MoneyWiseStaticDataType.CASHTYPE, myEditSet.getDataList(MoneyWiseStaticDataType.CASHTYPE, MoneyWiseCashCategoryTypeList.class));
215         }
216     }
217 
218     @Override
219     public void setCategoryType(final PrometheusStaticDataItem pType) {
220         setValueType((MoneyWiseCashCategoryType) pType);
221     }
222 
223     /**
224      * Update base category from an edited category.
225      *
226      * @param pCategory the edited category
227      * @return whether changes have been made
228      */
229     @Override
230     public boolean applyChanges(final PrometheusDataItem pCategory) {
231         /* Can only update from a cash category */
232         if (!(pCategory instanceof MoneyWiseCashCategory)) {
233             return false;
234         }
235         final MoneyWiseCashCategory myCategory = (MoneyWiseCashCategory) pCategory;
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 MoneyWiseDataSet 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 }