001: /*
002: * Copyright 2006-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.module.financial.service.impl;
017:
018: import java.util.Calendar;
019: import java.util.HashMap;
020:
021: import org.kuali.core.service.BusinessObjectService;
022: import org.kuali.core.service.DateTimeService;
023: import org.kuali.kfs.KFSConstants;
024: import org.kuali.kfs.service.ParameterService;
025: import org.kuali.module.chart.bo.Account;
026: import org.kuali.module.chart.bo.ObjectCode;
027: import org.kuali.module.chart.bo.OffsetDefinition;
028: import org.kuali.module.chart.service.AccountService;
029: import org.kuali.module.chart.service.ObjectCodeService;
030: import org.kuali.module.financial.bo.OffsetAccount;
031: import org.kuali.module.financial.exceptions.InvalidFlexibleOffsetException;
032: import org.kuali.module.financial.service.FlexibleOffsetAccountService;
033: import org.kuali.module.gl.bo.FlexibleAccountUpdateable;
034: import org.springframework.transaction.annotation.Transactional;
035:
036: /**
037: * This is the default implementation of the FlexibleOffsetAccountService interface.
038: */
039: @Transactional
040: public class FlexibleOffsetAccountServiceImpl implements
041: FlexibleOffsetAccountService {
042: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
043: .getLogger(FlexibleOffsetAccountServiceImpl.class);
044:
045: private BusinessObjectService businessObjectService;
046: private AccountService accountService;
047: private ObjectCodeService objectCodeService;
048: private DateTimeService dateTimeService;
049: private ParameterService parameterService;
050:
051: /**
052: * This method uses the parameters provided to retrieve an OffsetAccount instance if the flexible offset account flag is
053: * enabled.
054: *
055: * @param chartOfAccountsCode The chart code used to retrieve the flexible offset account.
056: * @param accountNumber The account number of the flexible offset account being retrieved.
057: * @param financialOffsetObjectCode The offset object code used to retrieve the offset account.
058: * @return A flexible offset account based on the parameters provided, or null if offsets are not enabled.
059: *
060: * @see FlexibleOffsetAccountService#getByPrimaryIdIfEnabled
061: */
062: public OffsetAccount getByPrimaryIdIfEnabled(
063: String chartOfAccountsCode, String accountNumber,
064: String financialOffsetObjectCode) {
065: LOG.debug("getByPrimaryIdIfEnabled() started");
066:
067: if (!getEnabled()) {
068: return null;
069: }
070: HashMap<String, Object> keys = new HashMap();
071: keys.put("chartOfAccountsCode", chartOfAccountsCode);
072: keys.put("accountNumber", accountNumber);
073: keys
074: .put("financialOffsetObjectCode",
075: financialOffsetObjectCode);
076: return (OffsetAccount) businessObjectService.findByPrimaryKey(
077: OffsetAccount.class, keys);
078: }
079:
080: /**
081: * This method queries the parameter table to retrieve the value of the flexible offset flag and returns the resulting value.
082: *
083: * @return True if flexible offsets are enabled, false otherwise.
084: *
085: * @see FlexibleOffsetAccountService#getEnabled
086: */
087: public boolean getEnabled() {
088: LOG.debug("getEnabled() started");
089: return parameterService
090: .getIndicatorParameter(
091: OffsetDefinition.class,
092: KFSConstants.SystemGroupParameterNames.FLEXIBLE_OFFSET_ENABLED_FLAG);
093: }
094:
095: /**
096: * This method modifies the origin entry provided with values from the associated flexible offset account, which is
097: * retrieved from the database using values provided by the origin entry.
098: *
099: * @param originEntry The origin entry to be updated with offset account details.
100: * @return False if the flexible offset flag is false, if there is no corresponding flexbile offset account, true otherwise.
101: *
102: * @see org.kuali.module.financial.service.FlexibleOffsetAccountService#updateOffset(org.kuali.module.gl.bo.OriginEntryFull)
103: */
104: public boolean updateOffset(FlexibleAccountUpdateable transaction) {
105: LOG.debug("setBusinessObjectService() started");
106:
107: if (!getEnabled()) {
108: return false;
109: }
110: String keyOfErrorMessage = "";
111:
112: Integer fiscalYear = transaction.getUniversityFiscalYear();
113: String chartOfAccountsCode = transaction
114: .getChartOfAccountsCode();
115: String accountNumber = transaction.getAccountNumber();
116:
117: String balanceTypeCode = transaction
118: .getFinancialBalanceTypeCode();
119: String documentTypeCode = transaction
120: .getFinancialDocumentTypeCode();
121:
122: // do nothing if there is no the offset account with the given chart of accounts code,
123: // account number and offset object code in the offset table.
124: OffsetAccount flexibleOffsetAccount = getByPrimaryIdIfEnabled(
125: chartOfAccountsCode, accountNumber, transaction
126: .getFinancialObjectCode());
127: if (flexibleOffsetAccount == null) {
128: return false;
129: }
130:
131: String offsetAccountNumber = flexibleOffsetAccount
132: .getFinancialOffsetAccountNumber();
133: String offsetChartOfAccountsCode = flexibleOffsetAccount
134: .getFinancialOffsetChartOfAccountCode();
135:
136: Account offsetAccount = accountService.getByPrimaryId(
137: offsetChartOfAccountsCode, offsetAccountNumber);
138: if (offsetAccount == null) {
139: throw new InvalidFlexibleOffsetException(
140: "Invalid Flexible Offset Account "
141: + offsetChartOfAccountsCode + "-"
142: + offsetAccountNumber);
143: }
144:
145: // Can't be closed and can't be expired
146: if (offsetAccount.isAccountClosedIndicator()) {
147: throw new InvalidFlexibleOffsetException(
148: "Closed Flexible Offset Account "
149: + offsetChartOfAccountsCode + "-"
150: + offsetAccountNumber);
151: }
152: if ((offsetAccount.getAccountExpirationDate() != null)
153: && isExpired(offsetAccount, dateTimeService
154: .getCurrentCalendar())) {
155: throw new InvalidFlexibleOffsetException(
156: "Expired Flexible Offset Account "
157: + offsetChartOfAccountsCode + "-"
158: + offsetAccountNumber);
159: }
160:
161: // If the chart changes, make sure the object code is still valid
162: if (!chartOfAccountsCode.equals(offsetChartOfAccountsCode)) {
163: ObjectCode objectCode = objectCodeService.getByPrimaryId(
164: fiscalYear, offsetChartOfAccountsCode, transaction
165: .getFinancialObjectCode());
166: if (objectCode == null) {
167: throw new InvalidFlexibleOffsetException(
168: "Invalid Object Code for flexible offset "
169: + fiscalYear + "-"
170: + offsetChartOfAccountsCode + "-"
171: + transaction.getFinancialObjectCode());
172: }
173: }
174:
175: // replace the chart and account of the given transaction with those of the offset account obtained above
176: transaction.setAccount(offsetAccount);
177: transaction.setAccountNumber(offsetAccountNumber);
178: transaction.setChartOfAccountsCode(offsetChartOfAccountsCode);
179:
180: // blank out the sub account and sub object since the account has been replaced
181: transaction.setSubAccountNumber(KFSConstants
182: .getDashSubAccountNumber());
183: transaction.setFinancialSubObjectCode(KFSConstants
184: .getDashFinancialSubObjectCode());
185: return true;
186: }
187:
188: /**
189: * This method determines if an account has expired. An account has expired if the expiration year of the account is
190: * less than the run date year or if the date of expiration occurred before the run date provided.
191: *
192: * @param account The account to be examined.
193: * @param runCalendar The date the expiration date is tested against.
194: * @return True if the account has expired, false otherwise.
195: */
196: private boolean isExpired(Account account, Calendar runCalendar) {
197:
198: Calendar expirationDate = Calendar.getInstance();
199: expirationDate.setTimeInMillis(account
200: .getAccountExpirationDate().getTime());
201:
202: int expirationYear = expirationDate.get(Calendar.YEAR);
203: int runYear = runCalendar.get(Calendar.YEAR);
204: int expirationDay = expirationDate.get(Calendar.DAY_OF_YEAR);
205: int runDay = runCalendar.get(Calendar.DAY_OF_YEAR);
206:
207: return (expirationYear < runYear)
208: || (expirationYear == runYear && expirationDay < runDay);
209: }
210:
211: /**
212: * Sets the local dateTimeService attribute.
213: * @param dateTimeService The DateTimeService instance to be set.
214: */
215: public void setDateTimeService(DateTimeService dateTimeService) {
216: this .dateTimeService = dateTimeService;
217: }
218:
219: /**
220: * Sets the local accountService attribute.
221: * @param accountService The AccountService instance to be set.
222: */
223: public void setAccountService(AccountService accountService) {
224: this .accountService = accountService;
225: }
226:
227: /**
228: * Sets the local objectCodeService attribute.
229: * @param objectCodeService The ObjectCodeService instance to be set.
230: */
231: public void setObjectCodeService(ObjectCodeService objectCodeService) {
232: this .objectCodeService = objectCodeService;
233: }
234:
235: /**
236: * Sets the local businessObjectService attribute.
237: * @param businessObjectService The BusinessObjectService instance to be set.
238: */
239: public void setBusinessObjectService(
240: BusinessObjectService businessObjectService) {
241: this .businessObjectService = businessObjectService;
242: }
243:
244: /**
245: * Sets the local parameterService attribute.
246: * @param parameterService The ParameterService instance to be set.
247: */
248: public void setParameterService(ParameterService parameterService) {
249: this.parameterService = parameterService;
250: }
251: }
|