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.gl.service.impl;
017
018 import java.util.Comparator;
019 import java.util.Map;
020
021 import org.apache.commons.lang.StringUtils;
022 import org.kuali.kfs.coa.businessobject.Account;
023 import org.kuali.kfs.coa.businessobject.SubFundGroup;
024 import org.kuali.kfs.gl.batch.service.AccountingCycleCachingService;
025 import org.kuali.kfs.gl.businessobject.OriginEntryInformation;
026 import org.kuali.kfs.gl.businessobject.PosterOutputSummaryAmountHolder;
027 import org.kuali.kfs.gl.businessobject.PosterOutputSummaryEntry;
028 import org.kuali.kfs.gl.businessobject.Transaction;
029 import org.kuali.kfs.gl.service.PosterOutputSummaryService;
030 import org.kuali.rice.kns.bo.PersistableBusinessObject;
031 import org.kuali.rice.kns.util.KualiDecimal;
032
033 /**
034 * The default implementation of the PosterOutputSummaryService
035 */
036 public class PosterOutputSummaryServiceImpl implements PosterOutputSummaryService {
037 private AccountingCycleCachingService accountingCycleCachingService;
038
039 /**
040 * Default implementation
041 * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#addOriginEntryAmountToAmountHolder(org.kuali.kfs.gl.businessobject.OriginEntryInformation, org.kuali.kfs.gl.businessobject.PosterOutputSummaryAmountHolder)
042 */
043 public void addAmountToAmountHolder(OriginEntryInformation originEntry, PosterOutputSummaryAmountHolder amountHolder) {
044 final String debitCreditCode = originEntry.getTransactionDebitCreditCode();
045 final KualiDecimal amount = originEntry.getTransactionLedgerEntryAmount();
046 final String objectTypeCode = originEntry.getFinancialObjectTypeCode();
047
048 amountHolder.addAmount(debitCreditCode, objectTypeCode, amount);
049 }
050
051 /**
052 * Default implementation
053 * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#addTransactionAmountToAmountHolder(org.kuali.kfs.gl.businessobject.Transaction, org.kuali.kfs.gl.businessobject.PosterOutputSummaryAmountHolder)
054 */
055 public void addAmountToAmountHolder(Transaction transaction, PosterOutputSummaryAmountHolder amountHolder) {
056 final String debitCreditCode = transaction.getTransactionDebitCreditCode();
057 final KualiDecimal amount = transaction.getTransactionLedgerEntryAmount();
058 final String objectTypeCode = transaction.getFinancialObjectTypeCode();
059
060 amountHolder.addAmount(debitCreditCode, objectTypeCode, amount);
061 }
062
063 /**
064 * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#getEntryComparator()
065 */
066 public Comparator<PosterOutputSummaryEntry> getEntryComparator() {
067 return new Comparator<PosterOutputSummaryEntry>() {
068
069 /**
070 * Compares the first PosterOutputSummaryEntry given to the second, based on - in order - balance type code,
071 * university fiscal year, fiscal period code, and finally fund group
072 * @param vladimir the first PosterOutputSummaryEntry to compare
073 * @param estragon the second PosterOutputSummaryEntry to compare
074 * @return the standard result of a compare operation: 0 if there's equality, less than 0 if vladimir is "less" than estragon, and more than 0 if vladimir is "greater" than estragon
075 */
076 public int compare(PosterOutputSummaryEntry vladimir, PosterOutputSummaryEntry estragon) {
077 if (shouldCompare(vladimir.getBalanceTypeCode(), estragon.getBalanceTypeCode())) {
078 return vladimir.getBalanceTypeCode().toUpperCase().compareTo(estragon.getBalanceTypeCode().toUpperCase());
079 } else if (shouldCompare(vladimir.getUniversityFiscalYear(), estragon.getUniversityFiscalYear())) {
080 return vladimir.getUniversityFiscalYear().compareTo(estragon.getUniversityFiscalYear());
081 } else if (shouldCompare(vladimir.getFiscalPeriodCode(), estragon.getFiscalPeriodCode())) {
082 return vladimir.getFiscalPeriodCode().toUpperCase().compareTo(estragon.getFiscalPeriodCode().toUpperCase());
083 } else if (shouldCompare(vladimir.getFundGroup(), estragon.getFundGroup())) {
084 return vladimir.getFundGroup().toUpperCase().compareTo(estragon.getFundGroup().toUpperCase());
085 } else {
086 return 0;
087 }
088 }
089
090 /**
091 * Determines if it's safe to compare two Strings
092 * @param s1 the first String we may compare
093 * @param s2 the second String we may compare
094 * @return true if comparison of these two Strings would be meaningful
095 */
096 protected boolean shouldCompare(String s1, String s2) {
097 return !StringUtils.isBlank(s1) && !StringUtils.isBlank(s2) && !s1.equalsIgnoreCase(s2);
098 }
099
100 /**
101 * Determine if it's safe to compare two Integers
102 * @param i1 the first Integer we may compare
103 * @param i2 the second Integer we may compare
104 * @return true if comparison of the two Integers would be meaningful
105 */
106 protected boolean shouldCompare(Integer i1, Integer i2) {
107 return i1 != null && i2 != null && !i1.equals(i2);
108 }
109 };
110 }
111
112 /**
113 * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#getPosterOutputSummaryEntryMapKey(org.kuali.kfs.gl.businessobject.OriginEntryInformation)
114 */
115 protected String getPosterOutputSummaryEntryMapKey(OriginEntryInformation originEntry) {
116 return buildKey(originEntry.getFinancialBalanceTypeCode(), originEntry.getUniversityFiscalYear(), originEntry.getUniversityFiscalPeriodCode(), originEntry.getChartOfAccountsCode(), originEntry.getAccountNumber());
117 }
118
119 /**
120 * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#getPosterOutputSummaryEntryMapKey(org.kuali.kfs.gl.businessobject.Transaction)
121 */
122 protected String getPosterOutputSummaryEntryMapKey(Transaction transaction) {
123 return buildKey(transaction.getFinancialBalanceTypeCode(), transaction.getUniversityFiscalYear(), transaction.getUniversityFiscalPeriodCode(), transaction.getChartOfAccountsCode(), transaction.getAccountNumber());
124 }
125
126 /**
127 * Builds a map key based on the given information
128 * @param balanceTypeCode the balance type code to put in the key
129 * @param universityFiscalYear the fiscal year to put in the key
130 * @param fiscalPeriodCode the period code to put in the key
131 * @param subFundGroupCode the sub fund group code to put in the key
132 * @return a key build from the various attributes
133 */
134 protected String buildKey(String balanceTypeCode, Integer universityFiscalYear, String fiscalPeriodCode, String chartOfAccountsCode, String accountNumber) {
135 return StringUtils.join(new String[] {balanceTypeCode, universityFiscalYear == null ? "" : universityFiscalYear.toString(), fiscalPeriodCode, getFundGroupCodeForAccount(chartOfAccountsCode, accountNumber)}, ':');
136 }
137
138 /**
139 * Returns the sub fund group for the given origin entry
140 * @param originEntry the origin entry to find the sub fund group for, from its account
141 * @return the sub fund group code related to the account used by this origin entry
142 */
143 protected String getFundGroupCodeForAccount(String chartOfAccountsCode, String accountNumber) {
144 final Account account = this.getAccountingCycleCachingService().getAccount(chartOfAccountsCode, accountNumber);
145 if (account != null) {
146 final SubFundGroup subFundGroup = this.getAccountingCycleCachingService().getSubFundGroup(account.getSubFundGroupCode());
147 if (subFundGroup != null) {
148 return subFundGroup.getFundGroupCode();
149 }
150 }
151 return "";
152 }
153
154 /**
155 * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#summarizeOriginEntry(org.kuali.kfs.gl.businessobject.OriginEntryInformation, java.util.Map)
156 */
157 public void summarize(OriginEntryInformation originEntry, Map<String, PosterOutputSummaryEntry> entries) {
158 final String key = getPosterOutputSummaryEntryMapKey(originEntry);
159 PosterOutputSummaryEntry entry = entries.get(key);
160 if (entry == null) {
161 entry = new PosterOutputSummaryEntry(originEntry.getFinancialBalanceTypeCode(), originEntry.getUniversityFiscalYear(), originEntry.getUniversityFiscalPeriodCode(), getFundGroupCodeForAccount(originEntry.getChartOfAccountsCode(), originEntry.getAccountNumber()));
162 entries.put(key, entry);
163 }
164 addAmountToAmountHolder(originEntry, entry);
165 }
166
167 /**
168 * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#summarizeTransaction(org.kuali.kfs.gl.businessobject.Transaction, java.util.Map)
169 */
170 public void summarize(Transaction transaction, Map<String, PosterOutputSummaryEntry> entries) {
171 final String key = getPosterOutputSummaryEntryMapKey(transaction);
172 PosterOutputSummaryEntry entry = entries.get(key);
173 if (entry == null) {
174 entry = new PosterOutputSummaryEntry(transaction.getFinancialBalanceTypeCode(), transaction.getUniversityFiscalYear(), transaction.getUniversityFiscalPeriodCode(), getFundGroupCodeForAccount(transaction.getChartOfAccountsCode(), transaction.getAccountNumber()));
175 entries.put(key, entry);
176 }
177 addAmountToAmountHolder(transaction, entry);
178 }
179
180 /**
181 * Gets the accountingCycleCachingService attribute.
182 * @return Returns the accountingCycleCachingService.
183 */
184 public AccountingCycleCachingService getAccountingCycleCachingService() {
185 return accountingCycleCachingService;
186 }
187
188 /**
189 * Sets the accountingCycleCachingService attribute value.
190 * @param accountingCycleCachingService The accountingCycleCachingService to set.
191 */
192 public void setAccountingCycleCachingService(AccountingCycleCachingService accountingCycleCachingService) {
193 this.accountingCycleCachingService = accountingCycleCachingService;
194 }
195 }