com.ut.healthelink.service.impl.transactionInManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.ut.healthelink.service.impl.transactionInManagerImpl.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ut.healthelink.service.impl;

import com.ut.healthelink.dao.messageTypeDAO;
import com.ut.healthelink.dao.transactionInDAO;
import com.ut.healthelink.dao.transactionOutDAO;
import com.ut.healthelink.model.CrosswalkData;
import com.ut.healthelink.model.Macros;
import com.ut.healthelink.model.Organization;
import com.ut.healthelink.model.MoveFilesLog;
import com.ut.healthelink.model.Transaction;
import com.ut.healthelink.model.TransactionInError;
import com.ut.healthelink.model.User;
import com.ut.healthelink.model.UserActivity;
import com.ut.healthelink.model.batchMultipleTargets;
import com.ut.healthelink.model.batchUploadSummary;
import com.ut.healthelink.model.batchUploads;
import com.ut.healthelink.model.configurationConnection;
import com.ut.healthelink.model.configurationDataTranslations;
import com.ut.healthelink.model.configurationFTPFields;
import com.ut.healthelink.model.configurationFormFields;
import com.ut.healthelink.model.configurationMessageSpecs;
import com.ut.healthelink.model.configurationRhapsodyFields;
import com.ut.healthelink.model.configurationTransport;
import com.ut.healthelink.model.fieldSelectOptions;
import com.ut.healthelink.model.mailMessage;
import com.ut.healthelink.model.transactionAttachment;
import com.ut.healthelink.model.transactionIn;
import com.ut.healthelink.model.transactionInRecords;
import com.ut.healthelink.model.transactionRecords;
import com.ut.healthelink.model.transactionTarget;
import com.ut.healthelink.model.custom.ConfigErrorInfo;
import com.ut.healthelink.model.custom.ConfigForInsert;
import com.ut.healthelink.model.custom.IdAndFieldValue;
import com.ut.healthelink.model.custom.TransErrorDetail;
import com.ut.healthelink.model.custom.TransErrorDetailDisplay;
import com.ut.healthelink.model.lutables.lu_ProcessStatus;
import com.ut.healthelink.model.messagePatients;
import com.ut.healthelink.model.systemSummary;
import com.ut.healthelink.reference.fileSystem;
import com.ut.healthelink.service.CCDtoTxt;
import com.ut.healthelink.service.configurationManager;
import com.ut.healthelink.service.configurationTransportManager;
import com.ut.healthelink.service.emailMessageManager;
import com.ut.healthelink.service.fileManager;
import com.ut.healthelink.service.hl7toTxt;
import com.ut.healthelink.service.messageTypeManager;
import com.ut.healthelink.service.organizationManager;
import com.ut.healthelink.service.sysAdminManager;
import com.ut.healthelink.service.userManager;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import org.springframework.stereotype.Service;

import com.ut.healthelink.service.transactionInManager;

import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.filefilter.HiddenFileFilter;
import org.apache.commons.validator.routines.UrlValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 *
 * @author chadmccue
 */
@Service
public class transactionInManagerImpl implements transactionInManager {

    @Autowired
    private transactionInDAO transactionInDAO;

    @Autowired
    private messageTypeDAO messageTypeDAO;

    @Autowired
    private configurationManager configurationManager;

    @Autowired
    private configurationTransportManager configurationtransportmanager;

    @Autowired
    private messageTypeManager messagetypemanager;

    @Autowired
    private organizationManager organizationmanager;

    @Autowired
    private transactionOutDAO transactionOutDAO;

    @Autowired
    private sysAdminManager sysAdminManager;

    @Autowired
    private userManager usermanager;

    @Autowired
    private fileManager filemanager;

    @Autowired
    private hl7toTxt hl7toTxt;

    @Autowired
    private CCDtoTxt ccdtotxt;

    @Autowired
    private emailMessageManager emailManager;

    private int processingSysErrorId = 5;

    //final status Ids
    private List<Integer> finalStatusIds = Arrays.asList(11, 12, 13, 16);

    private String archivePath = "/bowlink/archivesIn/";

    @Override
    @Transactional
    public String getFieldValue(String tableName, String tableCol, String idCol, int idValue) {
        return transactionInDAO.getFieldValue(tableName, tableCol, idCol, idValue);
    }

    @Override
    @Transactional
    public List<fieldSelectOptions> getFieldSelectOptions(int fieldId, int configId) {
        return transactionInDAO.getFieldSelectOptions(fieldId, configId);
    }

    @Override
    @Transactional
    public Integer submitBatchUpload(batchUploads batchUpload) throws Exception {
        return transactionInDAO.submitBatchUpload(batchUpload);
    }

    @Override
    @Transactional
    public void submitBatchUploadSummary(batchUploadSummary summary) throws Exception {
        transactionInDAO.submitBatchUploadSummary(summary);
    }

    @Override
    @Transactional
    public void submitBatchUploadChanges(batchUploads batchUpload) throws Exception {
        transactionInDAO.submitBatchUploadChanges(batchUpload);
    }

    @Override
    @Transactional
    public Integer submitTransactionIn(transactionIn transactionIn) throws Exception {
        return transactionInDAO.submitTransactionIn(transactionIn);
    }

    @Override
    @Transactional
    public void submitTransactionInChanges(transactionIn transactionIn) throws Exception {
        transactionInDAO.submitTransactionInChanges(transactionIn);
    }

    @Override
    @Transactional
    public Integer submitTransactionInRecords(transactionInRecords records) throws Exception {
        return transactionInDAO.submitTransactionInRecords(records);
    }

    @Override
    @Transactional
    public void submitTransactionInRecordsUpdates(transactionInRecords records) throws Exception {
        transactionInDAO.submitTransactionInRecordsUpdates(records);
    }

    @Override
    @Transactional
    public void submitTransactionTranslatedInRecords(int transactionId, int transactionRecordId, int configId)
            throws Exception {
        transactionInDAO.submitTransactionTranslatedInRecords(transactionId, transactionRecordId, configId);
    }

    @Override
    @Transactional
    public List<batchUploads> getpendingBatches(int userId, int orgId, Date fromDate, Date toDate)
            throws Exception {
        return transactionInDAO.getpendingBatches(userId, orgId, fromDate, toDate);
    }

    @Override
    @Transactional
    public List<transactionIn> getBatchTransactions(int batchId, int userId) throws Exception {
        return transactionInDAO.getBatchTransactions(batchId, userId);
    }

    @Override
    @Transactional
    public List<batchUploads> getsentBatches(int userId, int orgId, Date fromDate, Date toDate) throws Exception {
        return transactionInDAO.getsentBatches(userId, orgId, fromDate, toDate);
    }

    @Override
    @Transactional
    public batchUploads getBatchDetails(int batchId) throws Exception {
        return transactionInDAO.getBatchDetails(batchId);
    }

    @Override
    @Transactional
    public batchUploads getBatchDetailsByBatchName(String batchName) throws Exception {
        return transactionInDAO.getBatchDetailsByBatchName(batchName);
    }

    @Override
    @Transactional
    public transactionIn getTransactionDetails(int transactionId) throws Exception {
        return transactionInDAO.getTransactionDetails(transactionId);
    }

    @Override
    @Transactional
    public transactionInRecords getTransactionRecords(int transactionId) {
        return transactionInDAO.getTransactionRecords(transactionId);
    }

    @Override
    @Transactional
    public transactionInRecords getTransactionRecord(int recordId) {
        return transactionInDAO.getTransactionRecord(recordId);
    }

    @Override
    @Transactional
    public void submitTransactionTarget(transactionTarget transactionTarget) {
        transactionInDAO.submitTransactionTarget(transactionTarget);
    }

    @Override
    @Transactional
    public transactionTarget getTransactionTargetDetails(int transactionTargetId) {
        return transactionInDAO.getTransactionTargetDetails(transactionTargetId);
    }

    @Override
    @Transactional
    public void submitTransactionTargetChanges(transactionTarget transactionTarget) throws Exception {
        transactionInDAO.submitTransactionTargetChanges(transactionTarget);
    }

    @Override
    @Transactional
    public transactionTarget getTransactionTarget(int batchUploadId, int transactionInId) {
        return transactionInDAO.getTransactionTarget(batchUploadId, transactionInId);
    }

    /**
     * The 'uploadAttachment' function will take in the file and orgName and upload the file to the appropriate file on the file system.
     *
     * @param fileUpload The file to be uploaded
     * @param orgName The organization name that is uploading the file. This will be the folder where to save the file to.
     */
    @Override
    public String uploadAttachment(MultipartFile fileUpload, String orgName) throws Exception {

        MultipartFile file = fileUpload;
        String fileName = file.getOriginalFilename();

        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            inputStream = file.getInputStream();
            File newFile = null;

            //Set the directory to save the brochures to
            fileSystem dir = new fileSystem();
            dir.setDir(orgName, "attachments");

            newFile = new File(dir.getDir() + fileName);

            if (newFile.exists()) {
                int i = 1;
                while (newFile.exists()) {
                    int iDot = fileName.lastIndexOf(".");
                    newFile = new File(dir.getDir() + fileName.substring(0, iDot) + "_(" + ++i + ")"
                            + fileName.substring(iDot));
                }
                fileName = newFile.getName();
            } else {
                newFile.createNewFile();
            }

            outputStream = new FileOutputStream(newFile);
            int read = 0;
            byte[] bytes = new byte[1024];

            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
            outputStream.close();

            //Save the attachment
        } catch (IOException e) {
            e.printStackTrace();
        }

        return fileName;
    }

    @Override
    @Transactional
    public Integer submitAttachment(transactionAttachment attachment) throws Exception {
        return transactionInDAO.submitAttachment(attachment);
    }

    @Override
    @Transactional
    public transactionAttachment getAttachmentById(int attachmentId) throws Exception {
        return transactionInDAO.getAttachmentById(attachmentId);
    }

    @Override
    @Transactional
    public void submitAttachmentChanges(transactionAttachment attachment) throws Exception {
        transactionInDAO.submitAttachmentChanges(attachment);
    }

    @Override
    @Transactional
    public List<transactionAttachment> getAttachmentsByTransactionId(int transactionInId) throws Exception {
        return transactionInDAO.getAttachmentsByTransactionId(transactionInId);
    }

    @Override
    @Transactional
    public void removeAttachmentById(int attachmentId) throws Exception {

        /* Need to get the file name of the attachment */
        transactionAttachment attachment = getAttachmentById(attachmentId);

        /* Need to remove the attachment */
        fileSystem currdir = new fileSystem();
        currdir.setDirByName(attachment.getfileLocation());
        File currFile = new File(currdir.getDir() + attachment.getfileName());
        currFile.delete();

        /* Now remove the attachment from the database */
        transactionInDAO.removeAttachmentById(attachmentId);

    }

    @Override
    public List<ConfigForInsert> setConfigForInsert(int configId, int batchUploadId) {
        // we call sp and set the parameters here
        return transactionInDAO.setConfigForInsert(configId, batchUploadId);
    }

    @Override
    public List<Integer> getConfigIdsForBatch(int batchUploadId, boolean getAll) {
        return transactionInDAO.getConfigIdsForBatch(batchUploadId, getAll, 0);
    }

    @Override
    public List<Integer> getConfigIdsForBatch(int batchUploadId, boolean getAll, Integer transactionInId) {
        return transactionInDAO.getConfigIdsForBatch(batchUploadId, getAll, transactionInId);
    }

    @Override
    public List<Integer> getTransWithMultiValues(ConfigForInsert config) {
        return transactionInDAO.getTransWithMultiValues(config);
    }

    /**
     * These are ready records We will insert by configId All the values for being inserted into the same field would have been appended to the first field Id *
     */
    @Override
    public boolean insertSingleToMessageTables(ConfigForInsert configForInsert) {
        return transactionInDAO.insertSingleToMessageTables(configForInsert);
    }

    /**
     * this method takes in the transId, the delimited fields, loops them and insert them into the message table by string pairs. UT delimiter is ^^^^^
     */
    @Override
    public boolean insertMultiValToMessageTables(ConfigForInsert config, Integer subStringCounter,
            Integer transId) {
        return transactionInDAO.insertMultiValToMessageTables(config, subStringCounter, transId);
    }

    /**
     * The 'clearMessageTables' function will loop through all each message table and remove any rows matching transactionInIds belonging to a batch.
     *
     * @param batchId of the batch to be cleared.
     *
     * It will return 0 as in no errors.
     */
    @Override
    public Integer clearMessageTables(int batchId) {
        List<String> mts = transactionInDAO.getMessageTables();
        Integer sysErrorCount = 0;
        try {
            for (String mt : mts) {
                sysErrorCount = sysErrorCount + transactionInDAO.clearMessageTableForBatch(batchId, mt);
            }
            return sysErrorCount;
        } catch (Exception e) {
            System.err.println("clearMessageTables " + e.getStackTrace());
            return 1;

        }
    }

    @Override
    public List<Integer> getBlankTransIds(ConfigForInsert config) {
        return transactionInDAO.getBlankTransIds(config);
    }

    @Override
    public Integer countSubString(ConfigForInsert config, Integer transId) {
        return transactionInDAO.countSubString(config, transId);
    }

    /**
     * The 'getuploadedBatches' function calls getuploadedBatches(int userId, int orgId, Date fromDate, Date toDate, List<Integer> excludedStatusIds)
     *
     * It defaults excludedStatusIds to 1 as that is how the original fn is written. We wrote new method to pass in 1 as excludedStatusIds so we don't have to go back and modify every single method.
     *
     * @param userId
     * @param orgId
     * @param fromDate
     * @param todate
     *
     * It will return a list of batchUploads.
     */
    @Override
    public List<batchUploads> getuploadedBatches(int userId, int orgId, Date fromDate, Date toDate)
            throws Exception {
        return getuploadedBatches(userId, orgId, fromDate, toDate, Arrays.asList(1));
    }

    /**
     * The 'getuploadedBatches' function gets a list of batchUploads according to parameters being queried.
     *
     * @param userId
     * @param orgId
     * @param fromDate
     * @param todate
     * @param excludedStatusIds - statusIds for batches to exclude
     *
     * It will return a list of batchUploads.
     */
    @Override
    public List<batchUploads> getuploadedBatches(int userId, int orgId, Date fromDate, Date toDate,
            List<Integer> excludedStatusIds) throws Exception {
        return transactionInDAO.getuploadedBatches(userId, orgId, fromDate, toDate, excludedStatusIds);
    }

    /**
     * We will take a batch and then from its status etc we will decide if we want to process transactions or not. This method allowa admin to run just one batch This assumes batches SR - 6, Trans status REL We still run through entire process but these records should pass... (check to make sure it aligns with file upload) just be applying Macros / CW and inserting into our message tables This method will only process a batch that is RP or SSL
     *
     * We added to this method as if a batch is being call from fixErrors (ERG Form), we do not clear errors in transactionInErrors table. We default the flag to false as when it is call from old methods, we
     *
     * *
     */
    @Override
    public boolean processBatch(int batchUploadId, boolean doNotClearErrors, Integer transactionId)
            throws Exception {
        UserActivity ua = new UserActivity();
        Integer batchStausId = 29;
        List<Integer> errorStatusIds = Arrays.asList(11, 13, 14, 16);
        //get batch details
        batchUploads batch = getBatchDetails(batchUploadId);
        //this should be the same point of both ERG and Uploaded File *
        Integer systemErrorCount = 0;
        // Check to make sure the file is valid for processing, valid file is a batch with SSL (3) or SR (6)*

        boolean insertTargets = false;
        // we should only insert for batches that are just loaded
        if (batch.getstatusId() == 36) {
            insertTargets = true;
        }
        if ((batch.getstatusId() == 3 || batch.getstatusId() == 6 || batch.getstatusId() == 36)) {
            /** insert log**/
            try {
                //log user activity
                ua.setUserId(0);
                ua.setFeatureId(0);
                ua.setAccessMethod("System");
                ua.setActivity("System Processed File");
                ua.setBatchUploadId(batchUploadId);
                usermanager.insertUserLog(ua);
            } catch (Exception ex) {
                ex.printStackTrace();
                System.err.println("transactionId - insert user log" + ex.toString());
            }

            // set batch to SBP - 4*
            updateBatchStatus(batchUploadId, 4, "startDateTime");

            //clear transactionInError table for batch, if do not clear errors is true, we skip this.
            if (!doNotClearErrors) {
                systemErrorCount = systemErrorCount + clearTransactionInErrors(batchUploadId, true);
            }

            List<Integer> configIds = getConfigIdsForBatch(batchUploadId, false, transactionId);

            for (Integer configId : configIds) {
                //we need to run all checks before insert regardless *
                /**
                 * we are reordering 1. cw/macro, 2. required and 3. validate *
                 */
                // 1. grab the configurationDataTranslations and run cw/macros
                List<configurationDataTranslations> dataTranslations = configurationManager
                        .getDataTranslationsWithFieldNo(configId, 1); //while processing
                for (configurationDataTranslations cdt : dataTranslations) {
                    if (cdt.getCrosswalkId() != 0) {
                        systemErrorCount = systemErrorCount
                                + processCrosswalk(configId, batchUploadId, cdt, false, transactionId);
                    } else if (cdt.getMacroId() != 0) {
                        systemErrorCount = systemErrorCount
                                + processMacro(configId, batchUploadId, cdt, false, transactionId);
                    }
                }

                //check R/O
                List<configurationFormFields> reqFields = getRequiredFieldsForConfig(configId);

                for (configurationFormFields cff : reqFields) {
                    systemErrorCount = systemErrorCount
                            + insertFailedRequiredFields(cff, batchUploadId, transactionId);
                }
                // update status of the failed records to ERR - 14
                updateStatusForErrorTrans(batchUploadId, 14, false, transactionId);

                //run validation
                systemErrorCount = systemErrorCount + runValidations(batchUploadId, configId, transactionId);
                // update status of the failed records to ERR - 14
                updateStatusForErrorTrans(batchUploadId, 14, false, transactionId);

                /**
                 * targets should only be inserted if it hasn't gone through this loop already *
                 */
                if (insertTargets) {
                    //load our targets here
                    //load targets - we need to loadTarget only if field for target is blank, otherwise we load what user sent
                    Integer batchId = batchUploadId;
                    List<configurationConnection> batchTargetList = getBatchTargets(batchId, true);
                    int sourceConfigId = 0;
                    if (batchTargetList.size() <= 0) {
                        insertProcessingError(10, null, batchId, null, null, null, null, false, false,
                                "No valid connections were found for loading batch.");
                        updateTransactionStatus(batchId, 0, 0, 13);
                        updateRecordCounts(batchId, new ArrayList<Integer>(), false, "errorRecordCount");
                        updateRecordCounts(batchId, new ArrayList<Integer>(), false, "totalRecordCount");
                        updateBatchStatus(batchId, 7, "endDateTime");
                        return false;
                    } else {
                        for (configurationConnection bt : batchTargetList) {
                            /* populate batchUploadSummary need batchId, transactionInId,  configId, 
                             * sourceOrgId, messageTypeId - in configurations - missing targetOrgId, 
                             * if targetOrgCol has value, we populate - cms's target col could be 0, if spec has no target column,
                             * we insert all connections
                             * if targetOrgCol has value, we make sure value is valid
                             */
                            systemErrorCount = systemErrorCount + insertBatchUploadSummary(batch, bt);
                            if (sourceConfigId != bt.getsourceConfigId()) {
                                if (bt.getTargetOrgCol() != 0) {
                                    systemErrorCount = systemErrorCount + rejectInvalidTargetOrg(batchId, bt);
                                }
                                sourceConfigId = bt.getsourceConfigId();
                            }
                        }
                        systemErrorCount = systemErrorCount + setStatusForErrorCode(batchId, 11, 9, false);

                        //reject transactions with config that do not connections
                        systemErrorCount = systemErrorCount + rejectNoConnections(batch);
                        systemErrorCount = systemErrorCount + setStatusForErrorCode(batchId, 11, 10, false);

                        systemErrorCount = systemErrorCount + insertBatchTargets(batchId);

                        //handle duplicates, need to insert again and let it be its own row
                        systemErrorCount = systemErrorCount + newEntryForMultiTargets(batchId);

                    }
                }
                /**
                 * end of inserting target *
                 */

                /**
                 * we apply post processing rules here - categoryId 3 *
                 */
                //1. we loop it by config
                for (Integer postConfigId : configIds) {
                    List<configurationDataTranslations> postDataTranslations = configurationManager
                            .getDataTranslationsWithFieldNo(configId, 3); //while processing
                    for (configurationDataTranslations cdt : postDataTranslations) {
                        systemErrorCount = systemErrorCount
                                + processMacro(postConfigId, batchUploadId, cdt, false, transactionId);
                    }
                }

                /**
                 * if there are errors, those are system errors, they will be logged we get errorId 5 and email to admin, update batch to 29 *
                 */
                if (systemErrorCount > 0) {
                    setBatchToError(batchUploadId,
                            "System error occurred during processBatch, please review errors in audit report");
                    return false;
                }
            } //end of configs

            updateTransactionStatus(batchUploadId, transactionId, 10, 12);
            //transactionIn and transactionTarget status should be the same 
            copyTransactionInStatusToTarget(batchUploadId, transactionId);

            /**
             * batches gets process again when user hits release button, maybe have separate method call for those that are just going from pending release to release, have to think about scenario when upload file is huge *
             */
            List<configurationTransport> handlingDetails = getHandlingDetailsByBatch(batchUploadId);
            // multiple config should be set to handle the batch the same way - we email admin if we don't have one way of handling a batch
            if (handlingDetails.size() != 1) {
                //TODO email admin to fix problem
                updateRecordCounts(batchUploadId, new ArrayList<Integer>(), false, "totalRecordCount");
                // do we count pass records as errors?
                updateRecordCounts(batchUploadId, errorStatusIds, false, "errorRecordCount");
                setBatchToError(batchUploadId,
                        "Multiple or no file handling found, please check auto-release and error handling configurations");
                return false;
            }

            if (handlingDetails.size() == 1) {
                /**
                 * 1 = Post errors to ERG 2 = Reject record on error 3 = Reject submission on error 4 = Pass through errors
                 *
                 */

                if (getRecordCounts(batchUploadId, Arrays.asList(11, 12, 13, 16), false, false) > 0
                        && batch.getstatusId() == 6) {
                    //we stop here as batch is not in final status and release batch was triggered
                    batch.setstatusId(5);
                    batchStausId = 5;
                    updateRecordCounts(batchUploadId, new ArrayList<Integer>(), false, "totalRecordCount");
                    updateRecordCounts(batchUploadId, errorStatusIds, false, "errorRecordCount");
                    updateBatchStatus(batchUploadId, batchStausId, "endDateTime");
                    return true;
                }
                // if auto and batch contains transactions that are not final status
                if (batch.getstatusId() == 6 || (handlingDetails.get(0).getautoRelease()
                        && (handlingDetails.get(0).geterrorHandling() == 2
                                || handlingDetails.get(0).geterrorHandling() == 4
                                || handlingDetails.get(0).geterrorHandling() == 1))) {

                    if (handlingDetails.get(0).getautoRelease() && handlingDetails.get(0).geterrorHandling() == 1
                            && getRecordCounts(batchUploadId, Arrays.asList(11, 12, 13, 16), false, false) > 0) {
                        //post records to ERG
                        batch.setstatusId(5);
                        batchStausId = 5;
                        updateRecordCounts(batchUploadId, new ArrayList<Integer>(), false, "totalRecordCount");
                        updateRecordCounts(batchUploadId, errorStatusIds, false, "errorRecordCount");
                        updateBatchStatus(batchUploadId, batchStausId, "endDateTime");
                        return true;
                    }

                    //run check to make sure we have records 
                    if (getRecordCounts(batchUploadId, Arrays.asList(12), false, true) > 0) {
                        //we insert here
                        if (!insertTransactions(batchUploadId)) {
                            //something went wrong, we removed all inserted entries
                            clearMessageTables(batchUploadId);
                            updateRecordCounts(batchUploadId, new ArrayList<Integer>(), false, "totalRecordCount");
                            // do we count pass records as errors?
                            updateRecordCounts(batchUploadId, errorStatusIds, false, "errorRecordCount");
                            updateBatchStatus(batchUploadId, 29, "endDateTime");
                            return false;
                        }
                    }
                    // all went well
                    if (handlingDetails.get(0).geterrorHandling() == 4) {
                        //update to pass - 16
                        updateTransactionStatus(batchUploadId, transactionId, 14, 16);
                        //auto release, records 
                        updateTransactionTargetStatus(batchUploadId, transactionId, 14, 19);
                        updateTransactionTargetStatus(batchUploadId, transactionId, 16, 19);

                    }
                    if (handlingDetails.get(0).geterrorHandling() == 2) {
                        //reject errors
                        updateTransactionStatus(batchUploadId, transactionId, 14, 13);
                        copyTransactionInStatusToTarget(batchUploadId, transactionId);
                    }
                    updateTransactionStatus(batchUploadId, transactionId, 12, 19);
                    updateTransactionTargetStatus(batchUploadId, transactionId, 12, 19);
                    batchStausId = 24;

                } else if (handlingDetails.get(0).getautoRelease()
                        && handlingDetails.get(0).geterrorHandling() == 3) {
                    //auto-release, 3 = Reject submission on error 
                    batchStausId = 7;
                    //updating entire batch to reject since error transactionIds are in error tables
                    updateTransactionTargetStatus(batchUploadId, transactionId, 14, 13);
                    updateTransactionStatus(batchUploadId, transactionId, 14, 13);

                } else if (!handlingDetails.get(0).getautoRelease()
                        && handlingDetails.get(0).geterrorHandling() == 1) { //manual release
                    //transaction will be set to saved, batch will be set to RP
                    batchStausId = 5;
                    //we leave status alone as we already set them
                } else if (!handlingDetails.get(0).getautoRelease()
                        && handlingDetails.get(0).geterrorHandling() == 2) {
                    //reject records
                    batchStausId = 5;
                    updateTransactionStatus(batchUploadId, transactionId, 14, 13);
                    updateTransactionTargetStatus(batchUploadId, transactionId, 14, 13);
                } else if (!handlingDetails.get(0).getautoRelease()
                        && handlingDetails.get(0).geterrorHandling() == 3) {
                    batchStausId = 7;
                    updateTransactionStatus(batchUploadId, transactionId, 14, 13);
                    updateTransactionTargetStatus(batchUploadId, transactionId, 14, 13);
                } else if (!handlingDetails.get(0).getautoRelease()
                        && handlingDetails.get(0).geterrorHandling() == 4) {
                    batchStausId = 5;
                    // pass
                    updateTransactionStatus(batchUploadId, transactionId, 14, 16);
                    updateTransactionTargetStatus(batchUploadId, transactionId, 14, 16);
                } //end of checking auto/error handling

                updateRecordCounts(batchUploadId, new ArrayList<Integer>(), false, "totalRecordCount");
                // do we count pass records as errors?
                updateRecordCounts(batchUploadId, errorStatusIds, false, "errorRecordCount");
                updateBatchStatus(batchUploadId, batchStausId, "endDateTime");

            } //end of making sure there is one handling details for batch

        } // end of single batch insert 

        /** update log with transactionInIds **/
        try {
            if (ua != null) {
                ua.setTransactionInIds(
                        getTransactionInIdsFromBatch(batchUploadId).toString().replace("[", "").replace("]", ""));
                usermanager.updateUserActivity(ua);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("process batch - update user log" + ex.toString());
        }
        return true;
    }

    /**
     * This
     */
    @Override
    public void processBatches() {
        //0. grab all batches with SSL (3) - Loaded or ready for Release SR (6)
        //1. get all batches with SSA
        try {
            List<batchUploads> batches = getBatchesByStatusIds(Arrays.asList(3, 6, 36));
            if (batches != null && batches.size() != 0) {
                //we loop and process
                for (batchUploads batch : batches) {
                    try {
                        processBatch(batch.getId(), false, 0);
                    } catch (Exception ex) {
                        setBatchToError(batch.getId(), ("Errored at processBatches  " + ex.toString()));
                        ex.printStackTrace();
                    }
                }
            }
        } catch (Exception ex1) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ("processBatches error - " + ex1));
        }

    }

    @Override
    public void updateBatchStatus(Integer batchUploadId, Integer statusId, String timeField) throws Exception {
        transactionInDAO.updateBatchStatus(batchUploadId, statusId, timeField);
    }

    @Override
    public void updateTransactionStatus(Integer batchUploadId, Integer transactionId, Integer fromStatusId,
            Integer toStatusId) throws Exception {
        transactionInDAO.updateTransactionStatus(batchUploadId, transactionId, fromStatusId, toStatusId);
    }

    @Override
    public void updateTransactionTargetStatus(Integer batchUploadId, Integer transactionId, Integer fromStatusId,
            Integer toStatusId) throws Exception {
        transactionInDAO.updateTransactionTargetStatus(batchUploadId, transactionId, fromStatusId, toStatusId);
    }

    /**
     * provided the batch status is not one of the delivery status (22 SDL, 23 SDC) what would we like clear batch to do 1. Change batch process to SBP to nothing can be touch 2. remove records from message tables 3. figure out what status to set batch *
     */
    @Override
    public boolean clearBatch(Integer batchUploadId) throws Exception {
        boolean canDelete = allowBatchClear(batchUploadId);
        Integer sysError = 0;
        if (canDelete) {
            //TODO how much should we clear? Is it different for ERG and Upload?
            sysError = clearMessageTables(batchUploadId);
            if (sysError == 0) {
                int toBatchStatusId = 3; //SSA
                if (getBatchDetails(batchUploadId).gettransportMethodId() == 2) {
                    sysError = clearTransactionInErrors(batchUploadId, false);
                    toBatchStatusId = 5;
                    resetTransactionTranslatedIn(batchUploadId, true);
                    transactionInDAO.updateTransactionStatus(batchUploadId, 0, 0, 15);
                    transactionInDAO.updateBatchStatus(batchUploadId, toBatchStatusId, "startOver");
                } else {
                    toBatchStatusId = 2;
                    sysError = clearTransactionTables(batchUploadId, false);
                    updateRecordCounts(batchUploadId, new ArrayList<Integer>(), false, "errorRecordCount");
                    updateRecordCounts(batchUploadId, new ArrayList<Integer>(), false, "totalRecordCount");
                }
            }
        }
        if (sysError == 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean setDoNotProcess(Integer batchId) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public Integer clearTransactionInRecords(Integer batchUploadId) {
        return transactionInDAO.clearTransactionInRecords(batchUploadId);
    }

    /**
     * This method assumes that all records are validated and ready for insert We loop through each configuration and insert Transaction status will remain unchanged. *
     */
    @Override
    public boolean insertTransactions(Integer batchUploadId) {
        List<Integer> configIds = getConfigIdsForBatch(batchUploadId, true);
        boolean processTransactions = true;

        for (Integer configId : configIds) {

            //blank values are seen as space and will cause errors when insert if field is not use
            List<configurationFormFields> configurationFormFields = configurationtransportmanager
                    .getCffByValidationType(configId, 0);
            for (configurationFormFields cff : configurationFormFields) {
                updateBlanksToNull(cff, batchUploadId);
            }

            /**
             * this list have the insert /check statements for each message table *
             */
            List<ConfigForInsert> configforConfigIds = setConfigForInsert(configId, batchUploadId);
            /**
             * we loop though each table and grab the transactions that has multiple values for that table, we set it to a list *
             */
            for (ConfigForInsert config : configforConfigIds) {
                /**
                 * we grab list of ids with multiple for this config we use the checkDelim string to look for those transactions *
                 */
                List<Integer> transIds = getTransWithMultiValues(config);
                config.setLoopTransIds(transIds);
                /**
                 * we need to check if we need to insert in case the whole table is mapped but doesn't contain values *
                 */
                List<Integer> skipTheseIds = getBlankTransIds(config);
                config.setBlankValueTransId(skipTheseIds);

                //we insert single values
                if (!insertSingleToMessageTables(config)) {
                    return false;
                }

                //we loop through transactions with multiple values and use SP to loop values with delimiters
                for (Integer transId : transIds) {
                    //we check how long field is
                    Integer subStringTotal = countSubString(config, transId);
                    for (int i = 0; i <= subStringTotal; i++) {
                        if (!insertMultiValToMessageTables(config, i + 1, transId)) {
                            return false;
                        }
                    }
                }
            }
        }

        return processTransactions;
    }

    @Override
    public Integer clearTransactionTranslatedIn(Integer batchUploadId) {
        return transactionInDAO.clearTransactionTranslatedIn(batchUploadId);
    }

    @Override
    public Integer clearTransactionTables(Integer batchUploadId, boolean leaveFinalStatusIds) {
        //TODO have in transaction block for roll back?
        //we clear transactionTranslatedIn
        Integer cleared = clearTransactionTranslatedIn(batchUploadId);
        //we clear transactionInRecords
        cleared = cleared + clearTransactionInRecords(batchUploadId);
        //clear batchDownloadSummary
        cleared = cleared + clearBatchDownloadSummaryByUploadBatchId(batchUploadId);
        //clear transactionoutrecords
        cleared = cleared + clearTransactionOutRecordsByUploadBatchId(batchUploadId);
        cleared = cleared + clearTransactionTranslatedOutByUploadBatchId(batchUploadId);
        //we clear transactionTarget
        List<Integer> batchDLIds = getBatchDownloadIdsFromUploadId(batchUploadId);
        if (batchDLIds.size() > 0) {
            //need to get batchdownload Ids for transactiontargets
            cleared = cleared + clearTransactionTarget(batchUploadId);
            cleared = cleared + clearBatchDownloads(batchDLIds);
        }
        cleared = cleared + clearTransactionInErrors(batchUploadId, leaveFinalStatusIds);
        cleared = cleared + clearBatchUploadSummary(batchUploadId);
        cleared = cleared + clearMessageTables(batchUploadId);
        //we clear transactionIn
        cleared = cleared + clearTransactionIn(batchUploadId);
        //at SDC status, we have download batches, we need to clear those too

        if (cleared > 0) {
            flagAndEmailAdmin(batchUploadId);
        }
        return cleared;
    }

    @Override
    public Integer clearTransactionTarget(Integer batchUploadId) {
        return transactionInDAO.clearTransactionTarget(batchUploadId);
    }

    @Override
    public Integer clearTransactionIn(Integer batchUploadId) {
        return transactionInDAO.clearTransactionIn(batchUploadId);
    }

    @Override
    public void flagAndEmailAdmin(Integer batchUploadId) {
        // TODO Auto-generated method stub

    }

    @Override
    public List<configurationFormFields> getRequiredFieldsForConfig(Integer configId) {
        return configurationtransportmanager.getRequiredFieldsForConfig(configId);
    }

    @Override
    public Integer insertFailedRequiredFields(configurationFormFields cff, Integer batchUploadId,
            Integer transactionInId) {
        return transactionInDAO.insertFailedRequiredFields(cff, batchUploadId, transactionInId);
    }

    @Override
    public Integer clearTransactionInErrors(Integer batchUploadId, boolean leaveFinalStatusIds) {
        return transactionInDAO.clearTransactionInErrors(batchUploadId, leaveFinalStatusIds);
    }

    @Override
    public Integer deleteTransactionInErrorsByTransactionId(Integer transactionInId) {
        return transactionInDAO.deleteTransactionInErrorsByTransactionId(transactionInId);
    }

    /**
     * This method finds all error transactionInId in TransactionInErrors / TransactionOutErrors and update transactionIn with the appropriate error status It can be passed, reject and error
     *
     */
    @Override
    public void updateStatusForErrorTrans(Integer batchId, Integer statusId, boolean foroutboundProcessing,
            Integer transactionId) {
        transactionInDAO.updateStatusForErrorTrans(batchId, statusId, foroutboundProcessing, transactionId);
    }

    @Override
    public Integer runValidations(Integer batchUploadId, Integer configId, Integer transactionId) {
        Integer errorCount = 0;
        //1. we get validation types
        //2. we skip 1 as that is not necessary
        //3. we skip date (4) as there is no isDate function in MySQL
        //4. we skip the ids that are not null as Mysql will bomb out checking character placement
        //5. back to date, we grab transaction info and we loop (errId 7)

        /**
         * MySql RegEXP validate numeric - ^-?[0-9]+[.]?[0-9]*$|^-?[.][0-9]+$ validate email - ^[a-z0-9\._%+!$&*=^|~#%\'`?{}/\-]+@[a-z0-9\.-]+\.[a-z]{2,6}$ or ^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$ validate url - ^(https?://)?([\da-z.-]+).([a-z0-9])([0-9a-z]*)*[/]?$ - need to fix not correct - might have to run in java as mysql is not catching all. validate phone - should be no longer than 11 digits ^[0-9]{7,11}$ validate date - doing this in java
         *
         */
        //TODO was hoping to have one SP but concat in SP not setting and not catching errors correctly. Need to recheck
        List<configurationFormFields> configurationFormFields = configurationtransportmanager
                .getCffByValidationType(configId, 0);

        for (configurationFormFields cff : configurationFormFields) {
            String regEx = "";
            Integer validationTypeId = cff.getValidationType();
            switch (cff.getValidationType()) {
            case 1:
                break; // no validation
            //email calling SQL to validation and insert - one statement
            case 2:
                errorCount = errorCount
                        + genericValidation(cff, validationTypeId, batchUploadId, regEx, transactionId);
                break;
            //phone  calling SP to validation and insert - one statement 
            case 3:
                errorCount = errorCount
                        + genericValidation(cff, validationTypeId, batchUploadId, regEx, transactionId);
                break;
            // need to loop through each record / each field
            case 4:
                errorCount = errorCount + dateValidation(cff, validationTypeId, batchUploadId, transactionId);
                break;
            //numeric   calling SQL to validation and insert - one statement      
            case 5:
                errorCount = errorCount
                        + genericValidation(cff, validationTypeId, batchUploadId, regEx, transactionId);
                break;
            //url - need to rethink as regExp is not validating correctly
            case 6:
                errorCount = errorCount + urlValidation(cff, validationTypeId, batchUploadId, transactionId);
                break;
            //anything new we hope to only have to modify sp
            default:
                errorCount = errorCount
                        + genericValidation(cff, validationTypeId, batchUploadId, regEx, transactionId);
                break;
            }

        }
        return errorCount;
    }

    @Override
    public Integer genericValidation(configurationFormFields cff, Integer validationTypeId, Integer batchUploadId,
            String regEx, Integer transactionId) {
        return transactionInDAO.genericValidation(cff, validationTypeId, batchUploadId, regEx, transactionId);
    }

    @Override
    public Integer urlValidation(configurationFormFields cff, Integer validationTypeId, Integer batchUploadId,
            Integer transactionId) {
        try {
            //1. we grab all transactionInIds for messages that are not length of 0 and not null 
            List<transactionRecords> trs = null;
            //1. we grab all transactionInIds for messages that are not length of 0 and not null 
            if (transactionId == 0) {
                trs = getFieldColAndValues(batchUploadId, cff);
            } else {
                trs = getFieldColAndValueByTransactionId(cff, transactionId);
            }
            //2. we look at each column and check each value to make sure it is a valid url
            for (transactionRecords tr : trs) {
                //System.out.println(tr.getfieldValue());
                if (tr.getfieldValue() != null) {
                    //we append http:// if url doesn't start with it
                    String urlToValidate = tr.getfieldValue();
                    if (!urlToValidate.startsWith("http")) {
                        urlToValidate = "http://" + urlToValidate;
                    }
                    if (!isValidURL(urlToValidate)) {
                        insertValidationError(tr, cff, batchUploadId);
                    }

                }
            }
            return 0;
        } catch (Exception ex) {
            ex.printStackTrace();
            insertProcessingError(processingSysErrorId, cff.getconfigId(), batchUploadId, cff.getFieldNo(), null,
                    null, validationTypeId, false, false, (ex.getClass() + " " + ex.toString()));
            return 1;
        }

    }

    @Override
    public Integer dateValidation(configurationFormFields cff, Integer validationTypeId, Integer batchUploadId,
            Integer transactionId) {
        try {
            List<transactionRecords> trs = null;
            //1. we grab all transactionInIds for messages that are not length of 0 and not null 
            if (transactionId == 0) {
                trs = getFieldColAndValues(batchUploadId, cff);
            } else {
                trs = getFieldColAndValueByTransactionId(cff, transactionId);
            }
            //2. we look at each column and check each value by trying to convert it to a date
            for (transactionRecords tr : trs) {
                if (tr.getfieldValue() != null) {
                    //sql is picking up dates in mysql format and it is not massive inserting, running this check to avoid unnecessary sql call
                    //System.out.println(tr.getFieldValue());
                    //we check long dates
                    Date dateValue = null;
                    String mySQLDate = chkMySQLDate(tr.getFieldValue());

                    if (dateValue == null && mySQLDate.equalsIgnoreCase("")) {
                        dateValue = convertLongDate(tr.getFieldValue());
                    }
                    if (dateValue == null && mySQLDate.equalsIgnoreCase("")) {
                        dateValue = convertDate(tr.getfieldValue());
                    }

                    String formattedDate = null;
                    if (dateValue != null && mySQLDate.equalsIgnoreCase("")) {
                        formattedDate = formatDateForDB(dateValue);
                        //3. if it converts, we update the column value
                        updateFieldValue(tr, formattedDate);
                    }

                    if (formattedDate == null
                            && (mySQLDate.equalsIgnoreCase("") || mySQLDate.equalsIgnoreCase("ERROR"))) {
                        insertValidationError(tr, cff, batchUploadId);
                    }

                }
            }
            return 0;
        } catch (Exception ex) {
            ex.printStackTrace();
            insertProcessingError(processingSysErrorId, cff.getconfigId(), batchUploadId, cff.getFieldNo(), null,
                    null, validationTypeId, false, false, (ex.getClass() + " " + ex.toString()));
            return 1;
        }

    }

    /**
     * This method updates all the length of 0 values for a particular column for a batch and configuration to null.
     *
     */
    @Override
    public void updateBlanksToNull(configurationFormFields cff, Integer batchUploadId) {
        transactionInDAO.updateBlanksToNull(cff, batchUploadId);
    }

    @Override
    public List<transactionRecords> getFieldColAndValues(Integer batchUploadId, configurationFormFields cff) {
        return transactionInDAO.getFieldColAndValues(batchUploadId, cff);
    }

    /**
     * this method checks the potential day formats that a user can send in. We will check for long days such as February 2, 2014 Wednesday etc. Only accepting US format of month - day - year February 2, 2014 Sunday 2:00:02 PM February 2, 2014 02-02-2014 02/02/2014 02/02/14 02/2/14 12:02:00 PM etc.
     */
    /**
     * this method returns the pattern date is in so we can convert it properly and translate into mysql datetime insert format
     */
    public Date convertDate(String input) {

        // some regular expression
        String time = "(\\s(([01]?\\d)|(2[0123]))[:](([012345]\\d)|(60))" + "[:](([012345]\\d)|(60)))?"; // with a space before, zero or one time

        // no check for leap years (Schaltjahr)
        // and 31.02.2006 will also be correct
        String day = "(([12]\\d)|(3[01])|(0?[1-9]))"; // 01 up to 31
        String month = "((1[012])|(0\\d))"; // 01 up to 12
        String year = "\\d{4}";

        // define here all date format
        String date = input.replaceAll("/", "-");
        date = date.replaceAll("\\.", "-");
        //ArrayList<Pattern> patterns = new ArrayList<Pattern>();
        //Pattern pattern1 = Pattern.compile(day + "-" + month + "-" + year + time); //not matching, doesn't work for 01-02-2014 is it jan or feb, will only accept us dates
        Pattern pattern2 = Pattern.compile(year + "-" + month + "-" + day + time);
        Pattern pattern3 = Pattern.compile(month + "-" + day + "-" + year + time);
        // check dates
        //month needs to have leading 0
        if (date.indexOf("-") == 1) {
            date = "0" + date;
        }

        if (pattern2.matcher(date).matches()) {
            //we have y-m-d format, we transform and return date
            try {
                SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-mm-dd");
                dateformat.setLenient(false);
                Date dateValue = dateformat.parse(date);
                return dateValue;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }

        } else if (pattern3.matcher(date).matches()) {
            //we have m-d-y format, we transform and return date
            try {
                SimpleDateFormat dateformat = new SimpleDateFormat("MM-dd-yyyy");
                dateformat.setLenient(false);
                Date dateValue = dateformat.parse(date);
                return dateValue;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }

        } else {
            return null;
        }

    }

    @Override
    public void updateFieldValue(transactionRecords tr, String newValue) {
        transactionInDAO.updateFieldValue(tr, newValue);
    }

    @Override
    public void insertValidationError(transactionRecords tr, configurationFormFields cff, Integer batchUploadId) {
        transactionInDAO.insertValidationError(tr, cff, batchUploadId);
    }

    @Override
    @Transactional
    public List<Integer> getFeedbackReportConnection(int configId, int targetorgId) {
        return transactionInDAO.getFeedbackReportConnection(configId, targetorgId);
    }

    @Override
    public String formatDateForDB(Date date) {
        try {
            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
            return dateformat.format(date);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public Date convertLongDate(String dateValue) {

        Date date = null;
        //this checks convert long date such February 2, 2014
        try {
            date = java.text.DateFormat.getDateInstance().parse(dateValue);
            /** this method converts February 29 to March 1, 
             *  we need to run through check two to make sure it is valid 
             *  **/
            if (!recheckLongDate(dateValue, date.toString())) {
                return null;
            }
        } catch (Exception e) {
        }
        return date;
    }

    public String chkMySQLDate(String dateValue) {

        // some regular expression
        String time = "(\\s(([01]?\\d)|(2[0123]))[:](([012345]\\d)|(60))" + "[:](([012345]\\d)|(60)))?"; // with a space before, zero or one time

        // no check for leap years (Schaltjahr)
        // and 31.02.2006 will also be correct
        String day = "(([12]\\d)|(3[01])|(0?[1-9]))"; // 01 up to 31
        String month = "((1[012])|(0\\d))"; // 01 up to 12
        String year = "\\d{4}";

        // define here all date format
        String date = dateValue.replaceAll("/", "-");
        date = date.replaceAll("\\.", "-");
        Pattern pattern = Pattern.compile(year + "-" + month + "-" + day + time);

        // check dates
        if (pattern.matcher(date).matches()) {
            try {
                SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
                dateformat.setLenient(false);
                dateformat.parse(date);
                return "Valid";
            } catch (Exception e) {
                e.printStackTrace();
                return "Error";
            }
        } else {
            return "";
        }
    }

    @Override
    public boolean isValidURL(String url) {
        UrlValidator urlValidator = new UrlValidator();
        if (urlValidator.isValid(url)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Integer processCrosswalk(Integer configId, Integer batchId, configurationDataTranslations cdt,
            boolean foroutboundProcessing, Integer transactionId) {
        try {
            Integer errors = 0;
            // 1. we get the info for that cw (fieldNo, sourceVal, targetVal rel_crosswalkData)
            List<CrosswalkData> cdList = configurationManager.getCrosswalkData(cdt.getCrosswalkId());
            //we null forcw column, we translate and insert there, we then replace
            nullForCWCol(configId, batchId, foroutboundProcessing, transactionId);
            //we check to see if field value contains a list defined by UT delimiter
            List<Integer> cwMultiList = checkCWFieldForList(configId, batchId, cdt, foroutboundProcessing,
                    transactionId);
            if (cwMultiList.size() > 0) {
                // we loop through each field value in the list and apply cw
                errors = processMultiValueCWData(configId, batchId, cdt, cdList, foroutboundProcessing,
                        transactionId);
            } else {
                for (CrosswalkData cwd : cdList) {
                    executeSingleValueCWData(configId, batchId, cdt.getFieldNo(), cwd, foroutboundProcessing,
                            cdt.getFieldId(), transactionId);
                }
                if (cdt.getPassClear() == 1) {
                    //flag errors, anything row that is not null in F[FieldNo] but null in forCW
                    flagCWErrors(configId, batchId, cdt, foroutboundProcessing, transactionId);
                    //flag as error in transactionIn or transactionOut table
                    updateStatusForErrorTrans(batchId, 14, foroutboundProcessing, transactionId);

                }
                //we replace original F[FieldNo] column with data in forcw
                updateFieldNoWithCWData(configId, batchId, cdt.getFieldNo(), cdt.getPassClear(),
                        foroutboundProcessing, transactionId);
            }
            return errors;
        } catch (Exception e) {
            e.printStackTrace();
            return 1;
        }

    }

    @Override
    public Integer processMacro(Integer configId, Integer batchId, configurationDataTranslations cdt,
            boolean foroutboundProcessing, Integer transactionId) {
        // we clear forCW column for before we begin any translation
        nullForCWCol(configId, batchId, foroutboundProcessing, transactionId);
        try {
            Macros macro = configurationManager.getMacroById(cdt.getMacroId());
            int sysError = 0;
            try {
                // we expect the target field back so we can figure out clear pass option
                sysError = sysError
                        + executeMacro(configId, batchId, cdt, foroutboundProcessing, macro, transactionId);
                // insert macro errors
                flagMacroErrors(configId, batchId, cdt, foroutboundProcessing, transactionId);
                return sysError;
            } catch (Exception e) {
                e.printStackTrace();
                return 1;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 1;
        }

    }

    @Override
    public void nullForCWCol(Integer configId, Integer batchId, boolean foroutboundProcessing,
            Integer transactionId) {
        transactionInDAO.nullForCWCol(configId, batchId, foroutboundProcessing, transactionId);
    }

    @Override
    public void executeSingleValueCWData(Integer configId, Integer batchId, Integer fieldNo, CrosswalkData cwd,
            boolean foroutboundProcessing, Integer fieldId, Integer transactionId) {
        transactionInDAO.executeSingleValueCWData(configId, batchId, fieldNo, cwd, foroutboundProcessing, fieldId,
                transactionId);
    }

    @Override
    public void updateFieldNoWithCWData(Integer configId, Integer batchId, Integer fieldNo, Integer passClear,
            boolean foroutboundProcessing, Integer transactionId) {
        transactionInDAO.updateFieldNoWithCWData(configId, batchId, fieldNo, passClear, foroutboundProcessing,
                transactionId);
    }

    @Override
    public void flagCWErrors(Integer configId, Integer batchId, configurationDataTranslations cdt,
            boolean foroutboundProcessing, Integer transactionId) {
        transactionInDAO.flagCWErrors(configId, batchId, cdt, foroutboundProcessing, transactionId);
    }

    @Override
    public void flagMacroErrors(Integer configId, Integer batchId, configurationDataTranslations cdt,
            boolean foroutboundProcessing, Integer transactionId) {
        transactionInDAO.flagMacroErrors(configId, batchId, cdt, foroutboundProcessing, transactionId);
    }

    @Override
    public Integer executeMacro(Integer configId, Integer batchId, configurationDataTranslations cdt,
            boolean foroutboundProcessing, Macros macro, Integer transactionId) {
        return transactionInDAO.executeMacro(configId, batchId, cdt, foroutboundProcessing, macro, transactionId);

    }

    @Override
    public List<configurationTransport> getHandlingDetailsByBatch(int batchId) {
        try {
            return transactionInDAO.getHandlingDetailsByBatch(batchId);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public void insertProcessingError(Integer errorId, Integer configId, Integer batchId, Integer fieldNo,
            Integer macroId, Integer cwId, Integer validationTypeId, boolean required,
            boolean foroutboundProcessing, String errorCause) {
        insertProcessingError(errorId, configId, batchId, fieldNo, macroId, cwId, validationTypeId, required,
                foroutboundProcessing, errorCause, null);

    }

    @Override
    public void insertProcessingError(Integer errorId, Integer configId, Integer batchId, Integer fieldNo,
            Integer macroId, Integer cwId, Integer validationTypeId, boolean required,
            boolean foroutboundProcessing, String errorCause, Integer transactionId) {
        transactionInDAO.insertProcessingError(errorId, configId, batchId, fieldNo, macroId, cwId, validationTypeId,
                required, foroutboundProcessing, errorCause, transactionId);

    }

    @Override
    public void updateRecordCounts(Integer batchId, List<Integer> statusIds, boolean foroutboundProcessing,
            String colNameToUpdate) {
        transactionInDAO.updateRecordCounts(batchId, statusIds, foroutboundProcessing, colNameToUpdate);
    }

    @Override
    public Integer getRecordCounts(Integer batchId, List<Integer> statusIds, boolean foroutboundProcessing) {
        return transactionInDAO.getRecordCounts(batchId, statusIds, foroutboundProcessing, true);
    }

    @Override
    public Integer getRecordCounts(Integer batchId, List<Integer> statusIds, boolean foroutboundProcessing,
            boolean inStatusIds) {
        return transactionInDAO.getRecordCounts(batchId, statusIds, foroutboundProcessing, inStatusIds);
    }

    @Override
    public void resetTransactionTranslatedIn(Integer batchId, boolean resetAll) {
        resetTransactionTranslatedIn(batchId, resetAll, 0);
    }

    @Override
    public void resetTransactionTranslatedIn(Integer batchId, boolean resetAll, Integer transactionInId) {
        transactionInDAO.resetTransactionTranslatedIn(batchId, resetAll, transactionInId);
    }

    @Override
    public Integer copyTransactionInStatusToTarget(Integer batchId, Integer transactionId) {
        return transactionInDAO.copyTransactionInStatusToTarget(batchId, transactionId);
    }

    @Override
    public Integer insertLoadData(Integer batchId, String delimChar, String fileWithPath, String loadTableName,
            boolean containsHeaderRow) {
        return transactionInDAO.insertLoadData(batchId, delimChar, fileWithPath, loadTableName, containsHeaderRow);
    }

    @Override
    public Integer createLoadTable(String loadTableName) {
        return transactionInDAO.createLoadTable(loadTableName);
    }

    @Override
    public Integer dropLoadTable(String loadTableName) {
        return transactionInDAO.dropLoadTable(loadTableName);
    }

    @Override
    public Integer updateLoadTable(String loadTableName, Integer batchId) {
        return transactionInDAO.updateLoadTable(loadTableName, batchId);
    }

    @Override
    public Integer loadTransactionIn(String loadTableName, Integer batchId) {
        return transactionInDAO.loadTransactionIn(loadTableName, batchId);
    }

    @Override
    public Integer loadTransactionInRecords(Integer batchId) {
        return transactionInDAO.loadTransactionInRecords(batchId);
    }

    @Override
    public Integer loadTransactionInRecordsData(String loadTableName) {
        return transactionInDAO.loadTransactionInRecordsData(loadTableName);
    }

    @Override
    public Integer updateConfigIdForBatch(Integer batchId, Integer configId) {
        return transactionInDAO.updateConfigIdForBatch(batchId, configId);
    }

    @Override
    public Integer loadTransactionTranslatedIn(Integer batchId) {
        return transactionInDAO.loadTransactionTranslatedIn(batchId);
    }

    @Override
    public Integer insertBatchUploadSummary(batchUploads batchUpload, configurationConnection batchTargets) {
        int sysErrors = 0;
        //1. if no targetCol is given, we mass insert
        if (batchTargets.getTargetOrgCol() == 0) {
            sysErrors = sysErrors + transactionInDAO.insertBatchUploadSummaryAll(batchUpload, batchTargets);
        } else {
            sysErrors = sysErrors + insertBatchUploadSumByOrg(batchUpload, batchTargets);
        }
        return sysErrors;
    }

    @Override
    public Integer insertBatchTargets(Integer batchId) {
        return transactionInDAO.insertBatchTargets(batchId);
    }

    @Override
    public List<configurationConnection> getBatchTargets(Integer batchId, boolean active) {
        return transactionInDAO.getBatchTargets(batchId, active);
    }

    @Override
    public Integer clearBatchUploadSummary(Integer batchId) {
        return transactionInDAO.clearBatchUploadSummary(batchId);
    }

    /**
     * this method is called by scheduler. It will take all batches with status of SSA and load them. Batch will end with a status of LOADED.
     */
    @Override
    public void loadBatches() {
        //1. get all batches with SSA
        List<batchUploads> batches = getBatchesByStatusIds(Arrays.asList(2));
        if (batches != null && batches.size() != 0) {
            //we loop and process
            for (batchUploads batch : batches) {
                loadBatch(batch.getId());
            }

        }
    }

    @Override
    public boolean loadBatch(Integer batchId) {
        Integer batchStatusId = 38;
        List<Integer> errorStatusIds = Arrays.asList(11, 13, 14, 16);
        String processFolderPath = "/bowlink/loadFiles/";
        try {

            /** insert log**/
            try {
                //log user activity
                UserActivity ua = new UserActivity();
                ua.setUserId(0);
                ua.setFeatureId(0);
                ua.setAccessMethod("System");
                ua.setActivity("System Loaded Batch");
                ua.setBatchUploadId(batchId);
                usermanager.insertUserLog(ua);

            } catch (Exception ex) {
                ex.printStackTrace();
                System.err.println("loadBatch - insert user log" + ex.toString());
            }
            //first thing we do is get details, then we set it to  4
            batchUploads batch = getBatchDetails(batchId);
            // set batch to SBL - 38
            updateBatchStatus(batchId, batchStatusId, "startDateTime");

            // let's clear all tables first as we are starting over
            Integer sysErrors = clearTransactionTables(batchId, false);
            String errorMessage = "Load errors, please contact admin to review logs";
            // loading batch will take it all the way to loaded (9) status for
            if (sysErrors > 0) {
                insertProcessingError(5, null, batchId, null, null, null, null, false, false,
                        "Error cleaning out transaction tables.  Batch cannot be loaded.");
                updateBatchStatus(batchId, 39, "endDateTime");
                return false;
            }

            String loadTableName = "uploadTable_" + batch.getId();
            //make sure old table is dropped if exists
            Integer sysError = dropLoadTable(loadTableName);
            sysError = sysError + createLoadTable(loadTableName);

            //we need to index loadTable
            sysError = sysError + indexLoadTable(loadTableName);

            fileSystem dir = new fileSystem();
            dir.setDirByName("/");

            //2. we load data with my sql
            String actualFileName = null;
            String newfilename = null;

            /**
             * decoded files will always be in loadFiles folder with UTBatchName *
             */
            // all files are Base64 encoded at this point
            String encodedFilePath = dir.setPath(batch.getFileLocation());
            String encodedFileName = batch.getoriginalFileName();
            File encodedFile = new File(encodedFilePath + encodedFileName);
            String decodedFilePath = dir.setPath(processFolderPath);
            String decodedFileName = batch.getutBatchName();
            String decodedFileExt = batch.getoriginalFileName()
                    .substring(batch.getoriginalFileName().lastIndexOf("."));
            String strDecode = "";
            try {
                strDecode = filemanager.decodeFileToBase64Binary(encodedFile);
            } catch (Exception ex) {
                ex.printStackTrace();
                strDecode = "";
                sysErrors = 1;
                processingSysErrorId = 17;
            }

            if (!strDecode.equalsIgnoreCase("")) {
                //we write and decode file
                filemanager.writeFile((decodedFilePath + decodedFileName + decodedFileExt), strDecode);
                actualFileName = (decodedFilePath + decodedFileName + decodedFileExt);

                /*
                 If batch is set up for CCD input then we need to translate it
                 to a pipe-delimited text file.
                 */
                /** 
                 * here we need to check if we should change file to xml or hr for org
                 * sometimes org will send hl7 files over or .out or some other extension, they all need to be .hr
                 * all ccd file will need to end in xml
                 * 
                 */

                //so we check decodedFileName and change it to the proper extension if need be
                String chagneToExtension = "";
                String processFileName = batch.getoriginalFileName();
                /**
                 * For configId of 0, we need to check to see if org has hr or ccd
                 * if configId is not 0, we pull up the extension type and rename file
                 * if we find more than one file extension set up for org we reject them them
                 * file extension will be 4 (hr) or 9 (ccd)
                 * info we have from batchUpload - transportMethodId, configId, orgId
                 * 
                 */
                if (batch.getConfigId() != 0) {
                    configurationTransport ct = configurationtransportmanager
                            .getTransportDetails(batch.getConfigId());
                    if (ct.getfileType() == 9) {
                        chagneToExtension = "xml";
                    } else if (ct.getfileType() == 4) {
                        chagneToExtension = "hr";
                    }
                } else if (batch.getConfigId() == 0) {
                    //should restrict this to only 4/9
                    //see if the users has any 4/9 fileType, we don't need to worry about changing extension if org doesn't

                    List<configurationTransport> ctList = configurationtransportmanager
                            .getConfigurationTransportFileExtByFileType(batch.getOrgId(),
                                    batch.gettransportMethodId(), null, Arrays.asList(1), true, false);
                    if (ctList.size() > 1) {
                        //it is ok to have multiple if they are not using file type 4/9, so we check again
                        List<configurationTransport> ctList2 = configurationtransportmanager
                                .getConfigurationTransportFileExtByFileType(batch.getOrgId(),
                                        batch.gettransportMethodId(), Arrays.asList(4, 9), Arrays.asList(1), true,
                                        false);
                        if (ctList2.size() != 0) { //they have multiple file types defined along with hr or ccd, we fail them
                            //clean up
                            File tempLoadFile = new File(actualFileName);
                            if (tempLoadFile.exists()) {
                                tempLoadFile.delete();
                            }
                            //log
                            updateBatchStatus(batchId, 7, "endDateTime");
                            insertProcessingError(18, null, batchId, null, null, null, null, false, false,
                                    "Multiple file types were found for transport method.");
                            //get out of loop
                            return false;

                        }
                    } else if (ctList.size() == 1) {
                        if (ctList.get(0).getfileType() == 9) {
                            chagneToExtension = "xml";
                        } else if (ctList.get(0).getfileType() == 4) {
                            chagneToExtension = "hr";
                        }
                    }

                }

                if (chagneToExtension != "") {
                    processFileName = batch.getutBatchName() + "." + chagneToExtension;
                    //we overwrite file 
                    //old file is here actualFileName;
                    //new file is the same name with diff extension
                    File actualFile = new File(actualFileName);
                    File fileWithNewExtension = new File(decodedFilePath + processFileName);
                    Path fileWithOldExtension = actualFile.toPath();
                    Path renamedFile = fileWithNewExtension.toPath();
                    Files.move(fileWithOldExtension, renamedFile, REPLACE_EXISTING);
                }

                if (processFileName.endsWith(".xml")) {
                    newfilename = ccdtotxt.TranslateCCDtoTxt(decodedFilePath, decodedFileName, batch.getOrgId());
                    actualFileName = (decodedFilePath + newfilename);
                    //we remove temp load file 
                    File tempLoadFile = new File(decodedFilePath + processFileName);
                    if (tempLoadFile.exists()) {
                        tempLoadFile.delete();
                    }
                    /* 
                     if the original file name is a HL7 file (".hr") then we are going to translate it to
                     a pipe-delimited text file.
                     */
                } else if (processFileName.endsWith(".hr")) {

                    newfilename = hl7toTxt.TranslateHl7toTxt(decodedFilePath, decodedFileName, batch.getOrgId());
                    actualFileName = (decodedFilePath + newfilename);
                    //we remove temp load file 
                    File tempLoadFile = new File(decodedFilePath + processFileName);
                    if (tempLoadFile.exists()) {
                        tempLoadFile.delete();
                    }
                }

                //at this point, hl7 and hr are in unencoded plain text
                if (actualFileName.endsWith(".txt") || actualFileName.endsWith(".csv")) {
                    sysError = sysError + insertLoadData(batch.getId(), batch.getDelimChar(), actualFileName,
                            loadTableName, batch.isContainsHeaderRow());
                    File actualFile = new File(actualFileName);
                    //we are archiving it
                    File archiveFile = new File(dir.setPath(archivePath) + batch.getutBatchName() + "_dec"
                            + actualFileName.substring(actualFileName.lastIndexOf(".")));
                    Path archive = archiveFile.toPath();
                    Path actual = actualFile.toPath();
                    //we keep original file in archive folder
                    Files.move(actual, archive, REPLACE_EXISTING);
                }

                //3. we update batchId, loadRecordId
                sysError = sysError + updateLoadTable(loadTableName, batch.getId());

                // 4. we insert into transactionIn - status of invalid (11), batchId, loadRecordId
                sysError = sysError + loadTransactionIn(loadTableName, batch.getId());

                //5. we insert into transactionInRecords - we select transactionIn batchId, transactionInId
                sysError = sysError + loadTransactionInRecords(batch.getId());

                //6. we match loadRecordId and update transactionInRecords's F1-F255 data
                sysError = sysError + loadTransactionInRecordsData(loadTableName);

                //7. we delete loadTable
                sysError = sysError + dropLoadTable(loadTableName);

                //8. we see how if the file only has one upload type so we don't need to parse every line
                // if we only have one, we update the entire table 
                if (batch.getConfigId() != null && batch.getConfigId() != 0) {
                    // we update entire transactionIN with configId
                    sysError = sysError + updateConfigIdForBatch(batch.getId(), batch.getConfigId());
                } else {
                    //1. we get all configs for user - user might not have permission to submit but someone else in org does

                    List<configurationMessageSpecs> configurationMessageSpecs = configurationtransportmanager
                            .getConfigurationMessageSpecsForOrgTransport(batch.getOrgId(),
                                    batch.gettransportMethodId(), false);
                    //2. we get all rows for batch
                    List<transactionInRecords> tInRecords = getTransactionInRecordsForBatch(batch.getId());
                    if (tInRecords == null || tInRecords.size() == 0) {
                        updateBatchStatus(batchId, 7, "endDateTime");
                        insertProcessingError(7, null, batchId, null, null, null, null, false, false,
                                "No valid transactions were found for batch.");
                        return false;
                    }
                    if (configurationMessageSpecs == null || configurationMessageSpecs.size() == 0) {
                        insertProcessingError(6, null, batchId, null, null, null, null, false, false,
                                "No valid configurations were found for loading batch.");
                        // update all transactions to invalid
                        updateBatchStatus(batchId, 7, "endDateTime");
                        updateTransactionStatus(batchId, 0, 0, 11);
                        return false;
                    }
                    //if we only have one and it is set to 0,we can default, else we loop through
                    if (configurationMessageSpecs.size() == 1
                            && configurationMessageSpecs.get(0).getmessageTypeCol() == 0) {
                        sysError = sysError + updateConfigIdForBatch(batch.getId(),
                                configurationMessageSpecs.get(0).getconfigId());
                    } else {
                        //3 loop through each config and mass update by config
                        for (configurationMessageSpecs cms : configurationMessageSpecs) {
                            //we update by config
                            if (updateConfigIdForCMS(batchId, cms) != 0) {
                                sysError++;
                                insertProcessingError(processingSysErrorId, null, batch.getId(), null, null, null,
                                        null, false, false, "System error while checking configuration");
                                //system error - break
                                break;
                            }
                        }
                        // now we looped through config, we flag the invalid records.
                        sysError = flagInvalidConfig(batchId);
                        //we also need to flag and error the ones that a user is not supposed to upload for
                        sysError = flagNoPermissionConfig(batch);
                    }
                }

                //we populate transactionTranslatedIn
                sysError = sysError + loadTransactionTranslatedIn(batchId);

                //update data in transactionTranslatedIn
                resetTransactionTranslatedIn(batchId, true);
                int transactionId = 0;
                // we trim all values
                trimFieldValues(batchId, false, transactionId, true);

                //now that we have our config, we will apply pre-processing cw and macros to manipulate our data
                //1. find all configs for batch, loop and process
                List<Integer> configIds = getConfigIdsForBatch(batchId, false, transactionId);
                for (Integer configId : configIds) {
                    //we need to run all checks before insert regardless *
                    /**
                     * we are reordering 1. cw/macro, 2. required and 3. validate *
                     */
                    // 1. grab the configurationDataTranslations and run cw/macros
                    List<configurationDataTranslations> dataTranslations = configurationManager
                            .getDataTranslationsWithFieldNo(configId, 2); //pre processing
                    for (configurationDataTranslations cdt : dataTranslations) {
                        if (cdt.getCrosswalkId() != 0) {
                            sysError = sysError + processCrosswalk(configId, batchId, cdt, false, transactionId);
                        } else if (cdt.getMacroId() != 0) {
                            sysError = sysError + processMacro(configId, batchId, cdt, false, transactionId);
                        }
                    }

                }
            }
            if (sysErrors > 0) {
                insertProcessingError(processingSysErrorId, null, batchId, null, null, null, null, false, false,
                        errorMessage);
                updateBatchStatus(batchId, 39, "endDateTime");
                return false;
            }

            //we check handling here for rejecting entire batch
            List<configurationTransport> batchHandling = getHandlingDetailsByBatch(batchId);
            // if entire batch failed and have no configIds, there will be no error handling found
            if (getRecordCounts(batchId, Arrays.asList(11), false) == getRecordCounts(batchId,
                    new ArrayList<Integer>(), false)) {
                //entire batch failed, we reject entire batch
                updateRecordCounts(batchId, errorStatusIds, false, "errorRecordCount");
                updateRecordCounts(batchId, new ArrayList<Integer>(), false, "totalRecordCount");
                updateBatchStatus(batchId, 7, "endDateTime");
                return false;
            } else if (batchHandling.size() != 1) {
                //TODO email admin to fix problem
                insertProcessingError(8, null, batchId, null, null, null, null, false, false,
                        "Multiple or no file handling found, please check auto-release and error handling configurations");
                updateRecordCounts(batchId, new ArrayList<Integer>(), false, "totalRecordCount");
                // do we count pass records as errors?
                updateRecordCounts(batchId, errorStatusIds, false, "errorRecordCount");
                updateBatchStatus(batchId, 39, "endDateTime");
                return false;
            }
            if (batchHandling.size() == 1) {
                //reject submission on error
                if (batchHandling.get(0).geterrorHandling() == 3) {
                    // at this point we will only have invalid records
                    if (getRecordCounts(batchId, errorStatusIds, false) > 0) {
                        updateBatchStatus(batchId, 7, "endDateTime");
                        updateRecordCounts(batchId, errorStatusIds, false, "errorRecordCount");
                        //update loaded to rejected
                        updateTransactionStatus(batchId, 0, 9, 13);
                        return false;
                    }
                }
            }

            updateRecordCounts(batchId, errorStatusIds, false, "errorRecordCount");
            updateRecordCounts(batchId, new ArrayList<Integer>(), false, "totalRecordCount");
            //at the end of loaded, we update to PR
            updateTransactionStatus(batchId, 0, 9, 10);
            updateTransactionTargetStatus(batchId, 0, 9, 10);
            batchStatusId = 36; //loaded without targets

        } catch (Exception ex) {
            insertProcessingError(processingSysErrorId, null, batchId, null, null, null, null, false, false,
                    ("loadBatch error " + ex.getLocalizedMessage()));
            batchStatusId = 39;
        }

        try {
            updateBatchStatus(batchId, batchStatusId, "endDateTime");
            updateRecordCounts(batchId, new ArrayList<Integer>(), false, "totalRecordCount");
            // do we count pass records as errors?
            updateRecordCounts(batchId, errorStatusIds, false, "errorRecordCount");
        } catch (Exception ex1) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null,
                    ("loadBatch error at updating batch status - " + ex1));
            return false;
        }

        return true;
    }

    @Override
    public List<batchUploads> getBatchesByStatusIds(List<Integer> statusIds) {
        return transactionInDAO.getBatchesByStatusIds(statusIds);
    }

    @Override
    public void setBatchToError(Integer batchId, String errorMessage) throws Exception {
        try {
            //TODO send email here
            insertProcessingError(processingSysErrorId, null, batchId, null, null, null, null, false, false,
                    errorMessage);
            updateBatchStatus(batchId, 29, "endDateTime");
        } catch (Exception ex1) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null,
                    ("loadBatch error at updating batch status - " + ex1));

        }

    }

    @Override
    public void deleteMessage(int batchId, int transactionId) throws Exception {
        transactionInDAO.deleteMessage(batchId, transactionId);
    }

    @Override
    public void cancelMessageTransaction(int transactionId) throws Exception {
        transactionInDAO.cancelMessageTransaction(transactionId);
    }

    @Override
    public List<transactionInRecords> getTransactionInRecordsForBatch(Integer batchId) {
        return transactionInDAO.getTransactionInRecordsForBatch(batchId);
    }

    @Override
    public Integer updateConfigIdForCMS(Integer batchId, configurationMessageSpecs cms) {
        return transactionInDAO.updateConfigIdForCMS(batchId, cms);
    }

    @Override
    public Integer flagInvalidConfig(Integer batchId) {
        Integer sysErrors = 0;
        try {
            sysErrors = insertInvalidConfigError(batchId);
            sysErrors = sysErrors + updateInvalidConfigStatus(batchId);
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("flagInvalidConfig " + ex.toString());
            sysErrors++;
        }
        return sysErrors;
    }

    @Override
    public Integer insertInvalidConfigError(Integer batchId) {
        return transactionInDAO.insertInvalidConfigError(batchId);
    }

    @Override
    public Integer updateInvalidConfigStatus(Integer batchId) {
        return transactionInDAO.updateInvalidConfigStatus(batchId);
    }

    @Override
    public Integer indexLoadTable(String loadTableName) {
        return transactionInDAO.indexLoadTable(loadTableName);
    }

    @Override
    @Transactional
    public batchUploadSummary getUploadSummaryDetails(int transactionInId) {
        return transactionInDAO.getUploadSummaryDetails(transactionInId);
    }

    @Override
    public Integer clearBatchDownloadSummaryByUploadBatchId(Integer batchId) {
        return transactionInDAO.clearBatchDownloadSummaryByUploadBatchId(batchId);
    }

    @Override
    public Integer clearTransactionOutRecordsByUploadBatchId(Integer batchId) {
        return transactionInDAO.clearTransactionOutRecordsByUploadBatchId(batchId);
    }

    @Override
    public Integer clearTransactionTranslatedOutByUploadBatchId(Integer batchId) {
        return transactionInDAO.clearTransactionTranslatedOutByUploadBatchId(batchId);
    }

    @Override
    public Integer rejectInvalidTargetOrg(Integer batchId, configurationConnection batchTargets) {
        return transactionInDAO.rejectInvalidTargetOrg(batchId, batchTargets);
    }

    @Override
    public Integer insertBatchUploadSumByOrg(batchUploads batchUpload, configurationConnection batchTargets) {
        return transactionInDAO.insertBatchUploadSumByOrg(batchUpload, batchTargets);
    }

    @Override
    public Integer setStatusForErrorCode(Integer batchId, Integer statusId, Integer errorId,
            boolean foroutboundProcessing) {
        return transactionInDAO.setStatusForErrorCode(batchId, statusId, errorId, foroutboundProcessing);
    }

    @Override
    public Integer rejectNoConnections(batchUploads batch) {
        return transactionInDAO.rejectNoConnections(batch);
    }

    /**
     * we need to have one transactionIn entry for each transaction/target pair - there is no easy way to do it except to insert each duplicate one by one
     */
    @Override
    public Integer newEntryForMultiTargets(Integer batchId) {
        Integer sysError = 0;
        try {
            //1. we get duplicated transactionInIds
            List<Integer> transactionInIds = getDuplicatedIds(batchId);
            for (Integer transactionInId : transactionInIds) {
                //2. we get BATCHUPLOADSUMMARY
                List<batchUploadSummary> buses = getBatchUploadSummary(transactionInId);
                for (batchUploadSummary bus : buses) {
                    //we take each target and insert a new transaction into the transactionIn table
                    sysError = sysError + insertTransactionInByTargetId(bus);
                    //we get new tInId
                    Integer newTInId = getTransactionInIdByTargetId(bus);
                    //with new id, we update transactiontarget, batchUploadSummary
                    sysError = sysError + updateTInIdForTransactiontarget(bus, newTInId);
                    sysError = sysError + updateTINIDForBatchUploadSummary(bus, newTInId);
                    //we insert new entry into transactionInRecords and transactionTranslated In
                    sysError = sysError + copyTransactionInRecord(newTInId, bus.gettransactionInId());
                    sysError = sysError + insertTransactionTranslated(bus.gettransactionInId(), newTInId, bus);
                    sysError = sysError + insertTransactionInError(newTInId, bus.gettransactionInId());
                    //dup errors
                }

            }

            return sysError;
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("newEntryForMultiTargets " + ex.toString());
            return 1;
        }
    }

    @Override
    public List<Integer> getDuplicatedIds(Integer batchId) {
        return transactionInDAO.getDuplicatedIds(batchId);
    }

    @Override
    public List<batchUploadSummary> getBatchUploadSummary(Integer transactionInId) {
        return transactionInDAO.getBatchUploadSummary(transactionInId);
    }

    @Override
    public Integer insertTransactionInByTargetId(batchUploadSummary batchUploadSummary) {
        return transactionInDAO.insertTransactionInByTargetId(batchUploadSummary);
    }

    @Override
    public Integer getTransactionInIdByTargetId(batchUploadSummary bus) {
        return transactionInDAO.getTransactionInIdByTargetId(bus);
    }

    @Override
    public Integer updateTInIdForTransactiontarget(batchUploadSummary bus, Integer newTInId) {
        return transactionInDAO.updateTInIdForTransactiontarget(bus, newTInId);
    }

    @Override
    public Integer updateTINIDForBatchUploadSummary(batchUploadSummary bus, Integer newTInId) {
        return transactionInDAO.updateTINIDForBatchUploadSummary(bus, newTInId);
    }

    @Override
    public Integer copyTransactionInRecord(Integer newTInId, Integer oldTInId) {
        return transactionInDAO.copyTransactionInRecord(newTInId, oldTInId);
    }

    @Override
    public Integer insertTransactionTranslated(Integer oldInId, Integer newInId, batchUploadSummary bus) {
        return transactionInDAO.insertTransactionTranslated(oldInId, newInId, bus);
    }

    @Override
    @Transactional
    public List<batchUploads> getAllUploadedBatches(Date fromDate, Date toDate) throws Exception {
        return transactionInDAO.getAllUploadedBatches(fromDate, toDate, 0);
    }

    @Override
    @Transactional
    public List<batchUploads> getAllUploadedBatches(Date fromDate, Date toDate, Integer fetchSize)
            throws Exception {
        return transactionInDAO.getAllUploadedBatches(fromDate, toDate, fetchSize);
    }

    @Override
    public boolean searchTransactions(Transaction transaction, String searchTerm) throws Exception {

        boolean matchFound = false;

        if (transaction.getmessageTypeName().toLowerCase().matches(".*" + searchTerm + ".*")) {
            matchFound = true;
        }

        if (transaction.getreportableField1() != null
                && transaction.getreportableField1().toLowerCase().matches(".*" + searchTerm + ".*")) {
            matchFound = true;
        }

        if (transaction.getreportableField2() != null
                && transaction.getreportableField2().toLowerCase().matches(".*" + searchTerm + ".*")) {
            matchFound = true;
        }

        if (transaction.getreportableField3() != null
                && transaction.getreportableField3().toLowerCase().matches(".*" + searchTerm + ".*")) {
            matchFound = true;
        }

        if (transaction.getreportableField4() != null
                && transaction.getreportableField4().toLowerCase().matches(".*" + searchTerm + ".*")) {
            matchFound = true;
        }

        if (transaction.getstatusValue().toLowerCase().matches(".*" + searchTerm + ".*")) {
            matchFound = true;
        }

        if (transaction.gettargetOrgFields().size() > 0) {

            for (int i = 0; i < transaction.gettargetOrgFields().size(); i++) {
                if (transaction.gettargetOrgFields().get(i).getFieldValue() != null
                        && transaction.gettargetOrgFields().get(i).getFieldValue().toLowerCase()
                                .matches(".*" + searchTerm + ".*")) {
                    matchFound = true;
                }
            }

        }

        return matchFound;

    }

    @Override
    public systemSummary generateSystemInboundSummary() {

        systemSummary systemSummary = new systemSummary();

        try {

            /* Get batches submitted this hour */
            Calendar thishour = new GregorianCalendar();
            thishour.set(Calendar.MINUTE, 0);
            thishour.set(Calendar.SECOND, 0);
            thishour.set(Calendar.MILLISECOND, 0);

            Calendar nexthour = new GregorianCalendar();
            nexthour.set(Calendar.MINUTE, 0);
            nexthour.set(Calendar.SECOND, 0);
            nexthour.set(Calendar.MILLISECOND, 0);
            nexthour.add(Calendar.HOUR_OF_DAY, 1);

            //System.out.println("This Hour: " + thishour.getTime() + " Next Hour: " + nexthour.getTime());
            Integer batchesThisHour = transactionInDAO.getAllUploadedBatches(thishour.getTime(), nexthour.getTime())
                    .size();

            /* Get batches submitted today */
            Calendar starttoday = new GregorianCalendar();
            starttoday.set(Calendar.HOUR_OF_DAY, 0);
            starttoday.set(Calendar.MINUTE, 0);
            starttoday.set(Calendar.SECOND, 0);
            starttoday.set(Calendar.MILLISECOND, 0);

            Calendar starttomorrow = new GregorianCalendar();
            starttomorrow.set(Calendar.HOUR_OF_DAY, 0);
            starttomorrow.set(Calendar.MINUTE, 0);
            starttomorrow.set(Calendar.SECOND, 0);
            starttomorrow.set(Calendar.MILLISECOND, 0);
            starttomorrow.add(Calendar.DAY_OF_MONTH, 1);

            //System.out.println("Today: " + starttoday.getTime() + " Tomorrow: " + starttomorrow.getTime());
            Integer batchesToday = transactionInDAO
                    .getAllUploadedBatches(starttoday.getTime(), starttomorrow.getTime()).size();

            /* Get batches submitted this week */
            Calendar thisweek = new GregorianCalendar();
            thisweek.set(Calendar.HOUR_OF_DAY, 0);
            thisweek.set(Calendar.MINUTE, 0);
            thisweek.set(Calendar.SECOND, 0);
            thisweek.set(Calendar.MILLISECOND, 0);
            thisweek.set(Calendar.DAY_OF_WEEK, thisweek.getFirstDayOfWeek());

            Calendar nextweek = new GregorianCalendar();
            nextweek.set(Calendar.HOUR_OF_DAY, 0);
            nextweek.set(Calendar.MINUTE, 0);
            nextweek.set(Calendar.SECOND, 0);
            nextweek.set(Calendar.MILLISECOND, 0);
            nextweek.set(Calendar.DAY_OF_WEEK, thisweek.getFirstDayOfWeek());
            nextweek.add(Calendar.WEEK_OF_YEAR, 1);

            //System.out.println("This Week: " + thisweek.getTime() + " Next Week: " + nextweek.getTime());
            Integer batchesThisWeek = transactionInDAO.getAllUploadedBatches(thisweek.getTime(), nextweek.getTime())
                    .size();

            systemSummary.setBatchesPastHour(batchesThisHour);
            systemSummary.setBatchesToday(batchesToday);
            systemSummary.setBatchesThisWeek(batchesThisWeek);

            /* Get batches submitted yesterday */
        } catch (Exception ex) {
            Logger.getLogger(transactionInManagerImpl.class.getName()).log(Level.SEVERE, null, ex);
        }

        return systemSummary;

    }

    @Override
    public boolean checkPermissionForBatch(User userInfo, batchUploads batchInfo) {
        return transactionInDAO.checkPermissionForBatch(userInfo, batchInfo);
    }

    @Override
    public List<TransactionInError> getErrorList(Integer batchId) {
        return transactionInDAO.getErrorList(batchId);
    }

    //TODO need to write this better
    @Override
    public List<TransErrorDetailDisplay> populateErrorList(batchUploads batchInfo) {
        //we want to group by transaction
        List<TransErrorDetail> masterTedList = new ArrayList<TransErrorDetail>();
        List<TransErrorDetailDisplay> tedDisplayList = new ArrayList<TransErrorDetailDisplay>();
        try {
            ConfigErrorInfo configErrorInfo = new ConfigErrorInfo();
            configErrorInfo.setBatchId(batchInfo.getId());

            List<TransErrorDetail> tedList = getTransErrorDetailsForNoRptFields(batchInfo.getId(),
                    Arrays.asList(5, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20));
            if (tedList.size() > 0) {
                masterTedList.addAll(tedList);
            }
            /**
             * now get invalid configIds, errorId 6 - these are tied to transaction but not reportable fields since we don't know what configId it is. we don't know column that holds the field either since it didn't match with any for org, we display the first 4 columns
             */
            configErrorInfo = new ConfigErrorInfo();
            configErrorInfo.setBatchId(batchInfo.getId());
            tedList = getTransErrorDetailsForInvConfig(batchInfo.getId());
            if (tedList.size() > 0) {
                masterTedList.addAll(tedList);
            }
            //now get the rest by configId
            List<ConfigErrorInfo> confErrorListByConfig = getErrorConfigForBatch(batchInfo.getId());
            for (ConfigErrorInfo cei : confErrorListByConfig) {
                cei.setBatchId(batchInfo.getId());
                configErrorInfo = getHeaderForConfigErrorInfo(batchInfo.getId(), cei);
                //add error details
                String sqlStmt = "";
                if (configErrorInfo.getRptField1() != 0) {
                    sqlStmt = sqlStmt + "F" + configErrorInfo.getRptField1() + " as rptField1Value, ";
                } else {
                    sqlStmt = sqlStmt + "'' as rptField1Value, ";
                }
                if (configErrorInfo.getRptField2() != 0) {
                    sqlStmt = sqlStmt + "F" + configErrorInfo.getRptField2() + " as rptField2Value, ";
                } else {
                    sqlStmt = sqlStmt + "'' as rptField2Value, ";
                }
                if (configErrorInfo.getRptField3() != 0) {
                    sqlStmt = sqlStmt + "F" + configErrorInfo.getRptField3() + " as rptField3Value, ";
                } else {
                    sqlStmt = sqlStmt + "'' as rptField3Value, ";
                }
                if (configErrorInfo.getRptField4() != 0) {
                    sqlStmt = sqlStmt + "F" + configErrorInfo.getRptField4() + " as rptField4Value ";
                } else {
                    sqlStmt = sqlStmt + "'' as rptField4Value ";
                }

                tedList = getTransErrorDetails(batchInfo, configErrorInfo, sqlStmt);
                if (tedList.size() > 0) {
                    masterTedList.addAll(tedList);
                }
            }

            /**
             * custom group by - need to check if it is faster to just hit the db *
             */
            if (masterTedList.size() > 0) {
                Integer transactionInId = -1;
                TransErrorDetailDisplay tedd = new TransErrorDetailDisplay();
                List<TransErrorDetail> transErrorDetailList = new ArrayList<TransErrorDetail>();
                Integer counter = 0;

                /**
                 * we need to group them by transactionInId *
                 */
                for (TransErrorDetail ted : masterTedList) {
                    counter++;
                    if (!ted.getTransactionInId().equals(transactionInId)) {
                        if (transactionInId != -1) {
                            tedd.setTedList(transErrorDetailList);
                            transErrorDetailList = new ArrayList<TransErrorDetail>();
                            tedDisplayList.add(tedd);
                        }

                        transactionInId = ted.getTransactionInId();
                        tedd = new TransErrorDetailDisplay();
                        tedd.setTransactionInId(transactionInId);
                        tedd.setTransactionStatus(ted.getTransactionStatus());
                        tedd.setRptField1Label(ted.getRptField1Label());
                        tedd.setRptField2Label(ted.getRptField2Label());
                        tedd.setRptField3Label(ted.getRptField3Label());
                        tedd.setRptField4Label(ted.getRptField4Label());
                        tedd.setTransactionStatusValue(ted.getTransactionStatusValue());
                    }
                    transErrorDetailList.add(ted);
                    if (counter == masterTedList.size()) {
                        tedd.setTedList(transErrorDetailList);
                        transErrorDetailList = new ArrayList<TransErrorDetail>();
                        tedDisplayList.add(tedd);

                    }
                }
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("populateErrorList " + ex.toString());
        }

        return tedDisplayList;
    }

    @Override
    public List<TransErrorDetail> getTransErrorDetailsForNoRptFields(Integer batchId, List<Integer> errorCodes) {
        return transactionInDAO.getTransErrorDetailsForNoRptFields(batchId, errorCodes);
    }

    @Override
    public Integer getCountForErrorId(Integer batchId, Integer errorId) {
        return transactionInDAO.getCountForErrorId(batchId, errorId);
    }

    @Override
    public List<TransErrorDetail> getTransErrorDetailsForInvConfig(Integer batchId) {
        return transactionInDAO.getTransErrorDetailsForInvConfig(batchId);
    }

    @Override
    public List<ConfigErrorInfo> getErrorConfigForBatch(Integer batchId) {
        return transactionInDAO.getErrorConfigForBatch(batchId);
    }

    @Override
    public ConfigErrorInfo getHeaderForConfigErrorInfo(Integer batchId, ConfigErrorInfo configErrorInfo) {
        //we create header string
        List<Integer> rptFieldArray = Arrays.asList(configErrorInfo.getRptField1(), configErrorInfo.getRptField2(),
                configErrorInfo.getRptField3(), configErrorInfo.getRptField4());
        return transactionInDAO.getHeaderForConfigErrorInfo(batchId, configErrorInfo, rptFieldArray);
    }

    @Override
    public List<TransErrorDetail> getTransErrorDetails(batchUploads batchInfo, ConfigErrorInfo configErrorInfo,
            String sqlStmt) {
        List<TransErrorDetail> transErrorDetails;
        try {
            transErrorDetails = transactionInDAO.getTransErrorDetails(batchInfo, configErrorInfo);

            for (TransErrorDetail trd : transErrorDetails) {
                String newSQL = "";
                switch (trd.getErrorCode()) {
                case 2:
                    trd.setErrorInfo(messageTypeDAO.getValidationById(trd.getValidationTypeId()));
                    break;
                case 3:
                    trd.setErrorInfo(messagetypemanager.getCrosswalk(trd.getCwId()).getName());
                    break;
                case 4:
                    trd.setErrorInfo(configurationManager.getMacroById(trd.getMacroId()).getMacroName());
                    break;
                default:
                    break;
                }
                if (trd.getErrorFieldNo() != null) {
                    if (trd.getErrorCode() == 9) {
                        trd.setErrorFieldLabel("Target Org");
                    } else {
                        trd.setErrorFieldLabel(configurationtransportmanager
                                .getCFFByFieldNo(configErrorInfo.getConfigId(), trd.getErrorFieldNo())
                                .getFieldLabel());
                    }
                    newSQL = ", F" + trd.getErrorFieldNo() + " as errorData ";
                }
                trd = getTransErrorData(trd, sqlStmt + newSQL);
                trd.setRptField1Label(configErrorInfo.getRptFieldHeading1());
                trd.setRptField2Label(configErrorInfo.getRptFieldHeading2());
                trd.setRptField3Label(configErrorInfo.getRptFieldHeading3());
                trd.setRptField4Label(configErrorInfo.getRptFieldHeading4());
            }

            return transErrorDetails;

        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("getTransErrorDetails " + ex.toString());
            return null;
        }
    }

    @Override
    public TransErrorDetail getTransErrorData(TransErrorDetail ted, String sqlStmt) {
        //we create header string
        return transactionInDAO.getTransErrorData(ted, sqlStmt);
    }

    @Override
    public Integer flagNoPermissionConfig(batchUploads batch) {
        Integer sysErrors = 0;
        try {
            sysErrors = transactionInDAO.insertNoPermissionConfig(batch);
            sysErrors = sysErrors + transactionInDAO.updateStatusByErrorCode(batch.getId(), 11, 11);
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("flagNoPermissionConfig " + ex.toString());
            sysErrors++;
        }
        return sysErrors;
    }

    @Override
    public boolean hasPermissionForBatch(batchUploads batchInfo, User userInfo, boolean hasConfigurations) {
        boolean hasPermission = false;
        /**
         * user can view audit report if 1. uploaded by user 2. file type uploaded was for multiple types and user has configurations 3. user is in connection sender list for batch's configId
         */
        try {
            if (batchInfo.getuserId() == userInfo.getId()) {
                hasPermission = true;
            } else if (batchInfo.getConfigId() == 0 && hasConfigurations) {
                hasPermission = true;
            } else if (checkPermissionForBatch(userInfo, batchInfo)) {
                hasPermission = true;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("checkPermissionForBatch " + ex.toString());
        }
        return hasPermission;
    }

    @Override
    public batchUploads getBatchDetailsByTInId(Integer transactionInId) {
        return transactionInDAO.getBatchDetailsByTInId(transactionInId);
    }

    @Override
    public boolean allowBatchClear(Integer batchUploadId) {
        return transactionInDAO.allowBatchClear(batchUploadId);
    }

    @Override
    public void updateTranStatusByTInId(Integer transactionInId, Integer statusId) throws Exception {
        transactionInDAO.updateTranStatusByTInId(transactionInId, statusId);

    }

    @Override
    public List<batchUploads> populateBatchInfo(List<batchUploads> uploadedBatches, User userInfo) {
        try {
            for (batchUploads batch : uploadedBatches) {
                List<transactionIn> batchTransactions = getBatchTransactions(batch.getId(), userInfo.getId());
                batch.settotalTransactions(batchTransactions.size());

                lu_ProcessStatus processStatus = sysAdminManager.getProcessStatusById(batch.getstatusId());
                batch.setstatusValue(processStatus.getDisplayCode());
                if (batch.getstatusId() == 5) {
                    batch.setTransTotalNotFinal(getRecordCounts(batch.getId(), finalStatusIds, false, false));
                }

                User userDetails = usermanager.getUserById(batch.getuserId());
                String usersName = new StringBuilder().append(userDetails.getFirstName()).append(" ")
                        .append(userDetails.getLastName()).toString();
                batch.setusersName(usersName);

            }
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("populateBatchInfo " + ex.toString());
        }
        return uploadedBatches;
    }

    @Override
    public List<TransErrorDetail> getTransactionErrorsByFieldNo(int transactionInId, int fieldNo) throws Exception {
        return transactionInDAO.getTransactionErrorsByFieldNo(transactionInId, fieldNo);
    }

    @Override
    public List<UserActivity> getBatchActivities(batchUploads batchInfo, boolean forUsers,
            boolean foroutboundProcessing) {
        if (!forUsers) {
            //we have autolog that tracks the date/time each time the status change on a batch, not in use right now
            return null;
        } else {
            return transactionInDAO.getBatchUserActivities(batchInfo, foroutboundProcessing);
        }
    }

    @Override
    public List<transactionRecords> getFieldColAndValueByTransactionId(configurationFormFields cff,
            Integer transactionId) {
        return transactionInDAO.getFieldColAndValueByTransactionId(cff, transactionId);
    }

    @Override
    public Integer insertSFTPRun(MoveFilesLog sftpJob) {
        return transactionInDAO.insertSFTPRun(sftpJob);
    }

    @Override
    public void updateSFTPRun(MoveFilesLog sftpJob) throws Exception {
        transactionInDAO.updateSFTPRun(sftpJob);
    }

    @Override
    public List<batchUploads> getsentBatchesHistory(int userId, int orgId, int toOrgId, int messageTypeId,
            Date fromDate, Date toDate) throws Exception {
        return transactionInDAO.getsentBatchesHistory(userId, orgId, toOrgId, messageTypeId, fromDate, toDate);
    }

    /**
     * The sftp move files will grab all unique active SFTP pull paths and check folders for file. It will check path to see how many configurations it is associated with. It will also get the delimiter, check if there is a headerRow, how the file is being release. *
     */
    @Override
    public Integer moveSFTPFiles() {
        Integer sysErrors = 0;

        try {
            //1 . get distinct ftp paths
            List<configurationFTPFields> inputPaths = getFTPInfoForJob(1);

            //loop ftp paths and check
            for (configurationFTPFields ftpInfo : inputPaths) {
                //we insert job so if anything goes wrong or the scheduler overlaps, we won't be checking the same folder over and over
                MoveFilesLog sftpJob = new MoveFilesLog();
                sftpJob.setStatusId(1);
                sftpJob.setFolderPath(ftpInfo.getdirectory());
                sftpJob.setTransportMethodId(3);
                sftpJob.setMethod(1);
                Integer lastId = insertSFTPRun(sftpJob);
                sftpJob.setId(lastId);

                // check if directory exists, if not create
                fileSystem fileSystem = new fileSystem();
                String inPath = fileSystem.setPathFromRoot(ftpInfo.getdirectory());
                File f = new File(inPath);
                if (!f.exists()) {
                    sftpJob.setNotes("Directory " + ftpInfo.getdirectory() + " does not exist");
                    updateSFTPRun(sftpJob);
                    //need to get out of loop since set up was not done properly, but should not throw exception as rest of job should go on
                    sendEmailToAdmin(ftpInfo.getdirectory() + " does not exist", "SFTP Job Error");
                    break;
                }
                //we look up org for this path
                Integer orgId = configurationtransportmanager.getOrgIdForFTPPath(ftpInfo);

                sysErrors = sysErrors + moveFilesByPath(ftpInfo.getdirectory(), 3, orgId, ftpInfo.gettransportId());

                if (sysErrors == 0) {
                    sftpJob.setStatusId(2);
                    sftpJob.setEndDateTime(new Date());
                    updateSFTPRun(sftpJob);
                }
            }

            // if there are no errors, we release the folder path
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("moveSFTPFilesJob " + ex.toString());
            try {
                sendEmailToAdmin((ex.toString() + "<br/>" + Arrays.toString(ex.getStackTrace())),
                        "SFTP Job Error - main method errored");
            } catch (Exception ex1) {
                System.err.println("moveSFTPFilesJob " + Arrays.toString(ex1.getStackTrace()));
            }
            return 1;
        }
        return sysErrors;
    }

    @Override
    public Integer moveFilesByPath(String inPath, Integer transportMethodId, Integer orgId, Integer transportId) {
        Integer sysErrors = 0;

        try {
            fileSystem fileSystem = new fileSystem();
            String fileInPath = fileSystem.setPathFromRoot(inPath);
            File folder = new File(fileInPath);

            //list files
            //we only list visible files
            File[] listOfFiles = folder.listFiles((FileFilter) HiddenFileFilter.VISIBLE);

            Organization orgDetails = organizationmanager.getOrganizationById(orgId);
            String defPath = "/bowlink/" + orgDetails.getcleanURL() + "/input files/";
            String outPath = fileSystem.setPath(defPath);

            //too many variables that could come into play regarding file types, will check files with one method
            //loop files 
            for (File file : listOfFiles) {
                String fileName = file.getName();
                DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssS");
                Date date = new Date();
                /* Create the batch name (TransportMethodId+OrgId+Date/Time/Seconds) */
                String batchName = new StringBuilder().append(transportMethodId).append(orgId)
                        .append(dateFormat.format(date)).toString();

                if (!fileName.endsWith("_error")) {

                    try {

                        String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1);

                        //figure out how many active transports are using fileExt method for this particular path
                        List<configurationTransport> transportList = configurationtransportmanager
                                .getTransportListForFileExtAndPath(fileExt, transportMethodId, 1, inPath);

                        //figure out if files has distinct delimiters
                        List<configurationTransport> transports = configurationtransportmanager
                                .getConfigTransportForFileExtAndPath(fileExt, transportMethodId, 1, inPath);

                        batchUploads batchInfo = new batchUploads();
                        batchInfo.setOrgId(orgId);
                        batchInfo.settransportMethodId(transportMethodId);
                        batchInfo.setstatusId(4);
                        batchInfo.setstartDateTime(date);
                        batchInfo.setutBatchName(batchName);
                        batchInfo.setOriginalFolder(inPath);

                        Integer batchId = 0;
                        String newFileName = "";
                        Integer statusId = 4;
                        Integer configId = 0;
                        Integer fileSize = 0;
                        Integer encodingId = 1;
                        Integer errorId = 0;

                        if (transportList.size() == 0 || transports.size() == 0) { //neither of them should be 0
                            //no source transport is associated with this method / file
                            batchInfo.setuserId(usermanager.getUserByTypeByOrganization(orgId).get(0).getId());
                            batchInfo.setConfigId(0);
                            newFileName = newFileName(outPath, fileName);
                            batchInfo.setoriginalFileName(newFileName);
                            batchInfo.setFileLocation(defPath);
                            batchInfo.setEncodingId(encodingId);
                            batchId = (Integer) submitBatchUpload(batchInfo);
                            //insert error
                            errorId = 13;
                            statusId = 7;
                        } else if (transports.size() == 1) {
                            encodingId = transports.get(0).getEncodingId();
                            configurationTransport ct = configurationtransportmanager
                                    .getTransportDetailsByTransportId(transportId);
                            fileSize = ct.getmaxFileSize();
                            if (transportList.size() > 1) {
                                configId = 0;
                                fileSize = configurationtransportmanager.getMinMaxFileSize(fileExt,
                                        transportMethodId);
                            } else {
                                configId = ct.getconfigId();
                            }
                            batchInfo.setConfigId(configId);
                            batchInfo.setContainsHeaderRow(transports.get(0).getContainsHeaderRow());
                            batchInfo.setDelimChar(transports.get(0).getDelimChar());
                            batchInfo.setFileLocation(ct.getfileLocation());
                            outPath = fileSystem.setPath(ct.getfileLocation());
                            batchInfo.setOrgId(orgId);
                            newFileName = newFileName(outPath, fileName);
                            batchInfo.setoriginalFileName(newFileName);
                            batchInfo.setEncodingId(encodingId);

                            //find user 
                            List<User> users = usermanager.getSendersForConfig(Arrays.asList(ct.getconfigId()));
                            if (users.size() == 0) {
                                users = usermanager.getOrgUsersForConfig(Arrays.asList(ct.getconfigId()));
                            }

                            batchInfo.setuserId(users.get(0).getId());
                            batchId = (Integer) submitBatchUpload(batchInfo);
                            statusId = 2;

                        } else if (transportList.size() > 1 && transports.size() > 1) {
                            //we loop though our delimiters for this type of fileExt
                            String delimiter = "";
                            Integer fileDelimiter = 0;
                            String fileLocation = "";
                            Integer userId = 0;
                            //get distinct delimiters
                            List<configurationTransport> delimList = configurationtransportmanager
                                    .getDistinctDelimCharForFileExt(fileExt, transportMethodId);
                            List<configurationTransport> encodings = configurationtransportmanager
                                    .getTransportEncoding(fileExt, transportMethodId);
                            //we reject file is multiple encodings/delimiters are found for extension type as we won't know how to decode it and read delimiter
                            if (encodings.size() != 1) {
                                batchInfo.setuserId(usermanager.getUserByTypeByOrganization(orgId).get(0).getId());
                                statusId = 7;
                                errorId = 16;
                            } else {
                                encodingId = encodings.get(0).getEncodingId();
                                for (configurationTransport ctdelim : delimList) {
                                    fileSystem dir = new fileSystem();
                                    int delimCount = (Integer) dir.checkFileDelimiter(file, ctdelim.getDelimChar());
                                    if (delimCount > 3) {
                                        delimiter = ctdelim.getDelimChar();
                                        fileDelimiter = ctdelim.getfileDelimiter();
                                        statusId = 2;
                                        fileLocation = ctdelim.getfileLocation();
                                        break;
                                    }
                                }
                            }
                            // we don't have an error yet

                            if (errorId > 0) {
                                // some error detected from previous checks
                                userId = usermanager.getUserByTypeByOrganization(orgId).get(0).getId();
                                batchInfo.setConfigId(configId);
                                batchInfo.setFileLocation(defPath);
                                batchInfo.setOrgId(orgId);
                                newFileName = newFileName(outPath, fileName);
                                batchInfo.setoriginalFileName(newFileName);
                                batchInfo.setuserId(userId);
                                batchId = (Integer) submitBatchUpload(batchInfo);
                                batchInfo.setEncodingId(encodingId);
                            } else if (statusId != 2) {
                                //no vaild delimiter detected
                                statusId = 7;
                                userId = usermanager.getUserByTypeByOrganization(orgId).get(0).getId();
                                batchInfo.setConfigId(configId);
                                batchInfo.setFileLocation(defPath);
                                batchInfo.setOrgId(orgId);
                                newFileName = newFileName(outPath, fileName);
                                batchInfo.setoriginalFileName(newFileName);
                                batchInfo.setuserId(userId);
                                batchId = (Integer) submitBatchUpload(batchInfo);
                                batchInfo.setEncodingId(encodingId);
                                errorId = 15;
                            } else if (statusId == 2) {
                                encodingId = encodings.get(0).getEncodingId();
                                //we check to see if there is multi header row, if so, we reject because we don't know what header rows value to look for
                                List<configurationTransport> containsHeaderRowCount = configurationtransportmanager
                                        .getCountContainsHeaderRow(fileExt, transportMethodId);

                                if (containsHeaderRowCount.size() != 1) {
                                    batchInfo.setuserId(
                                            usermanager.getUserByTypeByOrganization(orgId).get(0).getId());
                                    statusId = 7;
                                    errorId = 14;
                                } else {
                                    List<Integer> totalConfigs = configurationtransportmanager
                                            .getConfigCount(fileExt, transportMethodId, fileDelimiter);

                                    //set how many configs we have
                                    if (totalConfigs.size() > 1) {
                                        configId = 0;
                                    } else {
                                        configId = totalConfigs.get(0);
                                    }

                                    //get path
                                    fileLocation = configurationtransportmanager
                                            .getTransportDetails(totalConfigs.get(0)).getfileLocation();
                                    fileSize = configurationtransportmanager
                                            .getTransportDetails(totalConfigs.get(0)).getmaxFileSize();
                                    List<User> users = usermanager.getSendersForConfig(totalConfigs);
                                    if (users.size() == 0) {
                                        users = usermanager.getOrgUsersForConfig(totalConfigs);
                                    }
                                    userId = users.get(0).getId();
                                    batchInfo.setContainsHeaderRow(
                                            containsHeaderRowCount.get(0).getContainsHeaderRow());
                                    batchInfo.setDelimChar(delimiter);
                                    batchInfo.setConfigId(configId);
                                    batchInfo.setFileLocation(fileLocation);
                                    outPath = fileSystem.setPath(fileLocation);
                                    batchInfo.setOrgId(orgId);
                                    newFileName = newFileName(outPath, fileName);
                                    batchInfo.setoriginalFileName(newFileName);
                                    batchInfo.setuserId(userId);
                                    batchInfo.setEncodingId(encodingId);
                                    batchId = (Integer) submitBatchUpload(batchInfo);
                                }
                            }
                        }
                        /** insert log**/
                        try {
                            //log user activity
                            UserActivity ua = new UserActivity();
                            ua.setUserId(0);
                            ua.setFeatureId(0);
                            ua.setAccessMethod("System");
                            ua.setActivity("System Uploaded File");
                            ua.setBatchUploadId(batchInfo.getId());
                            usermanager.insertUserLog(ua);

                        } catch (Exception ex) {
                            ex.printStackTrace();
                            System.err.println("moveFilesByPath - insert user log" + ex.toString());
                        }
                        //we encoded user's file if it is not
                        File newFile = new File(outPath + newFileName);
                        // now we move file
                        Path source = file.toPath();
                        Path target = newFile.toPath();

                        File archiveFile = new File(fileSystem.setPath(archivePath) + batchName
                                + newFileName.substring(newFileName.lastIndexOf(".")));
                        Path archive = archiveFile.toPath();
                        //we keep original file in archive folder
                        Files.copy(source, archive);

                        /**
                         * we check encoding here *
                         */
                        if (encodingId < 2) { //file is not encoded
                            String encodedOldFile = filemanager.encodeFileToBase64Binary(file);
                            filemanager.writeFile(newFile.getAbsolutePath(), encodedOldFile);
                            Files.delete(source);
                        } else {
                            Files.move(source, target);
                        }

                        if (statusId == 2) {
                            /**
                             * check file size if configId is 0 we go with the smallest file size *
                             */
                            long maxFileSize = fileSize * 1000000;
                            if (Files.size(target) > maxFileSize) {
                                statusId = 7;
                                errorId = 12;
                            }
                        }

                        if (statusId != 2) {
                            insertProcessingError(errorId, 0, batchId, null, null, null, null, false, false, "");
                        }

                        updateBatchStatus(batchId, statusId, "endDateTime");

                    } catch (Exception exAtFile) {
                        exAtFile.printStackTrace();
                        System.err.println("moveFilesByPath " + exAtFile.toString());
                        try {
                            sendEmailToAdmin(
                                    (exAtFile.toString() + "<br/>" + Arrays.toString(exAtFile.getStackTrace())),
                                    "moveFilesByPath - at rename file to error ");
                            //we need to move that file out of the way
                            file.renameTo((new File(file.getAbsolutePath() + batchName + "_error")));
                        } catch (Exception ex1) {
                            ex1.printStackTrace();
                            System.err.println("moveFilesByPath " + ex1.getMessage());

                        }
                    }
                }

            }

        } catch (Exception ex) {
            ex.printStackTrace();
            try {
                sendEmailToAdmin((ex.toString() + "<br/>" + Arrays.toString(ex.getStackTrace())),
                        "moveFilesByPath - issue with looping folder files");
            } catch (Exception ex1) {
                ex1.printStackTrace();
                System.err.println("moveFilesByPath " + ex1.getMessage());
            }
            return 1;
        }
        return sysErrors;
    }

    /**
     * this method grabs all distinct ftp path that need to be check for files *
     */
    @Override
    public List<configurationFTPFields> getFTPInfoForJob(Integer method) {
        return transactionInDAO.getFTPInfoForJob(method);
    }

    @Override
    public String newFileName(String path, String fileName) {
        try {
            File newFile = new File(path + fileName);
            if (newFile.exists()) {
                int i = 1;
                while (newFile.exists()) {
                    int iDot = fileName.lastIndexOf(".");
                    newFile = new File(
                            path + fileName.substring(0, iDot) + "_(" + ++i + ")" + fileName.substring(iDot));
                }
                fileName = newFile.getName();
            }
            return fileName;
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("newBatchName " + ex.toString());
            return null;
        }
    }

    @Override
    public List<batchUploadSummary> getBatchesToSentOrg(int srcorgId, int tgtOrgId, int messageTypeId)
            throws Exception {
        return transactionInDAO.getBatchesToSentOrg(srcorgId, tgtOrgId, messageTypeId);
    }

    @Override
    public messagePatients getPatientTransactionDetails(int transactionInId) {
        return transactionInDAO.getPatientTransactionDetails(transactionInId);
    }

    @Override
    public String copyUplaodedPath(configurationTransport transportDetails, MultipartFile fileUpload) {

        //save the file as is to input folder
        MultipartFile file = fileUpload;
        String fileName = file.getOriginalFilename();

        InputStream inputStream;
        OutputStream outputStream;

        try {
            inputStream = file.getInputStream();
            File newFile = null;

            //Set the directory to save the brochures to
            fileSystem dir = new fileSystem();

            String filelocation = transportDetails.getfileLocation();
            filelocation = filelocation.replace("/bowlink/", "");
            dir.setDirByName(filelocation);

            newFile = new File(dir.getDir() + fileName);

            if (newFile.exists()) {
                int i = 1;
                while (newFile.exists()) {
                    int iDot = fileName.lastIndexOf(".");
                    newFile = new File(dir.getDir() + fileName.substring(0, iDot) + "_(" + ++i + ")"
                            + fileName.substring(iDot));
                }
                fileName = newFile.getName();
                newFile.createNewFile();
            } else {
                newFile.createNewFile();
            }

            //Save the attachment
            outputStream = new FileOutputStream(newFile);
            int read = 0;
            byte[] bytes = new byte[1024];

            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
            outputStream.close();

            return fileName;
        } catch (IOException e) {
            System.err.println("copyUplaodedPath " + e.getCause());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * The 'chkUploadBatchFile' function will take in the file and orgName and upload the file to the appropriate file on the file system. The function will run the file through various validations. If a single validation fails the batch will be put in a error validation status and the file will be removed from the system. The user will receive an error message on the screen letting them know which validations have failed and be asked to upload a new file.
     *
     * The following validations will be taken place. - File is not empty - Proper file type (as determined in the configuration set up) - Proper delimiter (as determined in the configuration set up) - Does not exceed file size (as determined in the configuration set up)
     *
     * @param configId The configuration Id to get some validation parameters
     * @param fileUpload The file to be uploaded
     *
     */
    @Override
    public Map<String, String> chkUploadBatchFile(configurationTransport transportDetails, File uploadedFile)
            throws Exception {

        Map<String, String> batchFileResults = new HashMap<String, String>();

        try {
            long fileSize = uploadedFile.length();
            long fileSizeMB = (fileSize / (1024L * 1024L));

            /* 
             1 = File is empty
             2 = Too large
             3 = Wrong file type
             4 = Wrong delimiter
             */
            /* Make sure the file is not empty : ERROR CODE 1 */
            if (fileSize == 0) {
                batchFileResults.put("emptyFile", "1");
            }

            /* Make sure file is the correct size : ERROR CODE 2 */
            double maxFileSize = (double) transportDetails.getmaxFileSize();

            if (fileSizeMB > maxFileSize) {
                batchFileResults.put("wrongSize", "2");
            }

            String fileName = uploadedFile.getName();

            batchFileResults.put("fileName", fileName);

            /* Make sure file is the correct file type : ERROR CODE 3 */
            String ext = FilenameUtils.getExtension(uploadedFile.getAbsolutePath());

            String fileType = (String) configurationManager.getFileTypesById(transportDetails.getfileType());

            if ("hl7".equals(fileType)) {
                fileType = "hr";
            }

            if (ext == null ? fileType != null : !ext.equals(transportDetails.getfileExt())) {
                batchFileResults.put("wrongFileType", "3");
            }

            fileSystem dir = new fileSystem();

            /* Make sure the file has the correct delimiter : ERROR CODE 5 */
            String delimChar = (String) messageTypeDAO.getDelimiterChar(transportDetails.getfileDelimiter());

            //Check to make sure the file contains the selected delimiter
            //Set the directory that holds the crosswalk files
            int delimCount = (Integer) dir.checkFileDelimiter(uploadedFile, delimChar);

            if (delimCount < 3 && !"xml".equals(transportDetails.getfileExt())) {
                batchFileResults.put("wrongDelim", "4");
            }

            //Save the attachment
        } catch (Exception e) {
            e.printStackTrace();
        }

        return batchFileResults;

    }

    @Override
    public Integer moveRhapsodyFiles() {
        Integer sysErrors = 0;

        try {
            //1 . get distinct ftp paths
            List<configurationRhapsodyFields> inputPaths = getRhapsodyInfoForJob(1);

            //loop ftp paths and check
            for (configurationRhapsodyFields rhapsodyInfo : inputPaths) {
                //we insert job so if anything goes wrong or the scheduler overlaps, we won't be checking the same folder over and over
                MoveFilesLog moveJob = new MoveFilesLog();
                moveJob.setStatusId(1);
                moveJob.setFolderPath(rhapsodyInfo.getDirectory());
                moveJob.setTransportMethodId(5);
                moveJob.setMethod(1);
                Integer lastId = insertSFTPRun(moveJob);
                moveJob.setId(lastId);

                // check if directory exists, if not create
                fileSystem fileSystem = new fileSystem();
                //paths are from root instead of /home
                String inPath = fileSystem.setPathFromRoot(rhapsodyInfo.getDirectory());
                File f = new File(inPath);
                if (!f.exists()) {
                    moveJob.setNotes(("Directory " + rhapsodyInfo.getDirectory() + " does not exist"));
                    updateSFTPRun(moveJob);
                    //need to get out of loop since set up was not done properly, will try to throw error
                    sendEmailToAdmin((rhapsodyInfo.getDirectory() + " does not exist"), "Rhapsody Job Error");
                    break;
                }
                //we look up org for this path
                Integer orgId = configurationtransportmanager.getOrgIdForRhapsodyPath(rhapsodyInfo);

                sysErrors = sysErrors
                        + moveFilesByPath(rhapsodyInfo.getDirectory(), 5, orgId, rhapsodyInfo.getTransportId());

                if (sysErrors == 0) {
                    moveJob.setStatusId(2);
                    moveJob.setEndDateTime(new Date());
                    updateSFTPRun(moveJob);
                }
            }

            // if there are no errors, we release the folder path
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("moveRhapsodyFiles " + ex.toString());
            try {
                sendEmailToAdmin((ex.toString() + "<br/>" + Arrays.toString(ex.getStackTrace())),
                        "Rhapsody Job Error - main method errored");
            } catch (Exception ex1) {
                ex1.printStackTrace();
                System.err.println("moveRhapsodyFiles " + ex1.toString());
            }
            return 1;
        }
        return sysErrors;
    }

    /**
     * this method grabs all distinct ftp path that need to be check for files *
     */
    @Override
    public List<configurationRhapsodyFields> getRhapsodyInfoForJob(Integer method) {
        return transactionInDAO.getRhapsodyInfoForJob(method);
    }

    @Override
    public Integer insertTransactionInError(Integer newTInId, Integer oldTInId) {
        return transactionInDAO.insertTransactionInError(newTInId, oldTInId);
    }

    @Override
    public List<Integer> checkCWFieldForList(Integer configId, Integer batchId, configurationDataTranslations cdt,
            boolean foroutboundProcessing, Integer transactionId) {
        return transactionInDAO.checkCWFieldForList(configId, batchId, cdt, foroutboundProcessing, transactionId);
    }

    @Override
    public Integer processMultiValueCWData(Integer configId, Integer batchId, configurationDataTranslations cdt,
            List<CrosswalkData> cwdList, boolean foroutboundProcessing, Integer transactionId) {
        try {
            Integer error = 0;
            List<IdAndFieldValue> idAndValues = getIdAndValuesForConfigField(configId, batchId, cdt,
                    foroutboundProcessing, transactionId);
            //we turn cwdList into a map
            Map<String, String> cwMap = new HashMap<String, String>();
            for (CrosswalkData cw : cwdList) {
                cwMap.put(cw.getSourceValue(), cw.getTargetValue());
            }

            //1. we get list of ids for field
            for (IdAndFieldValue idAndValue : idAndValues) {
                Integer invalidCount = 0;
                Integer blankListLength = 0;
                List<String> values = new ArrayList<String>();

                List<String> fieldValues = Arrays.asList(idAndValue.getFieldValue().split("\\^\\^\\^\\^\\^", -1));
                //we loop through value and compare to cw
                for (String fieldValue : fieldValues) {
                    //sometimes user need to pass blank list, should not be count as an error
                    if (cwMap.containsKey(fieldValue.trim())) {
                        values.add(cwMap.get(fieldValue.trim()));
                    } else {
                        //we pass value
                        if (cdt.getPassClear() == 1) {
                            values.add(fieldValue.trim());
                            invalidCount = invalidCount + 1;
                            if (fieldValue.trim().length() != 0) {
                                blankListLength = blankListLength + 1;
                            }
                        }
                    }
                }

                String newValue = StringUtils.collectionToDelimitedString(values, "^^^^^");
                error = updateFieldValue(newValue, cdt.getFieldNo(), idAndValue.getTransactionId(),
                        foroutboundProcessing);

                //we insert error if no valid values were replaced
                if (invalidCount > 0 && blankListLength > 0) {
                    insertProcessingError(3, cdt.getconfigId(), batchId, cdt.getFieldNo(), null,
                            cdt.getCrosswalkId(), null, false, foroutboundProcessing, "",
                            idAndValue.getTransactionId());
                }
            }

            return error;
        } catch (Exception ex) {
            ex.printStackTrace();
            System.err.println("processMultiValueCWData " + ex.toString());
            return 1;

        }

    }

    @Override
    public List<IdAndFieldValue> getIdAndValuesForConfigField(Integer configId, Integer batchId,
            configurationDataTranslations cdt, boolean foroutboundProcessing, Integer transactionId) {
        return transactionInDAO.getIdAndValuesForConfigField(configId, batchId, cdt, foroutboundProcessing,
                transactionId);
    }

    @Override
    public Integer updateFieldValue(String fieldValue, Integer fieldNo, Integer transactionId,
            boolean foroutboundProcessing) {
        return transactionInDAO.updateFieldValue(fieldValue, fieldNo, transactionId, foroutboundProcessing);
    }

    @Override
    public void trimFieldValues(Integer batchId, boolean foroutboundProcessing, Integer transactionId,
            boolean trimAll) {
        transactionInDAO.trimFieldValues(batchId, foroutboundProcessing, transactionId, trimAll);
    }

    @Override
    public void updateTransactionTargetListStatus(List<transactionTarget> transactions, Integer statusId) {
        transactionInDAO.updateTransactionTargetListStatus(transactions, statusId);
    }

    @Override
    public void submitTransactionMultipleTargets(batchMultipleTargets target) {
        transactionInDAO.submitTransactionMultipleTargets(target);
    }

    @Override
    public List<batchMultipleTargets> getBatchMultipleTargets(Integer batchId) {
        return transactionInDAO.getBatchMultipleTargets(batchId);
    }

    @Override
    public Integer copyBatchDetails(Integer batchId, Integer tgtConfigId, Integer transactionId) {
        return transactionInDAO.copyBatchDetails(batchId, tgtConfigId, transactionId);
    }

    @Override
    public void sendEmailToAdmin(String message, String subject) throws Exception {
        try {
            mailMessage mail = new mailMessage();
            mail.setfromEmailAddress("dphuniversaltranslator@gmail.com");
            mail.setmessageBody(message);
            mail.setmessageSubject(subject + " " + InetAddress.getLocalHost().getHostAddress());
            mail.settoEmailAddress("dphuniversaltranslator@gmail.com");
            emailManager.sendEmail(mail);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new Exception(ex);
        }
    }

    @Override
    public List<batchUploadSummary> getuploadBatchesByConfigAndTarget(Integer configId, Integer orgId,
            Integer tgtConfigId) {
        return transactionInDAO.getuploadBatchesByConfigAndTarget(configId, orgId, tgtConfigId);
    }

    @Override
    public boolean searchBatchForHistory(batchUploads batchDetails, String searchTerm, Date fromDate, Date toDate)
            throws Exception {
        return transactionInDAO.searchBatchForHistory(batchDetails, searchTerm, fromDate, toDate);
    }

    @Override
    public Integer updateTranTargetStatusByUploadBatchId(Integer batchUploadId, Integer fromStatusId,
            Integer toStatusId) {
        return transactionInDAO.updateTranTargetStatusByUploadBatchId(batchUploadId, fromStatusId, toStatusId);
    }

    @Override
    public Integer updateBatchDLStatusByUploadBatchId(Integer batchUploadId, Integer fromStatusId,
            Integer toStatusId, String timeField) {
        return transactionInDAO.updateBatchDLStatusByUploadBatchId(batchUploadId, fromStatusId, toStatusId,
                timeField);
    }

    @Override
    public List<Integer> getBatchDownloadIdsFromUploadId(Integer batchUploadId) {
        return transactionInDAO.getBatchDownloadIdsFromUploadId(batchUploadId);
    }

    @Override
    public Integer clearBatchDownloads(List<Integer> batchDownloadIDs) {
        return transactionInDAO.clearBatchDownloads(batchDownloadIDs);
    }

    @Override
    public boolean recheckLongDate(String longDateVal, String convertedDate) {
        try {
            longDateVal = longDateVal.toLowerCase();
            convertedDate = convertedDate.toLowerCase();
            if (longDateVal.contains("jan") && convertedDate.contains("jan")) {
                return true;
            } else if (longDateVal.contains("feb") && convertedDate.contains("feb")) {
                return true;
            } else if (longDateVal.contains("mar") && convertedDate.contains("mar")) {
                return true;
            } else if (longDateVal.contains("apr") && convertedDate.contains("apr")) {
                return true;
            } else if (longDateVal.contains("may") && convertedDate.contains("may")) {
                return true;
            } else if (longDateVal.contains("jun") && convertedDate.contains("jun")) {
                return true;
            } else if (longDateVal.contains("jul") && convertedDate.contains("jul")) {
                return true;
            } else if (longDateVal.contains("aug") && convertedDate.contains("aug")) {
                return true;
            } else if (longDateVal.contains("sep") && convertedDate.contains("sep")) {
                return true;
            } else if (longDateVal.contains("oct") && convertedDate.contains("oct")) {
                return true;
            } else if (longDateVal.contains("nov") && convertedDate.contains("nov")) {
                return true;
            } else if (longDateVal.contains("dec") && convertedDate.contains("dec")) {
                return true;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
        return false;
    }

    @Override
    public List<Integer> getTransactionInIdsFromBatch(Integer batchUploadId) {
        return transactionInDAO.getTransactionInIdsFromBatch(batchUploadId);
    }

}