001 /* 002 * Copyright 2011 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 */ 016 package org.kuali.kfs.sys.document.service.impl; 017 018 import java.sql.Date; 019 import java.text.MessageFormat; 020 import java.util.List; 021 022 import org.kuali.kfs.coa.businessobject.AccountingPeriod; 023 import org.kuali.kfs.coa.businessobject.BalanceType; 024 import org.kuali.kfs.coa.businessobject.ObjectCode; 025 import org.kuali.kfs.coa.service.ObjectCodeService; 026 import org.kuali.kfs.coa.service.ObjectTypeService; 027 import org.kuali.kfs.sys.KFSConstants; 028 import org.kuali.kfs.sys.KFSKeyConstants; 029 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail; 030 import org.kuali.kfs.sys.context.SpringContext; 031 import org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService; 032 import org.kuali.rice.kns.datadictionary.AttributeDefinition; 033 import org.kuali.rice.kns.datadictionary.DataDictionaryEntry; 034 import org.kuali.rice.kns.service.DataDictionaryService; 035 import org.kuali.rice.kns.service.DateTimeService; 036 import org.kuali.rice.kns.service.KualiConfigurationService; 037 import org.kuali.rice.kns.util.GlobalVariables; 038 import org.kuali.rice.kns.util.ObjectUtils; 039 040 /** 041 * The default implementation of the AccountingDocumentRuleHelperService 042 */ 043 public class AccountingDocumentRuleHelperServiceImpl implements AccountingDocumentRuleHelperService { 044 private DataDictionaryService ddService; 045 private ObjectTypeService objectTypeService; 046 047 /** 048 * @see org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService#isExpense(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail) 049 */ 050 public boolean isExpense(GeneralLedgerPendingEntrySourceDetail postable) { 051 // return SpringContext.getBean(KualiConfigurationService.class).succeedsRule(KFSConstants.FINANCIAL_NAMESPACE, 052 // KUALI_TRANSACTION_PROCESSING_GLOBAL_RULES_SECURITY_GROUPING, APPLICATION_PARAMETER.EXPENSE_OBJECT_TYPE_CODES, 053 // getObjectCodeTypeCodeWithoutSideEffects(accountingLine) ); 054 List<String> expenseObjectTypes = objectTypeService.getCurrentYearBasicExpenseObjectTypes(); 055 return expenseObjectTypes.contains(getObjectCodeTypeCodeWithoutSideEffects(postable)); 056 } 057 058 /** 059 * @see org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService#isIncome(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail) 060 */ 061 public boolean isIncome(GeneralLedgerPendingEntrySourceDetail postable) { 062 List<String> incomeObjectTypes = objectTypeService.getCurrentYearBasicIncomeObjectTypes(); 063 return incomeObjectTypes.contains(getObjectCodeTypeCodeWithoutSideEffects(postable)); 064 } 065 066 /** 067 * Makes sure that the objectCode attribute is fully populated b/c we are using proxying in our persistence layer. 068 * 069 * @param accountingLine 070 * @return the object type code of the object code of the given accounting line 071 */ 072 public String getObjectCodeTypeCodeWithoutSideEffects(GeneralLedgerPendingEntrySourceDetail postable) { 073 Integer fiscalYear = postable.getPostingYear(); 074 String chartOfAccountsCode = postable.getChartOfAccountsCode(); 075 String financialObjectCode = postable.getFinancialObjectCode(); 076 077 ObjectCodeService objectCodeService = SpringContext.getBean(ObjectCodeService.class); 078 ObjectCode objectCode = objectCodeService.getByPrimaryIdWithCaching(fiscalYear, chartOfAccountsCode, financialObjectCode); 079 080 return ObjectUtils.isNotNull(objectCode) ? objectCode.getFinancialObjectTypeCode() : null; 081 } 082 083 /** 084 * @see org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService#isValidBalanceType(org.kuali.kfs.coa.businessobject.BalanceTyp, 085 * java.lang.String) 086 */ 087 public boolean isValidBalanceType(BalanceType balanceType, String errorPropertyName) { 088 return isValidBalanceType(balanceType, BalanceType.class, errorPropertyName, errorPropertyName); 089 } 090 091 /** 092 * Looks up a label from the data dictionary 093 * 094 * @param entryClass the class of the attribute to lookup the label for 095 * @param attributeName the attribute to look up the label for 096 * @return the label 097 */ 098 protected String getLabelFromDataDictionary(Class entryClass, String attributeName) { 099 DataDictionaryEntry entry = ddService.getDataDictionary().getDictionaryObjectEntry(entryClass.getName()); 100 if (entry == null) { 101 throw new IllegalArgumentException("Cannot find DataDictionary entry for " + entryClass); 102 } 103 AttributeDefinition attributeDefinition = entry.getAttributeDefinition(attributeName); 104 if (attributeDefinition == null) { 105 throw new IllegalArgumentException("Cannot find " + entryClass + " attribute with name " + attributeName); 106 } 107 return attributeDefinition.getLabel(); 108 } 109 110 /** 111 * @see org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService#isValidBalanceType(org.kuali.kfs.coa.businessobject.BalanceTyp, 112 * java.lang.Class, java.lang.String, java.lang.String) 113 */ 114 public boolean isValidBalanceType(BalanceType balanceType, Class entryClass, String attributeName, String errorPropertyName) { 115 String label = getLabelFromDataDictionary(entryClass, attributeName); 116 if (ObjectUtils.isNull(balanceType)) { 117 GlobalVariables.getMessageMap().putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, label); 118 return false; 119 } 120 // make sure it's active for usage 121 if (!balanceType.isActive()) { 122 GlobalVariables.getMessageMap().putError(errorPropertyName, KFSKeyConstants.ERROR_INACTIVE, label); 123 return false; 124 } 125 return true; 126 } 127 128 /** 129 * @see org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService#isValidOpenAccountingPeriod(org.kuali.kfs.coa.businessobject.AccountingPeriod, 130 * java.lang.Class, java.lang.String, java.lang.String) 131 */ 132 public boolean isValidOpenAccountingPeriod(AccountingPeriod accountingPeriod, Class entryClass, String attribueName, String errorPropertyName) { 133 // retrieve from system to make sure it exists 134 String label = getLabelFromDataDictionary(entryClass, attribueName); 135 if (ObjectUtils.isNull(accountingPeriod)) { 136 GlobalVariables.getMessageMap().putError(errorPropertyName, KFSKeyConstants.ERROR_EXISTENCE, label); 137 return false; 138 } 139 140 // make sure it's open for use 141 if (!accountingPeriod.isActive()) { 142 GlobalVariables.getMessageMap().putError(errorPropertyName, KFSKeyConstants.ERROR_DOCUMENT_ACCOUNTING_PERIOD_CLOSED); 143 return false; 144 } 145 146 return true; 147 } 148 149 /** 150 * @see org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService#isValidReversalDate(java.sql.Date, 151 * java.lang.String) 152 */ 153 public boolean isValidReversalDate(Date reversalDate, String errorPropertyName) { 154 java.sql.Date today = SpringContext.getBean(DateTimeService.class).getCurrentSqlDateMidnight(); 155 if (null != reversalDate && reversalDate.before(today)) { 156 GlobalVariables.getMessageMap().putError(errorPropertyName, KFSKeyConstants.ERROR_DOCUMENT_INCORRECT_REVERSAL_DATE); 157 return false; 158 } 159 else { 160 return true; 161 } 162 } 163 164 /** 165 * Gets the named property from KualiConfigurationService (i.e., from ApplicationResources.properties) and formats it with the 166 * given arguments (if any). 167 * 168 * @param propertyName 169 * @param arguments 170 * @return the formatted property (i.e., message), with any {@code {0}} replaced with the first argument, {@code {1}} with the 171 * second argument, etc. 172 */ 173 public String formatProperty(String propertyName, Object... arguments) { 174 return MessageFormat.format(SpringContext.getBean(KualiConfigurationService.class).getPropertyString(propertyName), arguments); 175 } 176 177 /** 178 * Sets the dataDictionaryService attribute value. 179 * 180 * @param ddService The ddService to set. 181 */ 182 public void setDataDictionaryService(DataDictionaryService ddService) { 183 this.ddService = ddService; 184 } 185 186 /** 187 * Sets the objectTypeService attribute value. 188 * 189 * @param objectTypeService The objectTypeService to set. 190 */ 191 public void setObjectTypeService(ObjectTypeService objectTypeService) { 192 this.objectTypeService = objectTypeService; 193 } 194 195 }