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.validate;
18  
19  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicDataType;
21  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseBasicResource;
22  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseDataValidator.MoneyWiseDataValidatorAutoCorrect;
23  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseLoan;
24  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseLoan.MoneyWiseLoanList;
25  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseLoanCategory;
26  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWiseLoanCategory.MoneyWiseLoanCategoryList;
27  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee;
28  import io.github.tonywasher.joceanus.moneywise.data.basic.MoneyWisePayee.MoneyWisePayeeList;
29  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency;
30  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseLoanCategoryClass;
31  import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
32  import io.github.tonywasher.joceanus.prometheus.data.PrometheusDataItem;
33  import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
34  
35  import java.util.Iterator;
36  
37  /**
38   * Validator for Loan.
39   */
40  public class MoneyWiseValidateLoan
41          extends MoneyWiseValidateAccount<MoneyWiseLoan>
42          implements MoneyWiseDataValidatorAutoCorrect<MoneyWiseLoan> {
43      /**
44       * New Account name.
45       */
46      private static final String NAME_NEWACCOUNT = MoneyWiseBasicResource.LOAN_NEWACCOUNT.getValue();
47  
48      /**
49       * The infoSet validator.
50       */
51      private final MoneyWiseValidateLoanInfoSet theInfoSet;
52  
53      /**
54       * Constructor.
55       */
56      MoneyWiseValidateLoan() {
57          theInfoSet = new MoneyWiseValidateLoanInfoSet();
58      }
59  
60      @Override
61      public void setEditSet(final PrometheusEditSet pEditSet) {
62          super.setEditSet(pEditSet);
63          theInfoSet.storeEditSet(pEditSet);
64      }
65  
66      @Override
67      public void validate(final PrometheusDataItem pLoan) {
68          final MoneyWiseLoan myLoan = (MoneyWiseLoan) pLoan;
69          final MoneyWisePayee myParent = myLoan.getParent();
70          final MoneyWiseLoanCategory myCategory = myLoan.getCategory();
71          final MoneyWiseCurrency myCurrency = myLoan.getAssetCurrency();
72          final MoneyWiseLoanCategoryClass myClass = myLoan.getCategoryClass();
73  
74          /* Validate base components */
75          super.validate(pLoan);
76  
77          /* Category must be non-null */
78          if (myCategory == null) {
79              pLoan.addError(PrometheusDataItem.ERROR_MISSING, MoneyWiseBasicResource.CATEGORY_NAME);
80          } else if (myCategory.getCategoryTypeClass().isParentCategory()) {
81              pLoan.addError(ERROR_BADCATEGORY, MoneyWiseBasicResource.CATEGORY_NAME);
82          }
83  
84          /* Currency must be non-null and enabled */
85          if (myCurrency == null) {
86              pLoan.addError(PrometheusDataItem.ERROR_MISSING, MoneyWiseStaticDataType.CURRENCY);
87          } else if (!myCurrency.getEnabled()) {
88              pLoan.addError(PrometheusDataItem.ERROR_DISABLED, MoneyWiseStaticDataType.CURRENCY);
89          }
90  
91          /* Loan must be a child */
92          if (!myClass.isChild()) {
93              pLoan.addError(PrometheusDataItem.ERROR_EXIST, MoneyWiseBasicResource.ASSET_PARENT);
94  
95              /* Must have parent */
96          } else if (myParent == null) {
97              pLoan.addError(PrometheusDataItem.ERROR_MISSING, MoneyWiseBasicResource.ASSET_PARENT);
98          } else {
99              /* Parent must be suitable */
100             if (!myParent.getCategoryClass().canParentLoan(myClass)) {
101                 pLoan.addError(ERROR_BADPARENT, MoneyWiseBasicResource.ASSET_PARENT);
102             }
103 
104             /* If we are open then parent must be open */
105             if (!myLoan.isClosed() && Boolean.TRUE.equals(myParent.isClosed())) {
106                 pLoan.addError(ERROR_PARCLOSED, MoneyWiseBasicResource.ASSET_CLOSED);
107             }
108         }
109 
110         /* If we have an infoSet */
111         if (myLoan.getInfoSet() != null) {
112             /* Validate the InfoSet */
113             theInfoSet.validate(myLoan.getInfoSet());
114         }
115 
116         /* Set validation flag */
117         if (!pLoan.hasErrors()) {
118             pLoan.setValidEdit();
119         }
120     }
121 
122     @Override
123     public void setDefaults(final MoneyWiseLoan pLoan) throws OceanusException {
124         /* Set values */
125         final MoneyWiseLoanList myList = pLoan.getList();
126         pLoan.setName(getUniqueName(myList, NAME_NEWACCOUNT));
127         pLoan.setCategory(getDefaultCategory());
128         pLoan.setAssetCurrency(getReportingCurrency());
129         pLoan.setClosed(Boolean.FALSE);
130         autoCorrect(pLoan);
131     }
132 
133     @Override
134     public void autoCorrect(final MoneyWiseLoan pLoan) throws OceanusException {
135         /* Access category class and parent */
136         final MoneyWiseLoanCategoryClass myClass = pLoan.getCategoryClass();
137         final MoneyWisePayee myParent = pLoan.getParent();
138 
139         /* Ensure that we have valid parent */
140         if (myParent == null
141                 || !myParent.getCategoryClass().canParentLoan(myClass)) {
142             pLoan.setParent(getDefaultParent(pLoan));
143         }
144 
145         /* autoCorrect the infoSet */
146         theInfoSet.autoCorrect(pLoan.getInfoSet());
147     }
148 
149     /**
150      * Obtain default category for new loan account.
151      *
152      * @return the default category
153      */
154     private MoneyWiseLoanCategory getDefaultCategory() {
155         /* loop through the categories */
156         final MoneyWiseLoanCategoryList myCategories
157                 = getEditSet().getDataList(MoneyWiseBasicDataType.LOANCATEGORY, MoneyWiseLoanCategoryList.class);
158         final Iterator<MoneyWiseLoanCategory> myIterator = myCategories.iterator();
159         while (myIterator.hasNext()) {
160             final MoneyWiseLoanCategory myCategory = myIterator.next();
161 
162             /* Ignore deleted categories */
163             if (myCategory.isDeleted()) {
164                 continue;
165             }
166 
167             /* If the category is not a parent */
168             if (!myCategory.isCategoryClass(MoneyWiseLoanCategoryClass.PARENT)) {
169                 return myCategory;
170             }
171         }
172 
173         /* Return no category */
174         return null;
175     }
176 
177     /**
178      * Obtain default parent for new loan.
179      *
180      * @param pLoan the loan
181      * @return the default parent
182      */
183     private MoneyWisePayee getDefaultParent(final MoneyWiseLoan pLoan) {
184         /* Access details */
185         final MoneyWisePayeeList myPayees = getEditSet().getDataList(MoneyWiseBasicDataType.PAYEE, MoneyWisePayeeList.class);
186         final MoneyWiseLoanCategoryClass myClass = pLoan.getCategoryClass();
187 
188         /* loop through the payees */
189         final Iterator<MoneyWisePayee> myIterator = myPayees.iterator();
190         while (myIterator.hasNext()) {
191             final MoneyWisePayee myPayee = myIterator.next();
192 
193             /* Ignore deleted and closed payees */
194             if (myPayee.isDeleted() || Boolean.TRUE.equals(myPayee.isClosed())) {
195                 continue;
196             }
197 
198             /* If the payee can parent */
199             if (myPayee.getCategoryClass().canParentLoan(myClass)) {
200                 return myPayee;
201             }
202         }
203 
204         /* Return no payee */
205         return null;
206     }
207 }