package com.mx.dla.dda.carga.transaccion.bos;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.executor.result.ResultMapException;
import org.apache.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;

import com.mx.dla.dda.carga.transaccion.daos.CargaTransaccionesDAO;
import com.mx.dla.dda.carga.transaccion.dtos.CargaTransaccionesDTO;
import com.mx.dla.dda.carga.transaccion.dtos.FechaBloqueoDTO;
import com.mx.dla.dda.carga.transaccion.dtos.PrincipalCargaTransaccionesDTO;
import com.mx.dla.dda.carga.transaccion.dtos.RowRepErrAsocTitulosDTO;
import com.mx.dla.dda.carga.transaccion.dtos.RowRepErrResumenCargaDTO;
import com.mx.dla.dda.carga.transaccion.dtos.RowReporteCargaDTO;
import com.mx.dla.dda.carga.transaccion.dtos.TitulosCargaTransaccionesDTO;
import com.mx.dla.dda.carga.transaccion.dtos.plantillaCargaTransaccionesDTO;
import com.mx.dla.dda.carga.transaccion.ws.asociarTitulosTransCntVigentes.ParamAsocTitTransCntVigentesDTO;
import com.mx.dla.dda.carga.transaccion.ws.asociarTitulosTransCntVigentes.ResponseAsociarTitTransCntVigentesDTO;
import com.mx.dla.dda.carga.transaccion.ws.procesarCargaTitulosPN.ParamCargaTitulosPNDTO;
import com.mx.dla.dda.carga.transaccion.ws.procesarCargaTitulosPN.ResponseCargaTitulosPNDTO;
import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.mx.dla.dda.excelMapper.bos.BeanPopulator;
import com.mx.dla.dda.excelMapper.bos.ExcelMapperTransform;
import com.mx.dla.dda.excelMapper.context.ExcelMapperContext;
import com.mx.dla.dda.excelMapper.dtos.ExcelMapper;
import com.mx.dla.dda.excelMapper.exceptions.ExcelMapperException;
import com.mx.dla.dda.reporte.ws.dtos.ParamGeneraReporteDTO;
import com.mx.dla.dda.reporte.ws.dtos.ResponseGeneraReporteDTO;
import com.mx.dla.dda.reportes.ExcelGeneratorProcess.bos.ExcelGeneratorProcessBO;
import com.mx.dla.dda.reportes.generaxml.generaXMLimpl;
import com.mx.dla.dda.restClient.bos.DLARestClient;
import com.mx.dla.dda.restClient.bos.DLARestClientFactory;
import com.mx.dla.dda.restClient.constants.DLARestServices;
import com.mx.dla.global.bos.BaseBO;

@Service
public class CargaTransaccionesBO extends BaseBO {

	@Value("${uri.file.reporte.TransaccionesvistaPrevia}")
	private String filePath;

	@Autowired
	private ExcelGeneratorProcessBO excelGeneratorProcessBO;

	@Value("${uri.file.carga.transacciones}")
	private String uriCarga;

	@Value("${uri.file.reporte.baseActivosSQL}")
	protected String uriSQL;

	@Autowired
	private BeanPopulator beanPopulator;

	@Autowired
	private DLARestClientFactory dlaRestClientFactory;

	@Autowired
	private CargaTransaccionesDAO cargaTransaccionesDAO;

	@Autowired
	private ExcelMapperContext excelMapperContext;

	@Autowired
	protected ExcelMapperTransform excelMapperTransform;

	@Autowired
	private generaXMLimpl genXml;

	private static Logger log = Logger.getLogger(CargaTransaccionesBO.class);

	ArrayList<String> textoSQLReporte = new ArrayList<String>();

	ResponseGeneraReporteDTO responseDTO = null;

	public List<CargaTransaccionesDTO> obtenCargaTransacciones(String mes)
			throws ResultMapException, SQLException, TransaccionException {

		List<CargaTransaccionesDTO> cargaTransacciones = null;

		mes = obtenFechaFront(mes);// mesSeparado.length == 3 ? "01/" + mesSeparado[0] + "/" + mesSeparado[2] :
									// "01/12/2017";

		try {
			cargaTransacciones = cargaTransaccionesDAO.obtenCargaTransacciones(mes);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return cargaTransacciones;
	}

	public PrincipalCargaTransaccionesDTO obtenerPrincipalCargaTransacciones(String mes)
			throws ResultMapException, SQLException, TransaccionException {
		PrincipalCargaTransaccionesDTO principalCarga = null;
		try {
			principalCarga = new PrincipalCargaTransaccionesDTO();
			principalCarga.setMesStr(obtenFechaFront(mes));
			principalCarga = cargaTransaccionesDAO.obtenerPrincipalCargaTransacciones(principalCarga);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}
		return principalCarga;
	}

	public PrincipalCargaTransaccionesDTO obtenerResumenCarga(String mes)
			throws ResultMapException, SQLException, TransaccionException {
		PrincipalCargaTransaccionesDTO resumencarga = null;

		try {

			resumencarga = cargaTransaccionesDAO.obtenerResumenCarga(mes);

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}
		return resumencarga;
	}

	public PrincipalCargaTransaccionesDTO obtenerResumenCargaIdCargaTrans(Long idCarga)
			throws ResultMapException, SQLException, TransaccionException {
		PrincipalCargaTransaccionesDTO resumencarga = null;

		try {

			resumencarga = cargaTransaccionesDAO.obtenerResumenCargaIdCarga(idCarga);

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}
		return resumencarga;
	}

	private String obtenFechaFront(String mes) {
		String[] mesSeparado = mes.split("/");
		return mesSeparado.length == 3 ? "01/" + mesSeparado[0] + "/" + mesSeparado[2] : "01/12/2017";
	}

	public PrincipalCargaTransaccionesDTO registraCargaTransacciones(String mes)
			throws ResultMapException, SQLException, TransaccionException {

		PrincipalCargaTransaccionesDTO cargaPrincipal = new PrincipalCargaTransaccionesDTO();
		cargaPrincipal.setMesStr(obtenFechaFront(mes));

		try {
			cargaTransaccionesDAO.registrarPrincipalCarga(cargaPrincipal);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return cargaPrincipal;
	}

	// may- 17 ____ funcion para recalculo de pago
	public ResponseAsociarTitTransCntVigentesDTO reCalculoPago(Long idCarga)
			throws ResultMapException, SQLException, TransaccionException, SocketTimeoutException, IOException {

		ParamAsocTitTransCntVigentesDTO request = new ParamAsocTitTransCntVigentesDTO();
		ResponseAsociarTitTransCntVigentesDTO response = null;
		DLARestClient client = null;

		try {

			Long idCargaTrans = idCarga;

			// proceso de recalculo de pago
			client = dlaRestClientFactory
					.getClient(DLARestServices.WS_CARGA_TRANSACCIONES_ASOCIARTITULOSTRANSCNTVIGENTES);
			request.setIdCargaTrans(idCargaTrans.toString());
			logger.debug("request : [{}]", request);
			response = client.get(request, ResponseAsociarTitTransCntVigentesDTO.class);
			logger.debug("response Recalculo Pago : [{}]", response);

			// llamada a SP DDA_CNT_CALCULAR_OVERAGE
			cargaTransaccionesDAO.calculaOverage(idCargaTrans);

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return response;
	}

	// funcion para carga de transacciones
	public ResponseCargaTitulosPNDTO cargarArchivoDeTransacciones(File fileUpload, String fileName, String expediente,
			String mes, Long idCarga) throws ResultMapException, SQLException, TransaccionException {

		ParamCargaTitulosPNDTO request = new ParamCargaTitulosPNDTO();
		ResponseCargaTitulosPNDTO response = null;
		DLARestClient client = null;
		PrincipalCargaTransaccionesDTO cargaPrincipal = null;

		if (idCarga == null) {
			cargaPrincipal = registraCargaTransacciones(mes);
		}

		try {

			Long idCargaOk = idCarga != null ? idCarga : cargaPrincipal.getIdCarga();

			String nombreArchivo = uriCarga + idCargaOk + expediente + fileName;
			fileName = idCargaOk + expediente + fileName;

			byte[] file = FileUtils.readFileToByteArray(fileUpload);
			File d = new File(nombreArchivo);

			d.setExecutable(true, false);
			d.setReadable(true, false);
			d.setWritable(true, false);

			FileUtils.writeByteArrayToFile(d, file);

			logger.info("Directorio: [{}]", nombreArchivo);
			logger.info("Archivo: [{}]", (idCargaOk + expediente + fileName));

			client = dlaRestClientFactory.getClient(DLARestServices.WS_CARGA_TRANSACCIONES_PROCESARCARGATITULOSPN);
			request.setNombreArchivo(fileName);
			request.setExpediente(expediente);
			request.setIdCargaTransacciones(idCargaOk.toString());
			logger.debug("request : [{}]", request);
			logger.debug("client!!! : [{}]", client);
			response = client.get(request, ResponseCargaTitulosPNDTO.class);
			response.setIdCarga(idCargaOk);

			logger.debug("response : [{}]", response);

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (IOException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return response;
	}

	// nuevo bo genera excel vista previa transaccion jul2017
	public InputStream dinamicIbatisRepVistaPrevia(String fileFileName, Long idCarga) throws ResultMapException,
			SQLException, TransaccionException, IOException, IllegalArgumentException, IllegalAccessException {
		String tituloReporte = "Reporte Transacciones Vista Previa";
		String archivoGen = "";
		List<String> listaPaises = null;
		String pivot_paises = "";
		String pivot_select = "";
		String excelFileName = fileFileName + ".xlsx";
		fileFileName = fileFileName + ".xml";

		listaPaises = obtenListaPaisesVistaPrevia();

		for (int N = 0; N < listaPaises.size(); N++) {
			pivot_paises = pivot_paises + "'" + listaPaises.get(N) + "'" + " AS " + listaPaises.get(N).replace(' ', '_')
					+ ",";
		}
		for (int N = 0; N < listaPaises.size(); N++) {
			pivot_select = pivot_select + "NVL(" + listaPaises.get(N).replace(' ', '_') + ", 0) as "
					+ listaPaises.get(N).replace(' ', '_') + ",";
		}

		List<Map<String, String>> response = cargaTransaccionesDAO.obtenRowReporte(idCarga,
				pivot_select.substring(0, pivot_select.length() - 1),
				pivot_paises.substring(0, pivot_paises.length() - 1));
		archivoGen = genXml.generaXMLvp(response, fileFileName, tituloReporte);

		logger.info("{}", response);
		logger.info("xml en la ruta {}", archivoGen);

		return excelGeneratorProcessBO.generaExcelProceso(fileFileName, excelFileName);

	}

	// nuevo bo genera reporte vista previa transaccion jul2017
	public List<LinkedHashMap<String, String>> generaRepVistaPrevia(Long idCarga) throws ResultMapException,
			SQLException, TransaccionException, IllegalArgumentException, IllegalAccessException {

		List<LinkedHashMap<String, String>> vistaprevia = null;

		try {
			List<String> listaPaises = null;
			String pivot_paises = "";
			String pivot_select = "";

			listaPaises = obtenListaPaisesVistaPrevia();

			for (int N = 0; N < listaPaises.size(); N++) {
				pivot_paises = pivot_paises + "'" + listaPaises.get(N) + "'" + " AS "
						+ listaPaises.get(N).replace(' ', '_') + ",";
			}
			for (int N = 0; N < listaPaises.size(); N++) {
				pivot_select = pivot_select + "NVL(" + listaPaises.get(N).replace(' ', '_') + ", 0) as "
						+ listaPaises.get(N).replace(' ', '_') + ",";
			}

			vistaprevia = cargaTransaccionesDAO.obtenReporteVistaPrevia(idCarga,
					pivot_select.substring(0, pivot_select.length() - 1),
					pivot_paises.substring(0, pivot_paises.length() - 1));

			logger.info("{}", vistaprevia);

		} catch (PersistenceException e) {
			logger.error("Error al generar vista previa - generaRepVistaPrevia ::: {}", e);
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			logger.error("Error al generar vista previa - generaRepVistaPrevia ::: {}", e);
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return vistaprevia;

	}

	// funcionalidad para llamar a Ws que ejecuta una consulta sql y la devuelve en
	// un json en el servidor
	public ResponseGeneraReporteDTO obtenerVistaPrevia(String fileName, Long idCarga) throws ResultMapException,
			SQLException, TransaccionException, IOException, IllegalArgumentException, IllegalAccessException {

		List<String> listaPaises = null;
		String id = idCarga.toString();
		String pivot_paises = "";
		String pivot_p = "";
		String pivot_select = "";
		String header = "";
		String first_header = "SELECT 'TIPO|ESTILO|CONCEPTO|";
		String finalHeader = "TOTAL|' as X from dual;";

		listaPaises = obtenListaPaisesVistaPrevia();

		for (int N = 0; N < listaPaises.size(); N++) {
			pivot_paises = pivot_paises + "'" + listaPaises.get(N) + "'" + " AS P" + N + ",";
			header = header + "P" + N + "|";
		}

		header = first_header + header + finalHeader;

		for (int N = 0; N < listaPaises.size(); N++) {
			pivot_p = pivot_p + "P" + N + " ||'|'||";
			pivot_select = pivot_select + "NVL(P" + N + ", 0) as P" + N + ",";
		}

		pivot_p = "SELECT TIPO ||'|'|| ESTILO ||'|'|| CONCEPTO ||'|'||" + pivot_p;

		textoSQLReporte.clear();
		textoSQLReporte.add("--[BEGIN]");
		textoSQLReporte.add(header);
		textoSQLReporte.add("--[END_HEADER]");
		textoSQLReporte.add(pivot_p);
		textoSQLReporte.add("TOTAL| AS X");
		textoSQLReporte.add(
				"from (SELECT CASE WHEN ESTUDIO IS NULL THEN 'total' WHEN TYPEA IS NULL THEN 'papa' ELSE ESTUDIO END AS TIPO, CASE WHEN ESTUDIO IS NULL THEN 'amarillo' WHEN TYPEA IS NULL THEN 'blanco' ELSE 'rosa' END AS ESTILO,	NVL(TYPEA, NVL(ESTUDIO, 'TOTAL')) AS CONCEPTO,");
		textoSQLReporte.add(pivot_select);
		textoSQLReporte.add("TOTAL||'|' AS X");
		textoSQLReporte.add(
				"FROM ( SELECT NVL(pv.DESCRIPCION, 'TOTAL') AS PAIS, ce.DESC_ESTUDIO AS ESTUDIO, ctt.TYPE_ABONO AS TYPEA, SUM(ctt.PAGO_MENSUAL) AS MONTO");
		textoSQLReporte.add(
				"FROM DDA_T_CARGA_TRANSACCION ct, DDA_T_CARGA_TRANSACCION_TITULO ctt, DDA_C_FILIAL cf, DDA_C_EMPRESA_VENTA ev, DDA_C_PAIS_VENTA pv, DDA_C_ESTUDIO ce WHERE ct.ID_CARGA_TRANS =");
		textoSQLReporte.add(id);
		textoSQLReporte.add(
				"AND ctt.ID_CARGA_TRANS = ct.ID_CARGA_TRANS AND ctt.ID_FILIAL = cf.ID_FILIAL AND cf.ID_EMPRESA = ev.ID_EMPRESA AND ev.ID_PAIS = pv.ID_PAIS AND ctt.ID_ESTUDIO = ce.ID_ESTUDIO");
		textoSQLReporte.add(
				"GROUP BY GROUPING SETS((), (ce.DESC_ESTUDIO), (pv.DESCRIPCION), (ce.DESC_ESTUDIO, pv.DESCRIPCION), (ce.DESC_ESTUDIO, ctt.TYPE_ABONO), (pv.DESCRIPCION, ce.DESC_ESTUDIO, ctt.TYPE_ABONO))) PIVOT(SUM(MONTO) FOR PAIS ");
		textoSQLReporte.add("IN (");
		textoSQLReporte.add(pivot_paises);
		textoSQLReporte.add("'TOTAL' AS TOTAL)) ORDER BY ESTUDIO NULLS FIRST, TYPEA NULLS FIRST);");
		textoSQLReporte.add("--[END]");

		logger.info("Lista Paises: [{}]", listaPaises);
		logger.info("FILE NAME: [{}]", fileName);
		logger.info("header: [{}]", header);
		logger.info("pivot_paises: [{}]", pivot_paises);
		logger.info("pivot_p: [{}]", pivot_p);

		File file = new File(uriSQL + fileName + ".sql");
		FileUtils.writeLines(file, textoSQLReporte);

		logger.debug("busca archivo en [{}]", file.getAbsolutePath());

		// Si se crea el archivo se ejecuta el WS
		if (file.exists()) {
			logger.info("Comienza llamada a Ws GENERA_TRANSACCIONES_VISTAPREVIA.");
			responseDTO = callWsGeneraReporte(fileName);
		}

		return responseDTO;
	}

	public ResponseGeneraReporteDTO callWsGeneraReporte(String archivo) throws SocketTimeoutException, IOException, TransaccionException {

		DLARestClient client = dlaRestClientFactory.getClient(DLARestServices.GENERA_TRANSACCIONES_VISTAPREVIA);
		ParamGeneraReporteDTO request = new ParamGeneraReporteDTO();

		logger.info("inicializa parametros.");
		request.setNombreArchivo(archivo);
		request.setFormato("json");
		request.setComprimir("n");

		logger.info("Request callWsGeneraReporte [{}]", request);
		ResponseGeneraReporteDTO response = client.get(request, ResponseGeneraReporteDTO.class);
		logger.info("Response callWsGeneraReporte [{}]", response);

		return response;

	}

	public JSONArray jsonVistaprevia(String ruta) {
		JSONArray lang = null;

		try {

			FileReader reader = new FileReader(filePath);
			JSONParser jsonParser = new JSONParser();
			JSONObject jsonObject = (JSONObject) jsonParser.parse(reader);

			lang = (JSONArray) jsonObject.get("rows");

			for (int i = 0; i < lang.size(); i++) {
				log.debug("The " + i + " element of the json: " + lang.get(i));
			}

		} catch (IOException e) {
			log.error(e.getMessage(), e);
		} catch (ParseException e) {
			log.error(e.getMessage(), e);
		} catch (NullPointerException e) {
			log.error(e.getMessage(), e);
		}

		return lang;
	}

	// may-17 funcion para obtener la informacion de detalle de carga para descarga
	// de excel...
	public byte[] obtenerDetalleErroresCarga(String mes) throws ResultMapException, SQLException, TransaccionException {

		List<RowRepErrResumenCargaDTO> rowReporteDetalleErroresCarga = new ArrayList<RowRepErrResumenCargaDTO>();
		byte[] fileExcel = null;
		try {

			rowReporteDetalleErroresCarga = cargaTransaccionesDAO.obtenRowReporteResumenCarga(mes);

			if (rowReporteDetalleErroresCarga == null || rowReporteDetalleErroresCarga.isEmpty()) {
				rowReporteDetalleErroresCarga = new ArrayList<RowRepErrResumenCargaDTO>();
				rowReporteDetalleErroresCarga.add(beanPopulator.initObject(RowRepErrResumenCargaDTO.class));
			}
			logger.debug("Descargar archivo Detalle Errores... se han  obtenido [{}]",
					rowReporteDetalleErroresCarga.size());
			fileExcel = excelMapperTransform.transformObjectToExcel(rowReporteDetalleErroresCarga,
					"repDetalleErrorCargaTransaccion", RowRepErrResumenCargaDTO.class);
			logger.debug("Descargar archivo, se ha generado binario.");

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (ExcelMapperException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (IOException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return fileExcel;
	}

	// may-17 funcion que recupera la lista de informacion que utilizara la descarga
	// de errores en excel en asoc. titulos
	public byte[] obtenerListaErrAsocTitulos(Long idCarga)
			throws ResultMapException, SQLException, TransaccionException {

		List<RowRepErrAsocTitulosDTO> rowListadoErroresAsocTitulos = new ArrayList<RowRepErrAsocTitulosDTO>();
		byte[] fileExcel = null;
		try {

			rowListadoErroresAsocTitulos = cargaTransaccionesDAO.obtenRowReporteErrAsocTitulos(idCarga);

			if (rowListadoErroresAsocTitulos == null || rowListadoErroresAsocTitulos.isEmpty()) {
				rowListadoErroresAsocTitulos = new ArrayList<RowRepErrAsocTitulosDTO>();
				rowListadoErroresAsocTitulos.add(beanPopulator.initObject(RowRepErrAsocTitulosDTO.class));
			}
			logger.debug("Descargar archivo errores Asoctitulos: [{}]", rowListadoErroresAsocTitulos.size());
			fileExcel = excelMapperTransform.transformObjectToExcel(rowListadoErroresAsocTitulos,
					"repErroresAsociacionTitulos", RowRepErrAsocTitulosDTO.class);
			logger.debug("Descargar archivo, se ha generado binario.");

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (ExcelMapperException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (IOException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return fileExcel;
	}

	public byte[] descargarArchivoTransacciones(List<CargaTransaccionesDTO> infoReporte)
			throws ResultMapException, SQLException, TransaccionException {

		for (CargaTransaccionesDTO c : infoReporte) {
			logger.debug("[{}]", c);
		}

		byte[] barchivo = null;
		ExcelMapper mapper = excelMapperContext.getExcelMapper("cargaTransacciones");
		log.info("mapper:" + mapper);
		try {

			barchivo = excelMapperTransform.transformObjectToExcel(infoReporte, mapper, CargaTransaccionesDTO.class);

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (ExcelMapperException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (IOException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return barchivo;
	}

	// Abr-17 se agrega funcionalidad de descarga excel en vista previa
	public byte[] descargaArchivoVistaPrevia(List<RowReporteCargaDTO> inforowReporte)
			throws ResultMapException, SQLException, TransaccionException {

		for (RowReporteCargaDTO c : inforowReporte) {
			logger.debug("[{}]", c);
		}

		byte[] barchivo = null;
		ExcelMapper mapper = excelMapperContext.getExcelMapper("cargaTransacciones2");

		try {

			barchivo = excelMapperTransform.transformObjectToExcel(inforowReporte, mapper, RowReporteCargaDTO.class);

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (ExcelMapperException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (IOException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return barchivo;

	}

	// may-23 se agrega funcion para descargar el detalle de error de carga
	// transacciones...
	public byte[] descargaArchivoResumenErroresCarga(List<RowRepErrResumenCargaDTO> infoRow)
			throws ResultMapException, SQLException, TransaccionException {
		for (RowRepErrResumenCargaDTO c : infoRow) {
			logger.debug("[{}]", c);
		}

		byte[] bFile = null;
		ExcelMapper mapper = excelMapperContext.getExcelMapper("repDetalleErrorCargaTransaccion");
		logger.debug("[{}]", mapper);
		log.info("mapper resumen carga:" + mapper);

		try {

			bFile = excelMapperTransform.transformObjectToExcel(infoRow, mapper, RowRepErrResumenCargaDTO.class);
			log.info("mapperDetalleCarga:" + mapper);

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (ExcelMapperException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (IOException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return bFile;
	}

	// may-17 se agrega funcion para descargar el Archivo excel en la asociacion de
	// titulos transacciones...
	public byte[] descargaArchivoErrAsocTitulos(List<RowRepErrAsocTitulosDTO> infoRowAsocTit)
			throws ResultMapException, SQLException, TransaccionException {
		for (RowRepErrAsocTitulosDTO c : infoRowAsocTit) {
			logger.debug("[{}]", c);
		}

		byte[] bFile = null;
		ExcelMapper mapper = excelMapperContext.getExcelMapper("repErroresAsociacionTitulos");
		logger.debug("[{}]", mapper);
		log.info("mapper Errores AsocTitulos:" + mapper);

		try {

			bFile = excelMapperTransform.transformObjectToExcel(infoRowAsocTit, mapper, RowRepErrAsocTitulosDTO.class);
			log.info("mapperDetalleCarga:" + mapper);

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (ExcelMapperException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (IOException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return bFile;
	}

	// servicio para titulos en contratos
	public List<TitulosCargaTransaccionesDTO> titulosdelaCarga(String mes)
			throws ResultMapException, SQLException, TransaccionException {
		List<TitulosCargaTransaccionesDTO> titulosCarga = null;

		try {
			titulosCarga = cargaTransaccionesDAO.titulosdelaCarga(mes);
			log.info(titulosCarga);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return titulosCarga;
	}

	// servicio para titulos de la carga sin IdBroadView
	public List<TitulosCargaTransaccionesDTO> sinIdBroadView(Long idCarga)
			throws ResultMapException, SQLException, TransaccionException {
		List<TitulosCargaTransaccionesDTO> sinIdBv = null;

		try {
			sinIdBv = cargaTransaccionesDAO.sinIdBroadView(idCarga);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return sinIdBv;
	}

	// servicio para titulos de la carga, el id broadView no existe
	public List<TitulosCargaTransaccionesDTO> idBroadViewNoExiste(Long idCarga)
			throws ResultMapException, SQLException, TransaccionException {
		List<TitulosCargaTransaccionesDTO> IdBvNoExiste = null;

		try {
			IdBvNoExiste = cargaTransaccionesDAO.idBroadViewNoExiste(idCarga);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return IdBvNoExiste;
	}

	// servicio para titulos de la carga, titulo y filial no existe
	public List<TitulosCargaTransaccionesDTO> tituloyFilialNoExiste(Long idCarga)
			throws ResultMapException, SQLException, TransaccionException {
		List<TitulosCargaTransaccionesDTO> tyfNoExiste = null;

		try {
			tyfNoExiste = cargaTransaccionesDAO.tituloyFilialNoExiste(idCarga);
			log.info(tyfNoExiste);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return tyfNoExiste;
	}

	// servicio para titulos de la carga, titulo fuera de periodo
	public List<TitulosCargaTransaccionesDTO> tituloFueradePeriodo(Long idCarga)
			throws ResultMapException, SQLException, TransaccionException {

		List<TitulosCargaTransaccionesDTO> titulofueraperiodo = null;

		try {
			titulofueraperiodo = cargaTransaccionesDAO.tituloFueradePeriodo(idCarga);
			log.info(titulofueraperiodo);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return titulofueraperiodo;
	}

	// Servicio para actualizar los Id's BroadView desde Asociacion de Titulos
	public void actualizarIdBv(String IdBv, Integer id_carga_titulo, String nombreEstandar)
			throws ResultMapException, SQLException, TransaccionException {
		try {
			TitulosCargaTransaccionesDTO itemTitulosCargaTransaccionesDTO = new TitulosCargaTransaccionesDTO();
			itemTitulosCargaTransaccionesDTO.setIdBv(IdBv);
			itemTitulosCargaTransaccionesDTO.setId_carga_titulo(id_carga_titulo);
			itemTitulosCargaTransaccionesDTO.setNombreEstandar(nombreEstandar);
			cargaTransaccionesDAO.actualizarIdBv(itemTitulosCargaTransaccionesDTO);
			log.info("Se va a actualizar IdBv:  " + IdBv + "con id carga: " + id_carga_titulo);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

	}

	public void ejecutaSP(String fecha) throws ResultMapException, SQLException, TransaccionException {
		try {
			cargaTransaccionesDAO.ejecutaSP(fecha);
			log.info("Se va a actualizar fecha:  " + fecha);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

	}

	public FechaBloqueoDTO consultaMesActual(String anio, String mes)
			throws ResultMapException, SQLException, TransaccionException {
		FechaBloqueoDTO response = new FechaBloqueoDTO();
		try {
			List<FechaBloqueoDTO> fechas = cargaTransaccionesDAO.consultarFechaActual(mes, anio);
			if (fechas.isEmpty()) {
				response.setDia("27");
				response.setMes(mes);
				response.setAnio(anio);
			} else {
				response = fechas.get(0);
			}
			log.info("Fecha recuperada:  " + response.getDia() + "/" + response.getMes() + "/" + response.getAnio());
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}
		return response;
	}

	public void ejecutaSP_porcR(String fecha) throws ResultMapException, SQLException, TransaccionException {
		try {
			cargaTransaccionesDAO.ejecutaSP_porcR(fecha);
			log.info("ejecutaSP_porcR:  " + fecha);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

	}

	public void ejecutaSP_MarcaCont(String in_Contrato, String in_Estudio)
			throws ResultMapException, SQLException, TransaccionException {
		try {
			cargaTransaccionesDAO.ejecutaSP_MarcaCont(in_Contrato, in_Estudio);
			log.info("ejecutaSP_MarcaCont:  " + in_Estudio);
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

	}

	public void validaCarga(Long idCarga) throws ResultMapException, SQLException, TransaccionException {
		PrincipalCargaTransaccionesDTO principalcarga = new PrincipalCargaTransaccionesDTO();
		try {
			if (idCarga != null) {
				principalcarga.setIdCarga(idCarga);
				cargaTransaccionesDAO.validaCarga(principalcarga);
				log.info("Se va a validar la carga:  ");
			}

		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}
	}

	public List<String> obtenListaPaises() throws ResultMapException, SQLException, TransaccionException {
		List<String> lista = null;
		try {
			lista = cargaTransaccionesDAO.obtenListaPaises();
			lista.add(0, "Estudio");
			lista.add("Total");
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return lista;
	}

	public List<String> obtenListaPaisesVistaPrevia() throws ResultMapException, SQLException, TransaccionException {
		List<String> lista = null;
		try {
			lista = cargaTransaccionesDAO.obtenListaPaises();
		} catch (PersistenceException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return lista;
	}

	public byte[] obtenPlantilla() throws ResultMapException, SQLException, TransaccionException {

		byte[] plantilla = null;
		List<plantillaCargaTransaccionesDTO> lista = new ArrayList<plantillaCargaTransaccionesDTO>();
		ExcelMapper mapper = null;

		plantillaCargaTransaccionesDTO li = new plantillaCargaTransaccionesDTO();
		lista.add(li);

		try {

			mapper = excelMapperContext.getExcelMapper("plantillaCargaTransacciones");
			plantilla = excelMapperTransform.transformObjectToExcel(lista, mapper,
					plantillaCargaTransaccionesDTO.class);

		} catch (ExcelMapperException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (IOException e) {
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		}

		return plantilla;
	}

}
