/*
* 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.module.ld.document.service.impl;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.kuali.kfs.gl.GeneralLedgerConstants;
import org.kuali.kfs.gl.businessobject.CorrectionChangeGroup;
import org.kuali.kfs.gl.businessobject.OriginEntryStatistics;
import org.kuali.kfs.gl.dataaccess.CorrectionChangeDao;
import org.kuali.kfs.gl.dataaccess.CorrectionChangeGroupDao;
import org.kuali.kfs.gl.dataaccess.CorrectionCriteriaDao;
import org.kuali.kfs.gl.document.CorrectionDocumentUtils;
import org.kuali.kfs.gl.document.service.impl.CorrectionDocumentServiceImpl;
import org.kuali.kfs.gl.document.web.CorrectionDocumentEntryMetadata;
import org.kuali.kfs.gl.report.CorrectionDocumentReport;
import org.kuali.kfs.gl.service.OriginEntryGroupService;
import org.kuali.kfs.module.ld.LaborPropertyConstants;
import org.kuali.kfs.module.ld.businessobject.LaborOriginEntry;
import org.kuali.kfs.module.ld.document.LaborCorrectionDocument;
import org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService;
import org.kuali.kfs.module.ld.service.LaborOriginEntryService;
import org.kuali.kfs.module.ld.util.LaborOriginEntryFileIterator;
import org.kuali.kfs.sys.FileUtil;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.service.DocumentNumberAwareReportWriterService;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.kew.api.WorkflowDocument;
import org.kuali.rice.kns.web.ui.Column;
import org.kuali.rice.krad.comparator.NumericValueComparator;
import org.kuali.rice.krad.comparator.StringValueComparator;
import org.kuali.rice.krad.comparator.TemporalValueComparator;
import org.kuali.rice.krad.dao.DocumentDao;
import org.springframework.transaction.annotation.Transactional;
/**
* Service implementation of LaborCorrectionDocumentService.
*/
@Transactional
public class LaborCorrectionDocumentServiceImpl extends CorrectionDocumentServiceImpl implements LaborCorrectionDocumentService {
private static Logger LOG = Logger.getLogger(LaborCorrectionDocumentServiceImpl.class);
protected OriginEntryGroupService originEntryGroupService;
private LaborOriginEntryService laborOriginEntryService;
private String llcpDirectoryName;
private String batchFileDirectoryName;
private DocumentDao documentDao;
private DocumentNumberAwareReportWriterService laborCorrectionDocumentReportWriterService;
protected static final String INPUT_ORIGIN_ENTRIES_FILE_SUFFIX = "-input.txt";
protected static final String OUTPUT_ORIGIN_ENTRIES_FILE_SUFFIX = "-output.txt";
protected static final String LLCP_OUTPUT_PREFIX = "llcp_output";
public final static int UNLIMITED_ABORT_THRESHOLD = CorrectionDocumentUtils.RECORD_COUNT_FUNCTIONALITY_LIMIT_IS_UNLIMITED;
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#findByDocumentNumberAndCorrectionChangeGroupNumber(java.lang.String,
* int)
*/
public CorrectionChangeGroup findByDocumentNumberAndCorrectionChangeGroupNumber(String docId, int i) {
return correctionChangeGroupDao.findByDocumentNumberAndCorrectionChangeGroupNumber(docId, i);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#findByDocumentHeaderIdAndCorrectionGroupNumber(java.lang.String,
* int)
*/
public List findByDocumentHeaderIdAndCorrectionGroupNumber(String docId, int i) {
return correctionChangeDao.findByDocumentHeaderIdAndCorrectionGroupNumber(docId, i);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#findByDocumentNumberAndCorrectionGroupNumber(java.lang.String,
* int)
*/
public List findByDocumentNumberAndCorrectionGroupNumber(String docId, int i) {
return correctionCriteriaDao.findByDocumentNumberAndCorrectionGroupNumber(docId, i);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#findByCorrectionDocumentHeaderId(java.lang.String)
*/
public LaborCorrectionDocument findByCorrectionDocumentHeaderId(String docId) {
return (LaborCorrectionDocument) documentDao.findByDocumentHeaderId(LaborCorrectionDocument.class, docId);
}
/**
* Sets the correctionChangeDao attribute value.
*
* @param correctionChangeDao The correctionChangeDao to set.
*/
public void setCorrectionChangeDao(CorrectionChangeDao correctionChangeDao) {
this.correctionChangeDao = correctionChangeDao;
}
/**
* Sets the correctionChangeDao attribute value.
*
* @param correctionChangeGroupDao The correctionChangeDao to set.
*/
public void setCorrectionChangeGroupDao(CorrectionChangeGroupDao correctionChangeGroupDao) {
this.correctionChangeGroupDao = correctionChangeGroupDao;
}
/**
* Sets the correctionCriteriaDao attribute value.
*
* @param correctionCriteriaDao The correctionCriteriaDao to set.
*/
public void setCorrectionCriteriaDao(CorrectionCriteriaDao correctionCriteriaDao) {
this.correctionCriteriaDao = correctionCriteriaDao;
}
/**
* Sets the documentDao attribute value.
*
* @param documentDao The documentDao to set.
*/
public void setDocumentDao(DocumentDao documentDao) {
this.documentDao = documentDao;
}
private List<Column> cachedColumns = null;
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#generateInputOriginEntryFileName(java.lang.String)
*/
protected String generateInputOriginEntryFileName(LaborCorrectionDocument document) {
String docId = document.getDocumentHeader().getDocumentNumber();
return generateInputOriginEntryFileName(docId);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#generateOutputOriginEntryFileName(java.lang.String)
*/
protected String generateOutputOriginEntryFileName(LaborCorrectionDocument document) {
String docId = document.getDocumentHeader().getDocumentNumber();
return generateOutputOriginEntryFileName(docId);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#generateInputOriginEntryFileName(java.lang.String)
*/
protected String generateInputOriginEntryFileName(String docId) {
return getOriginEntryStagingDirectoryPath() + File.separator + docId + INPUT_ORIGIN_ENTRIES_FILE_SUFFIX;
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#generateOutputOriginEntryFileName(java.lang.String)
*/
public String generateOutputOriginEntryFileName(String docId) {
return getOriginEntryStagingDirectoryPath() + File.separator + docId + OUTPUT_ORIGIN_ENTRIES_FILE_SUFFIX;
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#persistOriginEntriesToFile(org.kuali.kfs.module.ld.document.LaborCorrectionDocument,
* java.util.Iterator)
*/
public void persistInputOriginEntriesForInitiatedOrSavedDocument(LaborCorrectionDocument document, Iterator<LaborOriginEntry> entries) {
WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
if (!workflowDocument.isInitiated() && !workflowDocument.isSaved()) {
LOG.error("This method may only be called when the document is in the initiated or saved state.");
}
String fullPathUniqueFileName = generateInputOriginEntryFileName(document);
if ( LOG.isInfoEnabled() ) {
LOG.info( "About to save input labor origin entries for document " + document.getDocumentNumber() + " to file: " + fullPathUniqueFileName);
}
persistLaborOriginEntries(fullPathUniqueFileName, entries);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#persistOutputLaborOriginEntriesForInitiatedOrSavedDocument(org.kuali.kfs.module.ld.document.LaborCorrectionDocument,
* java.util.Iterator)
*/
public void persistOutputLaborOriginEntriesForInitiatedOrSavedDocument(LaborCorrectionDocument document, Iterator<LaborOriginEntry> entries) {
WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
if (!workflowDocument.isInitiated() && !workflowDocument.isSaved()) {
LOG.error("This method may only be called when the document is in the initiated or saved state.");
}
String fullPathUniqueFileName = generateOutputOriginEntryFileName(document);
if ( LOG.isInfoEnabled() ) {
LOG.info( "About to save output labor origin entries for document " + document.getDocumentNumber() + " to file: " + fullPathUniqueFileName);
}
persistLaborOriginEntries(fullPathUniqueFileName, entries);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#persistLaborOriginEntries(java.lang.String,
* java.util.Iterator)
*/
protected void persistLaborOriginEntries(String fullPathUniqueFileName, Iterator<LaborOriginEntry> entries) {
File fileOut = new File(fullPathUniqueFileName);
FileOutputStream streamOut = null;
BufferedOutputStream bufferedStreamOut = null;
try {
streamOut = new FileOutputStream(fileOut);
bufferedStreamOut = new BufferedOutputStream(streamOut);
byte[] newLine = "\n".getBytes();
while (entries.hasNext()) {
LaborOriginEntry entry = entries.next();
bufferedStreamOut.write(entry.getLine().getBytes());
bufferedStreamOut.write(newLine);
}
}
catch (IOException e) {
LOG.error("unable to persist labor origin entries to file: " + fullPathUniqueFileName, e);
throw new RuntimeException("unable to persist origin entries to file.", e);
}
finally {
try {
bufferedStreamOut.close();
streamOut.close();
}
catch (IOException e) {
LOG.error("unable to close output streams for file: " + fullPathUniqueFileName, e);
throw new RuntimeException("unable to close output streams", e);
}
}
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#openEntryOutputStreamForOutputGroup(org.kuali.kfs.module.ld.document.LaborCorrectionDocument)
*/
protected BufferedOutputStream openEntryOutputStreamForOutputGroup(LaborCorrectionDocument document) throws IOException {
String fullPathUniqueFileName = generateOutputOriginEntryFileName(document);
return new BufferedOutputStream(new FileOutputStream(fullPathUniqueFileName));
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#removePersistedInputOriginEntriesForInitiatedOrSavedDocument(org.kuali.kfs.module.ld.document.LaborCorrectionDocument)
*/
public void removePersistedInputOriginEntries(LaborCorrectionDocument document) {
String fullPathUniqueFileName = generateInputOriginEntryFileName(document);
removePersistedOriginEntries(fullPathUniqueFileName);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#removePersistedOutputOriginEntriesForInitiatedOrSavedDocument(org.kuali.kfs.module.ld.document.LaborCorrectionDocument)
*/
public void removePersistedOutputOriginEntries(LaborCorrectionDocument document) {
String fullPathUniqueFileName = generateOutputOriginEntryFileName(document);
removePersistedOriginEntries(fullPathUniqueFileName);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#removePersistedInputOriginEntries(java.lang.String)
*/
public void removePersistedInputOriginEntries(String docId) {
removePersistedOriginEntries(generateInputOriginEntryFileName(docId));
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#removePersistedOutputOriginEntries(java.lang.String)
*/
public void removePersistedOutputOriginEntries(String docId) {
removePersistedOriginEntries(generateOutputOriginEntryFileName(docId));
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#removePersistedOriginEntries(java.lang.String)
*/
protected void removePersistedOriginEntries(String fullPathUniqueFileName) {
File fileOut = new File(fullPathUniqueFileName);
if (fileOut.exists() && fileOut.isFile()) {
fileOut.delete();
}
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#retrievePersistedInputOriginEntries(org.kuali.kfs.module.ld.document.LaborCorrectionDocument,
* int)
*/
public List<LaborOriginEntry> retrievePersistedInputOriginEntries(LaborCorrectionDocument document, int abortThreshold) {
return retrievePersistedLaborOriginEntries(generateInputOriginEntryFileName(document), abortThreshold);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#retrievePersistedOutputOriginEntries(org.kuali.kfs.module.ld.document.LaborCorrectionDocument,
* int)
*/
public List<LaborOriginEntry> retrievePersistedOutputOriginEntries(LaborCorrectionDocument document, int abortThreshold) {
return retrievePersistedLaborOriginEntries(generateOutputOriginEntryFileName(document), abortThreshold);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#retrievePersistedLaborOriginEntries(java.lang.String, int)
*/
protected List<LaborOriginEntry> retrievePersistedLaborOriginEntries(String fullPathUniqueFileName, int abortThreshold) {
if ( LOG.isInfoEnabled() ) {
LOG.info( "Retrieving Entries from file " + fullPathUniqueFileName);
}
File fileIn = new File(fullPathUniqueFileName);
if (!fileIn.exists()) {
LOG.error("File " + fullPathUniqueFileName + " does not exist.");
throw new RuntimeException("File does not exist");
}
BufferedReader reader = null;
FileReader fReader = null;
List<LaborOriginEntry> entries = new ArrayList<LaborOriginEntry>();
int lineNumber = 0;
try {
fReader = new FileReader(fileIn);
reader = new BufferedReader(fReader);
String line;
while ((line = reader.readLine()) != null) {
LaborOriginEntry entry = new LaborOriginEntry();
entry.setFromTextFileForBatch(line, lineNumber);
if (abortThreshold != UNLIMITED_ABORT_THRESHOLD && lineNumber >= abortThreshold) {
return null;
}
lineNumber++;
entries.add(entry);
}
}
catch (IOException e) {
LOG.error("retrievePersistedOriginEntries() Error reading file " + fileIn.getAbsolutePath(), e);
throw new RuntimeException("Error reading file");
}
finally {
try {
if (fReader != null) {
fReader.close();
}
if (reader != null) {
reader.close();
}
}
catch (IOException e) {
LOG.error("Unable to close file " + fileIn.getAbsolutePath(), e);
throw new RuntimeException("Error closing file");
}
}
return entries;
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#retrievePersistedInputOriginEntriesAsIterator(org.kuali.kfs.module.ld.document.LaborCorrectionDocument)
*/
public Iterator<LaborOriginEntry> retrievePersistedInputOriginEntriesAsIterator(LaborCorrectionDocument document) {
String fullPathUniqueFileName = generateInputOriginEntryFileName(document);
return retrievePersistedLaborOriginEntriesAsIterator(fullPathUniqueFileName);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#retrievePersistedOutputOriginEntriesAsIterator(org.kuali.kfs.module.ld.document.LaborCorrectionDocument)
*/
public Iterator<LaborOriginEntry> retrievePersistedOutputOriginEntriesAsIterator(LaborCorrectionDocument document) {
String fullPathUniqueFileName = generateOutputOriginEntryFileName(document);
return retrievePersistedLaborOriginEntriesAsIterator(fullPathUniqueFileName);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#retrievePersistedLaborOriginEntriesAsIterator(java.lang.String)
*/
protected Iterator<LaborOriginEntry> retrievePersistedLaborOriginEntriesAsIterator(String fullPathUniqueFileName) {
if ( LOG.isInfoEnabled() ) {
LOG.info( "Retrieving Entries from file " + fullPathUniqueFileName);
}
File fileIn = new File(fullPathUniqueFileName);
if (!fileIn.exists()) {
LOG.error("File " + fullPathUniqueFileName + " does not exist.");
throw new RuntimeException("File does not exist");
}
BufferedReader reader = null;
FileReader fReader = null;
try {
fReader = new FileReader(fileIn);
reader = new BufferedReader(fReader);
return new LaborOriginEntryFileIterator(reader);
}
catch (IOException e) {
LOG.error("retrievePersistedOriginEntries() Error opening file " + fileIn.getAbsolutePath(), e);
throw new RuntimeException("Error opening file");
}
// don't close the reader, the iterator will take care of that
}
/**
* Returns true if and only if the file corresponding to this document's input origin entries are on the file system.
*
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#areInputOriginEntriesPersisted(org.kuali.kfs.module.ld.document.LaborCorrectionDocument)
*/
public boolean areInputOriginEntriesPersisted(LaborCorrectionDocument document) {
String fullPathUniqueFileName = generateInputOriginEntryFileName(document);
File file = new File(fullPathUniqueFileName);
return file.exists();
}
/**
* Returns true if and only if the file corresponding to this document's output origin entries are on the file system.
*
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#areOutputOriginEntriesPersisted(org.kuali.kfs.module.ld.document.LaborCorrectionDocument)
*/
public boolean areOutputOriginEntriesPersisted(LaborCorrectionDocument document) {
String fullPathUniqueFileName = generateOutputOriginEntryFileName(document);
File file = new File(fullPathUniqueFileName);
return file.exists();
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#writePersistedInputOriginEntriesToStream(java.io.OutputStream)
*/
public void writePersistedInputOriginEntriesToStream(LaborCorrectionDocument document, OutputStream out) throws IOException {
String fullPathUniqueFileName = generateInputOriginEntryFileName(document);
writePersistedOriginEntriesToStream(fullPathUniqueFileName, out);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#writePersistedOutputOriginEntriesToStream(java.io.OutputStream)
*/
public void writePersistedOutputOriginEntriesToStream(LaborCorrectionDocument document, OutputStream out) throws IOException {
String fullPathUniqueFileName = generateOutputOriginEntryFileName(document);
writePersistedOriginEntriesToStream(fullPathUniqueFileName, out);
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#writePersistedOriginEntriesToStream(java.lang.String,
* java.io.OutputStream)
*/
protected void writePersistedOriginEntriesToStream(String fullPathUniqueFileName, OutputStream out) throws IOException {
FileInputStream fileIn = new FileInputStream(fullPathUniqueFileName);
try {
byte[] buf = new byte[1000];
int bytesRead;
while ((bytesRead = fileIn.read(buf)) != -1) {
out.write(buf, 0, bytesRead);
}
} catch ( IOException ex ) {
LOG.error("Unable to write origin entries from " + fullPathUniqueFileName + "to output stream.",ex);
throw ex;
} catch ( RuntimeException ex ) {
LOG.error("Unable to write origin entries from " + fullPathUniqueFileName + "to output stream.",ex);
throw ex;
} finally {
fileIn.close();
}
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#writePersistedOriginEntriesToStream(org.kuali.kfs.module.ld.document.LaborCorrectionDocument,
* org.kuali.module.gl.util)
*/
public void persistOriginEntryGroupsForDocumentSave(LaborCorrectionDocument document, CorrectionDocumentEntryMetadata correctionDocumentEntryMetadata) {
if (correctionDocumentEntryMetadata.getAllEntries() == null && !correctionDocumentEntryMetadata.isRestrictedFunctionalityMode()) {
// if we don't have origin entries loaded and not in restricted functionality mode, then there's nothing worth
// persisting
removePersistedInputOriginEntries(document);
removePersistedOutputOriginEntries(document);
return;
}
if (!correctionDocumentEntryMetadata.getDataLoadedFlag() && !correctionDocumentEntryMetadata.isRestrictedFunctionalityMode()) {
// data is not loaded (maybe user selected a new group with no rows)
// clear out existing data
removePersistedInputOriginEntries(document);
removePersistedOutputOriginEntries(document);
return;
}
// reload the group from the origin entry service
Iterator<LaborOriginEntry> inputGroupEntries;
WorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
if ((workflowDocument.isSaved() && !(correctionDocumentEntryMetadata.getInputGroupIdFromLastDocumentLoad() != null && correctionDocumentEntryMetadata.getInputGroupIdFromLastDocumentLoad().equals(document.getCorrectionInputFileName()))) || workflowDocument.isInitiated()) {
// we haven't saved the origin entry group yet, so let's load the entries from the DB and persist them for the document
// this could be because we've previously saved the doc, but now we are now using a new input group, so we have to
// repersist the input group
//OriginEntryGroup group = originEntryGroupService.getExactMatchingEntryGroup(document.getCorrectionInputGroupId());
File file = new File(document.getCorrectionInputFileName());
inputGroupEntries = new LaborOriginEntryFileIterator(file);
persistInputOriginEntriesForInitiatedOrSavedDocument(document, inputGroupEntries);
// we've exhausted the iterator for the origin entries group
// reload the iterator from the file
inputGroupEntries = retrievePersistedInputOriginEntriesAsIterator(document);
}
else if (workflowDocument.isSaved() && correctionDocumentEntryMetadata.getInputGroupIdFromLastDocumentLoad().equals(document.getCorrectionInputFileName())) {
// we've saved the origin entries before, so just retrieve them
inputGroupEntries = retrievePersistedInputOriginEntriesAsIterator(document);
}
else {
LOG.error("Unexpected state while trying to persist/retrieve GLCP origin entries during document save: document status is " + workflowDocument.getStatus().values().toString() + " selected input group: " + document.getCorrectionInputFileName() + " last saved input group: " + correctionDocumentEntryMetadata.getInputGroupIdFromLastDocumentLoad());
throw new RuntimeException("Error persisting GLCP document origin entries.");
}
OriginEntryStatistics statistics;
if (LaborCorrectionDocumentService.CORRECTION_TYPE_MANUAL.equals(correctionDocumentEntryMetadata.getEditMethod())) {
// persist the allEntries element as the output group, since it has all of the modifications made by during the manual
// edits
Collection allEntries = new ArrayList();
allEntries.addAll(correctionDocumentEntryMetadata.getAllEntries());
persistOutputLaborOriginEntriesForInitiatedOrSavedDocument(document, allEntries.iterator());
// even though the struts action handler may have computed the doc totals, let's recompute them
statistics = CorrectionDocumentUtils.getStatistics(correctionDocumentEntryMetadata.getAllEntries());
}
else if (LaborCorrectionDocumentService.CORRECTION_TYPE_CRITERIA.equals(correctionDocumentEntryMetadata.getEditMethod())) {
// we want to persist the values of the output group. So reapply all of the criteria on each entry, one at a time
BufferedOutputStream bufferedOutputStream = null;
try {
bufferedOutputStream = openEntryOutputStreamForOutputGroup(document);
statistics = new OriginEntryStatistics();
byte[] newLine = "\n".getBytes();
while (inputGroupEntries.hasNext()) {
LaborOriginEntry entry = inputGroupEntries.next();
entry = (LaborOriginEntry) CorrectionDocumentUtils.applyCriteriaToEntry(entry, correctionDocumentEntryMetadata.getMatchCriteriaOnly(), document.getCorrectionChangeGroup());
if (entry != null) {
CorrectionDocumentUtils.updateStatisticsWithEntry(entry, statistics);
bufferedOutputStream.write(entry.getLine().getBytes());
bufferedOutputStream.write(newLine);
}
// else it was null, which means that the match criteria only flag was set, and the entry didn't match the
// criteria
}
}
catch (IOException e) {
LOG.error("Unable to persist persisted output entry", e);
throw new RuntimeException("Unable to persist output entry",e);
}
finally {
if (bufferedOutputStream != null) {
try {
bufferedOutputStream.close();
}
catch (IOException e) {
LOG.error("Unable to close output stream for persisted output entries", e);
throw new RuntimeException("Unable to close output entry file",e);
}
}
}
}
else if (LaborCorrectionDocumentService.CORRECTION_TYPE_REMOVE_GROUP_FROM_PROCESSING.equals(correctionDocumentEntryMetadata.getEditMethod())) {
// just wipe out the previous output entries
removePersistedOutputOriginEntries(document);
statistics = new OriginEntryStatistics();
}
else {
throw new RuntimeException("Unrecognized edit method: " + correctionDocumentEntryMetadata.getEditMethod());
}
CorrectionDocumentUtils.copyStatisticsToDocument(statistics, document);
}
/**
*
*/
public String createOutputFileForProcessing(String docId, java.util.Date today) {
File outputFile = new File(llcpDirectoryName + File.separator + docId + OUTPUT_ORIGIN_ENTRIES_FILE_SUFFIX);
String newFileName = batchFileDirectoryName + File.separator + LLCP_OUTPUT_PREFIX + "." + docId + buildFileExtensionWithDate(today);
File newFile = new File (newFileName);
FileReader inputFileReader;
FileWriter newFileWriter;
try{
// copy output file and put in OriginEntryInformation directory
inputFileReader = new FileReader(outputFile);
newFileWriter = new FileWriter(newFile);
int c;
while ((c = inputFileReader.read()) != -1){
newFileWriter.write(c);
}
inputFileReader.close();
newFileWriter.close();
// create done file, after successfully copying output file
String doneFileName = newFileName.replace(GeneralLedgerConstants.BatchFileSystem.EXTENSION, GeneralLedgerConstants.BatchFileSystem.DONE_FILE_EXTENSION);
File doneFile = new File(doneFileName);
if (!doneFile.exists()){
doneFile.createNewFile();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return newFileName;
}
/**
* Gets the OriginEntryStagingDirectoryPath attribute.
*
* @return Returns the getLlcpDirectoryName.
*/
protected String getOriginEntryStagingDirectoryPath() {
return getLlcpDirectoryName();
}
/**
* Gets the kualiConfigurationService attribute.
*
* @return Returns the kualiConfigurationService.
*/
public ConfigurationService getConfigurationService() {
return kualiConfigurationService;
}
/**
* Sets the kualiConfigurationService attribute value.
*
* @param kualiConfigurationService The kualiConfigurationService to set.
*/
public void setConfigurationService(ConfigurationService kualiConfigurationService) {
this.kualiConfigurationService = kualiConfigurationService;
}
/**
* Sets the originEntryService attribute value.
*
* @param originEntryService The originEntryService to set.
*/
public void setLaborOriginEntryService(LaborOriginEntryService laborOriginEntryService) {
this.laborOriginEntryService = laborOriginEntryService;
}
/**
* Gets the llcpDirectoryName attribute.
*
* @return Returns the llcpDirectoryName.
*/
public String getLlcpDirectoryName() {
return llcpDirectoryName;
}
/**
* Sets the llcpDirectoryName attribute value.
*
* @param llcpDirectoryName The llcpDirectoryName to set.
*/
public void setLlcpDirectoryName(String llcpDirectoryName) {
this.llcpDirectoryName = llcpDirectoryName;
//check directory directly when path is set
FileUtil.createDirectory(llcpDirectoryName);
}
/**
* Gets the originEntryGroupService attribute.
*
* @return Returns the originEntryGroupService.
*/
public OriginEntryGroupService getOriginEntryGroupService() {
return originEntryGroupService;
}
/**
* Sets the originEntryGroupService attribute value.
*
* @param originEntryGroupService The originEntryGroupService to set.
*/
public void setOriginEntryGroupService(OriginEntryGroupService originEntryGroupService) {
this.originEntryGroupService = originEntryGroupService;
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#getTableRenderColumnMetadata(java.lang.String)
*/
public List<Column> getTableRenderColumnMetadata(String docId) {
synchronized (this) {
if (cachedColumns == null) {
cachedColumns = new ArrayList<Column>();
Column columnToAdd;
columnToAdd = new Column();
columnToAdd.setColumnTitle("Fiscal Year");
columnToAdd.setPropertyName(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR);
columnToAdd.setValueComparator(NumericValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Chart Code");
columnToAdd.setPropertyName(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Account Number");
columnToAdd.setPropertyName(KFSPropertyConstants.ACCOUNT_NUMBER);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Sub Account Number");
columnToAdd.setPropertyName(KFSPropertyConstants.SUB_ACCOUNT_NUMBER);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Object Code");
columnToAdd.setPropertyName(KFSPropertyConstants.FINANCIAL_OBJECT_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Sub Object Code");
columnToAdd.setPropertyName(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Balance Type");
columnToAdd.setPropertyName(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Object Type");
columnToAdd.setPropertyName(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Fiscal Period");
columnToAdd.setPropertyName(KFSPropertyConstants.UNIVERSITY_FISCAL_PERIOD_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Document Type");
columnToAdd.setPropertyName(KFSPropertyConstants.FINANCIAL_DOCUMENT_TYPE_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Origin Code");
columnToAdd.setPropertyName(KFSPropertyConstants.FINANCIAL_SYSTEM_ORIGINATION_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Document Number");
columnToAdd.setPropertyName(KFSPropertyConstants.DOCUMENT_NUMBER);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Sequence Number");
columnToAdd.setValueComparator(NumericValueComparator.getInstance());
columnToAdd.setPropertyName(KFSPropertyConstants.TRANSACTION_ENTRY_SEQUENCE_NUMBER);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Position Number");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(KFSPropertyConstants.POSITION_NUMBER);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Project Code");
columnToAdd.setPropertyName(KFSPropertyConstants.PROJECT_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Description");
columnToAdd.setPropertyName(KFSPropertyConstants.TRANSACTION_LEDGER_ENTRY_DESC);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Amount");
columnToAdd.setValueComparator(NumericValueComparator.getInstance());
columnToAdd.setPropertyName(KFSPropertyConstants.TRANSACTION_LEDGER_ENTRY_AMOUNT);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Debit Credit Indicator");
columnToAdd.setPropertyName(KFSPropertyConstants.TRANSACTION_DEBIT_CREDIT_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Transaction Date");
columnToAdd.setPropertyName(KFSPropertyConstants.TRANSACTION_DATE);
columnToAdd.setValueComparator(TemporalValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Org Doc Number");
columnToAdd.setPropertyName(KFSPropertyConstants.ORGANIZATION_DOCUMENT_NUMBER);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Org Ref ID");
columnToAdd.setPropertyName(KFSPropertyConstants.ORGANIZATION_REFERENCE_ID);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Ref Doc Type");
columnToAdd.setPropertyName(KFSPropertyConstants.REFERENCE_FIN_DOCUMENT_TYPE_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Ref Origin Code");
columnToAdd.setPropertyName(KFSPropertyConstants.REFERENCE_FINANCIAL_SYSTEM_ORIGINATION_CODE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Ref Doc Number");
columnToAdd.setPropertyName(KFSPropertyConstants.FINANCIAL_DOCUMENT_REFERENCE_NBR);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Reversal Date");
columnToAdd.setPropertyName(KFSPropertyConstants.FINANCIAL_DOCUMENT_REVERSAL_DATE);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Enc Update Code");
columnToAdd.setPropertyName(KFSPropertyConstants.TRANSACTION_ENCUMBRANCE_UPDT_CD);
columnToAdd.setValueComparator(StringValueComparator.getInstance());
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Transaction Posting Date");
columnToAdd.setValueComparator(TemporalValueComparator.getInstance());
columnToAdd.setPropertyName(KFSPropertyConstants.TRANSACTION_POSTING_DATE);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Pay Period End Date");
columnToAdd.setValueComparator(TemporalValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.PAY_PERIOD_END_DATE);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Trn Total Hours");
columnToAdd.setValueComparator(NumericValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.TRANSACTION_TOTAL_HOURS);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Payroll EndDate Fiscal Year");
columnToAdd.setValueComparator(NumericValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.PAYROLL_END_DATE_FISCAL_YEAR);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Payroll EndDate Fiscal Period Code");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.PAYROLL_END_DATE_FISCAL_PERIOD_CODE);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Empl Id");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(KFSPropertyConstants.EMPLID);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Empl Record");
columnToAdd.setValueComparator(NumericValueComparator.getInstance());
columnToAdd.setPropertyName(KFSPropertyConstants.EMPLOYEE_RECORD);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Earn Code");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.EARN_CODE);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Pay Group");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.PAY_GROUP);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Salary Admin Plan");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.SALARY_ADMINISTRATION_PLAN);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Grade");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.GRADE);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Run Id");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.RUN_IDENTIFIER);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Original Chart Code");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.LABORLEDGER_ORIGINAL_CHART_OF_ACCOUNTS_CODE);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Original Account Number");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.LABORLEDGER_ORIGINAL_ACCOUNT_NUMBER);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Original Sub-Account Number");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.LABORLEDGER_ORIGINAL_SUB_ACCOUNT_NUMBER);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Original Object Code");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.LABORLEDGER_ORIGINAL_FINANCIAL_OBJECT_CODE);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Original Sub-Object Code");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.LABORLEDGER_ORIGINAL_FINANCIAL_SUB_OBJECT_CODE);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("Company");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.HRMS_COMPANY);
cachedColumns.add(columnToAdd);
columnToAdd = new Column();
columnToAdd.setColumnTitle("SetId");
columnToAdd.setValueComparator(StringValueComparator.getInstance());
columnToAdd.setPropertyName(LaborPropertyConstants.SET_ID);
cachedColumns.add(columnToAdd);
cachedColumns = Collections.unmodifiableList(cachedColumns);
}
}
return cachedColumns;
}
/**
* @see org.kuali.kfs.module.ld.document.service.LaborCorrectionDocumentService#generateCorrectionReport(org.kuali.kfs.module.ld.document.LaborCorrectionDocument)
*/
public void generateCorrectionReport(LaborCorrectionDocument document) {
CorrectionDocumentReport correctionReport = new CorrectionDocumentReport();
correctionReport.generateReport(laborCorrectionDocumentReportWriterService, document);
}
public void setBatchFileDirectoryName(String batchFileDirectoryName) {
this.batchFileDirectoryName = batchFileDirectoryName;
}
public String getBatchFileDirectoryName() {
return batchFileDirectoryName;
}
/**
* @return Returns the laborCorrectionDocumentReportWriterService.
*/
protected DocumentNumberAwareReportWriterService getLaborCorrectionDocumentReportWriterService() {
return laborCorrectionDocumentReportWriterService;
}
/**
* @param laborCorrectionDocumentReportWriterService The laborCorrectionDocumentReportWriterService to set.
*/
public void setLaborCorrectionDocumentReportWriterService(DocumentNumberAwareReportWriterService laborCorrectionDocumentReportWriterService) {
this.laborCorrectionDocumentReportWriterService = laborCorrectionDocumentReportWriterService;
}
protected static class LlcpFilenameFilter implements FilenameFilter {
String documentNumber;
public LlcpFilenameFilter( String documentNumber ) {
this.documentNumber = documentNumber;
}
public boolean accept(File dir, String name) {
return name.startsWith(LLCP_OUTPUT_PREFIX + "." + documentNumber);
}
}
@Override
public String[] findExistingCorrectionOutputFilesForDocument( String documentNumber ) {
return new File(batchFileDirectoryName).list( new LlcpFilenameFilter(documentNumber));
}
}