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 }