package com.fp.general.score.save; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.sql.Date; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.commons.lang.StringUtils; import com.fp.common.exception.ExceptionHandler; import com.fp.common.logger.APPLogger; import com.fp.dto.save.SaveRequest; import com.fp.loan.exception.LoanException; import com.fp.persistence.commondb.PersistenceHelper; import com.fp.persistence.commondb.PersistenceManager; import com.fp.persistence.commondb.data.SessionData; import com.fp.persistence.commondb.data.ThreadFacade; import com.fp.persistence.commondb.helper.FormatDates; import com.fp.persistence.pgeneral.score.TgeneScoreAdjustment; //import com.fp.persistence.ploan.acco.TloanPaymentBankProcess; /** * Clase que se encarga de procesar un archivo con información de pagos de créditos procedente de una canal de * recaudación * * @author Omar Villanueva * @version 2.1 */ public class UploadFileScoreThread extends Thread { private final Integer company; /* Arvhivo a procesar */ private final File file; /* Institución financiera a la que pertenece el archivo */ private final String bank; /* Directorio destino para el archivo luego de procesarlo */ private final StringBuilder targetPath; /* * Map para los formatos de nombres de archivos de las instituciones financieras parametrizadas en * TLOANPAYMENTACCOBANK */ private final Map mFileName; /* * Map para los numeros de hilos que se puede procesar en paralelo por cada una de las instituciones financieras * parametrizadas en TLOANPAYMENTACCOBANK */ private final Map mThreads; /* String para almacenar el log de errores en la carga de los archivos para mostrar al usuario en el front end */ private final StringBuilder sbLog; /* Separador de linea */ private final String new_line = System.getProperty("line.separator"); private final SaveRequest sr; /** * Constructor * * @param company * @param file * @param bank * @param targetPath * @param mFileName * @param mThreads * @param sbLog */ public UploadFileScoreThread(Integer company, File file, String bank, StringBuilder targetPath, Map mFileName, Map mThreads, StringBuilder sbLog, SaveRequest sr) { super(); this.company = company; this.file = file; this.bank = bank; this.targetPath = targetPath; this.mFileName = mFileName; this.mThreads = mThreads; this.sbLog = sbLog; this.sr=sr; } @Override public void run() { // boolean success = true; try { SessionData s = new SessionData(); s.setCompany(company); ThreadFacade.setSaveRequest(s); PersistenceHelper.setEntityManager(PersistenceManager.getInstance().createEntityManagerLocal()); PersistenceHelper.beginNewTransaction(); /* Procesar archivo */ process(); PersistenceHelper.commitNewTransaction(); /* Mover el archivo si la carga fue exitosa */ moveFile(); } catch (Exception e) { // success = false; PersistenceHelper.rollbackNewTransaction(); ExceptionHandler eh = new ExceptionHandler(e, "es"); APPLogger.getLogger().error("codigo ==>" + eh.getCode()); APPLogger.getLogger().error("user ==>" + eh.getUserMessage()); APPLogger.getLogger().error("technical ==>" + eh.getTechnicalMessage()); APPLogger.getLogger().error("stacktrace ==>" + eh.getStackTrace()); } finally { PersistenceHelper.closeSession(); } // /* Mover el archivo si la carga fue exitosa */ // if (success) { // try { // moveFile(); // } catch (Exception e) { // e.printStackTrace(); // } // } } /** * Método que procesa el archivo. Carga la data en la tabla TGENESCOREADJUSTMENT(---TLOANPAYMENTBANKPROCESS). Lanza un hilo por cada linea * que contiene el arvhivo. Se pueden lanzar varios hilos en paralelo. El numero máximo de hilos esta determinado * por el parametro threads fijado en la tabla TLOANPAYMENTACCOBANK * * @throws Exception */ private void process() throws Exception { /* Verificar si el archivo ya fue cargado anteriormente */ //String fileExist = TloanPaymentBankProcess.find(PersistenceHelper.getEntityManager(), company, file.getName()); String fileExist = TgeneScoreAdjustment.find(PersistenceHelper.getEntityManager(), company, file.getName()); if (fileExist != null) { sbLog.append(new LoanException("LOAN-0049", "EL ARCHIVO: {0} YA FUE CARGADO ANTERIORMENTE", file.getName()).getMessage()) .append(new_line); throw new LoanException("LOAN-0049", "EL ARCHIVO: {0} YA FUE CARGADO ANTERIORMENTE", file.getName()); } /* Verificar si el numero de hilos esta definido */ if (mThreads.get(bank) == null || mThreads.get(bank).compareTo(0) <= 0) { /* Agrega el mensaje al log de errores */ sbLog.append( new LoanException("LOAN-0041", "NUMERO DE HILOS NO DEFINIDO EN TLOANPAYMENTACCOBANK PARA INSTITUCION FINANCIERA: {0}", bank) .getMessage()).append(new_line); throw new LoanException("LOAN-0041", "NUMERO DE HILOS NO DEFINIDO EN TLOANPAYMENTACCOBANK PARA INSTITUCION FINANCIERA: {0}", bank); } ExecutorService pool = Executors.newFixedThreadPool(mThreads.get(bank)); /* Obtener la fecha de pago del archivo a procesar */ Date paymentDate = getDateFromFile(); try { BufferedReader input = new BufferedReader(new FileReader(file)); try { String line = null; int sequence = 0; Timestamp realDate = FormatDates.getInstance().getDataBaseTimestamp(); while ((line = input.readLine()) != null) { sequence++; /* Se lanza un hilo por cada linea del archivo que se debe procesar */ UploadLineScoreThread ult = new UploadLineScoreThread(company, file, bank, line, sequence, realDate, paymentDate, sr); pool.execute(ult); } } catch (IOException ioe) { throw ioe; } finally { input.close(); } } catch (IOException ioe) { throw ioe; } pool.shutdown(); boolean isfinish = pool.isTerminated(); while (!isfinish) { isfinish = pool.isTerminated(); Thread.sleep(600); } } /** * Método que obtiene la fecha desde el arvhivo proporcionado por el canal de recaudación. Esta es la fecha de pago * de la cuota del crédito * * @return * @throws Exception */ private Date getDateFromFile() throws Exception { Date date = null; String fileName = StringUtils.remove(mFileName.get(bank), '-'); int positionDate = fileName.indexOf("ddMM"); /* Procesa archivos que contengan el formato ddMM */ if (positionDate < 0) { /* Agrega el mensaje al log de errores */ sbLog.append( new LoanException("LOAN-0038", "FECHA INCORRECTAMENTE DEFINIDA EN TLOANPAYMENTACCOBANK PARA INSTITUCIÓN FINANCIERA: {0}", bank) .getMessage()).append(new_line); throw new LoanException("LOAN-0038", "FECHA INCORRECTAMENTE DEFINIDA EN TLOANPAYMENTACCOBANK PARA INSTITUCIÓN FINANCIERA: {0}", bank); } if (bank.compareTo("SP") == 0) { String formatDate = mFileName.get(bank).substring(positionDate, positionDate + 10); String strDate = file.getName().trim().substring(positionDate, positionDate + 10); date = getDateByFormat(strDate, formatDate); } return date; } /** * Método que devuelve la fecha según el formato requerido * * @param pStrDate * @param pFormat * @return * @throws Exception */ private Date getDateByFormat(String pStrDate, String pFormat) throws Exception { Date date = null; try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pFormat); date = new Date(simpleDateFormat.parse(pStrDate).getTime()); } catch (Exception e) { /* Agrega el mensaje al log de errores */ sbLog.append( new LoanException( "LOAN-0050", "EL FORMATO DE FECHA DEL ARCHIVO: {0} NO COINCIDE CON EL DEFINIDO EN TLOANPAYMENTACCOBANK PARA INSTITUCIÓN FINANCIERA: {1}", file.getName(), bank).getMessage()).append(new_line); throw new LoanException("LOAN-0050", "EL FORMATO DE FECHA DEL ARCHIVO: {0} NO COINCIDE CON EL DEFINIDO EN TLOANPAYMENTACCOBANK PARA INSTITUCIÓN FINANCIERA: {1}", file.getName(), bank); } return date; } /** * Método que mueve el archivo ya procesado al directorio destino * * @throws Exception */ private void moveFile() throws Exception { /* Directorio destino */ File targetDir = new File(targetPath.toString()); /* Mover el archivo al nuevo directorio */ boolean success = file.renameTo(new File(targetDir, file.getName())); if (!success) { /* Agrega el mensaje al log de errores */ sbLog.append(new LoanException("LOAN-0040", "EL ARCHIVO {0} ESTA SIENDO USADO POR OTRO PROCESO", file.getName()).getMessage()).append( new_line); throw new LoanException("LOAN-0040", "EL ARCHIVO {0} ESTA SIENDO USADO POR OTRO PROCESO", file.getName()); } } }