/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.gl.batch;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.Account;
import org.kuali.kfs.coa.service.AccountService;
import org.kuali.kfs.gl.batch.service.CollectorHelperService;
import org.kuali.kfs.gl.batch.service.impl.OriginEntryTotals;
import org.kuali.kfs.gl.businessobject.CollectorDetail;
import org.kuali.kfs.gl.businessobject.OriginEntryFull;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSKeyConstants;
import org.kuali.kfs.sys.batch.XmlBatchInputFileTypeBase;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.exception.ParseException;
import org.kuali.rice.core.api.datetime.DateTimeService;
import org.kuali.rice.krad.util.GlobalVariables;
/**
* Batch input type for the collector job.
*/
public class CollectorXmlInputFileType extends XmlBatchInputFileTypeBase {
private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CollectorXmlInputFileType.class);
protected DateTimeService dateTimeService;
private CollectorHelperService collectorHelperService;
/**
* Returns the identifier of the Collector's file type
*
* @return the Collector's file type identifier
* @see org.kuali.kfs.sys.batch.BatchInputFileType#getFileTypeIdentifer()
*/
public String getFileTypeIdentifer() {
return KFSConstants.COLLECTOR_XML_FILE_TYPE_INDENTIFIER;
}
/**
* Builds the file name using the following construction: All collector files start with gl_idbilltrans_ append the chartorg
* from the batch header append the username of the user who is uploading the file then the user supplied indentifier finally
* the timestamp
*
* @param user who uploaded the file
* @param parsedFileContents represents collector batch object
* @param userIdentifier user identifier for user who uploaded file
* @return String returns file name using the convention mentioned in the description
*
* @see org.kuali.kfs.sys.batch.BatchInputFileType#getFileName(org.kuali.rice.kim.api.identity.Person, java.lang.Object,
* java.lang.String)
*/
public String getFileName(String principalName, Object parsedFileContents, String userIdentifier) {
// this implementation assumes that there is only one batch in the XML file
CollectorBatch collectorBatch = ((List<CollectorBatch>) parsedFileContents).get(0);
String fileName = "gl_collector_" + collectorBatch.getChartOfAccountsCode() + collectorBatch.getOrganizationCode();
fileName += "_" + principalName;
if (StringUtils.isNotBlank(userIdentifier)) {
fileName += "_" + userIdentifier;
}
fileName += "_" + dateTimeService.toDateTimeStringForFilename(dateTimeService.getCurrentDate());
// remove spaces in filename
fileName = StringUtils.remove(fileName, " ");
return fileName;
}
public boolean validate(Object parsedFileContents) {
List<CollectorBatch> parsedBatches = (List<CollectorBatch>) parsedFileContents;
boolean allBatchesValid = true;
// add validation for chartCode-accountNumber, as chartCode is not required in xsd due to accounts-cant-cross-charts option
AccountService acctserv = SpringContext.getBean(AccountService.class);
for (CollectorBatch batch : parsedBatches) {
boolean isValid = true;
if (batch.getOriginEntries() != null) {
for (OriginEntryFull originEntry : batch.getOriginEntries()) {
// if chart code is empty while accounts cannot cross charts, then derive chart code from account number
if (StringUtils.isEmpty(originEntry.getChartOfAccountsCode())) {
if (acctserv.accountsCanCrossCharts()) {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_EMPTY_CHART, originEntry.getAccountNumber());
isValid = false;
}
else {
// accountNumber shall not be empty, otherwise won't pass schema validation
Account account = acctserv.getUniqueAccountForAccountNumber(originEntry.getAccountNumber());
if (account != null) {
originEntry.setChartOfAccountsCode(account.getChartOfAccountsCode());
}
else {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_INVALID_ACCOUNT, originEntry.getAccountNumber());
isValid = false;
}
}
}
}
}
if (batch.getCollectorDetails() != null) {
for (CollectorDetail collectorDetail : batch.getCollectorDetails()) {
// if chart code is empty while accounts cannot cross charts, then derive chart code from account number
if (StringUtils.isEmpty(collectorDetail.getChartOfAccountsCode())) {
if (acctserv.accountsCanCrossCharts()) {
// report error
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_EMPTY_CHART, collectorDetail.getAccountNumber());
isValid = false;
}
else {
// accountNumber shall not be empty, otherwise won't pass schema validation
Account account = acctserv.getUniqueAccountForAccountNumber(collectorDetail.getAccountNumber());
if (account != null) {
collectorDetail.setChartOfAccountsCode(account.getChartOfAccountsCode());
}
else {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_INVALID_ACCOUNT, collectorDetail.getAccountNumber());
isValid = false;
}
}
}
}
}
isValid &= collectorHelperService.performValidation(batch);
if (isValid) {
isValid = collectorHelperService.checkTrailerTotals(batch, null);
}
allBatchesValid &= isValid;
}
return allBatchesValid;
}
/**
* Returns the Collector's title key
*
* @return the title key for the Collector
* @see org.kuali.kfs.sys.batch.BatchInputFileType#getTitleKey()
*/
public String getTitleKey() {
return KFSKeyConstants.MESSAGE_BATCH_UPLOAD_TITLE_COLLECTOR;
}
public String getAuthorPrincipalName(File file) {
String[] fileNameParts = StringUtils.split(file.getName(), "_");
if (fileNameParts.length > 4) {
return fileNameParts[3];
}
return null;
}
@Override
public Object parse(byte[] fileByteContent) throws ParseException {
CollectorBatch batch = (CollectorBatch) super.parse(fileByteContent);
OriginEntryTotals totals = new OriginEntryTotals();
totals.addToTotals(batch.getOriginEntries().iterator());
batch.setOriginEntryTotals(totals);
return Arrays.asList(batch);
}
public void setDateTimeService(DateTimeService dateTimeService) {
this.dateTimeService = dateTimeService;
}
public void setCollectorHelperService(CollectorHelperService collectorHelperService) {
this.collectorHelperService = collectorHelperService;
}
}