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