View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.module.purap.document.validation.impl;
20  
21  import java.math.BigDecimal;
22  
23  import org.kuali.kfs.module.purap.PurapConstants;
24  import org.kuali.kfs.module.purap.PurapKeyConstants;
25  import org.kuali.kfs.module.purap.businessobject.PurApAccountingLine;
26  import org.kuali.kfs.module.purap.businessobject.PurApItem;
27  import org.kuali.kfs.module.purap.document.PurchasingAccountsPayableDocumentBase;
28  import org.kuali.kfs.sys.document.validation.GenericValidation;
29  import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
30  import org.kuali.rice.core.api.util.type.KualiDecimal;
31  import org.kuali.rice.krad.util.GlobalVariables;
32  
33  public class PurchasingAccountsPayablesItemPreCalculateValidations extends GenericValidation {
34      
35      private PurApItem item;
36      
37      /**
38       * @see org.kuali.kfs.sys.document.validation.Validation#validate(org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent)
39       */
40      public boolean validate(AttributedDocumentEvent event) {
41          
42          PurchasingAccountsPayableDocumentBase purApDocument = (PurchasingAccountsPayableDocumentBase) event.getDocument();
43          String accountDistributionMethod = purApDocument.getAccountDistributionMethod();
44  
45          if (PurapConstants.AccountDistributionMethodCodes.SEQUENTIAL_CODE.equalsIgnoreCase(accountDistributionMethod)) {
46              return this.checkTotalPercentAndTotalAmountsEqual(item);
47          }
48          
49          return this.checkTotalPercentOrTotalAmountsEqual(item);
50      }
51      
52      /**
53       * checks for both percent = 100% and item total = account amount total
54       * 
55       * @param item
56       * @return true when percent = 100% AND total amount = item total
57       */
58      public boolean checkTotalPercentAndTotalAmountsEqual(PurApItem item) {
59          boolean valid = true;
60          
61          valid &= validateTotalPercent(item, true);
62          
63          if (valid) {
64              valid &= validateTotalAmount(item, true);
65          }
66          
67          return valid;
68      }
69      
70      /**
71       * checks for only either percent = 100% or item total = account amount total
72       * 
73       * @param item
74       * @return true when either percent = 100% OR total amount = item total
75       */
76      public boolean checkTotalPercentOrTotalAmountsEqual(PurApItem item) {
77          boolean valid = false;
78          
79          boolean validPercent = validateTotalPercent(item, false);
80          if (validPercent) {
81              return true;
82          }
83          
84          boolean validAmount = validateTotalAmount(item, false);
85          if (validAmount) {
86              return true;
87          }
88          
89          KualiDecimal desiredAmount = (item.getTotalAmount() == null) ? new KualiDecimal(0) : item.getTotalAmount();
90          
91          if (!validPercent && !validAmount) {
92              GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_PERCENT_OR_AMOUNT_INVALID, item.getItemIdentifierString(),desiredAmount.toString());
93          } else {
94              if (!validPercent) {
95                  GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_TOTAL, item.getItemIdentifierString());
96              } else {
97                  if (!validAmount) {
98                      GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_TOTAL_AMOUNT, item.getItemIdentifierString(),desiredAmount.toString());
99                  }        
100             }
101         }
102         
103         return valid;
104     }
105     
106     /**
107      * Verifies account percent. If the total percent does not equal 100, 
108      * the validation fails.
109      * @param item
110      * @param writeErrorMessage true if error message to be added to global error variables, else false
111      * @return true if percent sum = 100%
112      */
113     public boolean validateTotalPercent(PurApItem item, boolean writeErrorMessage) {
114         boolean valid = true;
115         
116         if (item.getSourceAccountingLines().size() == 0) {
117             return valid;
118         }
119         
120         // validate that the percents total 100 for each item
121         BigDecimal totalPercent = BigDecimal.ZERO;
122         BigDecimal desiredPercent = new BigDecimal("100");
123         for (PurApAccountingLine account : item.getSourceAccountingLines()) {
124             if (account.getAccountLinePercent() != null) {
125                 totalPercent = totalPercent.add(account.getAccountLinePercent());
126             }
127             else {
128                 totalPercent = totalPercent.add(BigDecimal.ZERO);
129             }
130         }
131         if (desiredPercent.compareTo(totalPercent) != 0) {
132             if (writeErrorMessage) {
133                 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_TOTAL, item.getItemIdentifierString());
134             }
135             
136             valid = false;
137         }
138 
139         return valid;
140     }
141     
142     /**
143      * Verifies account amounts = item total. If does not equal then validation fails. 
144      * @param item
145      * @param writeErrorMessage true if error message to be added to global error variables, else false
146      * @return true if account amounts sum = item total
147      */
148     public boolean validateTotalAmount(PurApItem item, boolean writeErrorMessage) {
149         boolean valid = true;
150         
151         if (item.getSourceAccountingLines().size() == 0) {
152             return valid;
153         }
154         
155         if (item.getItemQuantity() == null || item.getItemUnitPrice() == null || item.getTotalAmount().compareTo(KualiDecimal.ZERO) == 0) {
156             //extended cost is not available yet so do not run validations....
157             return valid;
158         }
159         
160      // validate that the amount total 
161         KualiDecimal totalAmount = KualiDecimal.ZERO;
162         
163         KualiDecimal desiredAmount = (item.getTotalAmount() == null) ? new KualiDecimal(0) : item.getTotalAmount();
164         for (PurApAccountingLine account : item.getSourceAccountingLines()) {
165             if (account.getAmount() != null) {
166                 totalAmount = totalAmount.add(account.getAmount());
167             }
168             else {
169                 totalAmount = totalAmount.add(KualiDecimal.ZERO);
170             }
171         }
172         
173         if (desiredAmount.compareTo(totalAmount) != 0) {
174             if (writeErrorMessage) {
175                 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_TOTAL_AMOUNT, item.getItemIdentifierString(),desiredAmount.toString());
176             }
177             valid = false;
178         }
179 
180         return valid;
181     }
182     
183     /**
184      * Sets the accountingDocumentForValidation attribute value.
185      * 
186      * @param accountingDocumentForValidation The accountingDocumentForValidation to set.
187      */
188     public void setItem(PurApItem item) {
189         this.item = item;
190     }
191 }