001/* 002 * Copyright 2008 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.ole.module.purap.document.validation.impl; 017 018import org.kuali.ole.module.purap.PurapConstants; 019import org.kuali.ole.module.purap.PurapKeyConstants; 020import org.kuali.ole.module.purap.businessobject.PurApAccountingLine; 021import org.kuali.ole.module.purap.businessobject.PurApItem; 022import org.kuali.ole.module.purap.document.PurchasingAccountsPayableDocumentBase; 023import org.kuali.ole.sys.document.validation.GenericValidation; 024import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent; 025import org.kuali.rice.core.api.util.type.KualiDecimal; 026import org.kuali.rice.krad.util.GlobalVariables; 027 028import java.math.BigDecimal; 029 030public class PurchasingAccountsPayablesItemPreCalculateValidations extends GenericValidation { 031 032 private PurApItem item; 033 034 /** 035 * @see org.kuali.ole.sys.document.validation.Validation#validate(org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent) 036 */ 037 @Override 038 public boolean validate(AttributedDocumentEvent event) { 039 040 PurchasingAccountsPayableDocumentBase purApDocument = (PurchasingAccountsPayableDocumentBase) event.getDocument(); 041 String accountDistributionMethod = purApDocument.getAccountDistributionMethod(); 042 043 // OLE-3405 : disabling the distribution method choice 044 // JHK : In this case, we are going to ensure that the amounts and percents add up 045 // since that matches the OLE behavior where they both should be populated after a calculate. 046 //if (PurapConstants.AccountDistributionMethodCodes.SEQUENTIAL_CODE.equalsIgnoreCase(accountDistributionMethod)) { 047 return this.checkTotalPercentAndTotalAmountsEqual(item); 048 //} 049 050 //return this.checkTotalPercentOrTotalAmountsEqual(item); 051 } 052 053 /** 054 * checks for both percent = 100% and item total = account amount total 055 * 056 * @param item 057 * @return true when percent = 100% AND total amount = item total 058 */ 059 public boolean checkTotalPercentAndTotalAmountsEqual(PurApItem item) { 060 boolean valid = true; 061 062 valid &= validateTotalPercent(item, true); 063 064 if (valid) { 065 valid &= validateTotalAmount(item, true); 066 } 067 068 return valid; 069 } 070 071 /** 072 * checks for only either percent = 100% or item total = account amount total 073 * 074 * @param item 075 * @return true when either percent = 100% OR total amount = item total 076 */ 077 public boolean checkTotalPercentOrTotalAmountsEqual(PurApItem item) { 078 boolean valid = false; 079 080 boolean validPercent = validateTotalPercent(item, false); 081 if (validPercent) { 082 return true; 083 } 084 085 boolean validAmount = validateTotalAmount(item, false); 086 if (validAmount) { 087 return true; 088 } 089 090 KualiDecimal desiredAmount = (item.getTotalAmount() == null) ? new KualiDecimal(0) : item.getTotalAmount(); 091 092 if (!validPercent && !validAmount) { 093 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_PERCENT_OR_AMOUNT_INVALID, item.getItemIdentifierString(), desiredAmount.toString()); 094 } else { 095 if (!validPercent) { 096 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_TOTAL, item.getItemIdentifierString()); 097 } else { 098 if (!validAmount) { 099 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_TOTAL_AMOUNT, item.getItemIdentifierString(), desiredAmount.toString()); 100 } 101 } 102 } 103 104 return valid; 105 } 106 107 /** 108 * Verifies account percent. If the total percent does not equal 100, 109 * the validation fails. 110 * 111 * @param item 112 * @param writeErrorMessage true if error message to be added to global error variables, else false 113 * @return true if percent sum = 100% 114 */ 115 public boolean validateTotalPercent(PurApItem item, boolean writeErrorMessage) { 116 boolean valid = true; 117 118 if (item.getSourceAccountingLines().size() == 0) { 119 return valid; 120 } 121 122 // validate that the percents total 100 for each item 123 BigDecimal totalPercent = BigDecimal.ZERO; 124 BigDecimal desiredPercent = new BigDecimal("100"); 125 for (PurApAccountingLine account : item.getSourceAccountingLines()) { 126 if (account.getAccountLinePercent() != null) { 127 totalPercent = totalPercent.add(account.getAccountLinePercent()); 128 } else { 129 totalPercent = totalPercent.add(BigDecimal.ZERO); 130 } 131 } 132 if (desiredPercent.compareTo(totalPercent) != 0) { 133 if (writeErrorMessage) { 134 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_TOTAL, item.getItemIdentifierString()); 135 } 136 137 valid = false; 138 } 139 140 return valid; 141 } 142 143 /** 144 * Verifies account amounts = item total. If does not equal then validation fails. 145 * 146 * @param item 147 * @param writeErrorMessage true if error message to be added to global error variables, else false 148 * @return true if account amounts sum = item total 149 */ 150 public boolean validateTotalAmount(PurApItem item, boolean writeErrorMessage) { 151 boolean valid = true; 152 153 if (item.getSourceAccountingLines().size() == 0) { 154 return valid; 155 } 156 157 if (item.getItemQuantity() == null || item.getItemUnitPrice() == null || item.getTotalAmount().compareTo(KualiDecimal.ZERO) == 0) { 158 //extended cost is not available yet so do not run validations.... 159 return valid; 160 } 161 162 // validate that the amount total 163 KualiDecimal totalAmount = KualiDecimal.ZERO; 164 165 KualiDecimal desiredAmount = (item.getTotalAmount() == null) ? new KualiDecimal(0) : item.getTotalAmount(); 166 for (PurApAccountingLine account : item.getSourceAccountingLines()) { 167 if (account.getAmount() != null) { 168 totalAmount = totalAmount.add(account.getAmount()); 169 } else { 170 totalAmount = totalAmount.add(KualiDecimal.ZERO); 171 } 172 } 173 174 if (desiredAmount.compareTo(totalAmount) != 0) { 175 if (writeErrorMessage) { 176 GlobalVariables.getMessageMap().putError(PurapConstants.ITEM_TAB_ERROR_PROPERTY, PurapKeyConstants.ERROR_ITEM_ACCOUNTING_TOTAL_AMOUNT, item.getItemIdentifierString(), desiredAmount.toString()); 177 } 178 valid = false; 179 } 180 181 return valid; 182 } 183 184 /** 185 * Sets the accountingDocumentForValidation attribute value. 186 * 187 * @param accountingDocumentForValidation 188 * The accountingDocumentForValidation to set. 189 */ 190 public void setItem(PurApItem item) { 191 this.item = item; 192 } 193}