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