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.service.impl;
017    
018    import java.io.BufferedReader;
019    import java.io.File;
020    import java.io.FileNotFoundException;
021    import java.io.FileReader;
022    import java.io.PrintStream;
023    import java.lang.reflect.ParameterizedType;
024    import java.sql.Date;
025    import java.util.HashMap;
026    import java.util.Iterator;
027    import java.util.List;
028    import java.util.Map;
029    
030    import org.apache.commons.lang.StringUtils;
031    import org.kuali.kfs.gl.GeneralLedgerConstants;
032    import org.kuali.kfs.gl.batch.dataaccess.LedgerEntryBalanceCachingDao;
033    import org.kuali.kfs.gl.batch.service.BalancingService;
034    import org.kuali.kfs.gl.batch.service.PosterService;
035    import org.kuali.kfs.gl.businessobject.Balance;
036    import org.kuali.kfs.gl.businessobject.Entry;
037    import org.kuali.kfs.gl.businessobject.LedgerBalanceHistory;
038    import org.kuali.kfs.gl.businessobject.LedgerEntryHistory;
039    import org.kuali.kfs.gl.businessobject.OriginEntryInformation;
040    import org.kuali.kfs.gl.dataaccess.LedgerBalanceBalancingDao;
041    import org.kuali.kfs.gl.dataaccess.LedgerBalanceHistoryBalancingDao;
042    import org.kuali.kfs.gl.dataaccess.LedgerBalancingDao;
043    import org.kuali.kfs.gl.dataaccess.LedgerEntryBalancingDao;
044    import org.kuali.kfs.gl.dataaccess.LedgerEntryHistoryBalancingDao;
045    import org.kuali.kfs.sys.KFSKeyConstants;
046    import org.kuali.kfs.sys.KFSPropertyConstants;
047    import org.kuali.kfs.sys.Message;
048    import org.kuali.kfs.sys.service.ReportWriterService;
049    import org.kuali.kfs.sys.service.UniversityDateService;
050    import org.kuali.rice.kns.bo.PersistableBusinessObjectBase;
051    import org.kuali.rice.kns.service.BusinessObjectService;
052    import org.kuali.rice.kns.service.DateTimeService;
053    import org.kuali.rice.kns.service.KualiConfigurationService;
054    import org.kuali.rice.kns.service.ParameterService;
055    import org.kuali.rice.kns.util.KualiDecimal;
056    import org.kuali.rice.kns.util.ObjectUtils;
057    import org.springframework.transaction.annotation.Transactional;
058    
059    /**
060     * Base service implementation for BalancingService. Useful for generic implementation of common code between la`bor and GL balancing.
061     */
062    @Transactional
063    public abstract class BalancingServiceBaseImpl<T extends Entry, S extends Balance> implements BalancingService {
064        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BalancingServiceBaseImpl.class);
065    
066        // Used to enable us to do generic general ledger or labor balancing
067        protected Class<T> entryHistoryPersistentClass;
068        protected Class<S> balanceHistoryPersistentClass;
069        
070        protected ParameterService parameterService;
071        protected KualiConfigurationService kualiConfigurationService;
072        protected BusinessObjectService businessObjectService;
073        protected DateTimeService dateTimeService;
074        protected UniversityDateService universityDateService;
075        protected LedgerBalancingDao ledgerBalancingDao;
076        protected LedgerEntryBalancingDao ledgerEntryBalancingDao;
077        protected LedgerEntryBalanceCachingDao ledgerEntryBalanceCachingDao;
078        protected LedgerBalanceBalancingDao ledgerBalanceBalancingDao;
079        protected LedgerBalanceHistoryBalancingDao ledgerBalanceHistoryBalancingDao;
080        protected LedgerEntryHistoryBalancingDao ledgerEntryHistoryBalancingDao;
081        protected ReportWriterService reportWriterService;
082        protected String batchFileDirectoryName;
083        
084        /**
085         * Constructs a BalancingServiceBaseImpl.java. The generics are expected to be of type Balance and Entry respectively.
086         */
087        public BalancingServiceBaseImpl() {
088            super();
089            this.entryHistoryPersistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
090            this.balanceHistoryPersistentClass = (Class<S>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
091        }
092        
093        /**
094         * @see org.kuali.kfs.gl.batch.service.BalancingService#runBalancing()
095         */
096        public boolean runBalancing() {
097            // Prepare date constants used throughout the process
098            Integer currentUniversityFiscalYear = universityDateService.getCurrentFiscalYear();
099            int startUniversityFiscalYear = currentUniversityFiscalYear - this.getPastFiscalYearsToConsider();
100    
101            LOG.debug("Checking files required for balancing process are present.");
102            if(!this.isFilesReady()) {
103                reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.ERROR_BATCH_BALANCING_FILES));
104                
105                return false;
106            }
107            
108            LOG.debug("Checking data required for balancing process is present.");
109            boolean historyTablesPopulated = false;
110            // Following does not check for custom data (AccountBalance & Encumbrance) present. Should be OK since it can't exist without entry and balance data.
111            if (this.getHistoryCount(null, entryHistoryPersistentClass) == 0 || this.getHistoryCount(null, balanceHistoryPersistentClass) == 0) {
112                reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_DATA_INSERT), entryHistoryPersistentClass.getSimpleName(), balanceHistoryPersistentClass.getSimpleName());
113                reportWriterService.writeNewLines(1);
114                
115                ledgerBalancingDao.populateLedgerEntryHistory(startUniversityFiscalYear);
116                ledgerBalancingDao.populateLedgerBalanceHistory(startUniversityFiscalYear);
117                this.customPopulateHistoryTables(startUniversityFiscalYear);
118                
119                historyTablesPopulated = true;
120            }
121            
122            LOG.debug("Checking if obsolete historic data present. Deleting if yes.");
123            // This only happens on the first accounting cycle after universityDateService.getFirstDateOfFiscalYear(currentYear) but since we are not
124            // guaranteed a batch cycle on each day there isn't a generic way of only running this once during the year.
125            boolean obsoleteUniversityFiscalYearDeleted = false;
126            int obsoleteUniversityFiscalYear = startUniversityFiscalYear - 1;
127            if(this.getHistoryCount(obsoleteUniversityFiscalYear, entryHistoryPersistentClass) != 0 || this.getHistoryCount(obsoleteUniversityFiscalYear, balanceHistoryPersistentClass) != 0 || this.doesCustomHistoryExist(obsoleteUniversityFiscalYear)) {
128                reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_OBSOLETE_FISCAL_YEAR_DATA_DELETED), entryHistoryPersistentClass.getSimpleName(), balanceHistoryPersistentClass.getSimpleName(), obsoleteUniversityFiscalYear);
129                reportWriterService.writeNewLines(1);
130                this.deleteHistory(obsoleteUniversityFiscalYear, entryHistoryPersistentClass);
131                this.deleteHistory(obsoleteUniversityFiscalYear, balanceHistoryPersistentClass);
132                this.deleteCustomHistory(obsoleteUniversityFiscalYear);
133                obsoleteUniversityFiscalYearDeleted = true;
134            }
135            
136            // We only do update step if history has not been populated. If it has we can't run the update cycle because they were already picked up
137            int updateRecordsIgnored = 0;
138            if (!historyTablesPopulated) {
139                LOG.debug("Getting postable records and save them to history tables.");
140                updateRecordsIgnored = this.updateHistoriesHelper(PosterService.MODE_ENTRIES, startUniversityFiscalYear, this.getPosterInputFile(), this.getPosterErrorOutputFile());
141                updateRecordsIgnored += this.updateHistoriesHelper(PosterService.MODE_REVERSAL, startUniversityFiscalYear, this.getReversalInputFile(), this.getReversalErrorOutputFile());
142                updateRecordsIgnored += this.updateHistoriesHelper(PosterService.MODE_ICR, startUniversityFiscalYear, this.getICRInputFile(), this.getICRErrorOutputFile());
143            }
144    
145            LOG.debug("Comparing entry history table with the PRD counterpart.");
146            int countEntryComparisionFailure = this.compareEntryHistory();
147            if (countEntryComparisionFailure != 0) {
148                reportWriterService.writeNewLines(1);
149                reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_FAILURE_COUNT), entryHistoryPersistentClass.getSimpleName(), countEntryComparisionFailure, this.getComparisonFailuresToPrintPerReport());
150            }
151            
152            LOG.debug("Comparing balance history table with the PRD counterpart.");
153            int countBalanceComparisionFailure = this.compareBalanceHistory();
154            if (countBalanceComparisionFailure != 0) {
155                reportWriterService.writeNewLines(1);
156                reportWriterService.writeFormattedMessageLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_FAILURE_COUNT), balanceHistoryPersistentClass.getSimpleName(), countBalanceComparisionFailure, this.getComparisonFailuresToPrintPerReport());
157            }
158            
159            LOG.debug("Comparing custom, if any, history table with the PRD counterpart.");
160            Map<String, Integer> countCustomComparisionFailures = this.customCompareHistory();
161            
162            LOG.debug("Writing statistics section");
163            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_FISCAL_YEARS_INCLUDED), ledgerBalanceHistoryBalancingDao.findDistinctFiscalYears());
164            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_HISTORY_TABLES_INITIALIZED), historyTablesPopulated ? "Yes" : "No");
165            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_OBSOLETE_DELETED), obsoleteUniversityFiscalYearDeleted ? "Yes (" + obsoleteUniversityFiscalYear + ")": "No");
166            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_UPDATED_SKIPPED), updateRecordsIgnored);
167            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_COMPARISION_FAILURE), this.getShortTableLabel(entryHistoryPersistentClass.getSimpleName()), "(" + entryHistoryPersistentClass.getSimpleName() + ")", countEntryComparisionFailure);
168            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_COMPARISION_FAILURE), this.getShortTableLabel(balanceHistoryPersistentClass.getSimpleName()), "(" + balanceHistoryPersistentClass.getSimpleName() + ")", countBalanceComparisionFailure);
169            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ENTRY_SUM_ROW_COUNT_HISTORY), this.getShortTableLabel(entryHistoryPersistentClass.getSimpleName()), "(" + entryHistoryPersistentClass.getSimpleName() + ")", ledgerEntryHistoryBalancingDao.findSumRowCountGreaterOrEqualThan(startUniversityFiscalYear));
170            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_ENTRY_ROW_COUNT_PRODUCTION), this.getShortTableLabel((Entry.class).getSimpleName()), ledgerEntryBalancingDao.findCountGreaterOrEqualThan(startUniversityFiscalYear));
171            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_BALANCE_ROW_COUNT_HISTORY), this.getShortTableLabel(balanceHistoryPersistentClass.getSimpleName()), "(" + balanceHistoryPersistentClass.getSimpleName() + ")", this.getHistoryCount(null, balanceHistoryPersistentClass));
172            reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_BALANCE_ROW_COUNT_PRODUCTION), this.getShortTableLabel((Balance.class).getSimpleName()), ledgerBalanceBalancingDao.findCountGreaterOrEqualThan(startUniversityFiscalYear));
173            
174            if (ObjectUtils.isNotNull(countCustomComparisionFailures)) {
175                for (Iterator<String> names = countCustomComparisionFailures.keySet().iterator(); names.hasNext();) {
176                    String name = names.next();
177                    int count = countCustomComparisionFailures.get(name);
178                    
179                    reportWriterService.writeStatisticLine(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.REPORT_COMPARISION_FAILURE), this.getShortTableLabel(name), "(" + name + ")", count);
180                }
181            }
182            this.customPrintRowCountHistory(startUniversityFiscalYear);
183            
184            return true;
185        }
186        
187        /**
188         * @return if the files required for processing of this job are present and readable.
189         */
190        protected boolean isFilesReady() {
191            File inputFile = this.getPosterInputFile();
192            File errorFile = this.getPosterErrorOutputFile();
193            
194            return inputFile != null && errorFile != null && inputFile.exists() && errorFile.exists() && inputFile.canRead() && errorFile.canRead();
195        }
196        
197        /**
198         * Deletes data for the given fiscal year of entries from persistentClass.
199         * @param universityFiscalYear the given university fiscal year
200         * @param persistentClass table for which to delete the history
201         */
202        protected void deleteHistory(Integer universityFiscalYear, Class<? extends PersistableBusinessObjectBase> persistentClass) {
203            Map<String, Object> fieldValues = new HashMap<String, Object>();
204            fieldValues.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityFiscalYear);
205            
206            businessObjectService.deleteMatching(persistentClass, fieldValues);
207        }
208        
209        /**
210         * Gets count for given fiscal year of entries from persistentClass.
211         * @param fiscalYear parameter may be null which will get count for all years
212         * @param persistentClass table for which to get the count
213         * @return count
214         */
215        protected int getHistoryCount(Integer fiscalYear, Class<? extends PersistableBusinessObjectBase> persistentClass) {
216            Map<String, String> keyMap = new HashMap<String, String>();
217            
218            if (fiscalYear != null) {
219                keyMap.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear.toString());
220            }
221            
222            return businessObjectService.countMatching(persistentClass, keyMap);
223        }
224        
225        /**
226         * This is a helper method that wraps parsing poster entries for updateEntryHistory and updateBalanceHistory.
227         * @param startUniversityFiscalYear fiscal year for which to accept the earlier parsed lines from the input file
228         * @return indicated whether records where ignored due to being older then startUniversityFiscalYear
229         */
230        protected int updateHistoriesHelper(Integer postMode, Integer startUniversityFiscalYear, File inputFile, File errorFile) {
231            int ignoredRecordsFound = 0;
232            int lineNumber = 0;
233            
234            if ( inputFile == null || errorFile == null ) {
235                return 0;
236            }
237            try {
238                FileReader posterInputFileReader = new FileReader(inputFile);
239                BufferedReader posterInputBufferedReader = new BufferedReader(posterInputFileReader);
240                FileReader posterErrorFileReader = new FileReader(errorFile);
241                BufferedReader posterErrorBufferedReader = new BufferedReader(posterErrorFileReader);
242                
243                // Reading input and error lines in tandem. Eliminating input lines if they were a line in error.
244                String currentInputLine = posterInputBufferedReader.readLine();
245                String currentErrorLine = posterErrorBufferedReader.readLine();
246    
247                while (currentInputLine != null) {
248                    lineNumber++;
249                    
250                    if (!StringUtils.isEmpty(currentInputLine) && !StringUtils.isBlank(currentInputLine.trim())) {
251                        
252                        if(currentInputLine.equals(currentErrorLine)) {
253                            // Skip it, it's in error. Increment to next error line
254                            currentErrorLine = posterErrorBufferedReader.readLine();
255                        } else {
256                            // Line is good, parse it via delegation
257                            OriginEntryInformation originEntry = this.getOriginEntry(currentInputLine, lineNumber);
258                            
259                            if (originEntry.getUniversityFiscalYear() >= startUniversityFiscalYear) {
260                                // Line is in acceptable FY range, update history tables
261                                this.updateEntryHistory(postMode, originEntry);
262                                this.updateBalanceHistory(postMode, originEntry);
263                                this.updateCustomHistory(postMode, originEntry);
264                            } else {
265                                // Outside of trackable FY range. Log as being a failed line
266                                ignoredRecordsFound++;
267                                reportWriterService.writeError(originEntry, new Message(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.MESSAGE_BATCH_BALANCING_RECORD_BEFORE_FISCAL_YEAR), Message.TYPE_WARNING, startUniversityFiscalYear));
268                            }
269                        }
270                    }
271                    
272                    currentInputLine = posterInputBufferedReader.readLine();
273                }
274    
275                posterInputFileReader.close();
276                posterInputBufferedReader.close();
277                posterErrorFileReader.close();
278                posterErrorBufferedReader.close();
279            } catch (Exception e) {
280                LOG.fatal(String.format(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.ERROR_BATCH_BALANCING_UNKNOWN_FAILURE), e.getMessage(), lineNumber),e);
281                reportWriterService.writeFormattedMessageLine(String.format(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.ERROR_BATCH_BALANCING_UNKNOWN_FAILURE), e.getMessage(), lineNumber));
282                throw new RuntimeException(String.format(kualiConfigurationService.getPropertyString(KFSKeyConstants.Balancing.ERROR_BATCH_BALANCING_UNKNOWN_FAILURE), e.getMessage(), lineNumber),e);
283            }
284            
285            return ignoredRecordsFound;
286        }
287    
288        abstract protected Integer compareBalanceHistory();
289        abstract protected Integer compareEntryHistory();
290       
291        
292        /**
293         * Possible override if sub class has additional history tables. Populates custom history tables.
294         * @param fiscalYear fiscal year populate should start from
295         */
296        public void customPopulateHistoryTables(Integer fiscalYear) {
297            return;
298        }
299        
300        /**
301         * Possible override if sub class has additional history tables. This returns true if value populated in any such tables.
302         * @param fiscalYear given fiscal year
303         * @return if data exists for any such table for given year
304         */
305        protected boolean doesCustomHistoryExist(Integer fiscalYear) {
306            return false;
307        }
308        
309        /**
310         * Possible override if sub class has additional history tables. Deletes data in history table. Also
311         * should print message to that affect to be consistent with rest of functionality.
312         * @param fiscalYear given fiscal year
313         */
314        protected void deleteCustomHistory(Integer fiscalYear) {
315            return;
316        }
317        
318        /**
319         * Possible override if sub class has additional history tables. Updates history data for custom table(s).
320         * @param originEntry representing the update details
321         */
322        protected void updateCustomHistory(Integer postMode, OriginEntryInformation originEntry) {
323            return;
324        }
325        
326        /**
327         * Possible override if sub class has additional history tables.
328         * @return compare failures. As a HashMap of key: businessObjectName, value: count
329         */
330        protected Map<String, Integer> customCompareHistory() {
331            return null;
332        }
333        
334        /**
335         * Possible override if sub class has additional history tables. Prints the row count history for STATISTICS section.
336         * @param fiscalYear starting from which fiscal year the comparision should take place
337         */
338        protected void customPrintRowCountHistory(Integer fiscalYear){
339            return;
340        }
341        
342        /**
343         * Sets the ParameterService
344         * 
345         * @param parameterService The ParameterService to set.
346         */
347        public void setParameterService(ParameterService parameterService) {
348            this.parameterService = parameterService;
349        }
350        
351        /**
352         * Sets the KualiConfigurationService
353         * 
354         * @param kualiConfigurationService The KualiConfigurationService to set.
355         */
356        public void setKualiConfigurationService(KualiConfigurationService kualiConfigurationService) {
357            this.kualiConfigurationService = kualiConfigurationService;
358        }
359        
360        /**
361         * Sets the BusinessObjectService
362         * 
363         * @param businessObjectService The BusinessObjectService to set.
364         */
365        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
366            this.businessObjectService = businessObjectService;
367        }
368        
369        /**
370         * Sets the DateTimeService
371         * 
372         * @param dateTimeService The DateTimeService to set.
373         */
374        public void setDateTimeService(DateTimeService dateTimeService) {
375            this.dateTimeService = dateTimeService;
376        }
377    
378        /**
379         * Sets the UniversityDateService
380         * 
381         * @param universityDateService The UniversityDateService to set.
382         */
383        public void setUniversityDateService(UniversityDateService universityDateService) {
384            this.universityDateService = universityDateService;
385        }
386        
387        /**
388         * Sets the LedgerBalancingDao
389         * 
390         * @param ledgerBalancingDao The LedgerBalancingDao to set.
391         */
392        public void setLedgerBalancingDao(LedgerBalancingDao ledgerBalancingDao) {
393            this.ledgerBalancingDao = ledgerBalancingDao;
394        }
395    
396        /**
397         * Sets the LedgerEntryBalancingDao
398         * 
399         * @param ledgerEntryBalancingDao The LedgerEntryBalancingDao to set.
400         */
401        public void setLedgerEntryBalancingDao(LedgerEntryBalancingDao ledgerEntryBalancingDao) {
402            this.ledgerEntryBalancingDao = ledgerEntryBalancingDao;
403        }
404    
405        /**
406         * Sets the LedgerBalanceBalancingDao
407         * 
408         * @param ledgerBalanceBalancingDao The LedgerBalanceBalancingDao to set.
409         */
410        public void setLedgerBalanceBalancingDao(LedgerBalanceBalancingDao ledgerBalanceBalancingDao) {
411            this.ledgerBalanceBalancingDao = ledgerBalanceBalancingDao;
412        }
413    
414        /**
415         * Sets the ledgerBalanceHistoryBalancingDao
416         * 
417         * @param ledgerBalanceHistoryBalancingDao The LedgerBalanceHistoryBalancingDao to set.
418         */
419        public void setLedgerBalanceHistoryBalancingDao(LedgerBalanceHistoryBalancingDao ledgerBalanceHistoryBalancingDao) {
420            this.ledgerBalanceHistoryBalancingDao = ledgerBalanceHistoryBalancingDao;
421        }
422        
423        /**
424         * Sets the LedgerEntryHistoryBalancingDao
425         * 
426         * @param ledgerEntryHistoryBalancingDao The LedgerEntryHistoryBalancingDao to set.
427         */
428        public void setLedgerEntryHistoryBalancingDao(LedgerEntryHistoryBalancingDao ledgerEntryHistoryBalancingDao) {
429            this.ledgerEntryHistoryBalancingDao = ledgerEntryHistoryBalancingDao;
430        }
431    
432        /**
433         * Sets the reportWriterService
434         * 
435         * @param reportWriterService The reportWriterService to set.
436         */
437        public void setReportWriterService(ReportWriterService reportWriterService) {
438            this.reportWriterService = reportWriterService;
439        }
440        
441        /**
442         * Sets the batchFileDirectoryName
443         * 
444         * @param batchFileDirectoryName The batchFileDirectoryName to set.
445         */
446        public void setBatchFileDirectoryName(String batchFileDirectoryName) {
447            this.batchFileDirectoryName = batchFileDirectoryName;
448        }
449    
450        /**
451         * Sets the ledgerEntryBalanceCachingDao attribute value.
452         * @param ledgerEntryBalanceCachingDao The ledgerEntryBalanceCachingDao to set.
453         */
454        public void setLedgerEntryBalanceCachingDao(LedgerEntryBalanceCachingDao ledgerEntryBalanceCachingDao) {
455            this.ledgerEntryBalanceCachingDao = ledgerEntryBalanceCachingDao;
456        }
457    }