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: }
|