package com.mx.dla.dda.contrato.generales.bos;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.dla.dda.domain.constants.Operacion;
import com.dla.dda.domain.constants.OrigenCodes;
import com.dla.dda.domain.model.email.DetalleCorreoVO;
import com.dla.dda.domain.model.request.EmailRequest;
import com.dla.dda.domain.model.response.EmailResponse;
import com.mx.dla.admin.dtos.UsuarioDTO;
import com.mx.dla.dda.contrato.common.bos.CommonRestBO;
import com.mx.dla.dda.contrato.common.bos.DocumentoBO;
import com.mx.dla.dda.contrato.common.bos.JustificacionBO;
import com.mx.dla.dda.contrato.common.dtos.DocumentoDTO;
import com.mx.dla.dda.contrato.generales.daos.ValidacionGeneralesDAO;
import com.mx.dla.dda.contrato.generales.dtos.AreaDTO;
import com.mx.dla.dda.contrato.generales.dtos.AutorizadorDTO;
import com.mx.dla.dda.contrato.generales.dtos.BundleReturn;
import com.mx.dla.dda.contrato.generales.dtos.ContratoDTO;
import com.mx.dla.dda.contrato.generales.dtos.CorreoExternoDTO;
import com.mx.dla.dda.contrato.generales.dtos.DetalleCorreoDTO;
import com.mx.dla.dda.contrato.generales.dtos.WFPasoDTO;
import com.mx.dla.dda.contrato.generales.dtos.WFSeguimientoDTO;
import com.mx.dla.dda.contrato.generales.enums.Estatus;
import com.mx.dla.dda.contrato.generales.enums.MensajeTexto;
import com.mx.dla.dda.contrato.generales.enums.TipoMensaje;
import com.mx.dla.dda.contrato.transaccion.titulos.daos.TituloLoteTransDAO;
import com.mx.dla.dda.contrato.ws.amortizacioncontrato.ContratoTituloDTO;
import com.mx.dla.dda.contrato.ws.amortizacioncontrato.ParamCalcAmortCntDTO;
import com.mx.dla.dda.contrato.ws.amortizacioncontrato.ResponseCalcAmortCntDTO;
import com.mx.dla.dda.contrato.ws.dtos.ItemOrdenCompraDTO;
import com.mx.dla.dda.contrato.ws.dtos.ParamAdendumEnmiendaDTO;
import com.mx.dla.dda.contrato.ws.dtos.ParamOrdenCompraDTO;
import com.mx.dla.dda.contrato.ws.dtos.ResponseAdendumEnmiendaDTO;
import com.mx.dla.dda.contrato.ws.dtos.ResponseOrdenCompraDTO;
import com.mx.dla.dda.contrato.ws.validapresupuesto.ParamValidaPresupuestoCntDTO;
import com.mx.dla.dda.contrato.ws.validapresupuesto.ResponseValidaPresupuestoCntDTO;
import com.mx.dla.dda.contrato.ws.validarMinimoSeleccion.ParamValidaMinimoSeleccionDTO;
import com.mx.dla.dda.contrato.ws.validarMinimoSeleccion.ResponseValidaMinimoSeleccionDTO;
import com.mx.dla.dda.rest.services.client.JsonConverter;
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;

@Component
public class ValidacionGeneralesBO extends BaseBO{

	@Autowired
	private ValidacionGeneralesDAO validacionGeneralesDAO;
	
	@Autowired
	private DLARestClientFactory dlaRestClientFactory;
	
	@Autowired
	private OpcionesContratoBO opcionesContratoBO;
	
	@Autowired
	private ParametersWebService parametersWebService;
	
	@Autowired
	private CommonRestBO commonRestBO;
	
	@Autowired
	private JustificacionBO justificacionBO;
	
	@Autowired
	private GeneralesBO generalesBO;
	
	@Autowired
	private DocumentoBO documentoBO;
	
	@Autowired
	private TituloLoteTransDAO tituloLoteDAO;
	
	@Value("${ordenInterna.idPosicion}")
	private String idPosicionOrdInt;
	
/*
	public BundleReturn notificacionSAP(ContratoDTO contrato, String expedienteUsuario){
		
		BundleReturn respuesta = new BundleReturn();
		
		respuesta.setNumero(TipoMensaje.ERROR.getValor());
		respuesta.setEstado(false);
				
		boolean desicion = false;
		ResponseOrdenCompraDTO responseDTO = null;
		ResponseAdendumEnmiendaDTO responseAdendumDTO = null;
		//ContratoDTO contrato = generalesBO.obtenContrato(idContrato);
		
		if(contrato.getAmortizable().equals("SI")) { //Amortizable
			
			if(contrato.getIdTipoMovimiento() == 1) {//Nuevo
				 
				try {
					logger.info("antes de llamarCrearOrdenCompra.");
					responseDTO = llamaCrearOrdenCompra(contrato, expedienteUsuario);
					logger.info("despues de llamarCrearOrdenCompra.");
					desicion = responseDTO.getResultado();
					respuesta.setCadena(responseDTO.getMensaje());//informacion = responseDTO.getMensaje(); 
					
				}catch (Exception ex){
					logger.debug(ex.toString());
					respuesta.setCadena(MensajeTexto.TIEMPO_AGOTADO.getTexto()); //informacion = "Timepo agotado";
				}
				
				if(desicion){
					opcionesContratoBO.actulizaEstatus(Estatus.Vigente.getValor(), contrato.getIdContrato(), expedienteUsuario);
					respuesta.setCadena(MensajeTexto.LLAMADA_EXITOSA.getTexto()); //noMensaje = NumeroMensaje.OKLLAMADA.getValue() ;
					respuesta.setEstado(true);
					respuesta.setNumero(TipoMensaje.EXITO.getValor());
					opcionesContratoBO.llamarAjustaAddendum(contrato.getIdContrato());
					opcionesContratoBO.llamarReportePagos(contrato.getIdContrato());
					logger.info("antes de llamarAmortizacionInicial Original.");
					opcionesContratoBO.llamarAmortizacionInicial(contrato.getIdContrato());
					logger.info("despues de llamarAmortizacionInicial Original.");
					//logger.debug(" value: " + NumeroMensaje.OKLLAMADA.getValue());
				}else{
					respuesta.setCadena(MensajeTexto.LLAMADA_NO_EXITOSA.getTexto());//noMensaje = NumeroMensaje.NOOKLLAMADA.getValue() ;
					//logger.debug(" value: " + NumeroMensaje.NOOKLLAMADA.getValue());
				}
				
				logger.debug("Se termino de llamar a creaOrdenCompra(SUSCRIPCIÓN)");
				
			}else {//Adendum o Enmienda
				
				try {
					responseAdendumDTO = llamaCrearAdendumEnmienda(contrato, expedienteUsuario);
					desicion = responseAdendumDTO.getResultado();
					respuesta.setCadena(responseAdendumDTO.getMensaje());//;informacion = responseAdendumDTO.getMensaje();
				}catch(Exception ex) {
					logger.debug(ex.toString());
					respuesta.setCadena(MensajeTexto.TIEMPO_AGOTADO.getTexto()); //informacion = "Tiempo agotado";
				}
				
				if(desicion){
					opcionesContratoBO.actulizaEstatus(Estatus.Vigente.getValor(), contrato.getIdContrato(), expedienteUsuario);
					respuesta.setCadena(MensajeTexto.LLAMADA_EXITOSA.getTexto()); //noMensaje = NumeroMensaje.OKLLAMADA.getValue() ;
					respuesta.setEstado(true);
					respuesta.setNumero(TipoMensaje.EXITO.getValor());
					opcionesContratoBO.llamarAjustaAddendum(contrato.getIdContrato());
					opcionesContratoBO.llamarReportePagos(contrato.getIdContrato());
					logger.info("antes de llamarAmortizacionInicial Enmienda.");
					opcionesContratoBO.llamarAmortizacionInicial(contrato.getIdContrato());
					logger.info("despues de llamarAmortizacionInicial Enmienda.");
					//logger.debug(" value: " + NumeroMensaje.OKLLAMADA.getValue());
				}else{
					respuesta.setCadena(MensajeTexto.LLAMADA_NO_EXITOSA.getTexto());//noMensaje = NumeroMensaje.NOOKLLAMADA.getValue();
					//logger.debug(" value: " + NumeroMensaje.NOOKLLAMADA.getValue());
				}
				
				logger.debug("Se termino de llamar a crearAdendunEnmienda (SUSCRIPCIÓN)");
				
			}
			
		}else {// No Amortizable
			
			if(contrato.getIdTipoMovimiento() == 1) {//Nuevo
				
				try {
					responseDTO = llamaRegistrarSAPNoAmortizable(contrato, expedienteUsuario);//llamar a registroSAPNoAmortizable
					desicion = responseDTO.getResultado();
					respuesta.setCadena(responseDTO.getMensaje()); //informacion = responseDTO.getMensaje();
				}catch (Exception ex){
					logger.debug(ex.toString());
					respuesta.setCadena(MensajeTexto.TIEMPO_AGOTADO.getTexto());
				}
				
				if(desicion){
					opcionesContratoBO.actulizaEstatus(Estatus.Vigente.getValor(), contrato.getIdContrato(), expedienteUsuario);
					respuesta.setCadena(MensajeTexto.LLAMADA_EXITOSA.getTexto()); //noMensaje = NumeroMensaje.OKLLAMADA.getValue() ;
					respuesta.setEstado(true);
					respuesta.setNumero(TipoMensaje.EXITO.getValor());
					opcionesContratoBO.llamarAjustaAddendum(contrato.getIdContrato());
					opcionesContratoBO.llamarReportePagos(contrato.getIdContrato());
					//logger.debug(" value: " + NumeroMensaje.OKLLAMADA.getValue());
				}else{
					respuesta.setCadena(MensajeTexto.LLAMADA_NO_EXITOSA.getTexto());//noMensaje = NumeroMensaje.NOOKLLAMADA.getValue();
					//logger.debug(" value: " + NumeroMensaje.NOOKLLAMADA.getValue());
				}
				
				logger.debug("Se termino de llamar a registroSAPNoAmortizable (TRANSACCIONAL - LINCESE FEE)");
				
			}else {//Adendum o Enmienda
				
				try {
					responseAdendumDTO = llamaAdendumEnmiendaNoAmortizable(contrato, expedienteUsuario); //llamar a registroAdendumEnmiendaNoAmortizable
					desicion = responseAdendumDTO.getResultado();
					respuesta.setCadena(responseAdendumDTO.getMensaje()); //informacion = responseAdendumDTO.getMensaje();
				}catch(Exception ex) {
					logger.debug(ex.toString());
					respuesta.setCadena(MensajeTexto.TIEMPO_AGOTADO.getTexto());
				}
				
				if(desicion){
					opcionesContratoBO.actulizaEstatus(Estatus.Vigente.getValor(), contrato.getIdContrato(), expedienteUsuario);
					respuesta.setCadena(MensajeTexto.LLAMADA_EXITOSA.getTexto()); //noMensaje = NumeroMensaje.OKLLAMADA.getValue() ;
					respuesta.setEstado(true);
					respuesta.setNumero(TipoMensaje.EXITO.getValor());
					opcionesContratoBO.llamarAjustaAddendum(contrato.getIdContrato());
					opcionesContratoBO.llamarReportePagos(contrato.getIdContrato());
					//logger.debug(" value: " + NumeroMensaje.OKLLAMADA.getValue());
				}else{
					respuesta.setCadena(MensajeTexto.LLAMADA_NO_EXITOSA.getTexto());//noMensaje = NumeroMensaje.NOOKLLAMADA.getValue();
					//logger.debug(" value: " + NumeroMensaje.NOOKLLAMADA.getValue());
				}
				
				logger.debug("Se termino de llamar a registroAdendumEnmiendaNoAmortizable (TRANSACCIONAL - LINCESE FEE)");
			}
			
			//setNmensaje(NumeroMensaje.NOVALIDAWSOC.getValue());
		}
		
		
		//return noMensaje + "_" + informacion;
		return respuesta;
	}
*/
	
	
public BundleReturn notificacionSAP(ContratoDTO contrato, String expedienteUsuario){
		
		BundleReturn respuesta = new BundleReturn();
		
		respuesta.setNumero(TipoMensaje.ERROR.getValor());
		respuesta.setEstado(false);
				
		boolean desicion = false;
		ResponseOrdenCompraDTO responseDTO = null;
		ResponseAdendumEnmiendaDTO responseAdendumDTO = null;
		
		if(contrato.getAmortizable().equals("SI")) { //Amortizable (Suscripción o License Fee )
			
			if(contrato.getIdTipoMovimiento() == 1) {//Contrato Original o Addendum
				 
				try {
					logger.info("antes de llamarCrearOrdenCompra.");
					responseDTO = llamaCrearOrdenCompra(contrato, expedienteUsuario);
					logger.info("despues de llamarCrearOrdenCompra.");
					desicion = responseDTO.getResultado();
					respuesta.setCadena(responseDTO.getMensaje());
					
				}catch (Exception ex){
					logger.debug(ex.toString());
					respuesta.setCadena(MensajeTexto.TIEMPO_AGOTADO.getTexto());
				}
				
				if(desicion){
					
					respuesta.setCadena(MensajeTexto.LLAMADA_EXITOSA.getTexto()); //noMensaje = NumeroMensaje.OKLLAMADA.getValue() ;
					respuesta.setEstado(true);
					respuesta.setNumero(TipoMensaje.EXITO.getValor());
					
					procesarResultadosPorContrato(contrato.getIdContrato());
									
				}else{				
					respuesta.setCadena(MensajeTexto.LLAMADA_NO_EXITOSA.getTexto());
					//logger.debug(" value: " + NumeroMensaje.NOOKLLAMADA.getValue());
				}
				
				//logger.debug("Se termino de llamar a creaOrdenCompra(SUSCRIPCIÓN)");
				
			}else {//Enmienda
				
				try {
					logger.info("antes de llamaCrearEnmienda.");
					responseAdendumDTO = llamaCrearEnmienda(contrato, expedienteUsuario);
					logger.info("despues de llamaCrearEnmienda.");
					desicion = responseAdendumDTO.getResultado();
					respuesta.setCadena(responseAdendumDTO.getMensaje());
				}catch(Exception ex) {
					logger.debug(ex.toString());
					respuesta.setCadena(MensajeTexto.TIEMPO_AGOTADO.getTexto());
				}
				
				if(desicion){
					
					respuesta.setCadena(MensajeTexto.LLAMADA_EXITOSA.getTexto()); //noMensaje = NumeroMensaje.OKLLAMADA.getValue() ;
					respuesta.setEstado(true);
					respuesta.setNumero(TipoMensaje.EXITO.getValor());
					
					procesarResultadosPorContrato(contrato.getIdContrato());
					
				}else{				
					respuesta.setCadena(MensajeTexto.LLAMADA_NO_EXITOSA.getTexto());//noMensaje = NumeroMensaje.NOOKLLAMADA.getValue();
					//logger.debug(" value: " + NumeroMensaje.NOOKLLAMADA.getValue());
				}
				
				logger.debug("Se termino de llamar a crearAdendunEnmienda (SUSCRIPCIÓN)");
				
			}
			
		}else {// No Amortizable (Transaccional)
			
			if(contrato.getIdTipoMovimiento() == 1) {//Contrato Original o Addendum
				
				try {
					responseDTO = llamaRegistrarSAPNoAmortizable(contrato, expedienteUsuario);
					desicion = responseDTO.getResultado();
					respuesta.setCadena(responseDTO.getMensaje()); 
				}catch (Exception ex){
					logger.debug(ex.toString());
					respuesta.setCadena(MensajeTexto.TIEMPO_AGOTADO.getTexto());
				}
				
				if(desicion){
					
					respuesta.setCadena(MensajeTexto.LLAMADA_EXITOSA.getTexto()); //noMensaje = NumeroMensaje.OKLLAMADA.getValue() ;
					respuesta.setEstado(true);
					respuesta.setNumero(TipoMensaje.EXITO.getValor());
					
					procesarResultadosPorContrato(contrato.getIdContrato());
					
				}else{				
					respuesta.setCadena(MensajeTexto.LLAMADA_NO_EXITOSA.getTexto());//noMensaje = NumeroMensaje.NOOKLLAMADA.getValue();
					//logger.debug(" value: " + NumeroMensaje.NOOKLLAMADA.getValue());
				}
				
				logger.debug("Se termino de llamar a registroSAPNoAmortizable (TRANSACCIONAL - LINCESE FEE)");
				
			}else {//Enmienda
				
				try {
					responseAdendumDTO = llamaEnmiendaNoAmortizable(contrato, expedienteUsuario); //llamar a registroAdendumEnmiendaNoAmortizable
					desicion = responseAdendumDTO.getResultado();
					respuesta.setCadena(responseAdendumDTO.getMensaje()); //informacion = responseAdendumDTO.getMensaje();
				}catch(Exception ex) {
					logger.debug(ex.toString());
					respuesta.setCadena(MensajeTexto.TIEMPO_AGOTADO.getTexto());
				}
				
				if(desicion){
					
					respuesta.setCadena(MensajeTexto.LLAMADA_EXITOSA.getTexto()); //noMensaje = NumeroMensaje.OKLLAMADA.getValue() ;
					respuesta.setEstado(true);
					respuesta.setNumero(TipoMensaje.EXITO.getValor());
					
					procesarResultadosPorContrato(contrato.getIdContrato());
					
				}else{				
					respuesta.setCadena(MensajeTexto.LLAMADA_NO_EXITOSA.getTexto());//noMensaje = NumeroMensaje.NOOKLLAMADA.getValue();
					//logger.debug(" value: " + NumeroMensaje.NOOKLLAMADA.getValue());
				}
				
				logger.debug("Se termino de llamar a registroAdendumEnmiendaNoAmortizable (TRANSACCIONAL - LINCESE FEE)");
			}
			
			//setNmensaje(NumeroMensaje.NOVALIDAWSOC.getValue());
		}
		
		
		//return noMensaje + "_" + informacion;
		return respuesta;
	}

	public boolean validaEstudioContrato(Long idContrato) {
		
		String estudio = null;
		
		try {
			estudio = validacionGeneralesDAO.obtenerIdSapEstudioContrato(idContrato);
		} catch(Exception ex) {
			logger.error("", ex);
		}
		
		if(estudio == null) {
			return false;
		} else {
			return true;
		}
		
	}
	
	public ResponseValidaPresupuestoCntDTO obtenValidacionPresupuesto(Date fechaInicio, Long idContrato, String origen){
		
		
		DLARestClient client = dlaRestClientFactory.getClient(DLARestServices.VALIDAR_PRESUPUESTO_POR_CONTRATO);
		
		ParamValidaPresupuestoCntDTO req = new ParamValidaPresupuestoCntDTO();
		ResponseValidaPresupuestoCntDTO resp = null;
		
		//PresupuestoRequest req = new PresupuestoRequest();
		//PresupuestoResponse resp = null;
		
		//int annioActual = 0;
		//int annioInicioContrato = 0;
		
		//Calendar cal = Calendar.getInstance();
		
		//cal.setTime(fechaInicio);
		//annioInicioContrato = cal.get(Calendar.YEAR);
		
		//cal.setTime(new Date());
		//annioActual = cal.get(Calendar.YEAR);
		
		req.setIdContrato(idContrato.toString());
		//req.setAnnio(annioActual >= annioInicioContrato ? (annioActual+"") : (annioInicioContrato+""));
		//req.setOrigen(origen);

		//req.setAnnio(annio);
		//req.setAnio(annioActual >= annioInicioContrato ? annioActual : annioInicioContrato);
		//req.setAnio(annioInicioContrato);
		//req.setContrato(idContrato);
		//req.setOrigenTitulos(origen);
		
		//logger.info("Generales - Año : [{}]",  annioInicioContrato);
		
		logger.debug("request : [{}]",  req);
		
		try {
			resp = client.get(req, ResponseValidaPresupuestoCntDTO.class);
			logger.debug("response : [{}]", resp);
		}catch(Exception ex) {
			logger.error("", ex);
		}
		
		return resp;
	}
	
	public ResponseValidaMinimoSeleccionDTO obtenValidacionMinimoSeleccion(Long idContrato, String origen) {
	
		
		
		DLARestClient client = dlaRestClientFactory.getClient(DLARestServices.VALIDA_MINIMO_SELECCION);
		ParamValidaMinimoSeleccionDTO req = new ParamValidaMinimoSeleccionDTO();
		ResponseValidaMinimoSeleccionDTO resp = null;
		
		req.setIdContrato(idContrato.toString());
		req.setOrigenTitulos(origen);
		logger.debug("request : [{}]", req);
		
		try{
			resp = client.get(req, ResponseValidaMinimoSeleccionDTO.class);
			logger.debug("response : [{}]", resp);
		}catch(Exception ex){
			logger.error("", ex);
		}
		
		return resp;
	}
	
	
	public boolean llamdaCalcularAmortizacionPorContrato(Long idContrato) {
		
		boolean respuesta  = false;
		
		DLARestClient client = dlaRestClientFactory.getClient(DLARestServices.CALCULAR_AMORTIZACION_POR_CONTRATO);
		ParamCalcAmortCntDTO req = new ParamCalcAmortCntDTO();
		ResponseCalcAmortCntDTO resp = null;
		
		req.setIdContrato(idContrato.toString());
		
		String modulo = "AMORTIZACION"; //verificar si se cuenta con un enum para esta cadena
		
		//req.setModulo(modulo);
		//req.setLobTitulos(new ArrayList<ContratoTituloDTO>());
		logger.debug("request : [{}]", req);
		try {
			
			resp = client.get(req, ResponseCalcAmortCntDTO.class);
			logger.debug("response : [{}]", resp);
			
			respuesta = resp.getResultado();
			
			if(!respuesta) {
				opcionesContratoBO.registraProcesoPendiente(idContrato, modulo , 1);
			}
			
			
			
		}catch(Exception ex) {
			opcionesContratoBO.registraProcesoPendiente(idContrato, modulo, 1);
			logger.error("", ex);
		}
		
		return respuesta;
	}
	
	public BundleReturn validacionesParaFinalizarRegistro(Long idContrato, Long tipoContrato, Date fechaInicio, String origen, String expediente) {
		
		logger.info("Validando, idContrato : [{}] -- tipoContrato [{}]", idContrato, tipoContrato);
		String infoRespuesta  = "";
		//Integer numeroMensaje = NumeroMensaje.NOFINALIZA.getValue();
		BundleReturn respuesta = new BundleReturn();
		respuesta.setCadena(MensajeTexto.CONTRATO_NO_FINALIZADO.getTexto() + "_");//respuesta.setCadena("OK");
		respuesta.setNumero(TipoMensaje.ERROR.getValor());//respuesta.setNumero(NumeroMensaje.NOFINALIZA.getValue());
		respuesta.setEstado(false);
		
		//--Banderas para las reglas de Finalización
		boolean esEstudioOficial 		= false;
		Integer numeroDocumentos 		= 0;
		Integer numeroTerminos 			= 0;
		Integer numeroCondicionesPago 	= 0;
		Integer numeroTitulos 			= 0;
		Integer totalTitulos			= 0;
		Long apartado 					= null;
		Integer sinSubnumero 			= 0;
		Integer erroresMG				= 0;		
		
		//boolean esMontoMayorLF 			= false;
		Double costoSAP 				= 0.0;
		Double costoContrato			= 0.0;
				
		WFSeguimientoDTO wfSeguimiento = new WFSeguimientoDTO();
		wfSeguimiento.setIdContrato(idContrato);
		wfSeguimiento.setIdPasoWF(1);
		wfSeguimiento.setFecha1(new Date());
		wfSeguimiento.setEstaAutorizado(0);
		
		
		//--- Estas validaciónes aplica para los 3 tipos de Contratos (Suscripción, Transaccional y License Fee )
		//--- Estudio Oficial
		//--- Documentos Asociados al Contrato
		try{
			 	//--- Se valida que el estudio sea Oficial
				esEstudioOficial = validaEstudioContrato(idContrato);//--- Se valida que sea un estudio oficial 
				//--- Se valida que tenga documentos 
				numeroDocumentos = 1; // validacionGeneralesDAO.contarDocumentosContrato(idContrato); por el momento se comento que no es necesario validar que haya un documento asociado al contrato
		
			}catch(Exception e){
				
				logger.error("Erro : [{}]", e);
				
			}
			
			
		if( tipoContrato == 1 ) //--Es Suscripción
		{	
			try{
				//--- Se validan los Terminos Comerciales
				numeroTerminos = validacionGeneralesDAO.contarTerminosContrato(idContrato);
				
				//--- Se validan las Condiciones de Pago
				numeroCondicionesPago = validacionGeneralesDAO.contarCondicionesPagoContrato(idContrato);
				
				//--- Se validan las disminuciones que no tienen Subnumero
				sinSubnumero = validacionGeneralesDAO.contarSinSubnumero(idContrato);
				
				//--- Se valida el Apartado
				apartado = validacionGeneralesDAO.obtenerApartadoContrato(idContrato);
				
			}catch(Exception e){
				
				logger.error("Erro : [{}]", e);
				
			}
			
			//--- Se valida Presupuesto
			ResponseValidaPresupuestoCntDTO respuestaPresupuesto = null;
			respuestaPresupuesto = commonRestBO.validaPresupuesto(fechaInicio, idContrato, origen);
			
			//--- Se validan los Minimos de Selección
			ResponseValidaMinimoSeleccionDTO respuestaMinimos = null;
			respuestaMinimos = obtenValidacionMinimoSeleccion(idContrato, origen);
			
			if(esEstudioOficial)
			{	
				if(numeroDocumentos > 0) 
				{
					if(numeroTerminos > 0) 
					{
						if(numeroCondicionesPago > 0) 
						{
							if(sinSubnumero == 0)
							{
								if(apartado != null) 
								{
									if(respuestaPresupuesto.getResultado())
									{
										infoRespuesta = revisaMinimoCorreo(idContrato, expediente, fechaInicio, respuestaMinimos.getResultado(), respuesta, wfSeguimiento, infoRespuesta);
										
									}else{
										infoRespuesta += respuestaPresupuesto.getMensaje() + "_";
									}
						
								}else {
										infoRespuesta += MensajeTexto.CONTRATO_NO_TIENE_APARTADOS.getTexto() + "_";
								}
							}else{
								infoRespuesta += MensajeTexto.CONTRATO_CON_SINSUBNUMERO.getTexto() + "_";
							}
						}else {
							infoRespuesta += MensajeTexto.CONTRATO_NO_TIENE_CONDICIONES_PAGO.getTexto() + "_";
						}
					}else {
						infoRespuesta += MensajeTexto.CONTRATO_NO_TIENE_TERMINOS.getTexto() + "_";
					}
				}else {
					infoRespuesta += MensajeTexto.CONTRATO_NO_TIENE_DOCUMENTOS.getTexto() + "_";
				}
			}else {
				infoRespuesta += MensajeTexto.CONTRATO_NO_ESTUDIO_OFICIAL.getTexto() + "_";//hacer un append al final
			}			
									
		}//Termina if( tipoContrato == 1 ) //--Es Suscripción
		
		
		if( tipoContrato ==  2 )//-- Es Transaccional
		{
			//--- Se validan que no existan errores en el calculo del minimo garantizado ---//
			erroresMG = validacionGeneralesDAO.ObtenerErroresCalculoMinimoGarantizado(idContrato);
			logger.info( "Transaccional: Total Errores en calculo MG" + erroresMG);
			
			if(esEstudioOficial)
			{	
				logger.info( "Transaccional: es estudio oficial " + esEstudioOficial);
				
				if(numeroDocumentos > 0) 
				{
					logger.info( "Transaccional: numero de documentos " + numeroDocumentos);
					
					//if( erroresMG == 0 || erroresMG == null ) 
                                        if(true) 
					{
						logger.info( "Transaccional: No existen Errores en calculo" + erroresMG);
						infoRespuesta = revisaMinimoCorreo(idContrato, expediente, fechaInicio, true, respuesta, wfSeguimiento, infoRespuesta);
					}else{
						infoRespuesta += MensajeTexto.ERROR_CALCULO_MINIMO_GARANTIZADO.getTexto() + "_";
					}					
				}else {
					infoRespuesta += MensajeTexto.CONTRATO_NO_TIENE_DOCUMENTOS.getTexto() + "_";
				}
			}else {
				infoRespuesta += MensajeTexto.CONTRATO_NO_ESTUDIO_OFICIAL.getTexto() + "_";//hacer un append al final
			}	
			
		}//Termina if( tipoContrato ==  2 )//-- Es Transaccional
			
		
		
		if( tipoContrato ==  3 )//-- Es License Fee
		{
			try{
				//-- Para validar que el monto sea mayor al contrato anterior
				numeroTitulos 	= validacionGeneralesDAO.contarTitulosActivosContrato(idContrato);
				totalTitulos 	= validacionGeneralesDAO.obtenerTotalTitulosEnTerminos(idContrato);
				
				//-- Para validar que el monto sea mayor al contrato anterior
				costoSAP 		= validacionGeneralesDAO.obtenMontoContratoSAP(idContrato);
				costoContrato 	= validacionGeneralesDAO.obtenCantidad(idContrato);
				
				
			}catch(Exception e){
				
				logger.error("Erro : [{}]", e);
				
			}
			
			
			if(esEstudioOficial)
			{	
				logger.info( "License Fee: es estudio oficial " + esEstudioOficial);
				if(numeroDocumentos > 0) 
				{
					logger.info( "License Fee: numero de documentos " + numeroDocumentos);
					if( numeroTitulos == totalTitulos ) 
					{
						logger.info( "License Fee: numero de titulos y total de titulos " + numeroTitulos + "=" + totalTitulos );
						if( costoSAP <= costoContrato )
						{
							infoRespuesta = revisaMinimoCorreo(idContrato, expediente, fechaInicio, true, respuesta, wfSeguimiento, infoRespuesta);
							
						}else{
							logger.info( "License Fee: costo SAP y costo Contraro " + costoSAP + "<" + costoContrato);
							infoRespuesta += MensajeTexto.CONTRATO_COSTO_NO_DISMINUIR.getTexto() + "_";
						}
					}else {
							infoRespuesta += MensajeTexto.CONTRATO_NO_TITULOS_ESPECIFICADOS.getTexto() + "_";
					}
				}else {
					infoRespuesta += MensajeTexto.CONTRATO_NO_TIENE_DOCUMENTOS.getTexto() + "_";
				}
			}else {
				infoRespuesta += MensajeTexto.CONTRATO_NO_ESTUDIO_OFICIAL.getTexto() + "_";//hacer un append al final
			}
						
		}//Termina if( tipoContrato ==  3 )//-- Es License Fee
			
		
		if(!respuesta.getEstado()) {
			respuesta.setCadena(infoRespuesta);
		}
						
		return respuesta;
	}
	
	public String revisaMinimoCorreo(Long idContrato, String expediente,Date fechaInicio, boolean respuestaMinimos, BundleReturn respuesta, WFSeguimientoDTO wfSeguimiento, String infoRespuesta ){
		
		Map<String, Object> respuestaEnvioCorreo;
		
		if(respuestaMinimos) {
			
			respuestaEnvioCorreo = notificaFinalizacionRegistro(idContrato);
			
			//if((Boolean) respuestaEnvioCorreo.get("respuesta")) {
                        if(true) {
				
				respuesta.setCadena(MensajeTexto.CONTRATO_FINALIZADO.getTexto() + "_" + (String) respuestaEnvioCorreo.get("mensaje"));
				respuesta.setNumero(TipoMensaje.EXITO.getValor());
				respuesta.setEstado(true);
				opcionesContratoBO.actulizaEstatus(Estatus.Revision.getValor(), idContrato, expediente);
				validacionGeneralesDAO.registraWFSeguimiento(wfSeguimiento);
				esContratoSuscripcion(fechaInicio, idContrato);
				
			}else {
				infoRespuesta += (String) respuestaEnvioCorreo.get("mensaje");
			}
			
		}else {
			infoRespuesta += MensajeTexto.CONTRATO_NO_CUMPLE_MINIMOS.getTexto() + "_";
		}
		
		return infoRespuesta;
	}
	
	
	
	public String uneListaErrores(List<String> errores) {
		String cadenaErrores = "";
		
		if(errores.size() > 0) {
			
			for(int i = 0; i < errores.size(); i++) {
				cadenaErrores += "Error " + (i + 1) + " : " + errores.get(i) + ".";
				
				if(i < errores.size() - 1){
					cadenaErrores += "_";
				}
				
			}
			
		}
		
		return cadenaErrores;
	}
	
	public BundleReturn validaWorkFlow(Long idContrato, String expedienteUsuario, Integer ordenPasoWF, Integer noPasosWF, Date fechaInicioContrato , String fechaSincronizacionSAP, Long tipoContrato) {
		
		WFPasoDTO pasoActual = null;
		WFPasoDTO pasoSiguiente = null;
		List<AutorizadorDTO> autorizadores = null;
		List<CorreoExternoDTO> correosExternos = null;
		Long idMenu = null; // = 65L;								//verificar como obtner o cual sera su id definitivamente
		boolean seEnviaronCorreos = false;
		BundleReturn respuesta = new BundleReturn();
		String etiqueta = null;
		respuesta.setEstado(false);
		respuesta.setNumero(TipoMensaje.ERROR.getValor());
		SimpleDateFormat sdf = null;
		String sFechaInicio = null;
		Date fechaSAP = null;
		Date dFechaInicio = null;
		boolean seCambioEstatusPorFechas = false;
		String seccionExternos = "AUTORIZACION_WF_CEO"; //si se dese enviar a otro grupo de correos se debera definir en dda_t_correo_externo
		Date fechaRegistro = null;
		WFSeguimientoDTO wfSeguimiento = new WFSeguimientoDTO();
		Operacion tipo = null;
		
		try {
			
			pasoActual = validacionGeneralesDAO.obtnerWFPaso(ordenPasoWF);//generalesBO.obtenerAreaPorOrdenWF(noAreaWF);
			
			idMenu = 65L; //idMenu = validacionGeneralesDAO.obtenIdMenuParaAutorizarContrato("Autorizar contrato");
			
			logger.info("Area Actual : [{}]", pasoActual);
					
			if(ordenPasoWF < noPasosWF) {
				
				pasoSiguiente = validacionGeneralesDAO.obtnerWFPaso(ordenPasoWF + 1);//generalesBO.obtenerAreaPorOrdenWF(ordenPasoWF + 1);
				autorizadores =  validacionGeneralesDAO.obtenerAutorizador(idMenu, pasoSiguiente.getIdArea());//obtener correos de autorizadores de la siguiente area 
				etiqueta = MensajeTexto.ETIQUETA_AUTORIZACION_WF.getTexto();
				tipo = Operacion.CONTRATO;
			}else {
				
				autorizadores = validacionGeneralesDAO.obtenerTodosAreas();//validacionGeneralesDAO.obtenerAutorizador(idMenu, null);//obtener corrreos de autorizadores de todas las areas
				etiqueta = "Se ha autorizado ";
				seccionExternos = "AUTORIZACION_WF_CEO";
				etiqueta = MensajeTexto.ETIQUETA_FINALIZA_AUTORIZACION_WF.getTexto();
				tipo = Operacion.FINALIZO_AUTORIZACION;
			}
			
			logger.info("Area Siguiente : [{}] - autorizadores : [{}]", pasoSiguiente, autorizadores);
			
			if(autorizadores.size() > 0) {
				
				seEnviaronCorreos = mandaCorreo(idContrato, autorizadores, null, etiqueta, tipo);

				if(seEnviaronCorreos) {
					
					fechaRegistro  = new Date();
					
					validacionGeneralesDAO.registraPasoWF(idContrato, pasoActual.getOrdenWF(), expedienteUsuario, fechaRegistro); //registraAutorizacion(idContrato, pasoActual.getOrdenWF(), expedienteUsuario, fechaRegistro);
					
					//marcar al registro anterior como esta autorizado 
					validacionGeneralesDAO.actualizaEstaAutorizado(idContrato, pasoActual.getOrdenWF());
					// anexar el siguiente en la flujo de workflow
					if(pasoSiguiente != null) { //si el pasoSiguiente no es null registra en seguimiento WF
						wfSeguimiento.setIdContrato(idContrato);
						wfSeguimiento.setIdPasoWF(pasoSiguiente.getOrdenWF());
						wfSeguimiento.setFecha1(fechaRegistro);
						wfSeguimiento.setEstaAutorizado(0);
						validacionGeneralesDAO.registraWFSeguimiento(wfSeguimiento);
					}

					
					respuesta.setEstado(true);
					respuesta.setCadena(MensajeTexto.AUTORIZACION_REGISTRADA.getTexto());
					respuesta.setNumero(TipoMensaje.EXITO.getValor());
					
					
					if(ordenPasoWF == noPasosWF) {
						
						if(! opcionesContratoBO.tieneFechaAutorizacion(idContrato)) {
							opcionesContratoBO.actualizaFechaAutorizacion(new Date(), idContrato);	
						}
						
						if(opcionesContratoBO.esContratoAmortizable(idContrato)) {
							llamdaCalcularAmortizacionPorContrato(idContrato);
						}
						
						try {
							
							logger.debug("dateInicio [{}]", fechaInicioContrato);
							logger.debug("fecha Sincronizacion [{}]", fechaSincronizacionSAP);
							sdf = new SimpleDateFormat("MM/dd/yyyy");
							sFechaInicio = sdf.format(fechaInicioContrato);
							fechaSAP = sdf.parse(fechaSincronizacionSAP);
							dFechaInicio = sdf.parse(sFechaInicio);
							logger.debug("fechaInicio : [{}], fechaSAP [{}]", dFechaInicio, fechaSAP);
							
							
							if(dFechaInicio.compareTo(fechaSAP) < 0) {
								
								logger.debug("No entrara a notificar a SAP[{}]", idContrato);
								opcionesContratoBO.actulizaEstatus(Estatus.Vigente.getValor(), idContrato, expedienteUsuario);
								opcionesContratoBO.actualizaEstatusPadreContrato(idContrato, expedienteUsuario);
								seCambioEstatusPorFechas = true;
								
								procesarResultadosPorContrato(idContrato);
								/*opcionesContratoBO.llamarAjustaAddendum(idContrato);
								
								if(tipoContrato != 2)
									opcionesContratoBO.llamarReportePagos(idContrato);
								
								logger.debug("Se paso el contrato a Vigente.");*/
							}
							
						}catch(ParseException e) {
							logger.error("Error : [{}]", e);
						}
						
					}
					
					
				}else {
					respuesta.setCadena(MensajeTexto.AUTORIZACION_NO_REGISTRADA.getTexto());
				}
				
			}else {
				respuesta.setCadena(MensajeTexto.AUTORIZACION_VERIFICA.getTexto());
			}
			
			
			seEnviaronCorreos = false;
			
			if(pasoActual.getEnviaExterno() == 1){
				logger.debug("Se debera enviar correos externos.");
				//if()
				correosExternos = validacionGeneralesDAO.obtenerCorreoExterno(seccionExternos);
				seEnviaronCorreos = mandaCorreo(idContrato, null, correosExternos, etiqueta, tipo);
			
			}
			
			logger.debug("valores de estatus area : [{}], seCambioEstatusPorFechas : [{}]",pasoActual.getIdEstatus(),  seCambioEstatusPorFechas);
			
			if(pasoActual.getIdEstatus() != null && !seCambioEstatusPorFechas) {
				logger.info("se debera cambiar estatus : [{}]", pasoActual.getIdEstatus());
				opcionesContratoBO.actulizaEstatus(pasoActual.getIdEstatus(), idContrato, expedienteUsuario);
			}			
			
			
		}catch(Exception ex) {
			logger.error("Error : [{}]", ex);
		}
		
		return respuesta;
	}
	
	
	public boolean procesarResultadosPorContrato(Long idContrato){
		
		boolean resultado = true;
			
		ContratoDTO contrato = generalesBO.obtenContrato(idContrato);
						
		//--- Se ejecuta el Store Procedure DDA_AJUSTARADDENDUM que ajusta los catálogos del Contrato Original
		logger.info("Se ejecuta SP Ajusta Addendum." + idContrato );
		opcionesContratoBO.llamarAjustaAddendum(idContrato);
		
			
		try{
			if( contrato.getIdTipoContrato() != 2 ) { //-- Si es Suscripción o License Fee
				
				//--- Se ejecuta el Store Procedure DDA_REPORTEPAGOS 
				logger.info("Se ejecuta SP Reporte Pago [{}]:" + idContrato);
				opcionesContratoBO.llamarReportePagos(idContrato);
							
			}else{
				//--- Se ejecuta el Store Procedure DDA_CNT_CALCULAR_MG 
				logger.info("Se ejecuta SP Calculo de Minimo Garantizado");
				tituloLoteDAO.calcularMG(idContrato);
			}		
			
			if( contrato.getIdTipoContrato() == 1 ){ //-- Si es Suscripción por lo tanto es amortizable
				//--- Se ejecuta el Store Procedure DDA_AMORTIZACIONINICIAL 
				logger.info("Se ejecuta SP Amortizacion Inicial.");
				opcionesContratoBO.llamarAmortizacionInicial(idContrato);
				opcionesContratoBO.llamarAmortizacionCpv(idContrato);
					
			}
			
			
			if(contrato.getIdTipoMovimiento() == 1) //--- Si es contrato Original o Addendum
			{
				//--- Se registra el monto y año del contrato en DDA_T_CONTRATO_SAP ---//
				//---------------------------------------------------------------------//
				Date fechaInicio =  contrato.getFechaInicio();
				
				SimpleDateFormat formatoAnio = new SimpleDateFormat("yyyy");
				Long anio = Long.parseLong(formatoAnio.format(fechaInicio));
				
				Double cantidadContrato  = validacionGeneralesDAO.obtenCantidad(contrato.getIdContrato());
				String cantidad; 
				
				if( contrato.getIdTipoContrato() == 1 || contrato.getIdTipoContrato() == 3 )//Si es Suscripción o License Fee
				{ 
					if(cantidadContrato != null){
						cantidad = String.format("%.2f", cantidadContrato);// SUMA DE LOS VALORES DE TITULOS
					}
					else{
						cantidad = "1";
					}
				}
				else{	//  Si es Transaccional 
					cantidad = "1";
				}
				
				
				try{
					logger.info("Se registra el monto y año del contrato en DDA_T_CONTRATO_SAP cantidad : " + cantidad + "-> anio :" + anio + "-> idPosicionOrdInt :" + idPosicionOrdInt);
					validacionGeneralesDAO.registraContratoSAP(idContrato, anio, idPosicionOrdInt, cantidad);
				}catch(Exception ex) {
					logger.error("Error : ", ex);
				}
			
			}
			
		}catch(Exception ex) {
			logger.error("Error : ", ex);

		}
				
		return resultado;

	}	
	
	
	public boolean mandaCorreo(Long idContrato, List<AutorizadorDTO> autorizadores, List<CorreoExternoDTO> correosExternos, String etiqueta, Operacion tipo){
		
		boolean seEnvio = false;
		DetalleCorreoDTO detalleCorreo = null;
		String[] destinatarios = null;
		DecimalFormat decimalFormatterS = new DecimalFormat("$###,###.##");
		DecimalFormat decimalFormatter = new DecimalFormat("###,###.##");
		SimpleDateFormat formatoDeFecha = new SimpleDateFormat("MM/dd/yyyy");
		DetalleCorreoVO detalleCorreoVO = new DetalleCorreoVO();
		//String etiqueta = 

		
		try {
			
			detalleCorreo = validacionGeneralesDAO.obtenerDetalleParaCorreo(idContrato);
			
			logger.info("Detalle Correo : [{}]", detalleCorreo);
			
			detalleCorreoVO.setNumeroContrato(detalleCorreo.getNumeroContrato());
			detalleCorreoVO.setDescripcionEstudio(detalleCorreo.getDescripcionEstudio());
			detalleCorreoVO.setMonto(decimalFormatterS.format(detalleCorreo.getMonto()));
			detalleCorreoVO.setNoTitulos(decimalFormatter.format(detalleCorreo.getNoTitulos()));
			detalleCorreoVO.setVigencia(formatoDeFecha.format(detalleCorreo.getFechaInicio()) + " - " + formatoDeFecha.format(detalleCorreo.getFechaFin()));
			
			etiqueta = etiqueta.replace("nctoremp", detalleCorreoVO.getNumeroContrato());
			
			logger.info("Detalle Correo Formato : [{}]", detalleCorreoVO);
			
			if(autorizadores != null) {
				
				destinatarios = new String[autorizadores.size()];
				
				for(int i = 0; i < autorizadores.size(); i++) {
					destinatarios[i] = autorizadores.get(i).getEmail();
				}
				
				seEnvio = llamaServicioEnviaCorreo(idContrato, destinatarios, detalleCorreoVO, etiqueta, tipo, MensajeTexto.EMAIL_SUBJECT_AUTORIZACION.getTexto().replace("&oacute;", "ó"));
				
			}else {
				destinatarios = new String[correosExternos.size()];
				
				for(int i = 0; i < correosExternos.size(); i++) {
					destinatarios[i] = correosExternos.get(i).getCorreo();
				}
				
				seEnvio = llamaServicioEnviaCorreo(idContrato, destinatarios, detalleCorreoVO, etiqueta, tipo, MensajeTexto.EMAIL_SUBJECT_AUTORIZACION.getTexto());
			}
			
			
		}catch(Exception ex) {
			logger.error("Error : ", ex);
		}
		
		return seEnvio;
	}
	
	public boolean mandaCorreoRechazo(Long idContrato, List<AutorizadorDTO> autorizadores, String etiqueta, String motivo) {
		
		//logger.debug("Etiqueta : [{}] - Motivo : [{}]", etiqueta, motivo);
		
		DetalleCorreoVO detalleCorreoVO = new DetalleCorreoVO();
		boolean seEnvio = false;
		String[] destinatarios = null;
		
		detalleCorreoVO.setMotivo(motivo);
		detalleCorreoVO.setNumeroContrato(opcionesContratoBO.obtenerNumeroContrato(idContrato));
		
		etiqueta = etiqueta.replace("nctoremp", detalleCorreoVO.getNumeroContrato());
		
		if(autorizadores != null) {
			
			destinatarios = new String[autorizadores.size()];
			
			for(int i = 0; i < autorizadores.size(); i++) {
				destinatarios[i] = autorizadores.get(i).getEmail();
			}
			
			seEnvio = llamaServicioEnviaCorreo(idContrato, destinatarios, detalleCorreoVO, etiqueta, Operacion.NOAUTORIZA, MensajeTexto.EMAIL_SUBJECT_NO_AUTORIZACION.getTexto().replace("&oacute;", "ó"));
			
		}
		
		return seEnvio;
	}
	
	public boolean mandaCorreoNotificacionCreacionContrato(Long idContrato, String numeroContrato, Long idEstudio, Date fechaInicio, Date fechaFin) {
		
		DetalleCorreoVO detalleCorreoVO = new DetalleCorreoVO();
		boolean seEnvio = false;
		List<CorreoExternoDTO> correosExternos = validacionGeneralesDAO.obtenerCorreoExterno("CREACION_CONTRATO");
		String[] destinatarios;
		SimpleDateFormat formatoDeFecha = new SimpleDateFormat("MM/dd/yyyy");
		
		detalleCorreoVO.setNumeroContrato(numeroContrato);
		detalleCorreoVO.setDescripcionEstudio(validacionGeneralesDAO.obtenerDescripcionEstudio(idEstudio));
		detalleCorreoVO.setVigencia(formatoDeFecha.format(fechaInicio) + " - " + formatoDeFecha.format(fechaFin));
		String etiqueta = MensajeTexto.ETIQUETA_CREACION_CONTRATO.getTexto();
		etiqueta = etiqueta.replace("nctoremp", detalleCorreoVO.getNumeroContrato());
		
		if(correosExternos != null) {
			destinatarios = new String[correosExternos.size()];
			for(int i = 0; i < correosExternos.size(); i++){
				destinatarios[i] = correosExternos.get(i).getCorreo();
			}
			
			seEnvio = llamaServicioEnviaCorreo(idContrato, destinatarios, detalleCorreoVO, etiqueta, Operacion.CREACION_CONTRATO, "Notificación de creación del contrato ");
		}
		
		return seEnvio;
	}
	
	public boolean llamaServicioEnviaCorreo(Long idContrato, String[] destinatarios, DetalleCorreoVO detalleCorreo, String etiqueta , Operacion tipo, String subject) {
		
		String body = null;
		EmailRequest request = new EmailRequest();
		EmailResponse response  = null;
		boolean exito = false;
		DocumentoDTO documento = null;
		Map<String, String> destina = new HashMap<String, String>();
		
		try {
			
			for(String dest : destinatarios){
				destina.put(dest, dest);
			}
			
			documento = documentoBO.obtenerUltimoDocumento(idContrato);
			
			if(documento != null){
				detalleCorreo.setIdDocumento(documento.getIdContratoDocto());
			}
			
			body = JsonConverter.toJson(detalleCorreo);	
			
			logger.debug("body [{}]",body);
			
			request.setDate((new Date()).toString());
			request.setName("yussel luna");
			request.setToCompany("Derechos de Autor");
			request.setUserName("administrador@dladda.com");
			request.setDestinatarios(destina.values().toArray(new String[0]));//(destinatarios);
			request.setSubject(subject + detalleCorreo.getNumeroContrato());
			request.setBody(body);
			request.setOperacion(tipo);
			request.setEtiqueta(etiqueta);
			//request.setT
			
			//logger.debug("request [{}]",JsonConverter.toJson(request));
			
			// RFD CAMBIO 04022020
			
			
//			dLARestClient = dlaRestClientFactory.getClient(DLARestServices.ENVIA_CORREO);
//			response = dLARestClient.get(request, EmailResponse.class);
			
			logger.debug("response : [{}]", response);
			
//			if(response.getRespuesta().equals("true")) {
				exito = true;
//			}
			
		}catch (Exception ex) {
			logger.error("Error : [{}]", ex);
			exito = false;
		}
		
		return exito;
	}
	
	
	
	//----->
	
	public Map<String, Object> notificaFinalizacionRegistro(Long idContrato) {
		
		WFPasoDTO primerPaso = null;
		List<AutorizadorDTO> autorizadores;
		Boolean correoEnviado = false;
		String mensaje = "";
		Map<String, Object> respuesta = new HashMap<String, Object>();
		
		try {
			
			primerPaso = validacionGeneralesDAO.obtnerWFPaso(1); //generalesBO.obtenerAreaPorOrdenWF(1);
			autorizadores = validacionGeneralesDAO.obtenerAutorizador(65L, primerPaso.getIdArea());
			respuesta.put("respuesta", correoEnviado);
			
			if(autorizadores.size() > 0) {
				
				correoEnviado = mandaCorreo(idContrato, autorizadores, null, MensajeTexto.ETIQUETE_FINALIA_REGISTRO.getTexto(), Operacion.CONTRATO);
				
				respuesta.put("respuesta", correoEnviado);
				
				if(correoEnviado) {
					mensaje = MensajeTexto.NOTIFICACION_FINALIZO_REGISTRO.getTexto();
					respuesta.put("mensaje", mensaje);
				}else {
					mensaje = MensajeTexto.NOTIFICACION_NO_FINALIZO_REGISTRO.getTexto();
					respuesta.put("mensaje", mensaje);
				}
				
			}else {
				respuesta.put("mensaje",  MensajeTexto.AUTORIZACION_VERIFICA.getTexto());
			}
			
			
			
		}catch(Exception ex) {
			logger.error("Error :_ [{}]", ex);
		}
		
		return respuesta;
	}
	
	public BundleReturn noAceptarAutorizacion(Long idContrato, String motivo, Integer noPaso, UsuarioDTO usuario) {
		
		WFPasoDTO pasoActual = null;
		WFPasoDTO pasoAnterior = null;
		List<AutorizadorDTO> autorizadoresPrevios = null;
		Boolean seMandoCorreo = false;
		BundleReturn respuesta = new BundleReturn();
		String sarea = "";
		
		respuesta.setEstado(false);
		respuesta.setCadena(MensajeTexto.RECHAZO_NO_NOTIFICADO.getTexto());
		respuesta.setNumero(TipoMensaje.ERROR.getValor());
		String etiqueta = MensajeTexto.ETIQUETA_RECHAZO_AUTORIZACION_WF.getTexto();
		
		try {
			
			logger.debug("noPaso : [{}]", noPaso);
			
			
			pasoActual = validacionGeneralesDAO.obtnerWFPaso(noPaso); //generalesBO.obtenerAreaPorOrdenWF(noPaso);
			
			if(noPaso == 1) {
				//areaAnterior = generalesBO.obtenerAreaPorOrden(2);//especificar que area notifica a la primera
				pasoAnterior = validacionGeneralesDAO.obtnerWFPaso(2);
				autorizadoresPrevios = obtenerAutorizadorAreas();
			}else {
				pasoAnterior = validacionGeneralesDAO.obtnerWFPaso(noPaso - 1); //generalesBO.obtenerAreaPorOrdenWF(noPaso - 1);
				autorizadoresPrevios = validacionGeneralesDAO.obtenerAutorizador(65L, pasoAnterior.getIdArea());
			}
			
			
			logger.debug("pasoAnterior : [{}]", pasoAnterior);
			logger.debug("autorizadores anteriores : [{}]", autorizadoresPrevios);
			
			sarea = pasoActual.getDescripcionArea().replaceAll("ó", "&oacute;");
			
			etiqueta = etiqueta.replace("sarea", sarea);
			
			seMandoCorreo = mandaCorreoRechazo(idContrato, autorizadoresPrevios, etiqueta, motivo);
			
			if(seMandoCorreo) {
				
				justificacionBO.insertarJustificacion(motivo, idContrato, usuario);
				
				switch(noPaso){
					case 1 :
						opcionesContratoBO.actulizaEstatus(Estatus.Registro.getValor(), idContrato, usuario.getExpediente());
				    break;
					case 2 :
						opcionesContratoBO.actulizaEstatus(Estatus.Revision.getValor(), idContrato, usuario.getExpediente());
					default:
						validacionGeneralesDAO.eliminaAutorizacionRegistrada(idContrato, pasoAnterior.getOrdenWF());
				}
				
				validacionGeneralesDAO.actualizaEstaAutorizado(idContrato, pasoActual.getOrdenWF());
				
				respuesta.setEstado(true);
				respuesta.setCadena(MensajeTexto.RECHAZO_NOTIFICADO.getTexto());
				respuesta.setNumero(TipoMensaje.EXITO.getValor());
				
			}
			

		}catch(Exception ex) {
			logger.error("Error : [{}]", ex);
		}
		
		return respuesta;
		
	}
	
	public List<AutorizadorDTO> obtenerAutorizadorAreas() {
		
		List<AutorizadorDTO> autorizadores = new ArrayList<AutorizadorDTO>();
		List<AutorizadorDTO> autorizadoresAux = null;
		List<AreaDTO> areas;
		
		try {
			
			areas = generalesBO.obtenerAreasFinalizadoras();
			
			for(AreaDTO area : areas) {
				
				autorizadoresAux = validacionGeneralesDAO.obtenerAutorizador(65L, area.getIdArea());
				
				for(AutorizadorDTO autorizador : autorizadoresAux) {
					autorizadores.add(autorizador);
				}
				
				autorizadoresAux = null;
				
			}
			
		}catch(Exception ex) {
			logger.error("Error : [{}]", ex);
		}
		
		return autorizadores;
	}
	
	//----->
	
	public boolean esContratoSuscripcion(Date fechaInicio ,Long idContrato) {
		boolean respuesta = false;
		String tipoFees = null;
	
		try {
			
			tipoFees = validacionGeneralesDAO.obtenerTipoFees(idContrato);
			
			if(tipoFees != null) {
				if(tipoFees.equals("ESCALA")) {
					respuesta = true;
					commonRestBO.llamadaCostoTitulo(fechaInicio, idContrato, OrigenCodes.REAL.name());
				}
			}
			
		}catch(Exception ex) {
			logger.error("Error : [{}]", ex);
		}
		
		return respuesta;
	}
	
	//---------------
	
	
//	private RestTemplate restTemplate;
//	private HttpHeaders headers;
//	private ClientHttpRequestFactory factory; 
//	
//	public void configuraPlantilla(){
//		
//		restTemplate = new RestTemplate();
//		headers = new HttpHeaders();
//		factory = restTemplate.getRequestFactory();
//		
//		if(factory instanceof SimpleClientHttpRequestFactory){
//			
//			((SimpleClientHttpRequestFactory) factory).setConnectTimeout(30 * 1000);
//			((SimpleClientHttpRequestFactory) factory).setReadTimeout(30 * 1000);
//			log.debug("Inicilizando rest template");
//			
//		}else if(factory instanceof HttpComponentsClientHttpRequestFactory){
//			((HttpComponentsClientHttpRequestFactory) factory).setConnectTimeout(30 * 1000);
//			((HttpComponentsClientHttpRequestFactory) factory).setReadTimeout(30 * 1000);
//			log.debug("Inicilizando rest template");
//			
//		}
//		
//		restTemplate.setRequestFactory(factory);
//		headers.setContentType(MediaType.APPLICATION_JSON);
//	}
	
	private DLARestClient dLARestClient;
	
	
	public ResponseOrdenCompraDTO llamaCrearOrdenCompra(ContratoDTO contrato, String expediente) {
		
//		configuraPlantilla();
//		String url = env.getProperty("service.ordenInterna.url");
//		String metodo = env.getProperty("service.ordenInterna.metodo");
		
		logger.info("idContrato : " + contrato.getIdContrato() + ", expediente : " + expediente +" en llamarCrearOrdenCompra");
		
		ParamOrdenCompraDTO paramDTO = null;
		ResponseOrdenCompraDTO responseDTO = new ResponseOrdenCompraDTO();
		
		//logger.info("Antes de configurar parámetros.");
		paramDTO = parametersWebService.obtenParametroOrdenCompra(contrato, expediente);
		//logger.info("Despues de configurar parámetros.");
		
		logger.info("{}", printOrdenCompraRequest(paramDTO));
		
		//HttpEntity<ParamOrdenCompraDTO> entity = new HttpEntity<ParamOrdenCompraDTO>(paramDTO, headers);
		
		dLARestClient = dlaRestClientFactory.getClient(DLARestServices.REGISTRAR_SAP_SUSCRIPCION);
		responseDTO = dLARestClient.get(paramDTO, ResponseOrdenCompraDTO.class); //(ResponseOrdenCompraDTO) restTemplate.postForObject((url += metodo), entity, ResponseOrdenCompraDTO.class);
		

		logger.debug("Request : " + paramDTO + " Response : " + responseDTO);
		
		/*if(responseDTO.getResultado()) {
			
			Date fechaInicio =  contrato.getFechaInicio();
			
			SimpleDateFormat formatoAnio = new SimpleDateFormat("yyyy");
			Long anio = Long.parseLong(formatoAnio.format(fechaInicio));
			
			//logger.info("Entro a registras en Suscripcion el anio en SAP{}"+ anio );
			//Se debera verificar que si el parametro llevara mas de un item de cual se tomara la informacion para este registro
			//validacionGeneralesDAO.registraContratoSAP(contrato.getIdContrato(), anio, paramDTO.getItems().get(0).getIdPosicion(), paramDTO.getItems().get(0).getCantidad());
		}
		*/
		return responseDTO;
	}
	
	public ResponseAdendumEnmiendaDTO llamaCrearEnmienda(ContratoDTO contrato, String expediente) {
		
		ParamAdendumEnmiendaDTO paramDTO = null;
		ResponseAdendumEnmiendaDTO responseDTO = new ResponseAdendumEnmiendaDTO();
		
		//paramDTO = parametersWebService.obtenParametroAdendumEnmienda(contrato, expediente);
		paramDTO = parametersWebService.obtenParametroEnmienda(contrato, expediente);
		
		dLARestClient = dlaRestClientFactory.getClient(DLARestServices.REGISTRAR_SAP_ENMIENDA_SUSCRIPCION);
		
		responseDTO = dLARestClient.get(paramDTO, ResponseAdendumEnmiendaDTO.class);	
		
		logger.debug("Request: " + paramDTO + " Resonse: " + responseDTO);
		
		return responseDTO;
	}
	/*
	public ResponseAdendumEnmiendaDTO llamaCrearAdendumEnmienda(ContratoDTO contrato, String expediente) {
		
		//configuraPlantilla();
		
		//String url = env.getProperty("service.adendumEnmienda.url");
		//String metodo = env.getProperty("service.adendumEnmienda.metodo");
		
		
		ParamAdendumEnmiendaDTO paramDTO = null;
		ResponseAdendumEnmiendaDTO responseDTO = new ResponseAdendumEnmiendaDTO();
		
		paramDTO = parametersWebService.obtenParametroAdendumEnmienda(contrato, expediente);
		
		dLARestClient = dlaRestClientFactory.getClient(DLARestServices.REGISTRAR_SAP_ENMIENDA_SUSCRIPCION);
		
		responseDTO = dLARestClient.get(paramDTO, ResponseAdendumEnmiendaDTO.class);	
		
		//HttpEntity<ParamAdendumEnmiendaDTO> entity = new HttpEntity<ParamAdendumEnmiendaDTO>(paramDTO, headers);
		//responseDTO = (ResponseAdendumEnmiendaDTO) restTemplate.postForObject((url += metodo), entity, ResponseAdendumEnmiendaDTO.class);
		
		logger.debug("Request: " + paramDTO + " Resonse: " + responseDTO);
		
		//if(responseDTO.getResultado()) 
		//{
			//actualiza
		//	validacionGeneralesDAO.actualizaContratoSAP(contrato.getIdContratoOriginal(), paramDTO.getPosiciones().get(0).getCantidad());
		//}
		
		return responseDTO;
	}
	*/
	public ResponseOrdenCompraDTO llamaRegistrarSAPNoAmortizable(ContratoDTO contrato, String expediente) {
		
//		configuraPlantilla();
//		
//		String url = env.getProperty("service.noAmortizable.url");
//		String metodo = env.getProperty("service.noAmortizable.metodo");
		
		ParamOrdenCompraDTO paramDTO = null;
		ResponseOrdenCompraDTO responseDTO = new ResponseOrdenCompraDTO();
		
		paramDTO = parametersWebService.obtenParametroOrdenCompra(contrato, expediente);
		
		logger.info("{}", printOrdenCompraRequest(paramDTO));
		
		//dLARestClient = dlaRestClientFactory.getClient(DLARestServices.CREA_ORDEN_COMPRA_NO_AMORTIZABLE);
		
		if(contrato.getIdTipoContrato() == 2){//Transaccional
			dLARestClient = dlaRestClientFactory.getClient(DLARestServices.REGISTRAR_SAP_TRANSACCIONAL);
		}else{
			dLARestClient = dlaRestClientFactory.getClient(DLARestServices.REGISTRAR_SAP_LICENSE_FEE);
		}
		
		responseDTO = dLARestClient.get(paramDTO, ResponseOrdenCompraDTO.class);
		
//		HttpEntity<ParamOrdenCompraDTO> entity = new HttpEntity<ParamOrdenCompraDTO>(paramDTO, headers);
//		responseDTO = (ResponseOrdenCompraDTO) restTemplate.postForObject((url += metodo), entity, ResponseOrdenCompraDTO.class);
		
		logger.debug("Request: " + paramDTO + " Response: " + responseDTO);
		
		/*if(responseDTO.getResultado() ) {
			
			logger.info(contrato.getIdTipoContrato() + "->entra a validacionGeneralesDAO.registraContratoSAP");
			
			Date fechaInicio =  contrato.getFechaInicio();
			
			SimpleDateFormat formatoAnio = new SimpleDateFormat("yyyy");
			Long anio = Long.parseLong(formatoAnio.format(fechaInicio));
			
			//logger.info("Entro a registras en no amortizable el anio en SAP{}"+ anio );
			
			//Se debera verificar que si el parametro llevara mas de un item de cual se tomara la informacion para este registro
			//validacionGeneralesDAO.registraContratoSAP(contrato.getIdContrato(), anio, paramDTO.getItems().get(0).getIdPosicion(), paramDTO.getItems().get(0).getCantidad());
		}*/
		
		return responseDTO;
	}
	
	
	public ResponseAdendumEnmiendaDTO llamaEnmiendaNoAmortizable(ContratoDTO contrato, String expediente) {

		ParamAdendumEnmiendaDTO paramDTO = null;
		ResponseAdendumEnmiendaDTO responseDTO = new ResponseAdendumEnmiendaDTO();
		
		//paramDTO = parametersWebService.obtenParametroAdendumEnmienda(contrato, expediente);
		paramDTO = parametersWebService.obtenParametroEnmienda(contrato, expediente);
		
		if(contrato.getIdTipoContrato() == 2){//Transaccional
			dLARestClient = dlaRestClientFactory.getClient(DLARestServices.REGISTRAR_SAP_ENMIENDA_TRANSACCIONAL);
		}else{
			dLARestClient = dlaRestClientFactory.getClient(DLARestServices.REGISTRAR_SAP_ENMIENDA_LICENSE_FEE);
		}
		
		responseDTO = dLARestClient.get(paramDTO, ResponseAdendumEnmiendaDTO.class);
		
		logger.debug("Request: " + paramDTO + " Resonse: " + responseDTO);
		
		return responseDTO;
	}
	
	/*
	public ResponseAdendumEnmiendaDTO llamaAdendumEnmiendaNoAmortizable(ContratoDTO contrato, String expediente) {
//		
//		configuraPlantilla();
//		
//		String url = env.getProperty("service.adendumEnmiendaNoAmortizable.url");
//		String metodo = env.getProperty("service.adendumEnmiendaNoAmortizable.metodo");
//		
		
		ParamAdendumEnmiendaDTO paramDTO = null;
		ResponseAdendumEnmiendaDTO responseDTO = new ResponseAdendumEnmiendaDTO();
		
		//paramDTO = parametersWebService.obtenParametroAdendumEnmienda(contrato, expediente);
		paramDTO = parametersWebService.obtenParametroEnmienda(contrato, expediente);
		
		if(contrato.getIdTipoContrato() == 2){//Transaccional
			dLARestClient = dlaRestClientFactory.getClient(DLARestServices.REGISTRAR_SAP_ENMIENDA_TRANSACCIONAL);
		}else{
			dLARestClient = dlaRestClientFactory.getClient(DLARestServices.REGISTRAR_SAP_ENMIENDA_LICENSE_FEE);
		}
		
		responseDTO = dLARestClient.get(paramDTO, ResponseAdendumEnmiendaDTO.class);
		
		//HttpEntity<ParamAdendumEnmiendaDTO> entity = new HttpEntity<ParamAdendumEnmiendaDTO>(paramDTO, headers);
		//responseDTO = (ResponseAdendumEnmiendaDTO) restTemplate.postForObject((url += metodo), entity, ResponseAdendumEnmiendaDTO.class);
		
		logger.debug("Request: " + paramDTO + " Resonse: " + responseDTO);
		
		//if(responseDTO.getResultado()) {
		//	//actualiza
		//	validacionGeneralesDAO.actualizaContratoSAP(contrato.getIdContratoOriginal(), paramDTO.getPosiciones().get(0).getCantidad());
		//}
		
		return responseDTO;
	}
	
	*/
	public String printOrdenCompraRequest(ParamOrdenCompraDTO request) {

		if (request != null) {

			StringBuilder result = new StringBuilder();
			String SEPARATOR_LINE = ", ";
			String NEW_LINE = System.getProperty("line.separator");
			result.append(NEW_LINE);
			result.append(" [Header] ");
			result.append(" sociedad: " + request.getSociedad() + SEPARATOR_LINE);
			result.append(" claseDoc: " + request.getClaseDoc() + SEPARATOR_LINE);
			result.append(" idProveedor: " + request.getIdProveedor() + SEPARATOR_LINE);
			result.append(" orgCompras: " + request.getOrgCompras() + SEPARATOR_LINE);
			result.append(" grupoCompras: " + request.getGrupoCompras() + SEPARATOR_LINE);
			result.append(" fechaDoc: " + request.getFechaDoc() + SEPARATOR_LINE);
			result.append(" referencia: " + request.getReferencia() + SEPARATOR_LINE);
			result.append(" idContrato: " + request.getIdContrato() + SEPARATOR_LINE);
			result.append(" expediente: " + request.getExpediente());
			result.append(" [/Header] ");

			result.append(NEW_LINE);

			result.append(" [Body] ");
			List<ItemOrdenCompraDTO> items = request.getItems();

			if (items != null && items.size() > 0) {
				for (ItemOrdenCompraDTO item : items) {
					result.append(NEW_LINE);
					result.append("     [Item] ");
					result.append(" idPosicion: " + item.getIdPosicion() + SEPARATOR_LINE);
					result.append(" idMaterial: " + item.getIdMaterial() + SEPARATOR_LINE);
					result.append(" centro: " + item.getCentro() + SEPARATOR_LINE);
					result.append(" cantidad: " + item.getCantidad() + SEPARATOR_LINE);
					result.append(" precio: " + item.getPrecio() + SEPARATOR_LINE);
					result.append(" indicadorIVA: " + item.getIndicadorIVA() + SEPARATOR_LINE);
					result.append(" tipoImputacion: " + item.getTipoImputacion() + SEPARATOR_LINE);
					result.append(" idPosicionAcc: " + item.getIdPosicionAcc() + SEPARATOR_LINE);
					result.append(" centroCostos: " + item.getCentroCostos() + SEPARATOR_LINE);
					result.append(" idOrden: " + item.getIdOrden());
					result.append(" [/Item] ");
				}
			}

			result.append(NEW_LINE);
			result.append(" [/Body] ");
			NEW_LINE = null;

			return result.toString();

		}
		else
			return null;

	}
	
}