View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.gl.service.impl;
20  
21  import java.util.Comparator;
22  import java.util.Map;
23  
24  import org.apache.commons.lang.StringUtils;
25  import org.kuali.kfs.coa.businessobject.Account;
26  import org.kuali.kfs.coa.businessobject.SubFundGroup;
27  import org.kuali.kfs.gl.batch.service.AccountingCycleCachingService;
28  import org.kuali.kfs.gl.businessobject.OriginEntryInformation;
29  import org.kuali.kfs.gl.businessobject.PosterOutputSummaryAmountHolder;
30  import org.kuali.kfs.gl.businessobject.PosterOutputSummaryEntry;
31  import org.kuali.kfs.gl.businessobject.Transaction;
32  import org.kuali.kfs.gl.service.PosterOutputSummaryService;
33  import org.kuali.rice.core.api.util.type.KualiDecimal;
34  
35  /**
36   * The default implementation of the PosterOutputSummaryService
37   */
38  public class PosterOutputSummaryServiceImpl implements PosterOutputSummaryService {
39      private AccountingCycleCachingService accountingCycleCachingService;
40  
41      /**
42       * Default implementation
43       * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#addOriginEntryAmountToAmountHolder(org.kuali.kfs.gl.businessobject.OriginEntryInformation, org.kuali.kfs.gl.businessobject.PosterOutputSummaryAmountHolder)
44       */
45      public void addAmountToAmountHolder(OriginEntryInformation originEntry, PosterOutputSummaryAmountHolder amountHolder) {
46          final String debitCreditCode = originEntry.getTransactionDebitCreditCode();
47          final KualiDecimal amount = originEntry.getTransactionLedgerEntryAmount();
48          final String objectTypeCode = originEntry.getFinancialObjectTypeCode();
49          
50          amountHolder.addAmount(debitCreditCode, objectTypeCode, amount);
51      }
52  
53      /**
54       * Default implementation
55       * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#addTransactionAmountToAmountHolder(org.kuali.kfs.gl.businessobject.Transaction, org.kuali.kfs.gl.businessobject.PosterOutputSummaryAmountHolder)
56       */
57      public void addAmountToAmountHolder(Transaction transaction, PosterOutputSummaryAmountHolder amountHolder) {
58          final String debitCreditCode = transaction.getTransactionDebitCreditCode();
59          final KualiDecimal amount = transaction.getTransactionLedgerEntryAmount();
60          final String objectTypeCode = transaction.getFinancialObjectTypeCode();
61  
62          amountHolder.addAmount(debitCreditCode, objectTypeCode, amount);
63      }
64  
65      /**
66       * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#getEntryComparator()
67       */
68      public Comparator<PosterOutputSummaryEntry> getEntryComparator() {
69          return new Comparator<PosterOutputSummaryEntry>() {
70              
71              /**
72               * Compares the first PosterOutputSummaryEntry given to the second, based on - in order - balance type code,
73               * university fiscal year, fiscal period code, and finally fund group
74               * @param vladimir the first PosterOutputSummaryEntry to compare
75               * @param estragon the second PosterOutputSummaryEntry to compare
76               * @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
77               */
78              public int compare(PosterOutputSummaryEntry vladimir, PosterOutputSummaryEntry estragon) {
79                  if (shouldCompare(vladimir.getBalanceTypeCode(), estragon.getBalanceTypeCode())) {
80                      return vladimir.getBalanceTypeCode().toUpperCase().compareTo(estragon.getBalanceTypeCode().toUpperCase());
81                  } else if (shouldCompare(vladimir.getUniversityFiscalYear(), estragon.getUniversityFiscalYear())) {
82                      return vladimir.getUniversityFiscalYear().compareTo(estragon.getUniversityFiscalYear());
83                  } else if (shouldCompare(vladimir.getFiscalPeriodCode(), estragon.getFiscalPeriodCode())) {
84                      return vladimir.getFiscalPeriodCode().toUpperCase().compareTo(estragon.getFiscalPeriodCode().toUpperCase());
85                  } else if (shouldCompare(vladimir.getFundGroup(), estragon.getFundGroup())) {
86                      return vladimir.getFundGroup().toUpperCase().compareTo(estragon.getFundGroup().toUpperCase());
87                  } else {
88                      return 0;
89                  }
90              }
91              
92              /**
93               * Determines if it's safe to compare two Strings
94               * @param s1 the first String we may compare
95               * @param s2 the second String we may compare
96               * @return true if comparison of these two Strings would be meaningful
97               */
98              protected boolean shouldCompare(String s1, String s2) {
99                  return !StringUtils.isBlank(s1) && !StringUtils.isBlank(s2) && !s1.equalsIgnoreCase(s2);
100             }
101             
102             /**
103              * Determine if it's safe to compare two Integers
104              * @param i1 the first Integer we may compare
105              * @param i2 the second Integer we may compare
106              * @return true if comparison of the two Integers would be meaningful
107              */
108             protected boolean shouldCompare(Integer i1, Integer i2) {
109                 return i1 != null && i2 != null && !i1.equals(i2);
110             }
111         };
112     }
113 
114     /**
115      * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#getPosterOutputSummaryEntryMapKey(org.kuali.kfs.gl.businessobject.OriginEntryInformation)
116      */
117     protected String getPosterOutputSummaryEntryMapKey(OriginEntryInformation originEntry) {
118         return buildKey(originEntry.getFinancialBalanceTypeCode(), originEntry.getUniversityFiscalYear(), originEntry.getUniversityFiscalPeriodCode(), originEntry.getChartOfAccountsCode(), originEntry.getAccountNumber());
119     }
120 
121     /**
122      * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#getPosterOutputSummaryEntryMapKey(org.kuali.kfs.gl.businessobject.Transaction)
123      */
124     protected String getPosterOutputSummaryEntryMapKey(Transaction transaction) {
125         return buildKey(transaction.getFinancialBalanceTypeCode(), transaction.getUniversityFiscalYear(), transaction.getUniversityFiscalPeriodCode(), transaction.getChartOfAccountsCode(), transaction.getAccountNumber());
126     }
127 
128     /**
129      * Builds a map key based on the given information
130      * @param balanceTypeCode the balance type code to put in the key
131      * @param universityFiscalYear the fiscal year to put in the key
132      * @param fiscalPeriodCode the period code to put in the key
133      * @param subFundGroupCode the sub fund group code to put in the key
134      * @return a key build from the various attributes
135      */
136     protected String buildKey(String balanceTypeCode, Integer universityFiscalYear, String fiscalPeriodCode, String chartOfAccountsCode, String accountNumber) {
137         return StringUtils.join(new String[] {balanceTypeCode, universityFiscalYear == null ? "" : universityFiscalYear.toString(), fiscalPeriodCode, getFundGroupCodeForAccount(chartOfAccountsCode, accountNumber)}, ':');
138     }
139     
140     /**
141      * Returns the sub fund group for the given origin entry
142      * @param originEntry the origin entry to find the sub fund group for, from its account
143      * @return the sub fund group code related to the account used by this origin entry
144      */
145     protected String getFundGroupCodeForAccount(String chartOfAccountsCode, String accountNumber) {
146         final Account account = this.getAccountingCycleCachingService().getAccount(chartOfAccountsCode, accountNumber);
147         if (account != null) {
148             final SubFundGroup subFundGroup = this.getAccountingCycleCachingService().getSubFundGroup(account.getSubFundGroupCode());
149             if (subFundGroup != null) {
150                 return subFundGroup.getFundGroupCode();
151             }
152         }
153         return "";
154     }
155 
156     /**
157      * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#summarizeOriginEntry(org.kuali.kfs.gl.businessobject.OriginEntryInformation, java.util.Map)
158      */
159     public void summarize(OriginEntryInformation originEntry, Map<String, PosterOutputSummaryEntry> entries) {
160         final String key = getPosterOutputSummaryEntryMapKey(originEntry);
161         PosterOutputSummaryEntry entry = entries.get(key);
162         if (entry == null) {
163             entry = new PosterOutputSummaryEntry(originEntry.getFinancialBalanceTypeCode(), originEntry.getUniversityFiscalYear(), originEntry.getUniversityFiscalPeriodCode(), getFundGroupCodeForAccount(originEntry.getChartOfAccountsCode(), originEntry.getAccountNumber()));
164             entries.put(key, entry);
165         }
166         addAmountToAmountHolder(originEntry, entry);
167     }
168 
169     /**
170      * @see org.kuali.kfs.gl.service.PosterOutputSummaryService#summarizeTransaction(org.kuali.kfs.gl.businessobject.Transaction, java.util.Map)
171      */
172     public void summarize(Transaction transaction, Map<String, PosterOutputSummaryEntry> entries) {
173         final String key = getPosterOutputSummaryEntryMapKey(transaction);
174         PosterOutputSummaryEntry entry = entries.get(key);
175         if (entry == null) {
176             entry = new PosterOutputSummaryEntry(transaction.getFinancialBalanceTypeCode(), transaction.getUniversityFiscalYear(), transaction.getUniversityFiscalPeriodCode(), getFundGroupCodeForAccount(transaction.getChartOfAccountsCode(), transaction.getAccountNumber()));
177             entries.put(key, entry);
178         }
179         addAmountToAmountHolder(transaction, entry);
180     }
181 
182     /**
183      * Gets the accountingCycleCachingService attribute. 
184      * @return Returns the accountingCycleCachingService.
185      */
186     public AccountingCycleCachingService getAccountingCycleCachingService() {
187         return accountingCycleCachingService;
188     }
189 
190     /**
191      * Sets the accountingCycleCachingService attribute value.
192      * @param accountingCycleCachingService The accountingCycleCachingService to set.
193      */
194     public void setAccountingCycleCachingService(AccountingCycleCachingService accountingCycleCachingService) {
195         this.accountingCycleCachingService = accountingCycleCachingService;
196     }
197 }