/*
* 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.pdp.batch;
import java.io.File;
import java.sql.Timestamp;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.Account;
import org.kuali.kfs.coa.service.AccountService;
import org.kuali.kfs.pdp.PdpConstants;
import org.kuali.kfs.pdp.PdpKeyConstants;
import org.kuali.kfs.pdp.businessobject.LoadPaymentStatus;
import org.kuali.kfs.pdp.businessobject.PaymentAccountDetail;
import org.kuali.kfs.pdp.businessobject.PaymentDetail;
import org.kuali.kfs.pdp.businessobject.PaymentFileLoad;
import org.kuali.kfs.pdp.businessobject.PaymentGroup;
import org.kuali.kfs.pdp.service.PaymentFileService;
import org.kuali.kfs.pdp.service.PdpEmailService;
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;
import org.kuali.rice.krad.util.MessageMap;
/**
* Batch input type for the PDP payment file.
*/
public class PaymentInputFileType extends XmlBatchInputFileTypeBase {
private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PaymentInputFileType.class);
private DateTimeService dateTimeService;
private PaymentFileService paymentFileService;
private PdpEmailService paymentFileEmailService;
/**
* @see org.kuali.kfs.sys.batch.BatchInputFileType#getFileName(org.kuali.rice.kim.api.identity.Person, java.lang.Object,
* java.lang.String)
*/
@Override
public String getFileName(String principalName, Object parsedFileContents, String fileUserIdentifer) {
Timestamp currentTimestamp = dateTimeService.getCurrentTimestamp();
String fileName = PdpConstants.PDP_FILE_UPLOAD_FILE_PREFIX + "_" + principalName;
if (StringUtils.isNotBlank(fileUserIdentifer)) {
fileName += "_" + StringUtils.remove(fileUserIdentifer, " ");
}
fileName += "_" + dateTimeService.toString(currentTimestamp, "yyyyMMdd_HHmmss");
// remove spaces in filename
fileName = StringUtils.remove(fileName, " ");
return fileName;
}
@Override
public String getAuthorPrincipalName(File file) {
String[] fileNameParts = StringUtils.split(file.getName(), "_");
if (fileNameParts.length > 3) {
return fileNameParts[2];
}
return null;
}
/**
* @see org.kuali.kfs.sys.batch.BatchInputFileType#getFileTypeIdentifer()
*/
@Override
public String getFileTypeIdentifer() {
return PdpConstants.PAYMENT_FILE_TYPE_INDENTIFIER;
}
/**
* @see org.kuali.kfs.sys.batch.BatchInputFileType#validate(java.lang.Object)
*/
@Override
public boolean validate(Object parsedFileContents) {
PaymentFileLoad paymentFile = (PaymentFileLoad) parsedFileContents;
// 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);
boolean validAccounts = true;
if (paymentFile.getPaymentGroups() != null) {
for (PaymentGroup payGroup : paymentFile.getPaymentGroups()) {
if (payGroup.getPaymentDetails() == null) {
continue;
}
for (PaymentDetail payDetail : payGroup.getPaymentDetails()) {
if (payDetail.getAccountDetail() == null) {
continue;
}
for (PaymentAccountDetail acctDetail : payDetail.getAccountDetail()) {
// if chart code is empty while accounts cannot cross charts, then derive chart code from account number
if (StringUtils.isEmpty(acctDetail.getFinChartCode())) {
if (acctserv.accountsCanCrossCharts()) {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_EMPTY_CHART, acctDetail.getAccountNbr());
validAccounts = false;
}
else {
// accountNumber shall not be empty, otherwise won't pass schema validation
Account account = acctserv.getUniqueAccountForAccountNumber(acctDetail.getAccountNbr());
if (account != null) {
acctDetail.setFinChartCode(account.getChartOfAccountsCode());
}
else {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_FILE_INVALID_ACCOUNT, acctDetail.getAccountNbr());
validAccounts = false;
}
}
}
}
}
}
}
paymentFileService.doPaymentFileValidation(paymentFile, GlobalVariables.getMessageMap());
return validAccounts && paymentFile.isPassedValidation();
}
/**
* @see org.kuali.kfs.sys.batch.BatchInputType#getTitleKey()
*/
@Override
public String getTitleKey() {
return PdpKeyConstants.MESSAGE_BATCH_UPLOAD_TITLE_PAYMENT;
}
/**
* @see org.kuali.kfs.sys.batch.BatchInputFileTypeBase#process(java.lang.String, java.lang.Object)
*/
@Override
public void process(String fileName, Object parsedFileContents) {
PaymentFileLoad paymentFile = (PaymentFileLoad) parsedFileContents;
if (paymentFile.isPassedValidation()) {
// collect various information for status of load
LoadPaymentStatus status = new LoadPaymentStatus();
status.setMessageMap(new MessageMap());
paymentFileService.loadPayments(paymentFile, status, fileName);
paymentFileService.createOutputFile(status, fileName);
}
}
/**
* Overridden so we can send the error email here. (keep it consistent between the batch processing and the
* online file upload web processing)
*
* @see org.kuali.kfs.sys.batch.XmlBatchInputFileTypeBase#parse(byte[])
*/
@Override
public Object parse(byte[] fileByteContent) throws ParseException {
PaymentFileLoad paymentFile = null;
try {
paymentFile = (PaymentFileLoad) super.parse(fileByteContent);
} catch (ParseException e1) {
LOG.error("Error parsing xml contents: " + e1.getMessage());
MessageMap errorMap = new MessageMap();
errorMap.putError(KFSConstants.GLOBAL_ERRORS, KFSKeyConstants.ERROR_BATCH_UPLOAD_PARSING_XML, new String[] { "Error parsing xml contents: " + e1.getMessage() });
// Send error email
paymentFileEmailService.sendErrorEmail(paymentFile, errorMap);
throw new ParseException("Error parsing xml contents: " + e1.getMessage(), e1);
}
return paymentFile;
}
/**
* Sets the paymentFileService attribute value.
*
* @param paymentFileService The paymentFileService to set.
*/
public void setPaymentFileService(PaymentFileService paymentFileService) {
this.paymentFileService = paymentFileService;
}
/**
* Sets the dateTimeService attribute value.
*
* @param dateTimeService The dateTimeService to set.
*/
public void setDateTimeService(DateTimeService dateTimeService) {
this.dateTimeService = dateTimeService;
}
/**
* Sets the paymentFileEmailService attribute value.
*
* @param paymentFileEmailService The paymentFileEmailService to set.
*/
public void setPaymentFileEmailService(PdpEmailService paymentFileEmailService) {
this.paymentFileEmailService = paymentFileEmailService;
}
}