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.report;
017
018 import java.util.ArrayList;
019 import java.util.Collections;
020 import java.util.LinkedHashMap;
021 import java.util.List;
022 import java.util.Map;
023
024 import org.apache.commons.lang.StringUtils;
025 import org.kuali.kfs.gl.businessobject.LedgerBalanceTypeSummaryTotalLine;
026 import org.kuali.kfs.gl.businessobject.LedgerSummaryDetailLine;
027 import org.kuali.kfs.gl.businessobject.LedgerSummaryTotalLine;
028 import org.kuali.kfs.gl.businessobject.OriginEntryInformation;
029 import org.kuali.kfs.sys.DynamicCollectionComparator;
030 import org.kuali.kfs.sys.KFSConstants;
031 import org.kuali.kfs.sys.service.ReportWriterService;
032
033 /**
034 * Helper class which can summarize entries by balance type and then print out a ledger summary report
035 */
036 public class LedgerSummaryReport {
037 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LedgerSummaryReport.class);
038
039 private LedgerSummaryTotalLine ledgerTotalLine;
040 private Map<String, LedgerBalanceTypeSummaryTotalLine> balanceTypeTotals;
041 Map<String, LedgerSummaryDetailLine> details;
042
043 /**
044 * Constructs a LedgerSummaryReport
045 */
046 public LedgerSummaryReport() {
047 ledgerTotalLine = new LedgerSummaryTotalLine();
048 balanceTypeTotals = new LinkedHashMap<String, LedgerBalanceTypeSummaryTotalLine>();
049 details = new LinkedHashMap<String, LedgerSummaryDetailLine>();
050 }
051
052 /**
053 * Summarizes an entry into the various totals which this report is keeping
054 * @param entry an entry to summarize
055 */
056 public void summarizeEntry(OriginEntryInformation entry) {
057 LedgerBalanceTypeSummaryTotalLine balanceTypeTotal = getBalanceTypeSummaryTotalLine(entry, balanceTypeTotals);
058 LedgerSummaryDetailLine detailLine = getDetailLine(entry, details);
059 addEntryToLedgerSummaries(entry, ledgerTotalLine, balanceTypeTotal, detailLine);
060 }
061
062 /**
063 * Retrieves the proper balance type summarizer from the given map, or creates a new summarizer and puts it in the Map if it doesn't already exist
064 * @param entry the origin entry to find a balance type summarizer for
065 * @param balanceTypeTotals the Map of balance type summarizers
066 * @return the proper balance type summarizer
067 */
068 protected LedgerBalanceTypeSummaryTotalLine getBalanceTypeSummaryTotalLine(OriginEntryInformation entry, Map<String, LedgerBalanceTypeSummaryTotalLine> balanceTypeTotals) {
069 final String balanceTypeCode = (StringUtils.isBlank(entry.getFinancialBalanceTypeCode())) ? " " : entry.getFinancialBalanceTypeCode();
070 LedgerBalanceTypeSummaryTotalLine balanceTypeTotal = balanceTypeTotals.get(balanceTypeCode);
071 if (balanceTypeTotal == null) {
072 balanceTypeTotal = new LedgerBalanceTypeSummaryTotalLine(balanceTypeCode);
073 balanceTypeTotals.put(balanceTypeCode, balanceTypeTotal);
074 }
075 return balanceTypeTotal;
076 }
077
078 /**
079 * Retrieves the proper detail line summarizer from the given map, or creates a new summarizer and adds it to the map if needed
080 * @param entry the origin entry to find a detail line summarizer for
081 * @param detailLines a Map of detail line summarizers
082 * @return the proper detail line summarizer
083 */
084 protected LedgerSummaryDetailLine getDetailLine(OriginEntryInformation entry, Map<String, LedgerSummaryDetailLine> detailLines) {
085 final String key = LedgerSummaryDetailLine.getKeyString(entry);
086 LedgerSummaryDetailLine detailLine = detailLines.get(key);
087 if (detailLine == null) {
088 detailLine = new LedgerSummaryDetailLine(entry.getFinancialBalanceTypeCode(), entry.getFinancialSystemOriginationCode(), entry.getUniversityFiscalYear(), entry.getUniversityFiscalPeriodCode());
089 detailLines.put(detailLine.getKey(), detailLine);
090 }
091 return detailLine;
092 }
093
094 /**
095 * Adds the amount of the origin entry into the appropriate total - debit, credit, or budget - on the various ledger summarizers
096 * @param originEntry the origin entry to add the total from
097 * @param totalLine a complete total to add the amount to
098 * @param balanceTypeTotal the total for the entries with the same balance type as the origin entry to add the amount to
099 * @param detailLine the proper detail amount to add the amoun tto
100 */
101 protected void addEntryToLedgerSummaries(OriginEntryInformation originEntry, LedgerSummaryTotalLine totalLine, LedgerBalanceTypeSummaryTotalLine balanceTypeTotal, LedgerSummaryDetailLine detailLine) {
102 if (originEntry.getTransactionDebitCreditCode() != null && originEntry.getTransactionDebitCreditCode().equals(KFSConstants.GL_DEBIT_CODE)) {
103 totalLine.addDebitAmount(originEntry.getTransactionLedgerEntryAmount());
104 balanceTypeTotal.addDebitAmount(originEntry.getTransactionLedgerEntryAmount());
105 detailLine.addDebitAmount(originEntry.getTransactionLedgerEntryAmount());
106 } else if (originEntry.getTransactionDebitCreditCode() != null && originEntry.getTransactionDebitCreditCode().equals(KFSConstants.GL_CREDIT_CODE)) {
107 totalLine.addCreditAmount(originEntry.getTransactionLedgerEntryAmount());
108 balanceTypeTotal.addCreditAmount(originEntry.getTransactionLedgerEntryAmount());
109 detailLine.addCreditAmount(originEntry.getTransactionLedgerEntryAmount());
110 } else{
111 totalLine.addBudgetAmount(originEntry.getTransactionLedgerEntryAmount());
112 balanceTypeTotal.addBudgetAmount(originEntry.getTransactionLedgerEntryAmount());
113 detailLine.addBudgetAmount(originEntry.getTransactionLedgerEntryAmount());
114 }
115 }
116
117 /**
118 * Writes the report of totals to the given reportWriterService
119 * @param reportWriterService a report writer service to write the ledger summary report to
120 */
121 public void writeReport(ReportWriterService reportWriterService) {
122 if (details.size() > 0) {
123 List<LedgerSummaryDetailLine> detailList = new ArrayList<LedgerSummaryDetailLine>(details.values());
124 DynamicCollectionComparator.sort(detailList, LedgerSummaryDetailLine.keyFields);
125
126 reportWriterService.writeTableHeader(detailList.get(0));
127 String currentBalanceType = detailList.get(0).getFinancialBalanceTypeCode();
128 currentBalanceType = StringUtils.isBlank(currentBalanceType) ? " " : currentBalanceType;
129
130 for (LedgerSummaryDetailLine detailLine : detailList) {
131 String detailLineBalanceType = (StringUtils.isBlank(detailLine.getFinancialBalanceTypeCode())) ? " " : detailLine.getFinancialBalanceTypeCode();
132 if (!detailLineBalanceType.equals(currentBalanceType)) {
133 LedgerBalanceTypeSummaryTotalLine subTitleLine = balanceTypeTotals.get(currentBalanceType);
134
135 if (subTitleLine != null) {
136 reportWriterService.writeTableRow(subTitleLine);
137 reportWriterService.writeTableRowSeparationLine(subTitleLine);
138 }
139 currentBalanceType = detailLineBalanceType;
140 }
141
142 reportWriterService.writeTableRow(detailLine);
143 }
144 final LedgerBalanceTypeSummaryTotalLine lastLine = balanceTypeTotals.get(detailList.get(detailList.size()-1).getFinancialBalanceTypeCode());
145 if (lastLine != null) {
146 reportWriterService.writeTableRow(lastLine);
147 }
148
149 reportWriterService.writeTableRowSeparationLine(ledgerTotalLine);
150 reportWriterService.writeTableRow(ledgerTotalLine);
151 }
152 }
153
154 }