001: /*
002: * Copyright 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.gl.util;
017:
018: import java.util.Collections;
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.LinkedHashMap;
022: import java.util.List;
023: import java.util.Map;
024: import java.util.Set;
025: import java.util.SortedMap;
026: import java.util.TreeMap;
027: import java.util.TreeSet;
028:
029: import org.kuali.core.util.ErrorMap;
030: import org.kuali.module.gl.batch.collector.CollectorBatch;
031: import org.kuali.module.gl.bo.CollectorDetail;
032: import org.kuali.module.gl.bo.Transaction;
033: import org.kuali.module.gl.service.impl.scrubber.DemergerReportData;
034: import org.kuali.module.gl.service.impl.scrubber.ScrubberReportData;
035:
036: /**
037: * This class aggregates all of the status information together from all of the collector-related processes. Note: this code assumes
038: * that each batch is identified by a different collector batch name.
039: */
040: public class CollectorReportData {
041: private Map<String, String> emailSendingStatus;
042:
043: private Set<String> unparsableBatchNames;
044: private Map<String, List<Message>> validationErrorsForBatchName;
045: private Map<String, OriginEntryTotals> collectorFileTotals;
046: private Map<String, CollectorBatch> addedBatches;
047: private Map<String, Map<CollectorDetail, List<Message>>> detailScrubberErrors;
048: private Map<String, Map<Transaction, List<Message>>> originEntryScrubberErrors;
049: private Map<String, ScrubberReportData> scrubberReportDataForBatchName;
050: private Map<String, DemergerReportData> demergerReportDataForBatchName;
051: private Map<String, Integer> numDetailAccountValuesChangedForBatchName;
052:
053: private Map<String, Integer> numDetailDeletedForBatchName;
054: private Map<String, Map<DocumentGroupData, OriginEntryTotals>> totalsOnInputOriginEntriesAssociatedWithErrorGroupForBatchName;
055: private Map<String, Integer> numInputDetailsForBatchName;
056: private Map<String, Integer> numSavedDetailsForBatchName;
057: private SortedMap<String, ErrorMap> errorsForBatchName;
058: private Map<String, Boolean> validationStatuses;
059:
060: private LedgerEntryHolder ledgerEntryHolder;
061:
062: private int numPersistedBatches;
063: private int numNotPersistedBatches;
064:
065: public CollectorReportData() {
066: emailSendingStatus = new HashMap<String, String>();
067: unparsableBatchNames = new TreeSet<String>();
068: validationErrorsForBatchName = new HashMap<String, List<Message>>();
069: collectorFileTotals = new HashMap<String, OriginEntryTotals>();
070: addedBatches = new LinkedHashMap<String, CollectorBatch>();
071: detailScrubberErrors = new HashMap<String, Map<CollectorDetail, List<Message>>>();
072: originEntryScrubberErrors = new HashMap<String, Map<Transaction, List<Message>>>();
073: scrubberReportDataForBatchName = new HashMap<String, ScrubberReportData>();
074: demergerReportDataForBatchName = new HashMap<String, DemergerReportData>();
075: numDetailAccountValuesChangedForBatchName = new HashMap<String, Integer>();
076: numDetailDeletedForBatchName = new HashMap<String, Integer>();
077: totalsOnInputOriginEntriesAssociatedWithErrorGroupForBatchName = new HashMap<String, Map<DocumentGroupData, OriginEntryTotals>>();
078: ledgerEntryHolder = null;
079: numInputDetailsForBatchName = new HashMap<String, Integer>();
080: numSavedDetailsForBatchName = new HashMap<String, Integer>();
081: errorsForBatchName = new TreeMap<String, ErrorMap>();
082: validationStatuses = new HashMap<String, Boolean>();
083:
084: numPersistedBatches = 0;
085: numNotPersistedBatches = 0;
086: }
087:
088: /**
089: * Adds a batch to this report data object. If the batch (identified using batch.getBatchName()) has already been added, then an
090: * exception is thrown.
091: *
092: * @param batch collector batch from xml input
093: */
094: public void addBatch(CollectorBatch batch) {
095: if (isBatchAdded(batch)) {
096: throw new RuntimeException("Can't add a batch twice");
097: }
098: addedBatches.put(batch.getBatchName(), batch);
099: }
100:
101: /**
102: * Returns whether a batch has already been added
103: *
104: * @param batch collector batch from xml input
105: * @return true if batch has already been added
106: */
107: public boolean isBatchAdded(CollectorBatch batch) {
108: return addedBatches.containsKey(batch.getBatchName());
109: }
110:
111: /**
112: * Returns the number of batches that have been added using the {@link #addBatch(CollectorBatch)} method
113: *
114: * @return number of added batches
115: */
116: public int getNumberOfAddedBatches() {
117: return addedBatches.size();
118: }
119:
120: /**
121: * Throws exception if batch has not been added
122: *
123: * @param batch
124: */
125: protected void throwExceptionIfBatchNotAdded(CollectorBatch batch) {
126: if (!isBatchAdded(batch)) {
127: throw new RuntimeException("Batch must be added first");
128: }
129: }
130:
131: /**
132: * Stores the errors encountered trying to scrub the InterDepartmentalBilling records in the given batch. This method must be
133: * called after addBatch has been called with the same batch. Previously saved errors for this batch will be overwritten.
134: *
135: * @param batch collector batch from input xml
136: * @param errorsMap contains a map of all errors encountered while trying to scrub InterDepartmentalBilling records
137: */
138: public void setBatchDetailScrubberErrors(CollectorBatch batch,
139: Map<CollectorDetail, List<Message>> errorsMap) {
140: throwExceptionIfBatchNotAdded(batch);
141:
142: detailScrubberErrors.put(batch.getBatchName(), errorsMap);
143: }
144:
145: /**
146: * Stores the errors encountered trying to scrub the InterDepartmentalBilling records in the given batch. This method must be
147: * called after addBatch has been called with the same batch. Previously saved errors for this batch will be overwritten.
148: *
149: * @param batch collector batch from input xml
150: * @param errorsMap
151: */
152: public void setBatchOriginEntryScrubberErrors(CollectorBatch batch,
153: Map<Transaction, List<Message>> errorsMap) {
154: throwExceptionIfBatchNotAdded(batch);
155:
156: originEntryScrubberErrors.put(batch.getBatchName(), errorsMap);
157: }
158:
159: /**
160: * Returns the scrubber errors related to a batch
161: *
162: * @param batch collector batch from input xml
163: * @return Map returns a map containing a list of error messages for each transaction
164: */
165: public Map<Transaction, List<Message>> getBatchOriginEntryScrubberErrors(
166: CollectorBatch batch) {
167: throwExceptionIfBatchNotAdded(batch);
168:
169: return originEntryScrubberErrors.get(batch.getBatchName());
170: }
171:
172: public void setScrubberReportData(CollectorBatch batch,
173: ScrubberReportData scrubberReportData) {
174: throwExceptionIfBatchNotAdded(batch);
175:
176: scrubberReportDataForBatchName.put(batch.getBatchName(),
177: scrubberReportData);
178: }
179:
180: public ScrubberReportData getScrubberReportData(CollectorBatch batch) {
181: throwExceptionIfBatchNotAdded(batch);
182:
183: return scrubberReportDataForBatchName.get(batch.getBatchName());
184: }
185:
186: public void setDemergerReportData(CollectorBatch batch,
187: DemergerReportData demergerReportData) {
188: throwExceptionIfBatchNotAdded(batch);
189:
190: demergerReportDataForBatchName.put(batch.getBatchName(),
191: demergerReportData);
192: }
193:
194: public DemergerReportData getDemergerReportData(CollectorBatch batch) {
195: throwExceptionIfBatchNotAdded(batch);
196:
197: return demergerReportDataForBatchName.get(batch.getBatchName());
198: }
199:
200: public void markUnparsableBatchNames(String batchName) {
201: unparsableBatchNames.add(batchName);
202: }
203:
204: public Set<String> getAllUnparsableBatchNames() {
205: return Collections.unmodifiableSet(unparsableBatchNames);
206: }
207:
208: public void setEmailSendingStatusForParsedBatch(
209: CollectorBatch batch, String emailStatus) {
210: throwExceptionIfBatchNotAdded(batch);
211:
212: emailSendingStatus.put(batch.getBatchName(), emailStatus);
213: }
214:
215: public Iterator<CollectorBatch> getAddedBatches() {
216: return addedBatches.values().iterator();
217: }
218:
219: public void setOriginEntryTotals(CollectorBatch batch,
220: OriginEntryTotals totals) {
221: throwExceptionIfBatchNotAdded(batch);
222:
223: collectorFileTotals.put(batch.getBatchName(), totals);
224: }
225:
226: public OriginEntryTotals getOriginEntryTotals(CollectorBatch batch) {
227: throwExceptionIfBatchNotAdded(batch);
228:
229: return collectorFileTotals.get(batch.getBatchName());
230: }
231:
232: /**
233: * Sets the number of times the details in a batch have had their account numbers changed
234: *
235: * @param batch collector batch from input xml
236: */
237: public void setNumDetailAccountValuesChanged(CollectorBatch batch,
238: Integer numDetailAccountValuesChanged) {
239: throwExceptionIfBatchNotAdded(batch);
240:
241: numDetailAccountValuesChangedForBatchName.put(batch
242: .getBatchName(), numDetailAccountValuesChanged);
243: }
244:
245: public Integer getNumDetailAccountValuesChanged(CollectorBatch batch) {
246: throwExceptionIfBatchNotAdded(batch);
247:
248: return numDetailAccountValuesChangedForBatchName.get(batch
249: .getBatchName());
250: }
251:
252: public void setNumDetailDeleted(CollectorBatch batch,
253: Integer numDetailDeleted) {
254: throwExceptionIfBatchNotAdded(batch);
255:
256: numDetailDeletedForBatchName.put(batch.getBatchName(),
257: numDetailDeleted);
258: }
259:
260: public Integer getNumDetailDeleted(CollectorBatch batch) {
261: throwExceptionIfBatchNotAdded(batch);
262:
263: return numDetailDeletedForBatchName.get(batch.getBatchName());
264: }
265:
266: /**
267: * Stores the totals or all origin entries in the input group that match the document group (doc #, doc type, origination code)
268: * of at least one origin entry in the error group, which is generated by the scrubber
269: *
270: * @param batch collector batch from input xml
271: * @param totals a map such that the key is a document group (doc #, doc type, origination code) and the value is the totals of
272: * the origin entry of all those
273: */
274: public void setTotalsOnInputOriginEntriesAssociatedWithErrorGroup(
275: CollectorBatch batch,
276: Map<DocumentGroupData, OriginEntryTotals> totals) {
277: throwExceptionIfBatchNotAdded(batch);
278:
279: totalsOnInputOriginEntriesAssociatedWithErrorGroupForBatchName
280: .put(batch.getBatchName(), totals);
281: }
282:
283: /**
284: * Returns the totals or all origin entries in the input group that match the document group (doc #, doc type, origination code)
285: * of at least one origin entry in the error group, which is generated by the scrubber
286: *
287: * @param batch return a map such that the key is a document group (doc #, doc type, origination code) and the value is the
288: * totals of the origin entry of all those
289: */
290: public Map<DocumentGroupData, OriginEntryTotals> getTotalsOnInputOriginEntriesAssociatedWithErrorGroup(
291: CollectorBatch batch) {
292: throwExceptionIfBatchNotAdded(batch);
293:
294: return totalsOnInputOriginEntriesAssociatedWithErrorGroupForBatchName
295: .get(batch.getBatchName());
296: }
297:
298: /**
299: * Gets the ledgerEntryHolder attribute.
300: *
301: * @return Returns the ledgerEntryHolder.
302: */
303: public LedgerEntryHolder getLedgerEntryHolder() {
304: return ledgerEntryHolder;
305: }
306:
307: /**
308: * Sets the ledgerEntryHolder attribute value.
309: *
310: * @param ledgerEntryHolder The ledgerEntryHolder to set.
311: */
312: public void setLedgerEntryHolder(LedgerEntryHolder ledgerEntryHolder) {
313: this .ledgerEntryHolder = ledgerEntryHolder;
314: }
315:
316: public void setNumInputDetails(CollectorBatch batch) {
317: throwExceptionIfBatchNotAdded(batch);
318:
319: numInputDetailsForBatchName.put(batch.getBatchName(), batch
320: .getCollectorDetails().size());
321: }
322:
323: public Integer getNumInputDetails(CollectorBatch batch) {
324: throwExceptionIfBatchNotAdded(batch);
325:
326: return numInputDetailsForBatchName.get(batch.getBatchName());
327: }
328:
329: public void setNumSavedDetails(CollectorBatch batch,
330: Integer numSavedDetails) {
331: throwExceptionIfBatchNotAdded(batch);
332:
333: numSavedDetailsForBatchName.put(batch.getBatchName(),
334: numSavedDetails);
335: }
336:
337: public Integer getNumSavedDetails(CollectorBatch batch) {
338: throwExceptionIfBatchNotAdded(batch);
339:
340: return numSavedDetailsForBatchName.get(batch.getBatchName());
341: }
342:
343: /**
344: * Retrieves an error map instance for a batch name (typically the file name of the batch file). Each instance of this class
345: * guarantees that each time this method is called with specific batch name, the same error map instance is returned, and that
346: * each that no 2 different batch names will return the same instance
347: *
348: * @param batchName a batch name
349: * @return a error map instance specific to this batch name
350: */
351: public ErrorMap getErrorMapForBatchName(String batchName) {
352: ErrorMap errorMap = errorsForBatchName.get(batchName);
353: if (errorMap == null) {
354: errorMap = new ErrorMap();
355: errorsForBatchName.put(batchName, errorMap);
356: }
357: return errorMap;
358: }
359:
360: /**
361: * Returns a set of batch names that were passed in as parameters into {@link #getErrorMapForBatchName(String)}.
362: *
363: * @return a set of batch names that have an associated error map
364: */
365: public Set<String> getBatchNamesWithErrorMap() {
366: return errorsForBatchName.keySet();
367: }
368:
369: public void incrementNumPersistedBatches() {
370: numPersistedBatches++;
371: }
372:
373: /**
374: * Gets the numPersistedBatches attribute.
375: *
376: * @return Returns the numPersistedBatches.
377: */
378: public int getNumPersistedBatches() {
379: return numPersistedBatches;
380: }
381:
382: public void incrementNumNonPersistedBatches() {
383: numNotPersistedBatches++;
384: }
385:
386: /**
387: * Gets the numNotPersistedBatches attribute.
388: *
389: * @return Returns the numNotPersistedBatches.
390: */
391: public int getNumNotPersistedBatches() {
392: return numNotPersistedBatches;
393: }
394:
395: /**
396: * Marks whether or not a batch is valid or not
397: *
398: * @param batch collector batch from input xml
399: * @param validStatus valid status fro batch
400: */
401: public void markValidationStatus(CollectorBatch batch,
402: boolean validStatus) {
403: throwExceptionIfBatchNotAdded(batch);
404:
405: validationStatuses.put(batch.getBatchName(), new Boolean(
406: validStatus));
407: }
408:
409: /**
410: * Returns true if batch is valid; False if invalid
411: *
412: * @param batch collector batch from input xml
413: * @return true if batch is valid
414: */
415: public boolean isBatchValid(CollectorBatch batch) {
416: throwExceptionIfBatchNotAdded(batch);
417:
418: return (Boolean) validationStatuses.get(batch.getBatchName())
419: .booleanValue();
420: }
421: }
|