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 }