Source Code Cross Referenced for CollectorHelperServiceImpl.java in  » ERP-CRM-Financial » Kuali-Financial-System » org » kuali » module » gl » service » impl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » Kuali Financial System » org.kuali.module.gl.service.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.service.impl;
017:
018:        import java.io.FileInputStream;
019:        import java.io.FileNotFoundException;
020:        import java.io.IOException;
021:        import java.io.InputStream;
022:        import java.util.HashSet;
023:        import java.util.List;
024:        import java.util.Set;
025:
026:        import org.apache.commons.io.IOUtils;
027:        import org.apache.commons.lang.StringUtils;
028:        import org.apache.log4j.Logger;
029:        import org.kuali.core.service.BusinessObjectService;
030:        import org.kuali.core.service.DateTimeService;
031:        import org.kuali.core.service.KualiConfigurationService;
032:        import org.kuali.core.service.MailService;
033:        import org.kuali.core.util.ErrorMap;
034:        import org.kuali.core.util.GlobalVariables;
035:        import org.kuali.core.util.KualiDecimal;
036:        import org.kuali.kfs.KFSConstants;
037:        import org.kuali.kfs.KFSKeyConstants;
038:        import org.kuali.kfs.KFSPropertyConstants;
039:        import org.kuali.kfs.KFSConstants.SystemGroupParameterNames;
040:        import org.kuali.kfs.batch.BatchInputFileType;
041:        import org.kuali.kfs.context.SpringContext;
042:        import org.kuali.kfs.exceptions.XMLParseException;
043:        import org.kuali.kfs.service.BatchInputFileService;
044:        import org.kuali.kfs.service.ParameterService;
045:        import org.kuali.module.chart.bo.ObjectType;
046:        import org.kuali.module.chart.bo.codes.BalanceTyp;
047:        import org.kuali.module.gl.batch.collector.CollectorBatch;
048:        import org.kuali.module.gl.batch.collector.CollectorStep;
049:        import org.kuali.module.gl.bo.CollectorDetail;
050:        import org.kuali.module.gl.bo.CollectorHeader;
051:        import org.kuali.module.gl.bo.OriginEntryFull;
052:        import org.kuali.module.gl.bo.OriginEntryGroup;
053:        import org.kuali.module.gl.service.CollectorDetailService;
054:        import org.kuali.module.gl.service.CollectorHelperService;
055:        import org.kuali.module.gl.service.CollectorScrubberService;
056:        import org.kuali.module.gl.service.OriginEntryGroupService;
057:        import org.kuali.module.gl.service.OriginEntryService;
058:        import org.kuali.module.gl.util.CollectorReportData;
059:        import org.kuali.module.gl.util.CollectorScrubberStatus;
060:        import org.kuali.module.gl.util.OriginEntryTotals;
061:
062:        /**
063:         * The base implementation of CollectorHelperService
064:         * @see org.kuali.module.gl.service.CollectorService
065:         */
066:        public class CollectorHelperServiceImpl implements 
067:                CollectorHelperService {
068:            private static Logger LOG = Logger
069:                    .getLogger(CollectorHelperServiceImpl.class);
070:
071:            private static final String CURRENCY_SYMBOL = "$";
072:
073:            private CollectorDetailService collectorDetailService;
074:            private OriginEntryService originEntryService;
075:            private OriginEntryGroupService originEntryGroupService;
076:            private ParameterService parameterService;
077:            private KualiConfigurationService configurationService;
078:            private MailService mailService;
079:            private DateTimeService dateTimeService;
080:            private BatchInputFileService batchInputFileService;
081:            private BatchInputFileType collectorInputFileType;
082:            private CollectorScrubberService collectorScrubberService;
083:
084:            /**
085:             * Parses the given file, validates the batch, stores the entries, and sends email.
086:             * @param fileName - name of file to load (including path)
087:             * @param group the group into which to persist the origin entries for the collector batch/file
088:             * @param collectorReportData the object used to store all of the collector status information for reporting
089:             * @param collectorScrubberStatuses if the collector scrubber is able to be invoked upon this collector batch, then the status
090:             *        info of the collector status run is added to the end of this list
091:             * @return boolean - true if load was successful, false if errors were encountered
092:             * @see org.kuali.module.gl.service.CollectorService#loadCollectorFile(java.lang.String)
093:             */
094:            public boolean loadCollectorFile(String fileName,
095:                    OriginEntryGroup originEntryGroup,
096:                    CollectorReportData collectorReportData,
097:                    List<CollectorScrubberStatus> collectorScrubberStatuses) {
098:                boolean isValid = true;
099:
100:                // the batch name is the file name
101:                // we can't use the global variables map to store errors because multiple collector batches/files run by the same thread
102:                // if we used the global variables map, all of the parse/validation errors from one file would be retained when
103:                // parsing/validating the
104:                // the next file, causing all subsequent files to fail validation. So, instead we do one unique error map per file
105:                ErrorMap errorMap = collectorReportData
106:                        .getErrorMapForBatchName(fileName);
107:
108:                CollectorBatch batch = doCollectorFileParse(fileName, errorMap);
109:
110:                // terminate if there were parse errors
111:                if (!errorMap.isEmpty()) {
112:                    isValid = false;
113:                    collectorReportData.markUnparsableBatchNames(fileName);
114:                }
115:
116:                if (isValid) {
117:                    batch.setBatchName(fileName);
118:                    collectorReportData.addBatch(batch);
119:                    collectorReportData.setNumInputDetails(batch);
120:                    // check totals
121:                    isValid = checkTrailerTotals(batch, collectorReportData,
122:                            errorMap);
123:                }
124:
125:                // do validation, base collector files rules and total checks
126:                if (isValid) {
127:                    isValid = performValidation(batch, errorMap);
128:                }
129:
130:                if (isValid) {
131:                    CollectorScrubberStatus collectorScrubberStatus = collectorScrubberService
132:                            .scrub(batch, collectorReportData);
133:                    collectorScrubberStatuses.add(collectorScrubberStatus);
134:                    processInterDepartmentalBillingAmounts(batch);
135:
136:                    // store origin group, entries, and id billings
137:                    batch.setDefaultsAndStore(originEntryGroup,
138:                            collectorReportData);
139:                    collectorReportData.incrementNumPersistedBatches();
140:
141:                    // mark batch as valid
142:                    collectorReportData.markValidationStatus(batch, true);
143:                } else {
144:                    collectorReportData.incrementNumNonPersistedBatches();
145:
146:                    // mark batch as invalid
147:                    collectorReportData.markValidationStatus(batch, false);
148:                }
149:
150:                return isValid;
151:            }
152:
153:            /**
154:             * After a parse error, tries to go through the file to see if the email address can be determined. This method will not throw
155:             * an exception.
156:             * 
157:             * It's not doing much right now, just returning null
158:             * 
159:             * @param fileName the name of the file that a parsing error occurred on
160:             * @return the email from the file
161:             */
162:            protected String attemptToParseEmailAfterParseError(String fileName) {
163:                return null;
164:            }
165:
166:            /**
167:             * Calls batch input service to parse the xml contents into an object. Any errors will be contained in GlobalVariables.errorMap
168:             * 
169:             * @param fileName the name of the file to parse
170:             * @param errorMap a map of errors resultant from the parsing
171:             * @return the CollectorBatch of details parsed from the file
172:             */
173:            private CollectorBatch doCollectorFileParse(String fileName,
174:                    ErrorMap errorMap) {
175:
176:                InputStream inputStream = null;
177:                try {
178:                    inputStream = new FileInputStream(fileName);
179:                } catch (FileNotFoundException e) {
180:                    LOG.error("file to parse not found " + fileName, e);
181:                    throw new RuntimeException(
182:                            "Cannot find the file requested to be parsed "
183:                                    + fileName + " " + e.getMessage(), e);
184:                }
185:
186:                CollectorBatch parsedObject = null;
187:                try {
188:                    byte[] fileByteContent = IOUtils.toByteArray(inputStream);
189:                    parsedObject = (CollectorBatch) batchInputFileService
190:                            .parse(collectorInputFileType, fileByteContent);
191:                } catch (IOException e) {
192:                    LOG.error("error while getting file bytes:  "
193:                            + e.getMessage(), e);
194:                    throw new RuntimeException(
195:                            "Error encountered while attempting to get file bytes: "
196:                                    + e.getMessage(), e);
197:                } catch (XMLParseException e1) {
198:                    LOG.error("errors parsing xml " + e1.getMessage(), e1);
199:                    errorMap.putError(KFSConstants.GLOBAL_ERRORS,
200:                            KFSKeyConstants.ERROR_BATCH_UPLOAD_PARSING_XML,
201:                            new String[] { e1.getMessage() });
202:                }
203:
204:                return parsedObject;
205:            }
206:
207:            /**
208:             * Validates the contents of a parsed file.
209:             * 
210:             * @param batch - batch to validate
211:             * @return boolean - true if validation was OK, false if there were errors
212:             * @see org.kuali.module.gl.service.CollectorHelperService#performValidation(org.kuali.module.gl.batch.collector.CollectorBatch)
213:             */
214:            public boolean performValidation(CollectorBatch batch) {
215:                return performValidation(batch, GlobalVariables.getErrorMap());
216:            }
217:
218:            /**
219:             * Performs the following checks on the collector batch: Any errors will be contained in GlobalVariables.errorMap
220:             * 
221:             * @param batch - batch to validate
222:             * @param errorMap the map into which to put errors encountered during validation
223:             * @return boolean - true if validation was successful, false it not
224:             */
225:            protected boolean performValidation(CollectorBatch batch,
226:                    ErrorMap errorMap) {
227:                boolean valid = true;
228:
229:                boolean performDuplicateHeaderCheck = parameterService
230:                        .getIndicatorParameter(
231:                                CollectorStep.class,
232:                                SystemGroupParameterNames.COLLECTOR_PERFORM_DUPLICATE_HEADER_CHECK);
233:                if (performDuplicateHeaderCheck) {
234:                    valid = duplicateHeaderCheck(batch, errorMap);
235:                }
236:                if (valid) {
237:                    valid = checkForMixedDocumentTypes(batch, errorMap);
238:                }
239:
240:                if (valid) {
241:                    valid = checkForMixedBalanceTypes(batch, errorMap);
242:                }
243:
244:                if (valid) {
245:                    valid = checkDetailKeys(batch, errorMap);
246:                }
247:
248:                return valid;
249:            }
250:
251:            /**
252:             * Modifies the amounts in the ID Billing Detail rows, depending on specific business rules. For this default implementation,
253:             * see the {@link #negateAmountIfNecessary(InterDepartmentalBilling, BalanceTyp, ObjectType, CollectorBatch)} method to see how
254:             * the billing detail amounts are modified.
255:             * 
256:             * @param batch a CollectorBatch to process
257:             */
258:            protected void processInterDepartmentalBillingAmounts(
259:                    CollectorBatch batch) {
260:                for (CollectorDetail collectorDetail : batch
261:                        .getCollectorDetails()) {
262:                    String balanceTypeCode = getBalanceTypeCode(
263:                            collectorDetail, batch);
264:
265:                    BalanceTyp balanceTyp = new BalanceTyp();
266:                    balanceTyp.setFinancialBalanceTypeCode(balanceTypeCode);
267:                    balanceTyp = (BalanceTyp) SpringContext.getBean(
268:                            BusinessObjectService.class).retrieve(balanceTyp);
269:                    if (balanceTyp == null) {
270:                        // no balance type in db
271:                        LOG
272:                                .info("No balance type code found for ID billing record. "
273:                                        + collectorDetail);
274:                        continue;
275:                    }
276:
277:                    collectorDetail
278:                            .refreshReferenceObject(KFSPropertyConstants.FINANCIAL_OBJECT);
279:                    if (collectorDetail.getFinancialObject() == null) {
280:                        // no object code in db
281:                        LOG.info("No object code found for ID billing record. "
282:                                + collectorDetail);
283:                        continue;
284:                    }
285:                    ObjectType objectType = collectorDetail
286:                            .getFinancialObject().getFinancialObjectType();
287:
288:                    /** Commented out for KULRNE-5922 */
289:                    // negateAmountIfNecessary(collectorDetail, balanceTyp, objectType, batch);
290:                }
291:            }
292:
293:            /**
294:             * Negates the amount of the internal departmental billing detail record if necessary. For this default implementation, if the
295:             * balance type's offset indicator is yes and the object type has a debit indicator, then the amount is negated.
296:             * 
297:             * @param collectorDetail the collector detail
298:             * @param balanceTyp the balance type
299:             * @param objectType the object type
300:             * @param batch the patch to which the interDepartmentalBilling parameter belongs
301:             */
302:            protected void negateAmountIfNecessary(
303:                    CollectorDetail collectorDetail, BalanceTyp balanceTyp,
304:                    ObjectType objectType, CollectorBatch batch) {
305:                if (balanceTyp != null && objectType != null) {
306:                    if (balanceTyp.isFinancialOffsetGenerationIndicator()) {
307:                        if (KFSConstants.GL_DEBIT_CODE.equals(objectType
308:                                .getFinObjectTypeDebitcreditCd())) {
309:                            KualiDecimal amount = collectorDetail
310:                                    .getCollectorDetailItemAmount();
311:                            amount = amount.negated();
312:                            collectorDetail
313:                                    .setCollectorDetailItemAmount(amount);
314:                        }
315:                    }
316:                }
317:            }
318:
319:            /**
320:             * Returns the balance type code for the interDepartmentalBilling record. This default implementation will look into the system
321:             * parameters to determine the balance type
322:             * 
323:             * @param interDepartmentalBilling a inter departmental billing detail record
324:             * @param batch the batch to which the interDepartmentalBilling billing belongs
325:             * @return the balance type code for the billing detail
326:             */
327:            protected String getBalanceTypeCode(
328:                    CollectorDetail collectorDetail, CollectorBatch batch) {
329:                return collectorDetail.getFinancialBalanceTypeCode();
330:            }
331:
332:            /**
333:             * Checks header against previously loaded batch headers for a duplicate submission.
334:             * 
335:             * @param batch - batch to check
336:             * @return true if header if OK, false if header was used previously
337:             */
338:            private boolean duplicateHeaderCheck(CollectorBatch batch,
339:                    ErrorMap errorMap) {
340:                boolean validHeader = true;
341:
342:                CollectorHeader foundHeader = batch.retrieveDuplicateHeader();
343:
344:                if (foundHeader != null) {
345:                    LOG
346:                            .error("batch header was matched to a previously loaded batch");
347:                    errorMap.putError(KFSConstants.GLOBAL_ERRORS,
348:                            KFSKeyConstants.Collector.DUPLICATE_BATCH_HEADER);
349:
350:                    validHeader = false;
351:                }
352:
353:                return validHeader;
354:            }
355:
356:            /**
357:             * Iterates through the origin entries and builds a map on the document types. Then checks there was only one document type
358:             * found.
359:             * 
360:             * @param batch - batch to check document types
361:             * @return true if there is only one document type, false if multiple document types were found.
362:             */
363:            private boolean checkForMixedDocumentTypes(CollectorBatch batch,
364:                    ErrorMap errorMap) {
365:                boolean docTypesNotMixed = true;
366:
367:                Set batchDocumentTypes = new HashSet();
368:                for (OriginEntryFull entry : batch.getOriginEntries()) {
369:                    batchDocumentTypes
370:                            .add(entry.getFinancialDocumentTypeCode());
371:                }
372:
373:                if (batchDocumentTypes.size() > 1) {
374:                    LOG.error("mixed document types found in batch");
375:                    errorMap.putError(KFSConstants.GLOBAL_ERRORS,
376:                            KFSKeyConstants.Collector.MIXED_DOCUMENT_TYPES);
377:
378:                    docTypesNotMixed = false;
379:                }
380:
381:                return docTypesNotMixed;
382:            }
383:
384:            /**
385:             * Iterates through the origin entries and builds a map on the balance types. Then checks there was only one balance type found.
386:             * 
387:             * @param batch - batch to check balance types
388:             * @return true if there is only one balance type, false if multiple balance types were found
389:             */
390:            private boolean checkForMixedBalanceTypes(CollectorBatch batch,
391:                    ErrorMap errorMap) {
392:                boolean balanceTypesNotMixed = true;
393:
394:                Set balanceTypes = new HashSet();
395:                for (OriginEntryFull entry : batch.getOriginEntries()) {
396:                    balanceTypes.add(entry.getFinancialBalanceTypeCode());
397:                }
398:
399:                if (balanceTypes.size() > 1) {
400:                    LOG.error("mixed balance types found in batch");
401:                    errorMap.putError(KFSConstants.GLOBAL_ERRORS,
402:                            KFSKeyConstants.Collector.MIXED_BALANCE_TYPES);
403:
404:                    balanceTypesNotMixed = false;
405:                }
406:
407:                return balanceTypesNotMixed;
408:            }
409:
410:            /**
411:             * Verifies each detail (id billing) record key has an corresponding gl entry in the same batch. The key is built by joining the
412:             * values of chart of accounts code, account number, sub account number, object code, and sub object code.
413:             * 
414:             * @param batch - batch to validate
415:             * @return true if all detail records had matching keys, false otherwise
416:             */
417:            private boolean checkDetailKeys(CollectorBatch batch,
418:                    ErrorMap errorMap) {
419:                boolean detailKeysFound = true;
420:
421:                // build a Set of keys from the gl entries to compare with
422:                Set glEntryKeys = new HashSet();
423:                for (OriginEntryFull entry : batch.getOriginEntries()) {
424:                    glEntryKeys
425:                            .add(generateOriginEntryMatchingKey(entry, ", "));
426:                }
427:
428:                for (CollectorDetail collectorDetail : batch
429:                        .getCollectorDetails()) {
430:                    String collectorDetailKey = generateCollectorDetailMatchingKey(
431:                            collectorDetail, ", ");
432:                    if (!glEntryKeys.contains(collectorDetailKey)) {
433:                        LOG
434:                                .error("found detail key without a matching gl entry key "
435:                                        + collectorDetailKey);
436:                        errorMap
437:                                .putError(
438:                                        KFSConstants.GLOBAL_ERRORS,
439:                                        KFSKeyConstants.Collector.NONMATCHING_DETAIL_KEY,
440:                                        collectorDetailKey);
441:
442:                        detailKeysFound = false;
443:                    }
444:                }
445:
446:                return detailKeysFound;
447:            }
448:
449:            /**
450:             * Generates a String representation of the OriginEntryFull's primary key
451:             * 
452:             * @param entry origin entry to get key from
453:             * @param delimiter the String delimiter to separate parts of the key
454:             * @return the key as a String
455:             */
456:            private String generateOriginEntryMatchingKey(
457:                    OriginEntryFull entry, String delimiter) {
458:                return StringUtils.join(new String[] {
459:                        entry.getUniversityFiscalYear().toString(),
460:                        entry.getUniversityFiscalPeriodCode(),
461:                        entry.getChartOfAccountsCode(),
462:                        entry.getAccountNumber(), entry.getSubAccountNumber(),
463:                        entry.getFinancialObjectCode(),
464:                        entry.getFinancialSubObjectCode(),
465:                        entry.getFinancialBalanceTypeCode(),
466:                        entry.getFinancialObjectTypeCode(),
467:                        entry.getDocumentNumber(),
468:                        entry.getFinancialDocumentTypeCode(),
469:                        entry.getFinancialSystemOriginationCode() }, delimiter);
470:            }
471:
472:            /**
473:             * Generates a String representation of the CollectorDetail's primary key
474:             * 
475:             * @param collectorDetail collector detail to get key from
476:             * @param delimiter the String delimiter to separate parts of the key
477:             * @return the key as a String
478:             */
479:            private String generateCollectorDetailMatchingKey(
480:                    CollectorDetail collectorDetail, String delimiter) {
481:                return StringUtils.join(new String[] {
482:                        collectorDetail.getUniversityFiscalYear().toString(),
483:                        collectorDetail.getUniversityFiscalPeriodCode(),
484:                        collectorDetail.getChartOfAccountsCode(),
485:                        collectorDetail.getAccountNumber(),
486:                        collectorDetail.getSubAccountNumber(),
487:                        collectorDetail.getFinancialObjectCode(),
488:                        collectorDetail.getFinancialSubObjectCode(),
489:                        collectorDetail.getFinancialBalanceTypeCode(),
490:                        collectorDetail.getFinancialObjectTypeCode(),
491:                        collectorDetail.getDocumentNumber(),
492:                        collectorDetail.getFinancialDocumentTypeCode(),
493:                        collectorDetail.getFinancialSystemOriginationCode() },
494:                        delimiter);
495:            }
496:
497:            /**
498:             * Checks the batch total line count and amounts against the trailer. Any errors will be contained in GlobalVariables.errorMap
499:             * 
500:             * @param batch batch to check totals for
501:             * @param collectorReportData collector report data (optional)
502:             * @see org.kuali.module.gl.service.CollectorHelperService#checkTrailerTotals(org.kuali.module.gl.batch.collector.CollectorBatch,
503:             *      org.kuali.module.gl.util.CollectorReportData)
504:             */
505:            public boolean checkTrailerTotals(CollectorBatch batch,
506:                    CollectorReportData collectorReportData) {
507:                return checkTrailerTotals(batch, collectorReportData,
508:                        GlobalVariables.getErrorMap());
509:            }
510:
511:            /**
512:             * Checks the batch total line count and amounts against the trailer. Any errors will be contained in GlobalVariables.errorMap
513:             * 
514:             * @param batch - batch to check totals for
515:             * @return boolean - true if validation was successful, false it not
516:             */
517:            protected boolean checkTrailerTotals(CollectorBatch batch,
518:                    CollectorReportData collectorReportData, ErrorMap errorMap) {
519:                boolean trailerTotalsMatch = true;
520:
521:                int actualRecordCount = batch.getOriginEntries().size()
522:                        + batch.getCollectorDetails().size();
523:                if (actualRecordCount != batch.getTotalRecords()) {
524:                    LOG
525:                            .error("trailer check on total count did not pass, expected count: "
526:                                    + String.valueOf(batch.getTotalRecords())
527:                                    + ", actual count: "
528:                                    + String.valueOf(actualRecordCount));
529:                    errorMap
530:                            .putError(
531:                                    KFSConstants.GLOBAL_ERRORS,
532:                                    KFSKeyConstants.Collector.TRAILER_ERROR_COUNTNOMATCH,
533:                                    String.valueOf(batch.getTotalRecords()),
534:                                    String.valueOf(actualRecordCount));
535:
536:                    trailerTotalsMatch = false;
537:                }
538:
539:                OriginEntryTotals totals = new OriginEntryTotals();
540:                totals.addToTotals(batch.getOriginEntries().iterator());
541:
542:                if (collectorReportData != null) {
543:                    collectorReportData.setOriginEntryTotals(batch, totals);
544:                }
545:
546:                if (batch.getOriginEntries().size() == 0) {
547:                    if (!KualiDecimal.ZERO.equals(batch.getTotalAmount())) {
548:                        LOG
549:                                .error("trailer total should be zero when there are no origin entries");
550:                        errorMap
551:                                .putError(
552:                                        KFSConstants.GLOBAL_ERRORS,
553:                                        KFSKeyConstants.Collector.TRAILER_ERROR_AMOUNT_SHOULD_BE_ZERO);
554:                    }
555:                    return false;
556:                }
557:
558:                // retrieve document types that balance by equal debits and credits
559:                String[] documentTypes = parameterService
560:                        .getParameterValues(
561:                                CollectorStep.class,
562:                                KFSConstants.SystemGroupParameterNames.COLLECTOR_EQUAL_DC_TOTAL_DOCUMENT_TYPES)
563:                        .toArray(new String[] {});
564:
565:                boolean equalDebitCreditTotal = false;
566:                for (int i = 0; i < documentTypes.length; i++) {
567:                    String documentType = StringUtils.remove(documentTypes[i],
568:                            "*");
569:                    if (batch.getOriginEntries().get(0)
570:                            .getFinancialDocumentTypeCode().startsWith(
571:                                    documentType.toUpperCase())
572:                            && KFSConstants.BALANCE_TYPE_ACTUAL.equals(batch
573:                                    .getOriginEntries().get(0)
574:                                    .getFinancialBalanceTypeCode())) {
575:                        equalDebitCreditTotal = true;
576:                    }
577:                }
578:
579:                if (equalDebitCreditTotal) {
580:                    // credits must equal debits must equal total trailer amount
581:                    if (!totals.getCreditAmount().equals(
582:                            totals.getDebitAmount())
583:                            || !totals.getCreditAmount().equals(
584:                                    batch.getTotalAmount())) {
585:                        LOG
586:                                .error("trailer check on total amount did not pass, debit should equal credit, should equal trailer total");
587:                        errorMap
588:                                .putError(
589:                                        KFSConstants.GLOBAL_ERRORS,
590:                                        KFSKeyConstants.Collector.TRAILER_ERROR_AMOUNTNOMATCH1,
591:                                        totals.getCreditAmount().toString(),
592:                                        totals.getDebitAmount().toString(),
593:                                        batch.getTotalAmount().toString());
594:                        trailerTotalsMatch = false;
595:                    }
596:                } else {
597:                    // credits plus debits plus other amount must equal trailer
598:                    KualiDecimal totalGlEntries = totals.getCreditAmount().add(
599:                            totals.getDebitAmount()).add(
600:                            totals.getOtherAmount());
601:                    if (!totalGlEntries.equals(batch.getTotalAmount())) {
602:                        LOG
603:                                .error("trailer check on total amount did not pass, sum of gl entry amounts should equal trailer total");
604:                        errorMap
605:                                .putError(
606:                                        KFSConstants.GLOBAL_ERRORS,
607:                                        KFSKeyConstants.Collector.TRAILER_ERROR_AMOUNTNOMATCH2,
608:                                        totalGlEntries.toString(), batch
609:                                                .getTotalAmount().toString());
610:                        trailerTotalsMatch = false;
611:                    }
612:                }
613:
614:                return trailerTotalsMatch;
615:            }
616:
617:            public void setCollectorDetailService(
618:                    CollectorDetailService collectorDetailService) {
619:                this .collectorDetailService = collectorDetailService;
620:            }
621:
622:            public void setOriginEntryGroupService(
623:                    OriginEntryGroupService originEntryGroupService) {
624:                this .originEntryGroupService = originEntryGroupService;
625:            }
626:
627:            public void setOriginEntryService(
628:                    OriginEntryService originEntryService) {
629:                this .originEntryService = originEntryService;
630:            }
631:
632:            /**
633:             * Returns the name of the directory where Collector files are saved
634:             * 
635:             * @return the name of the staging directory
636:             */
637:            public String getStagingDirectory() {
638:                return configurationService
639:                        .getPropertyString(KFSConstants.GL_COLLECTOR_STAGING_DIRECTORY);
640:            }
641:
642:            public void setDateTimeService(DateTimeService dateTimeService) {
643:                this .dateTimeService = dateTimeService;
644:            }
645:
646:            public void setMailService(MailService mailService) {
647:                this .mailService = mailService;
648:            }
649:
650:            public void setBatchInputFileService(
651:                    BatchInputFileService batchInputFileService) {
652:                this .batchInputFileService = batchInputFileService;
653:            }
654:
655:            public void setCollectorInputFileType(
656:                    BatchInputFileType collectorInputFileType) {
657:                this .collectorInputFileType = collectorInputFileType;
658:            }
659:
660:            /**
661:             * Sets the collectorScrubberService attribute value.
662:             * 
663:             * @param collectorScrubberService The collectorScrubberService to set.
664:             */
665:            public void setCollectorScrubberService(
666:                    CollectorScrubberService collectorScrubberService) {
667:                this .collectorScrubberService = collectorScrubberService;
668:            }
669:
670:            public void setConfigurationService(
671:                    KualiConfigurationService configurationService) {
672:                this .configurationService = configurationService;
673:            }
674:
675:            public void setParameterService(ParameterService parameterService) {
676:                this.parameterService = parameterService;
677:            }
678:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.