package mx.com.amx.mx.dda.crn.dao;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import mx.com.amx.mx.dda.crn.dto.ContratoDTO;
import mx.com.amx.mx.dda.crn.dto.ContratoPagoDTO;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import mx.com.amx.mx.dda.crn.dto.ContratoTituloDTO;
import mx.com.amx.mx.dda.crn.dto.DatosCntTituloExhibicionDTO;
import mx.com.amx.mx.dda.crn.dto.ItemActivoFijoDTO;
import mx.com.amx.mx.dda.crn.dto.ParametroDTO;
import mx.com.amx.mx.dda.crn.dto.RespSAPActivoFijoDTO;
import mx.com.amx.mx.dda.crn.dto.TituloDTO;

@Component
@Qualifier("ddaexhibicionDAO")
public class DDAExhibicionDAO implements IDDAExhibicionDAO {

    private final Logger LOG = Logger.getLogger(this.getClass().getSimpleName());
    private final String ARCHIVO_PROPIEDADES = "/general.properties";
    Properties env = new Properties();
    private JdbcTemplate jdbcTemplate;

    private String AMBIENTE;
    private String VALOR_REFERENCIA;
    private String PUEDE_EJECUTAR;
    private String NOTIFICACION_INICIADO;
    private String MODULO;
    private String ESTATUS_VIGENTE;
    private String SUBNUMERO;
    private String CENTRO_COSTO;

    public DDAExhibicionDAO() {
        super();
        try {
            env.load(this.getClass().getResourceAsStream(ARCHIVO_PROPIEDADES));
            AMBIENTE = env.getProperty("ambiente");
            CENTRO_COSTO = env.getProperty(AMBIENTE + ".centro.costo");
            VALOR_REFERENCIA = env.getProperty("valor.referencia");
            PUEDE_EJECUTAR = env.getProperty("puede.ejecutar");
            NOTIFICACION_INICIADO = env.getProperty("notificacion.iniciado");
            MODULO = env.getProperty("modulo");
            ESTATUS_VIGENTE = env.getProperty("estatus.vigente");
            SUBNUMERO = env.getProperty("subnumero");

        } catch (Exception e) {
            LOG.error(">Constructor[" + this.getClass().getSimpleName() + "] Ocurrio un error : " + e.getMessage());
        }

    }

    @Override
    public boolean verificaEjecutandoseProcesoNotificacion() throws Exception {
        boolean lboEjecutando = Boolean.FALSE;
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();
        
        try {
            
            sb.append("select DECODE(VALOR, 1,'INICIADO', 0,'STANDBY', 'STANDBY') as VALOR_TEXTO ");
            sb.append("from DLA_C_PARAMETRO ");
            sb.append("where CLAVE = ? AND MODULO = ? ");

            LOG.debug(">Sql_D [verificaEjecutandoseProcesoNotificacion]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(NOTIFICACION_INICIADO);
            qryParams.add(MODULO);

            String lstValor = (String) jdbcTemplate.queryForObject(lstSQL, qryParams.toArray(), String.class);

            if (lstValor.equalsIgnoreCase("INICIADO")) {
                lboEjecutando = Boolean.TRUE;
            }

        } catch (EmptyResultDataAccessException er) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::verificaEjecutandoseProcesoNotificacion]: No se encontraron registros coincidentes con la clave especificada. " + er.getMessage());
            throw new Exception("No se encontraron registros coincidentes con la clave especificada");

        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::verificaEjecutandoseProcesoNotificacion]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return lboEjecutando;
    }

    @Override
    public boolean puedeIniciarProcesoNotificacion() throws Exception {
        boolean resultado = Boolean.FALSE;
        StringBuilder sb = new StringBuilder();
        StringBuilder sbD = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();
        Integer day = 27;
        
        try {
            sbD.append("SELECT NVL(MAX(extract(day from fecha)), 27) FROM DDA_T_BLOQUEO_CIERRESAP ");
            sbD.append("WHERE extract(month from sysdate) = extract(month from fecha) ");
            sbD.append("AND extract(year from sysdate) = extract(year from fecha) ");

            day = (Integer) jdbcTemplate.queryForObject(sbD.toString(), qryParams.toArray(), Integer.class);
        } catch (Exception er) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::verificaEjecutandoseProcesoNotificacion]: Error en consulta de fecha de bloqueo. " + er.getMessage());
            throw new Exception("Error en la consulta del dia de bloqueo");
        }

        try {
            //--Ejecucion
            Calendar today = Calendar.getInstance();
            if (today.get(Calendar.DAY_OF_MONTH) < day) {
                sb.append("select ");
                sb.append("NVL(VALOR,'0') as VALOR ");
                sb.append("from ");
                sb.append("DLA_C_PARAMETRO ");
                sb.append("where ");
                sb.append("CLAVE = ? ");
                sb.append("AND MODULO = ? ");

                //--Debug
                LOG.debug(">Sql_D [puedeIniciarProcesoNotificacion]:" + sb.toString());

                final String lstSQL = sb.toString();
                qryParams.add(PUEDE_EJECUTAR);
                qryParams.add(MODULO);

                String lstValor = (String) jdbcTemplate.queryForObject(lstSQL, qryParams.toArray(), String.class);

                if (lstValor.equals("1")) {
                    resultado = Boolean.TRUE;
                }
            }
        } catch (EmptyResultDataAccessException er) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::puedeIniciarProcesoNotificacion]: No se encontraron registros coincidentes con la clave especificada. " + er.getMessage());
            throw new Exception("No se encontraron registros coincidentes con la clave especificada");

        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::puedeIniciarProcesoNotificacion]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return resultado;
    }

    @Override
    public boolean updateEjecutandoseProcesoNotificacion(String pstValor) throws Exception {
        boolean resultado = Boolean.FALSE;
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {
            String lstValor = (pstValor != null && pstValor.length() > 0) ? pstValor : "";

            //--Ejecucion
            sb.append("update ");
            sb.append("DLA_C_PARAMETRO ");
            sb.append("set VALOR = ? ");
            sb.append("where ");
            sb.append("CLAVE = ? ");
            sb.append("AND MODULO = ? ");

            //--Debug
            LOG.debug(">Sql_D [updateEjecutandoseProcesoNotificacion]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(lstValor);
            qryParams.add(NOTIFICACION_INICIADO);
            qryParams.add(MODULO);

            int lnuRowsUpdate = jdbcTemplate.update(lstSQL, qryParams.toArray());

            if (lnuRowsUpdate > 0) {
                resultado = Boolean.TRUE;
            }
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::updateEjecutandoseProcesoNotificacion]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return resultado;
    }

    @Override
    public List<ParametroDTO> getValorDiaNotificacion() throws Exception {
        List<ParametroDTO> lobResultado = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {
            //--Ejecucion
            sb.append("select ");
            sb.append("NVL(VALOR,'-1') as VALOR ");
            sb.append("from ");
            sb.append("DLA_C_PARAMETRO ");
            sb.append("where ");
            sb.append("CLAVE = ? ");
            sb.append("AND MODULO = ? ");

            //--Debug
            LOG.debug(">Sql_D [getValorDiaNotificacion]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(VALOR_REFERENCIA);
            qryParams.add(MODULO);

            lobResultado = (ArrayList<ParametroDTO>) getJdbcTemplate().query(lstSQL, qryParams.toArray(), new BeanPropertyRowMapper<>(ParametroDTO.class));
        } catch (EmptyResultDataAccessException er) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::getValorDiaNotificacion]: No se encontraron registros coincidentes con la clave especificada. " + er.getMessage());
            throw new Exception("No se encontraron registros coincidentes con la clave especificada");

        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::getValorDiaNotificacion]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return lobResultado;
    }

    @Override
    public List<DatosCntTituloExhibicionDTO> obtenerTitulosRecienExhibidos(String pstFechaReferencia) throws Exception {
        List<DatosCntTituloExhibicionDTO> lobResultado = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {
            //String lstFechaReferencia = (pstFechaReferencia != null && pstFechaReferencia.length() > 0) ? pstFechaReferencia : "";

            //--Ejecucion
            sb.append("SELECT ID_SAP,SUM(COSTO) AS COSTO,MIN(FECHA_INICIO) AS FECHA_INICIO ,MAX(VIDA_UTIL) AS VIDA_UTIL,MIN(FECHA_CONTABILIZACION) AS FECHA_CONTABILIZACION, ");
            sb.append("MIN(ID_TITULO_CNTORIG) AS ID_TITULO_CNTORIG, SUBNUMERO, NUMERO_CONTRATO, MAX(FECHA_VENCIMIENTO) AS FECHA_VENCIMIENTO FROM ( ");
            sb.append("select ");
            sb.append("cnttit.ID_SAP, ");
            sb.append("trunc(cnttit.COSTO,2) as COSTO, ");
            sb.append("to_char(cnttit.FECHA_INICIO,'YYYYMMDD') as FECHA_INICIO, ");
            sb.append("cnttit.VIDA_UTIL, ");
            sb.append("to_char(cnttit.FECHA_INICIO,'DD/MM/YYYY') as FECHA_CONTABILIZACION, ");
            sb.append("cnttit.ID_TITULO_CNTORIG, ");
            sb.append("cnttit.SUBNUMERO, ");
            sb.append("cnt.NUMERO_CONTRATO, ");
            sb.append("to_char(cnt.FECHA_INICIO,'YYYYMMDD') AS FECHA_VENCIMIENTO ");
            sb.append("from ");
            sb.append("DDA_T_CONTRATO_TITULO cnttit, ");
            sb.append("DDA_T_CONTRATO cnt ");
            sb.append("where ");
            sb.append("cnttit.ID_CONTRATO = cnt.ID_CONTRATO ");
            sb.append("and cnttit.ID_SAP is not null ");
            sb.append("and cnttit.SUBNUMERO is not null ");
            sb.append("and cnt.ID_ESTATUS = ? ");
            sb.append("and cnttit.FECHA_NOTIFSAP is null ");
            sb.append("ORDER BY CNTTIT.FECHA_INICIO DESC) ");
            sb.append("WHERE rownum < 901 ");
            sb.append("GROUP BY ID_SAP, SUBNUMERO, NUMERO_CONTRATO");

            //--Debug
            LOG.debug(">Sql_D [obtenerTitulosRecienExhibidos]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(ESTATUS_VIGENTE);
            //qryParams.add(lstFechaReferencia);

            lobResultado = (ArrayList<DatosCntTituloExhibicionDTO>) getJdbcTemplate().query(lstSQL, qryParams.toArray(), new BeanPropertyRowMapper<>(DatosCntTituloExhibicionDTO.class));
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::obtenerTitulosRecienExhibidos]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return lobResultado;
    }
    
    @Override
    public List<DatosCntTituloExhibicionDTO> obtenerContratosRecienExhibidos(String pstFechaReferencia) throws Exception {
        List<DatosCntTituloExhibicionDTO> lobResultado = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {
            //String lstFechaReferencia = (pstFechaReferencia != null && pstFechaReferencia.length() > 0) ? pstFechaReferencia : "";

            //--Ejecucion
            sb.append("SELECT ID_SAP,SUM(COSTO) AS COSTO,MIN(FECHA_INICIO) AS FECHA_INICIO ,MAX(VIDA_UTIL) AS VIDA_UTIL,MIN(FECHA_CONTABILIZACION) AS FECHA_CONTABILIZACION, "); 
            sb.append("MIN(ID_TITULO_CNTORIG) AS ID_TITULO_CNTORIG, MIN(SUBNUMERO) AS SUBNUMERO, NUMERO_CONTRATO, MAX(FECHA_VENCIMIENTO) AS FECHA_VENCIMIENTO FROM ( ");
            sb.append("select ");
            sb.append("cnttit.ID_SAP, ");
            sb.append("trunc(cnttit.COSTO,2) as COSTO, ");
            sb.append("to_char(cnttit.FECHA_INICIO,'YYYYMMDD') as FECHA_INICIO, ");
            sb.append("cnttit.VIDA_UTIL, ");
            sb.append("to_char(cnttit.FECHA_INICIO,'DD/MM/YYYY') as FECHA_CONTABILIZACION, ");
            sb.append("cnttit.ID_TITULO_CNTORIG, ");
            sb.append("cnttit.SUBNUMERO, ");
            sb.append("cnt.NUMERO_CONTRATO, ");
            sb.append("to_char(cnt.FECHA_INICIO,'YYYYMMDD') AS FECHA_VENCIMIENTO ");
            sb.append("from ");
            sb.append("DDA_T_CONTRATO_TITULO cnttit, ");
            sb.append("DDA_T_CONTRATO cnt ");
            sb.append("where ");
            sb.append("cnttit.ID_CONTRATO = cnt.ID_CONTRATO ");
            sb.append("and cnttit.ID_SAP is not null ");
            sb.append("and cnt.ID_ESTATUS = ? ");
            sb.append("and cnttit.FECHA_NOTIFSAP is null ");
            sb.append("ORDER BY CNTTIT.FECHA_INICIO DESC) ");
            sb.append("WHERE rownum < 901 ");
            sb.append("GROUP BY ID_SAP, NUMERO_CONTRATO ");

            //--Debug
            LOG.debug(">Sql_D [obtenerTitulosRecienExhibidos]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(ESTATUS_VIGENTE);
            //qryParams.add(lstFechaReferencia);

            lobResultado = (ArrayList<DatosCntTituloExhibicionDTO>) getJdbcTemplate().query(lstSQL, qryParams.toArray(), new BeanPropertyRowMapper<>(DatosCntTituloExhibicionDTO.class));
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::obtenerTitulosRecienExhibidos]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return lobResultado;
    }

    
    /*
    boolean resultado = Boolean.FALSE;
        StringBuilder sb = new StringBuilder();
        final String sbCon = "SELECT NOMBRE_UNICO AS nombre, TEMPORADA AS temporada FROM DDA_T_CONTRATO_TITULO WHERE ID_TITULO_CNTORIG = ?";
        List<Object> qryParam = new ArrayList<>();
        List<Object> qryParams = new ArrayList<>();

        try {
            String lstIdTituloCntOriginal = (dto.getID_DDA() != null && dto.getID_DDA().length() > 0) ? dto.getID_DDA() : "";
            String lstIdSAP = (dto.getID_SAP() != null && dto.getID_SAP().length() > 0) ? dto.getID_SAP() : "";
            String lstSubNumero = (dto.getSUBNUMERO() != null && dto.getSUBNUMERO().length() > 0) ? dto.getSUBNUMERO() : "";

            qryParam.add(lstIdTituloCntOriginal);
            List<TituloDTO> lobResultado = getJdbcTemplate().query(sbCon, qryParam.toArray(), new BeanPropertyRowMapper<>(TituloDTO.class));
            int lnuRowsUpdate = 0;
            //--Ejecucion
            if (Objects.nonNull(lobResultado) && lobResultado.size() > 0) {
                if (Objects.isNull(lobResultado.get(0).getTemporada())) {
                    sb.append("update ");
                    sb.append("DDA_T_CONTRATO_TITULO ");
                    sb.append("set ID_SAP = ?, ");
                    sb.append("SUBNUMERO = ? ");
                    sb.append("where ");
                    sb.append("ID_TITULO_CNTORIG = ? ");
                    qryParams.add(lstIdSAP);
                    qryParams.add(lstSubNumero);
                    qryParams.add(lstIdTituloCntOriginal);
                    LOG.debug(">Sql_D [Actualizacion de un solo titulo]:" + sb.toString());
                } else {
                    sb.append("update ");
                    sb.append("DDA_T_CONTRATO_TITULO ");
                    sb.append("set ID_SAP = ?, ");
                    sb.append("SUBNUMERO = ? ");
                    sb.append("where ");
                    sb.append("NOMBRE_UNICO = ? ");
                    sb.append("AND TEMPORADA = ? ");
                    qryParams.add(lstIdSAP);
                    qryParams.add(lstSubNumero);
                    qryParams.add(lobResultado.get(0).getNombre());
                    qryParams.add(lobResultado.get(0).getTemporada());
                    LOG.debug(">Sql_D [Actualizacion de todos los titulos de la serie]:" + sb.toString());
                }
                LOG.debug(">Sql_D [actualizaIdSAPCntTitulo]:" + sb.toString());
                final String lstSQL = sb.toString();
                lnuRowsUpdate = jdbcTemplate.update(lstSQL, qryParams.toArray());

            }

            if (lnuRowsUpdate > 0) {
                resultado = Boolean.TRUE;
            }
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::actualizaIdSAPCntTitulo]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return resultado;
    */
    
    @Override
    public boolean actualizaFechaNotificacion(ContratoTituloDTO dto) throws Exception {
        boolean resultado = Boolean.FALSE;
        StringBuilder sb = new StringBuilder();
        final String sbCon = "SELECT NOMBRE_UNICO AS nombre, TEMPORADA AS temporada, ID_CONTRATO AS contrato FROM DDA_T_CONTRATO_TITULO WHERE ID_TITULO_CNTORIG = ?";
        List<Object> qryParam = new ArrayList<>();
        List<Object> qryParams = new ArrayList<>();

        try {
            String lstIdTituloCntOrig = (dto.getID_TITULO_CNTORIG() != null && dto.getID_TITULO_CNTORIG().length() > 0) ? dto.getID_TITULO_CNTORIG() : "";
            
            qryParam.add(lstIdTituloCntOrig);
            List<TituloDTO> lobResultado = getJdbcTemplate().query(sbCon, qryParam.toArray(), new BeanPropertyRowMapper<>(TituloDTO.class));
            int lnuRowsUpdate = 0;
            
            if (Objects.nonNull(lobResultado) && lobResultado.size() > 0) {
                if (Objects.isNull(lobResultado.get(0).getTemporada())) {
                    sb.append("UPDATE DDA_T_CONTRATO_TITULO ");
                    sb.append("SET ");
                    sb.append("FECHA_NOTIFSAP = SYSDATE ");
                    sb.append("WHERE ");
                    sb.append("ID_TITULO_CNTORIG = ? ");
                    qryParams.add(lstIdTituloCntOrig);
                    LOG.debug(">Sql_D [Actualizacion de un solo titulo]:" + sb.toString());
                } else {
                    sb.append("UPDATE DDA_T_CONTRATO_TITULO ");
                    sb.append("SET ");
                    sb.append("FECHA_NOTIFSAP = SYSDATE ");
                    sb.append("WHERE ");
                    sb.append("NOMBRE_UNICO = ? ");
                    sb.append("AND TEMPORADA = ? ");
                    sb.append("AND ID_CONTRATO = ? ");                    
                    qryParams.add(lobResultado.get(0).getNombre());
                    qryParams.add(lobResultado.get(0).getTemporada());
                    qryParams.add(lobResultado.get(0).getContrato());
                    LOG.debug(">Sql_D [Actualizacion de todos los titulos de la serie]:" + sb.toString());
                }
            }

            //--Debug
            LOG.debug(">Sql_D [actualizaFechaNotificacion]:" + sb.toString());

            final String lstSQL = sb.toString();

            lnuRowsUpdate = jdbcTemplate.update(lstSQL, qryParams.toArray());

            if (lnuRowsUpdate > 0) {
                resultado = Boolean.TRUE;
            }
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::actualizaFechaNotificacion]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return resultado;
    }

    @Override
    public boolean insertarRegistroSubnum(String pstIdTituloCntOrig) throws Exception {
        boolean resultado = Boolean.FALSE;
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {
            String lstIdTituloCntOrig = (pstIdTituloCntOrig != null && pstIdTituloCntOrig.length() > 0) ? pstIdTituloCntOrig : "";

            //--Ejecucion
            sb.append("INSERT INTO DDA_T_CONTRATO_SAP_SUBNUM ");
            sb.append("( ");
            sb.append("ID_REGISTRO_SAP, ");
            sb.append("ID_CONTRATO, ");
            sb.append("ID_TITULO_CNT, ");
            sb.append("ID_TITULO_CNTORIG, ");
            sb.append("AUMENTO, ");
            sb.append("FECHA_SAP, ");
            sb.append("SUBNUMERO ");
            sb.append(") ");
            sb.append("select ");
            sb.append("DDA_SQT_CONTRATO_SAP_SUBNUM.NEXTVAL as ID_REGISTRO_SAP, ");
            sb.append("cnt.ID_CONTRATO as ID_CONTRATO, ");
            sb.append("cnt.ID_TITULO_CNT as ID_TITULO_CNT, ");
            sb.append("cnt.ID_TITULO_CNTORIG as ID_TITULO_CNTORIG, ");
            sb.append("cnt.COSTO as AUMENTO, ");
            sb.append("SYSDATE as FECHA_SAP, ");
            sb.append("cnt.SUBNUMERO ");
            sb.append("from ");
            sb.append("DDA_T_CONTRATO_TITULO cnt ");
            sb.append("where ");
            sb.append("ID_TITULO_CNTORIG = ? ");

            //--Debug
            LOG.debug(">Sql_D [insertarRegistroSubnum]:" + sb.toString());

            final String sql = sb.toString();
            qryParams.add(lstIdTituloCntOrig);
            int lnumRowsInsertados = jdbcTemplate.update(sql, qryParams.toArray());

            if (lnumRowsInsertados > 0) {
                resultado = Boolean.TRUE;
            }
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::insertarRegistroSubnum]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return resultado;
    }

    @Override
    public List<ItemActivoFijoDTO> obtenerTitulosSinIdSAP_RecienExhibidos(String pstFechaReferencia) throws Exception {
        List<ItemActivoFijoDTO> lobResultado = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {

            //--Ejecucion
            sb.append("SELECT ordenCompra,proveedor,descripcion,MIN(codigoDDA) as codigoDDA,centroCosto,");
            sb.append("MIN(programID) as programID, contratoDDA, inicioAmortizacion, temporada, SUM(costo) as costo FROM (");
            sb.append("select ");
            sb.append("contrato.ID_SAP as ordenCompra, ");
            //sb.append("'3000100006' as proveedor, ");
            sb.append("estudio.ID_SAP as proveedor, ");
            sb.append("cnttit.nombre_unico as descripcion, ");
            sb.append("cnttit.ID_TITULO_CNTORIG as codigoDDA, ");
            sb.append("'");
            sb.append(CENTRO_COSTO);
            sb.append("' as centroCosto, ");
            sb.append("cnttit.ID_BV as programID, ");
            sb.append("contrato.NUMERO_CONTRATO AS contratoDDA, ");
            sb.append("REPLACE(to_char(cnttit.FECHA_INICIO,'yyyy-mm-dd') ,'-','')  AS inicioAmortizacion, ");
            sb.append("cnttit.TEMPORADA as temporada, ");
            sb.append("cnttit.COSTO AS costo ");
            sb.append("from ");
            sb.append("DDA_T_CONTRATO_TITULO cnttit, ");
            sb.append("DDA_T_CONTRATO contrato, ");
            sb.append("DDA_C_ESTUDIO estudio ");
            sb.append("where ");
            sb.append("cnttit.ID_CONTRATO = contrato.ID_CONTRATO ");
            sb.append("and contrato.ID_ESTUDIO = estudio.ID_ESTUDIO ");
            sb.append("and cnttit.ID_SAP is null ");
            sb.append("and contrato.ID_ESTATUS  = ? ");
            sb.append("and estudio.ID_SAP is not null ");
            sb.append("and contrato.ID_SAP is not null ");
            sb.append("and contrato.ID_TIPO_CONTRATO = 1 ");
            sb.append("ORDER BY CNTTIT.FECHA_INICIO DESC)");
            sb.append("WHERE ROWNUM < 901 AND inicioAmortizacion IS NOT NULL ");
            sb.append("GROUP BY ordenCompra, proveedor, descripcion, centroCosto, contratoDDA, inicioAmortizacion, temporada ");
            sb.append("ORDER BY inicioAmortizacion DESC ");

            //--Debug
            LOG.debug(">Sql_D [obtenerTitulosSinIdSAP_RecienExhibidos]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(ESTATUS_VIGENTE);
            //qryParams.add(lstFechaReferencia);

            lobResultado = getJdbcTemplate().query(lstSQL, qryParams.toArray(), new BeanPropertyRowMapper<>(ItemActivoFijoDTO.class));
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::obtenerTitulosRecienExhibidos]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return lobResultado;
    }
    
    @Override
    public List<ItemActivoFijoDTO> obtenerContratosConTitulosSinIdSAP_RecienExhibidos(String pstFechaReferencia) throws Exception {
        List<ItemActivoFijoDTO> lobResultado = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {

            //--Ejecucion
            sb.append("select ");
            sb.append("contrato.ID_SAP as ordenCompra, ");
            sb.append("estudio.ID_SAP as proveedor, ");
            sb.append("'ACTIVO PRINCIPAL' as descripcion, ");
            sb.append("MIN(cnttit.ID_TITULO_CNTORIG) as codigoDDA, ");
            sb.append("'");
            sb.append(CENTRO_COSTO);
            sb.append("' as centroCosto, ");
            sb.append("MIN(cnttit.ID_BV)  as programID, ");
            sb.append("contrato.NUMERO_CONTRATO AS contratoDDA, ");
            sb.append("REPLACE(to_char(MIN(cnttit.FECHA_INICIO),'yyyy-mm-dd') ,'-','')  AS inicioAmortizacion, ");
            sb.append("SUM(cnttit.COSTO) AS costo ");
            sb.append("from ");
            sb.append("DDA_T_CONTRATO_TITULO cnttit, ");
            sb.append("DDA_T_CONTRATO contrato, ");
            sb.append("DDA_C_ESTUDIO estudio ");
            sb.append("where ");
            sb.append("cnttit.ID_CONTRATO = contrato.ID_CONTRATO ");
            sb.append("and contrato.ID_ESTUDIO = estudio.ID_ESTUDIO ");
            sb.append("and cnttit.ID_SAP is null ");
            sb.append("and contrato.ID_ESTATUS  = ? ");
            sb.append("and estudio.ID_SAP is not null ");
            sb.append("and contrato.ID_SAP is not null ");
            sb.append("and contrato.ID_TIPO_CONTRATO = 1 ");
            sb.append("GROUP BY contrato.ID_SAP, estudio.ID_SAP, contrato.NUMERO_CONTRATO, contrato.ID_CONTRATO_BV, contrato.NUMERO_CONTRATO ");
            sb.append("ORDER BY ordenCompra, inicioAmortizacion DESC ");

            //--Debug
            LOG.debug(">Sql_D [obtenerTitulosSinIdSAP_RecienExhibidos]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(ESTATUS_VIGENTE);
            //qryParams.add(lstFechaReferencia);

            lobResultado = getJdbcTemplate().query(lstSQL, qryParams.toArray(), new BeanPropertyRowMapper<>(ItemActivoFijoDTO.class));
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::obtenerTitulosRecienExhibidos]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return lobResultado;
    }

    @Override
    public boolean actualizaIdSAPCntTitulo(RespSAPActivoFijoDTO dto) throws Exception {
        boolean resultado = Boolean.FALSE;
        StringBuilder sb = new StringBuilder();
        final String sbCon = "SELECT NOMBRE_UNICO AS nombre, TEMPORADA AS temporada FROM DDA_T_CONTRATO_TITULO WHERE ID_TITULO_CNTORIG = ?";
        List<Object> qryParam = new ArrayList<>();
        List<Object> qryParams = new ArrayList<>();

        try {
            String lstIdTituloCntOriginal = (dto.getID_DDA() != null && dto.getID_DDA().length() > 0) ? dto.getID_DDA() : "";
            String lstIdSAP = (dto.getID_SAP() != null && dto.getID_SAP().length() > 0) ? dto.getID_SAP() : "";
            String lstSubNumero = (dto.getSUBNUMERO() != null && dto.getSUBNUMERO().length() > 0) ? dto.getSUBNUMERO() : "";

            qryParam.add(lstIdTituloCntOriginal);
            List<TituloDTO> lobResultado = getJdbcTemplate().query(sbCon, qryParam.toArray(), new BeanPropertyRowMapper<>(TituloDTO.class));
            int lnuRowsUpdate = 0;
            //--Ejecucion
            if (Objects.nonNull(lobResultado) && lobResultado.size() > 0) {
                if (Objects.isNull(lobResultado.get(0).getTemporada())) {
                    sb.append("update ");
                    sb.append("DDA_T_CONTRATO_TITULO ");
                    sb.append("set ID_SAP = ?, ");
                    sb.append("SUBNUMERO = ? ");
                    sb.append("where ");
                    sb.append("ID_TITULO_CNTORIG = ? ");
                    qryParams.add(lstIdSAP);
                    qryParams.add(lstSubNumero);
                    qryParams.add(lstIdTituloCntOriginal);
                    LOG.debug(">Sql_D [Actualizacion de un solo titulo]:" + sb.toString());
                } else {
                    sb.append("update ");
                    sb.append("DDA_T_CONTRATO_TITULO ");
                    sb.append("set ID_SAP = ?, ");
                    sb.append("SUBNUMERO = ? ");
                    sb.append("where ");
                    sb.append("NOMBRE_UNICO = ? ");
                    sb.append("AND TEMPORADA = ? ");
                    qryParams.add(lstIdSAP);
                    qryParams.add(lstSubNumero);
                    qryParams.add(lobResultado.get(0).getNombre());
                    qryParams.add(lobResultado.get(0).getTemporada());
                    LOG.debug(">Sql_D [Actualizacion de todos los titulos de la serie]:" + sb.toString());
                }
                LOG.debug(">Sql_D [actualizaIdSAPCntTitulo]:" + sb.toString());
                final String lstSQL = sb.toString();
                lnuRowsUpdate = jdbcTemplate.update(lstSQL, qryParams.toArray());

            }

            if (lnuRowsUpdate > 0) {
                resultado = Boolean.TRUE;
            }
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::actualizaIdSAPCntTitulo]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return resultado;
    }

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public boolean ejecutarSPAmortizacionReal() throws Exception {
        boolean resultado = Boolean.FALSE;
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {
            //--Ejecucion
            sb.append("call DDA_AMORTIZACIONREAL()");

            //--Debug
            LOG.debug(">Sql_D [ejecutarSPAmortizacionReal]:" + sb.toString());

            final String lstSQL = sb.toString();

            int lnuRowsUpdate = jdbcTemplate.update(lstSQL, qryParams.toArray());

            if (lnuRowsUpdate >= 0) {
                resultado = Boolean.TRUE;
            }
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::ejecutarSPAmortizacionReal]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return resultado;
    }

    @Override
    public List<ContratoDTO> obtenerContratos() throws Exception {
        List<ContratoDTO> lobResultado = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {

            //--Ejecucion
            sb.append("select ");
            sb.append("cnt.ID_SAP AS ordenCompra, ");
            sb.append("cnt.ID_CONTRATO AS idcontratoDDA, ");
            sb.append("cnt.NUMERO_CONTRATO AS contratoDDA, ");
            sb.append("ROUND(SUM(cnttit.COSTO),2) AS valorcondicion, ");
            sb.append("REPLACE(to_char(MIN(cnt.FECHA_FIN),'yyyy-mm-dd') ,'-','') AS fechavencimiento ");
            sb.append("from ");
            sb.append("DDA_T_CONTRATO_TITULO cnttit, ");
            sb.append("DDA_T_CONTRATO cnt ");
            sb.append("where ");
            sb.append("cnttit.ID_CONTRATO = cnt.ID_CONTRATO ");
            sb.append("and cnttit.ID_SAP is not null ");
            sb.append("and cnt.ID_ESTATUS = ? ");
            sb.append("and cnttit.FECHA_NOTIFSAP is null ");
            sb.append("GROUP BY cnt.ID_SAP, cnt.ID_CONTRATO, cnt.NUMERO_CONTRATO ");

            //--Debug
            LOG.debug(">Sql_D [obtenerContratos]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(ESTATUS_VIGENTE);

            lobResultado = (ArrayList<ContratoDTO>) getJdbcTemplate().query(lstSQL, qryParams.toArray(), new BeanPropertyRowMapper<>(ContratoDTO.class));
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::obtenerTitulosRecienExhibidos]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }
        return lobResultado;
    }
    
    @Override
    public List<ContratoDTO> obtenerContratosCandidatos() throws Exception {
        List<ContratoDTO> lobResultado = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {

            //--Ejecucion
            sb.append("select ");
            sb.append("cnt.ID_SAP AS ordenCompra, ");
            sb.append("cnt.ID_CONTRATO AS idcontratoDDA, ");
            sb.append("cnt.NUMERO_CONTRATO AS contratoDDA, ");
            sb.append("ROUND(SUM(cnttit.COSTO),2) AS valorcondicion, ");
            sb.append("REPLACE(to_char(MIN(cnt.FECHA_FIN),'yyyy-mm-dd') ,'-','') AS fechavencimiento ");
            sb.append("from ");
            sb.append("DDA_T_CONTRATO_TITULO cnttit, ");
            sb.append("DDA_T_CONTRATO cnt ");
            sb.append("where ");
            sb.append("cnttit.ID_CONTRATO = cnt.ID_CONTRATO ");
            sb.append("and cnt.ID_ESTATUS = ? ");
            sb.append("and (cnttit.ID_SAP is null ");
            sb.append("or cnttit.FECHA_NOTIFSAP is null )");
            sb.append("GROUP BY cnt.ID_SAP, cnt.ID_CONTRATO, cnt.NUMERO_CONTRATO ");

            //--Debug
            LOG.debug(">Sql_D [obtenerContratos]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(ESTATUS_VIGENTE);

            lobResultado = (ArrayList<ContratoDTO>) getJdbcTemplate().query(lstSQL, qryParams.toArray(), new BeanPropertyRowMapper<>(ContratoDTO.class));
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::obtenerTitulosRecienExhibidos]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }
        return lobResultado;
    }
    
    public List<ContratoPagoDTO> obtenerCondicionesComerciales(String idContrato) throws Exception{
        List<ContratoPagoDTO> lobResultado = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {

            //--Ejecucion
            sb.append("SELECT monto, REPLACE(to_char(FECHA,'yyyy-mm-dd') ,'-','') AS fecha  FROM DDA_T_CONTRATO_TERMINO_PAGO WHERE ID_CONTRATO = ? ");

            //--Debug
            LOG.debug(">Sql_D [obtenerContratos]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(idContrato);

            lobResultado = (ArrayList<ContratoPagoDTO>) getJdbcTemplate().query(lstSQL, qryParams.toArray(), new BeanPropertyRowMapper<>(ContratoPagoDTO.class));
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::obtenerTitulosRecienExhibidos]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }
        
        return lobResultado;
    }
    
    @Override
    public List<ContratoPagoDTO> obtenerAnticipo(String idContrato) throws Exception{
        List<ContratoPagoDTO> lobResultado = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();
        try {
            //--Ejecucion
            sb.append("SELECT anticipo_monto AS monto, REPLACE(to_char(anticipo_fecha,'yyyy-mm-dd') ,'-','') AS fecha  FROM DDA_T_CONTRATO_TERMINO WHERE  ID_CONTRATO = ? ");

            //--Debug
            LOG.debug(">Sql_D [obtenerContratos]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(idContrato);

            lobResultado = (ArrayList<ContratoPagoDTO>) getJdbcTemplate().query(lstSQL, qryParams.toArray(), new BeanPropertyRowMapper<>(ContratoPagoDTO.class));
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::obtenerTitulosRecienExhibidos]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }
    
        return lobResultado;
    }

    @Override
    public boolean eliminarIdSAPCntTitulo(String idcontrato) throws Exception {
        boolean resultado = Boolean.FALSE;
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();

        try {

            //--Ejecucion
            sb.append("update ");
            sb.append("DDA_T_CONTRATO_TITULO ");
            sb.append("set ID_SAP = NULL, ");
            sb.append("SUBNUMERO = NULL ");
            sb.append("where ");
            sb.append("ID_CONTRATO = ? and ID_SAP is not null and FECHA_NOTIFSAP is null ");

            //--Debug
            LOG.debug(">Sql_D [eliminarIdSAPCntTitulo]:" + sb.toString());

            final String lstSQL = sb.toString();
            qryParams.add(idcontrato);

            int lnuRowsUpdate = jdbcTemplate.update(lstSQL, qryParams.toArray());

            if (lnuRowsUpdate > 0) {
                resultado = Boolean.TRUE;
            }
        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::actualizaIdSAPCntTitulo]: " + e.getMessage());
            throw new Exception(e.getMessage());
        }

        return resultado;
    }
    
    @Override
    public void actualizarEstatusSapTitulosByContrato(String mensaje, String idContrato) {
        StringBuffer sb = new StringBuffer();
        StringBuffer sbD = new StringBuffer();
        List<Object> qryParams = new ArrayList<Object>();

        try {
            //--Debug
            sbD.append("UPDATE DDA_T_CONTRATO_TITULO SET ESTATUS_SAP =' ");
            sbD.append(mensaje);
            sbD.append("' WHERE ID_CONTRATO = ");
            sbD.append(idContrato);
            LOG.debug(">Sql_D [actualizarEstatusSapTitulosByContrato]:" + sbD.toString());

            //--Ejecucion
            sb.append("UPDATE DDA_T_CONTRATO_TITULO SET ESTATUS_SAP =' ");
            sb.append(mensaje);
            sb.append("' WHERE ID_CONTRATO = ");
            sb.append(idContrato);

            final String lstSQL = sb.toString();

            jdbcTemplate.update(lstSQL, qryParams.toArray());

        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::actualizarEstatusSapTitulosByContrato]: " + e.getMessage());
        }
    }
    
    @Override
    public void actualizarEstatusSapTitulosByTitulo(String mensaje, String idtitulo) {
        StringBuffer sb = new StringBuffer();
        StringBuffer sbD = new StringBuffer();
        List<Object> qryParams = new ArrayList<Object>();
        
        final String sbCon = "SELECT NOMBRE_UNICO AS nombre, TEMPORADA AS temporada, ID_CONTRATO AS contrato FROM DDA_T_CONTRATO_TITULO WHERE ID_TITULO_CNTORIG = ?";
        List<Object> qryParam = new ArrayList<>();
        qryParam.add(idtitulo);
        
        

        try {
            //--Debug
            sbD.append("UPDATE DDA_T_CONTRATO_TITULO SET ESTATUS_SAP =' ");
            sbD.append(mensaje);
            sbD.append("' WHERE ID_TITULO_CNT = ");
            sbD.append(idtitulo);
            LOG.debug(">Sql_D [actualizarEstatusSapTitulos]:" + sbD.toString());
            
            List<TituloDTO> lobResultado = getJdbcTemplate().query(sbCon, qryParam.toArray(), new BeanPropertyRowMapper<>(TituloDTO.class));
        
            if (Objects.nonNull(lobResultado) && lobResultado.size() > 0) {
                if (Objects.isNull(lobResultado.get(0).getTemporada())) {
                    sb.append("UPDATE DDA_T_CONTRATO_TITULO SET ESTATUS_SAP = ? ");
                    sb.append(" WHERE ID_TITULO_CNT = ?  ");
                    qryParams.add(mensaje);
                    qryParams.add(idtitulo);
                } else {
                    sb.append("UPDATE DDA_T_CONTRATO_TITULO SET ESTATUS_SAP = ? ");
                    sb.append("WHERE ");
                    sb.append("NOMBRE_UNICO = ? ");
                    sb.append("AND TEMPORADA = ? ");
                    sb.append("AND ID_CONTRATO = ? ");
                    qryParams.add(mensaje);
                    qryParams.add(lobResultado.get(0).getNombre());
                    qryParams.add(lobResultado.get(0).getTemporada());
                    qryParams.add(lobResultado.get(0).getContrato());
                }
            }

            //--Ejecucion
            final String lstSQL = sb.toString();

            jdbcTemplate.update(lstSQL, qryParams.toArray());

        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::ejecutarSPAmortizacionAjustada]: " + e.getMessage());
        }
    }
    
    public String validarIdSap(String numeroContrato){
        StringBuilder sb = new StringBuilder();
        List<Object> qryParams = new ArrayList<>();
        String lstValor = "";
        try {
            
            sb.append("SELECT tit.ID_SAP AS ID_SAP FROM DDA_T_CONTRATO cnt inner join DDA_T_CONTRATO_TITULO tit on cnt.ID_CONTRATO = tit.ID_CONTRATO ");
            sb.append("WHERE cnt.NUMERO_CONTRATO = '" + numeroContrato + "' AND tit.ID_SAP IS NOT NULL GROUP BY tit.ID_SAP ");

            LOG.debug(">Sql_D [verificaEjecutandoseProcesoNotificacion]:" + sb.toString());

            final String lstSQL = sb.toString();

            lstValor = (String) jdbcTemplate.queryForObject(lstSQL, qryParams.toArray(), String.class);

            if (Objects.nonNull(lstValor) && !lstValor.isEmpty()) {
                lstValor = "";
            }

        } catch (EmptyResultDataAccessException er) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::verificaEjecutandoseProcesoNotificacion]: No se encontraron registros coincidentes con la clave especificada. " + er.getMessage());

        } catch (Exception e) {
            LOG.error("Exception[" + this.getClass().getSimpleName() + "::verificaEjecutandoseProcesoNotificacion]: " + e.getMessage());
        }
        return lstValor;
    }

    

}
