001/*
002 * Copyright 2006 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 */
016package org.kuali.ole.fp.batch.service.impl;
017
018import java.io.FileInputStream;
019import java.io.FileNotFoundException;
020import java.io.IOException;
021import java.util.ArrayList;
022import java.util.Collection;
023import java.util.HashMap;
024import java.util.List;
025
026import org.apache.commons.io.IOUtils;
027import org.apache.commons.lang.NumberUtils;
028import org.apache.commons.lang.ObjectUtils;
029import org.kuali.ole.fp.batch.service.ProcurementCardLoadTransactionsService;
030import org.kuali.ole.fp.businessobject.ProcurementCardTransaction;
031import org.kuali.ole.sys.batch.BatchInputFileType;
032import org.kuali.ole.sys.batch.InitiateDirectoryBase;
033import org.kuali.ole.sys.batch.service.BatchInputFileService;
034import org.kuali.ole.sys.exception.ParseException;
035import org.kuali.ole.sys.service.ReportWriterService;
036import org.kuali.rice.krad.service.BusinessObjectService;
037
038/**
039 * This is the default implementation of the ProcurementCardLoadTransactionsService interface.
040 * Handles loading, parsing, and storing of incoming procurement card batch files.
041 * 
042 * @see org.kuali.ole.fp.batch.service.ProcurementCardCreateDocumentService
043 */
044public class ProcurementCardLoadTransactionsServiceImpl extends InitiateDirectoryBase implements ProcurementCardLoadTransactionsService {
045    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ProcurementCardLoadTransactionsServiceImpl.class);
046
047    protected BusinessObjectService businessObjectService;
048    protected BatchInputFileService batchInputFileService;
049    protected BatchInputFileType procurementCardInputFileType;
050
051    /**
052     * @see org.kuali.ole.fp.batch.service.ProcurementCardLoadTransactionsService#loadProcurementCardFile(java.lang.String, org.kuali.ole.sys.service.ReportWriterService)
053     */
054    public boolean loadProcurementCardFile(String fileName, ReportWriterService reportWriterService) {
055        
056        //add a step to check for directory paths
057        prepareDirectories(getRequiredDirectoryNames());
058        
059        FileInputStream fileContents;
060        try {
061            fileContents = new FileInputStream(fileName);
062        }
063        catch (FileNotFoundException e1) {
064            LOG.error("file to parse not found " + fileName, e1);
065            throw new RuntimeException("Cannot find the file requested to be parsed " + fileName + " " + e1.getMessage(), e1);
066        }
067
068        Collection pcardTransactions = new ArrayList();
069        try {
070            byte[] fileByteContent = IOUtils.toByteArray(fileContents);
071            pcardTransactions = (Collection) batchInputFileService.parse(procurementCardInputFileType, fileByteContent);
072        }
073        catch (IOException e) {
074            LOG.error("Error while getting file bytes:  " + e.getMessage(), e);
075            reportWriterService.writeFormattedMessageLine("%s cannot be processed. \n\tFile byptes error: %s", fileName, e.getMessage());
076            return false;
077        }
078        catch (ParseException e) {
079            LOG.error("Error parsing xml " + e.getMessage());
080            reportWriterService.writeFormattedMessageLine("%s cannot be processed. \n\tXML parsing error: %s", fileName, e.getMessage());
081            return false;
082        }
083
084        if (pcardTransactions.isEmpty()) {
085            LOG.warn("No PCard transactions in input file " + fileName);
086            reportWriterService.writeFormattedMessageLine("%s is processed. No PCard transactios in file. ", fileName);
087        }else{
088        loadTransactions((List) pcardTransactions);
089            LOG.info("Total transactions loaded: " + String.valueOf(pcardTransactions.size()));
090            reportWriterService.writeFormattedMessageLine("%s is processed. %d transaction(s) loaded. ", fileName, pcardTransactions.size());
091        }
092
093        return true;
094    }
095
096    /**
097     * Calls businessObjectService to remove all the procurement card transaction rows from the transaction load table.
098     */
099    public void cleanTransactionsTable() {
100        businessObjectService.deleteMatching(ProcurementCardTransaction.class, new HashMap());
101    }
102
103    /**
104     * Loads all the parsed XML transactions into the temp transaction table.
105     * 
106     * @param transactions List of ProcurementCardTransactions to load.
107     */
108    protected void loadTransactions(List transactions) {
109        businessObjectService.save(transactions);
110    }
111
112    /**
113     * Sets the businessObjectService attribute value.
114     * @param businessObjectService The businessObjectService to set.
115     */
116    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
117        this.businessObjectService = businessObjectService;
118    }
119
120    /**
121     * Sets the batchInputFileService attribute value.
122     * @param batchInputFileService The batchInputFileService to set.
123     */
124    public void setBatchInputFileService(BatchInputFileService batchInputFileService) {
125        this.batchInputFileService = batchInputFileService;
126    }
127
128    /**
129     * Sets the procurementCardInputFileType attribute value.
130     * @param procurementCardInputFileType The procurementCardInputFileType to set.
131     */
132    public void setProcurementCardInputFileType(BatchInputFileType procurementCardInputFileType) {
133        this.procurementCardInputFileType = procurementCardInputFileType;
134    }
135
136    /**
137     * @see org.kuali.ole.sys.batch.service.impl.InitiateDirectoryImpl#getRequiredDirectoryNames()
138     */
139    @Override
140    public List<String> getRequiredDirectoryNames() {
141        return new ArrayList<String>() {{add(procurementCardInputFileType.getDirectoryPath()); }};
142    }
143
144}