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.batch;
017    
018    import java.io.BufferedReader;
019    import java.io.FileReader;
020    import java.io.IOException;
021    import java.io.PrintStream;
022    import java.sql.Date;
023    import java.text.SimpleDateFormat;
024    import java.util.ArrayList;
025    import java.util.LinkedHashMap;
026    import java.util.List;
027    import java.util.Map;
028    
029    import org.apache.commons.io.IOUtils;
030    import org.apache.commons.lang.StringUtils;
031    import org.kuali.kfs.coa.businessobject.Chart;
032    import org.kuali.kfs.coa.businessobject.Organization;
033    import org.kuali.kfs.gl.GeneralLedgerConstants;
034    import org.kuali.kfs.gl.batch.service.RunDateService;
035    import org.kuali.kfs.gl.batch.service.impl.OriginEntryTotals;
036    import org.kuali.kfs.gl.businessobject.CollectorDetail;
037    import org.kuali.kfs.gl.businessobject.CollectorHeader;
038    import org.kuali.kfs.gl.businessobject.OriginEntryFull;
039    import org.kuali.kfs.gl.businessobject.OriginEntryGroup;
040    import org.kuali.kfs.gl.businessobject.OriginEntrySource;
041    import org.kuali.kfs.gl.report.CollectorReportData;
042    import org.kuali.kfs.gl.service.CollectorDetailService;
043    import org.kuali.kfs.sys.KFSConstants;
044    import org.kuali.kfs.sys.KFSKeyConstants;
045    import org.kuali.kfs.sys.KFSPropertyConstants;
046    import org.kuali.kfs.sys.ObjectUtil;
047    import org.kuali.kfs.sys.context.SpringContext;
048    import org.kuali.kfs.sys.exception.ParseException;
049    import org.kuali.rice.kns.bo.PersistableBusinessObjectBase;
050    import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
051    import org.kuali.rice.kns.service.BusinessObjectService;
052    import org.kuali.rice.kns.service.DataDictionaryService;
053    import org.kuali.rice.kns.service.DateTimeService;
054    import org.kuali.rice.kns.util.KualiDecimal;
055    import org.kuali.rice.kns.util.MessageMap;
056    
057    /**
058     * Object representation of collector xml input.
059     */
060    public class CollectorBatch extends PersistableBusinessObjectBase {
061        // way to distinguish this batch from others
062        private String batchName;
063    
064        // common field for header records and trailer records
065        private String universityFiscalYear;
066        private String chartOfAccountsCode;
067        private String organizationCode;
068        private Date transmissionDate;
069        private String recordType;
070        
071        // header record additional fields
072        private String personUserID;
073        private Integer batchSequenceNumber;
074        private String emailAddress;
075        private String campusCode;
076        private String phoneNumber;
077        private String mailingAddress;
078        private String departmentName;
079    
080        private List<OriginEntryFull> originEntries;
081        private List<CollectorDetail> collectorDetails;
082    
083        // trailer records
084        private String firstEmptyField; //first,second,third Empty Fields are dummy fields to read the spaces in the file using dd
085        private String secondEmptyField;
086        private Integer totalRecords;
087        private KualiDecimal totalAmount;
088        
089        private MessageMap messageMap;
090        private OriginEntryTotals originEntryTotals;
091        
092        private boolean headerlessBatch;
093        
094        private static CollectorBatchHeaderFieldUtil collectorBatchHeaderFieldUtil;
095        private static CollectorBatchTrailerRecordFieldUtil collectorBatchTrailerRecordFieldUtil;
096        
097        /**
098         * Constructs a CollectorBatch
099         */
100        public CollectorBatch() {
101            originEntries = new ArrayList();
102            collectorDetails = new ArrayList();
103            messageMap = new MessageMap();
104            originEntryTotals = null;
105            totalRecords = 0;
106            headerlessBatch = false;
107        }
108    
109        /**
110         * Gets the universityFiscalYear attribute. 
111         */
112        public String getUniversityFiscalYear() {
113            return universityFiscalYear;
114        }
115        
116        /**
117         * Sets the universityFiscalYear attribute
118         */
119        public void setUniversityFiscalYear(String universityFiscalYear) {
120            this.universityFiscalYear = universityFiscalYear;
121        }
122        
123        /**
124         * Gets the batchSequenceNumber attribute.
125         */
126        public Integer getBatchSequenceNumber() {
127            return batchSequenceNumber;
128        }
129    
130        /**
131         * Sets the batchSequenceNumber attribute value.
132         */
133        public void setBatchSequenceNumber(Integer batchSequenceNumber) {
134            this.batchSequenceNumber = batchSequenceNumber;
135        }
136    
137        /**
138         * Gets the chartOfAccountsCode attribute.
139         */
140        public String getChartOfAccountsCode() {
141            return chartOfAccountsCode;
142        }
143    
144        /**
145         * Sets the chartOfAccountsCode attribute value.
146         */
147        public void setChartOfAccountsCode(String chartOfAccountsCode) {
148            this.chartOfAccountsCode = chartOfAccountsCode;
149        }
150    
151        /**
152         * Gets the organizationCode attribute.
153         */
154        public String getOrganizationCode() {
155            return organizationCode;
156        }
157    
158        /**
159         * Sets the organizationCode attribute value.
160         */
161        public void setOrganizationCode(String organizationCode) {
162            this.organizationCode = organizationCode;
163        }
164    
165        /**
166         * Gets the totalAmount attribute.
167         */
168        public KualiDecimal getTotalAmount() {
169            return totalAmount;
170        }
171    
172        /**
173         * Sets the totalAmount attribute value.
174         */
175        public void setTotalAmount(KualiDecimal totalAmount) {
176            this.totalAmount = totalAmount;
177        }
178    
179        /**
180         * Sets the total amount from the String.
181         */
182        public void setTotalAmount(String totalAmount) {
183            this.totalAmount = new KualiDecimal(totalAmount);
184        }
185    
186        /**
187         * Sets the total amount field to null.
188         */
189        public void clearTotalAmount() {
190            this.totalAmount = null;
191        }
192    
193        /**
194         * Gets the secondEmptyField attribute
195         */
196        public String getSecondEmptyField() {
197            return secondEmptyField;
198        }
199        
200        /**
201         * Sets the secondEmptyField attribute
202         */
203        public void setSecondEmptyField(String secondEmptyField) {
204            this.secondEmptyField = secondEmptyField;
205        }
206        
207        /**
208         * Gets the firstEmptyField attribute
209         */
210        public String getFirstEmptyField() {
211            return firstEmptyField;
212        }
213        
214        /**
215         * Sets the firstEmptyField attribute
216         */
217        public void setFirstEmptyField(String firstEmptyField) {
218            this.firstEmptyField = firstEmptyField;
219        }
220    
221        /**
222         * Gets the totalRecords attribute.
223         */
224        public Integer getTotalRecords() {
225            return totalRecords;
226        }
227    
228        /**
229         * Sets the totalRecords attribute value.
230         */
231        public void setTotalRecords(Integer totalRecords) {
232            this.totalRecords = totalRecords;
233        }
234    
235        /**
236         * Gets the transmissionDate attribute.
237         */
238        public Date getTransmissionDate() {
239            return transmissionDate;
240        }
241    
242        /**
243         * Sets the transmissionDate attribute value.
244         */
245        public void setTransmissionDate(Date transmissionDate) {
246            this.transmissionDate = transmissionDate;
247        }
248    
249        /**
250         * Gets the recordType attribute.
251         */
252        public String getRecordType() {
253            return recordType;
254        }
255        
256        /**
257         * Sets the recordType attribute.
258         */
259        public void setRecordType(String recordType) {
260            this.recordType = recordType;
261        }
262            
263        /**
264         * Gets the emailAddress attribute.
265         */
266        public String getEmailAddress() {
267            return emailAddress;
268        }
269    
270        /**
271         * Sets the emailAddress attribute value.
272         */
273        public void setEmailAddress(String emailAddress) {
274            this.emailAddress = emailAddress;
275        }
276    
277        /**
278         * Gets the personUserID attribute.
279         */
280        public String getPersonUserID() {
281            return personUserID;
282        }
283    
284        /**
285         * Sets the personUserID attribute value.
286         */
287        public void setPersonUserID(String personUserID) {
288            this.personUserID = personUserID;
289        }
290    
291        /**
292         * Gets the idBillings attribute.
293         */
294        public List<CollectorDetail> getCollectorDetails() {
295            return collectorDetails;
296        }
297    
298        /**
299         * Sets the idBillings attribute value.
300         */
301        public void setCollectorDetails(List<CollectorDetail> idDetails) {
302            this.collectorDetails = idDetails;
303        }
304    
305        /**
306         * Gets the originEntries attribute.
307         */
308        public List<OriginEntryFull> getOriginEntries() {
309            return originEntries;
310        }
311    
312        /**
313         * Sets the originEntries attribute value.
314         */
315        public void setOriginEntries(List<OriginEntryFull> batchOriginEntry) {
316            this.originEntries = batchOriginEntry;
317        }
318    
319        /**
320         * Adds a processed origin entry to the list.
321         */
322        public void addOriginEntry(OriginEntryFull orginEntry) {
323            this.originEntries.add(orginEntry);
324        }
325    
326        /**
327         * Adds a processed id billing to the list.
328         */
329        public void addCollectorDetail(CollectorDetail collectorDetail) {
330            this.collectorDetails.add(collectorDetail);
331        }
332    
333        /**
334         * Attempts to retrieve a collector header already exists with the primary key values given for this object
335         * 
336         * @return the CollectorHeader found in the database
337         */
338        public CollectorHeader retrieveDuplicateHeader() {
339            // checkHeader is used to check whether a record with the same PK values exist already (i.e. only PK values are filled in).
340            CollectorHeader checkHeader = createCollectorHeaderWithPKValuesOnly();
341    
342            CollectorHeader foundHeader = (CollectorHeader) SpringContext.getBean(BusinessObjectService.class).retrieve(checkHeader);
343            return foundHeader;
344        }
345    
346        /**
347         * Sets defaults for fields not populated from file. Store an origin entry group, all gl entries and id billing entries from the
348         * processed file. Also write the header for the duplicate file check.
349         * 
350         * @param originEntryGroup the group into which to store the origin entries
351         * @param collectorReportData report data
352         */
353        public void setDefaultsAndStore(CollectorReportData collectorReportData, String demergerOutputFileName, PrintStream originEntryOutputPs) {
354            BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);  
355            CollectorDetailService collectorDetailService = SpringContext.getBean(CollectorDetailService.class);
356            
357            // persistHeader is used to persist a collector header record into the DB
358            CollectorHeader persistHeader = createCollectorHeaderForStorage();
359            CollectorHeader foundHeader = retrieveDuplicateHeader();
360    
361            if (foundHeader != null) {
362                // update the version number to prevent OptimisticLockingExceptions
363                persistHeader.setVersionNumber(foundHeader.getVersionNumber());
364            }
365            businessObjectService.save(persistHeader);
366                  
367            // store origin entries by using the demerger output file
368            
369            BufferedReader inputFileReader = null;
370            try {
371                inputFileReader = new BufferedReader(new FileReader(demergerOutputFileName));
372                String line = null;
373                while ((line = inputFileReader.readLine()) != null) {
374                    originEntryOutputPs.printf("%s\n", line);
375                }
376            }
377            catch (IOException e) {
378                throw new RuntimeException("IO Error encountered trying to persist collector batch.", e);
379            }
380            finally {
381                IOUtils.closeQuietly(inputFileReader);
382                inputFileReader = null;
383            }  
384            Date nowDate  = new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime());
385            RunDateService runDateService = SpringContext.getBean(RunDateService.class);
386            Date createDate = new java.sql.Date((runDateService.calculateRunDate(nowDate).getTime()));
387            
388            Integer sequenceNumber = new Integer(0);
389            Integer nextSequence = collectorDetailService.getNextCreateSequence(createDate);
390            if (nextSequence != null) {
391                sequenceNumber = nextSequence;
392            }
393            int countOfdetails = collectorDetails.size();
394            for (int numSavedDetails = 0; numSavedDetails < countOfdetails; numSavedDetails++) {
395                CollectorDetail idDetail = this.collectorDetails.get(numSavedDetails);           
396              //  setDefaultsCollectorDetail(idDetail);
397             
398                idDetail.setTransactionLedgerEntrySequenceNumber( ++sequenceNumber);
399                idDetail.setCreateDate(createDate);
400                CollectorDetail foundIdDetail = (CollectorDetail) businessObjectService.retrieve(idDetail);
401                if (foundIdDetail != null) {
402                    idDetail.setVersionNumber(foundIdDetail.getVersionNumber());
403                }
404    
405                businessObjectService.save(idDetail);
406            }
407            
408            collectorReportData.setNumSavedDetails(this, countOfdetails);
409        }
410    
411        /**
412         * Uppercases the appropriate fields in the batch, if told to do so by the data dictionary
413         */
414        public void prepareDataForStorage() {
415            BusinessObjectDictionaryService businessObjectDictionaryService = SpringContext.getBean(BusinessObjectDictionaryService.class);
416            DataDictionaryService dataDictionaryService = SpringContext.getBean(DataDictionaryService.class);
417    
418            // uppercase the data used to generate the collector header
419            if (dataDictionaryService.getAttributeForceUppercase(Chart.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE)) {
420                setChartOfAccountsCode(getChartOfAccountsCode().toUpperCase());
421            }
422            if (dataDictionaryService.getAttributeForceUppercase(Organization.class, KFSPropertyConstants.ORGANIZATION_CODE)) {
423                setOrganizationCode(getOrganizationCode().toUpperCase());
424            }
425    
426            // now uppercase all of the origin entry data
427            for (OriginEntryFull entry : originEntries) {
428                businessObjectDictionaryService.performForceUppercase(entry);
429            }
430    
431            // uppercase the id billing entries
432            for (CollectorDetail collectorDetail : collectorDetails) {
433                businessObjectDictionaryService.performForceUppercase(collectorDetail);
434            }
435        }
436    
437        /**
438         * Creates origin entry group from header fields.
439         * 
440         * @return OriginEntryGroup
441         */
442        private OriginEntryGroup createOriginEntryGroup() {
443            OriginEntryGroup group = new OriginEntryGroup();
444    
445            group.setSourceCode(OriginEntrySource.COLLECTOR);
446            group.setDate(new java.sql.Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime()));
447            group.setProcess(new Boolean(true));
448            group.setScrub(new Boolean(true));
449            group.setValid(new Boolean(true));
450    
451            return group;
452        }
453    
454        /**
455         * Creates a CollectorHeader from the batch to be used for storage
456         * 
457         * @return CollectorHeader
458         */
459        public CollectorHeader createCollectorHeaderForStorage() {
460            CollectorHeader header = new CollectorHeader();
461    
462            header.setChartOfAccountsCode(getChartOfAccountsCode());
463            header.setOrganizationCode(getOrganizationCode());
464            header.setProcessTransmissionDate(getTransmissionDate());
465            header.setProcessBatchSequenceNumber(getBatchSequenceNumber());
466            header.setProcessTotalRecordCount(getTotalRecords());
467            header.setProcessTotalAmount(getTotalAmount());
468            header.setContactCampusCode(getCampusCode());
469            header.setContactPersonPhoneNumber(getPhoneNumber());
470            header.setContactMailingAddress(getMailingAddress());
471            header.setContactDepartmentName(getDepartmentName());
472    
473            return header;
474        }
475    
476        /**
477         * Creates an origin entry record with the PK values filled in only. This is useful to check for duplicate headers.
478         * 
479         * @return CollectorHeader with chart of accounts code, organization code, process transmission date, batch sequence number
480         * total record count, and process total amount from this CollectorBatch
481         */
482        public CollectorHeader createCollectorHeaderWithPKValuesOnly() {
483            CollectorHeader header = new CollectorHeader();
484    
485            header.setChartOfAccountsCode(getChartOfAccountsCode());
486            header.setOrganizationCode(getOrganizationCode());
487            header.setProcessTransmissionDate(getTransmissionDate());
488            header.setProcessBatchSequenceNumber(getBatchSequenceNumber());
489            header.setProcessTotalRecordCount(getTotalRecords());
490            header.setProcessTotalAmount(getTotalAmount());
491    
492            return header;
493        }
494    
495    //    /**
496    //     * Sets defaults for missing id billing fields.
497    //     * 
498    //     * @param idDetail CollectorDetail object which has its create date being set
499    //     */
500    //    private void setDefaultsCollectorDetail(CollectorDetail idDetail) {
501    //        // TODO: Get current fiscal year and period if blank?
502    //        // idBilling.setUniversityFiscalPeriodCode(String.valueOf(RandomUtils.nextInt(2)));
503    //        // idBilling.setCreateSequence(String.valueOf(RandomUtils.nextInt(2)));
504    //        // idBilling.setInterDepartmentalBillingSequenceNumber(String.valueOf(RandomUtils.nextInt(2)));
505    //        idDetail.setCreateDate(new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime()));
506    //        
507    //    }
508    
509        /**
510         * Gets the campusCode attribute.
511         * 
512         * @return Returns the campusCode.
513         */
514        public String getCampusCode() {
515            return campusCode;
516        }
517    
518        /**
519         * Sets the campusCode attribute value.
520         * 
521         * @param campusCode The campusCode to set.
522         */
523        public void setCampusCode(String campusCode) {
524            this.campusCode = campusCode;
525        }
526    
527        /**
528         * Gets the departmentName attribute.
529         * 
530         * @return Returns the departmentName.
531         */
532        public String getDepartmentName() {
533            return departmentName;
534        }
535    
536        /**
537         * Sets the departmentName attribute value.
538         * 
539         * @param departmentName The departmentName to set.
540         */
541        public void setDepartmentName(String departmentName) {
542            this.departmentName = departmentName;
543        }
544    
545        /**
546         * Gets the mailingAddress attribute.
547         * 
548         * @return Returns the mailingAddress.
549         */
550        public String getMailingAddress() {
551            return mailingAddress;
552        }
553    
554        /**
555         * Sets the mailingAddress attribute value.
556         * 
557         * @param mailingAddress The mailingAddress to set.
558         */
559        public void setMailingAddress(String mailingAddress) {
560            this.mailingAddress = mailingAddress;
561        }
562    
563        /**
564         * Gets the phoneNumber attribute.
565         * 
566         * @return Returns the phoneNumber.
567         */
568        public String getPhoneNumber() {
569            return phoneNumber;
570        }
571    
572        /**
573         * Sets the phoneNumber attribute value.
574         * 
575         * @param phoneNumber The phoneNumber to set.
576         */
577        public void setPhoneNumber(String phoneNumber) {
578            this.phoneNumber = phoneNumber;
579        }
580    
581        /**
582         * Gets the batchName attribute.
583         * 
584         * @return Returns the batchName.
585         */
586        public String getBatchName() {
587            return batchName;
588        }
589    
590        /**
591         * Sets the batchName attribute value.
592         * 
593         * @param batchName The batchName to set.
594         */
595        public void setBatchName(String batchName) {
596            this.batchName = batchName;
597        }
598    
599        public MessageMap getMessageMap() {
600            return messageMap;
601        }
602    
603        public void setMessageMap(MessageMap messageMap) {
604            if (messageMap == null) {
605                throw new NullPointerException("messageMap is null");
606            }
607            if (this.messageMap.hasMessages()) {
608                throw new RuntimeException("Cannot reset MessageMap unless original instance has no messages.");
609            }
610            this.messageMap = messageMap;
611        }
612    
613        public OriginEntryTotals getOriginEntryTotals() {
614            return originEntryTotals;
615        }
616    
617        public void setOriginEntryTotals(OriginEntryTotals originEntryTotals) {
618            this.originEntryTotals = originEntryTotals;
619        }
620    
621        public boolean isHeaderlessBatch() {
622            return headerlessBatch;
623        }
624    
625        public void setHeaderlessBatch(boolean headerlessBatch) {
626            this.headerlessBatch = headerlessBatch;
627        }
628        
629        protected LinkedHashMap toStringMapper() {
630            LinkedHashMap map = new LinkedHashMap();
631            map.put("chartOfAccountsCode", getChartOfAccountsCode());
632            map.put("organizationCode", getOrganizationCode());
633            map.put("transmissionDate", getTransmissionDate());
634            map.put("personUserID", getPersonUserID());
635            map.put("batchSequenceNumber", getBatchSequenceNumber());
636            map.put("emailAddress", getEmailAddress());
637            map.put("campusCode", getCampusCode());
638            map.put("phoneNumber", getPhoneNumber());
639            map.put("mailingAddress", getMailingAddress());
640            map.put("departmentName", getDepartmentName());
641            map.put("firstEmptyField", getFirstEmptyField());
642            map.put("totalRecords", getTotalRecords());        
643            map.put("secondEmptyField", getSecondEmptyField());
644            map.put("totalAmount", getTotalAmount());
645            
646            return map;
647        }
648        
649        protected Date parseSqlDate(String date) throws ParseException {
650            try {
651                return new Date(new SimpleDateFormat("yy-MM-dd").parse(date).getTime());
652            }
653            catch (java.text.ParseException e) {
654                throw new ParseException(e.getMessage(), e);
655            }
656        }
657        
658        protected String getValue(String headerLine, int s, int e) {
659              return org.springframework.util.StringUtils.trimTrailingWhitespace(StringUtils.substring(headerLine, s, e));
660          }
661        
662        /**
663         * @return the static instance of the CollectorBatchHeaderFieldUtil
664         */
665        protected static CollectorBatchHeaderFieldUtil getCollectorBatchHeaderFieldUtil() {
666            if (collectorBatchHeaderFieldUtil == null) {
667                collectorBatchHeaderFieldUtil = new CollectorBatchHeaderFieldUtil();
668            }
669            return collectorBatchHeaderFieldUtil;
670        }
671        
672        public void setFromTextFileForCollectorBatch(String headerLine) {
673            try{
674                final Map<String, Integer> pMap = getCollectorBatchHeaderFieldUtil().getFieldBeginningPositionMap();
675                
676                headerLine = org.apache.commons.lang.StringUtils.rightPad(headerLine, GeneralLedgerConstants.getSpaceAllCollectorBatchHeaderFields().length(), ' ');
677                
678                setChartOfAccountsCode(getValue(headerLine, pMap.get(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE), pMap.get(KFSPropertyConstants.ORGANIZATION_CODE)));
679                setOrganizationCode(getValue(headerLine, pMap.get(KFSPropertyConstants.ORGANIZATION_CODE), pMap.get(KFSPropertyConstants.TRANSMISSION_DATE)));
680    
681                String transmissionDate = org.apache.commons.lang.StringUtils.trim(getValue(headerLine, pMap.get(KFSPropertyConstants.TRANSMISSION_DATE), pMap.get(KFSPropertyConstants.COLLECTOR_BATCH_RECORD_TYPE)));
682                try {
683                    setTransmissionDate(parseSqlDate(transmissionDate));
684                }
685                catch (ParseException e) {
686                    getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.Collector.HEADER_BAD_TRANSMISSION_DATE_FORMAT, transmissionDate);
687                    setTransmissionDate(null);
688                }
689                String batchNumber = org.apache.commons.lang.StringUtils.trim(getValue(headerLine, pMap.get(KFSPropertyConstants.BATCH_SEQUENCE_NUMBER), pMap.get(KFSPropertyConstants.EMAIL_ADDRESS)));
690                
691                if (ObjectUtil.isInteger(batchNumber)) { 
692                    setBatchSequenceNumber(new Integer(batchNumber));
693                } else {
694                    setBatchSequenceNumber(0);
695                }
696                setEmailAddress(getValue(headerLine, pMap.get(KFSPropertyConstants.EMAIL_ADDRESS), pMap.get(KFSPropertyConstants.COLLECTOR_BATCH_PERSON_USER_ID)));
697                setPersonUserID(getValue(headerLine, pMap.get(KFSPropertyConstants.COLLECTOR_BATCH_PERSON_USER_ID), pMap.get(KFSPropertyConstants.DEPARTMENT_NAME)));
698                setDepartmentName(getValue(headerLine, pMap.get(KFSPropertyConstants.DEPARTMENT_NAME), pMap.get(KFSPropertyConstants.MAILING_ADDRESS)));
699                setMailingAddress(getValue(headerLine, pMap.get(KFSPropertyConstants.MAILING_ADDRESS), pMap.get(KFSPropertyConstants.CAMPUS_CODE)));
700                setCampusCode(getValue(headerLine, pMap.get(KFSPropertyConstants.CAMPUS_CODE), pMap.get(KFSPropertyConstants.PHONE_NUMBER)));
701                setPhoneNumber(org.apache.commons.lang.StringUtils.trim(getValue(headerLine, pMap.get(KFSPropertyConstants.PHONE_NUMBER), GeneralLedgerConstants.getSpaceAllCollectorBatchHeaderFields().length())));
702            } catch (Exception e){
703                throw new RuntimeException(e + " occurred in CollectorBatch.setFromTextFileForCollectorBatch()");
704            }
705        }
706        
707        /**
708         * @return the static instance of the CollectorBatchTrailerRecordFieldUtil
709         */
710        protected static CollectorBatchTrailerRecordFieldUtil getCollectorBatchTrailerRecordFieldUtil() {
711            if (collectorBatchTrailerRecordFieldUtil == null) {
712                collectorBatchTrailerRecordFieldUtil = new CollectorBatchTrailerRecordFieldUtil();
713            }
714            return collectorBatchTrailerRecordFieldUtil;
715        }
716        
717        public void setFromTextFileForCollectorBatchTrailerRecord(String trailerLine, int lineNumber) {
718            final Map<String, Integer> pMap = getCollectorBatchTrailerRecordFieldUtil().getFieldBeginningPositionMap();
719    
720            trailerLine = org.apache.commons.lang.StringUtils.rightPad(trailerLine, GeneralLedgerConstants.getSpaceAllCollectorBatchTrailerFields().length(), ' ');
721            setTotalRecords(new Integer(org.apache.commons.lang.StringUtils.trim(getValue(trailerLine, pMap.get(KFSPropertyConstants.TOTAL_RECORDS), pMap.get(KFSPropertyConstants.TRAILER_RECORD_SECOND_EMPTY_FIELD)))));
722            
723            String trailerAmount = org.apache.commons.lang.StringUtils.trim(getValue(trailerLine, pMap.get(KFSPropertyConstants.TOTAL_AMOUNT), GeneralLedgerConstants.getSpaceAllCollectorBatchTrailerFields().length()));
724            
725            try {
726                setTotalAmount(trailerAmount);
727            }
728            catch (NumberFormatException e) {
729                setTotalAmount(KualiDecimal.ZERO);
730                getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_CUSTOM, "Collector trailer total amount cannot be parsed on line " + lineNumber + " amount string " + trailerAmount);
731            }
732        }
733    }