/**
 * 
 */
package com.ejie.ad74a.dao.iml;

import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.ad74a.dao.CopagoBeneficiarioDao;
import com.ejie.ad74a.model.Mensualidad;
import com.ejie.ad74a.model.Solicitante;
import com.ejie.ad74a.util.UtilProperties;
import com.ejie.ad74a.util.constantes.ConstantesBatch;

/**
 * Implementacion de la capa de persistencia para el proceso de copago para
 * solicitantes
 * 
 * @author BICUGUAL
 *
 */
@Repository
public class CopagoBeneficiarioDaoImpl implements CopagoBeneficiarioDao {

	public static final String T_SOLICITANTES = "AD74A.AD74A01T00";
	public static final String T_PRECIOS_PUBLICOS = "AD74A.AD74A77T00";
	public static final String T_PRECIOS_BENEFICIARIO = "AD74A.AD74A91T00";
	public static final String T_CUENTAS = "AD74A.AD74A05T00";
	public static final String T_DIRECCIONES = "AD74A.AD74A06T00";
	public static final String T_MENSUALIDADES = "AD74A.AD74A89T00";
	public static final String T_MENSUALIDADES_ESPEJO = "AD74A.AD74A89T02";
	public static final String T_PISOS_TUTELADOS = "AD74A.AD74A32T00";
	public static final String T_PISOS_TUTE_SOLI = "AD74A.AD74A32T01";

	public static final String SEQUENCE_MENSUALIDADES = "SEQ_MENSUALIDADES.NEXTVAL";
	public static final String SEQUENCE_MENSUALIDADES_ESPEJO = "SEQ_MENSUALIDADES_ESPEJO.NEXTVAL";

	public static final String DBLINK_AE01B = "@AE01B_DBL0.BATERA.EUSKADI.EUS";
	public static final String T_LIQUIDACIONES = "AE01B.AE01B00T00" + DBLINK_AE01B;

	public static final String SQL_SOLICITANTES = getSqlSolicitantes();
	public static final String SQL_SOLICITANTES_MENS_ESPEJO = getSqlSolicitantesConMensualidadEspejo();
	public static final String SQL_SOLICITANTES_PEN_LIQ = getSqlSolicitantesPendientesLiquidacion();

	JdbcTemplate jdbcTemplate;

	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	@Override
	public List<Solicitante> findSolicitantesByProvincia(String idProvincia, Date fInicio, Date fFin, int anyo,
			int mes) {

		String sql = SQL_SOLICITANTES;

		int limit = Integer.parseInt(UtilProperties.Props.BATCH_LIMIT.val());

		if (limit > 0) {
			sql = "SELECT * FROM ( " + "SELECT ROWNUM as rnum, sqlPrincipal.*  FROM	( " + sql + ") sqlPrincipal "
					+ " ) sqls " + " WHERE rnum <= " + limit;
		}

		MapSqlParameterSource parameters = new MapSqlParameterSource().addValue("idProvincia", idProvincia)
				.addValue("fInicioMensualidad", fInicio).addValue("fFinMensualidad", fFin).addValue("anyo", anyo)
				.addValue("mes", mes);

		NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
		return namedParameterJdbcTemplate.query(sql, parameters, new SolicitanteMapper());
	}

	@Override
	public int deleteMensualidadesEspejoEjecucion(String idEjecucion) {
		StringBuilder delete = new StringBuilder("DELETE FROM ").append(T_MENSUALIDADES_ESPEJO)
				.append(" WHERE ID_EJEC_PROCES_89 = ?");
		return jdbcTemplate.update(delete.toString(), idEjecucion);
	}

	@Override
	public int createMensualidadesEspejoBatch(List<Mensualidad> lstMensualidadesSolicitante, int batchSize,
			final boolean modoPrueba) {
		StringBuilder insert = new StringBuilder("INSERT INTO ").append(T_MENSUALIDADES_ESPEJO).append(
				" (ID_MENSUALIDAD_ESPEJO, ID_MENSUALIDAD_89, ID_SOLICITANTE_89, ANYO_89, MES_89, GRUPO_IMPAGO_89, EXONERACION_89, F_ALTA_89, USU_ALTA_89, IMPORTE_89, ID_EJEC_PROCES_89, MODO_PRUEBA) ")
				.append(" VALUES( ").append(SEQUENCE_MENSUALIDADES_ESPEJO).append(", ");
		if (modoPrueba) {
			insert.append("null,");// En modo prueba no se genera id final de la mensualidad
		} else {
			insert.append(SEQUENCE_MENSUALIDADES).append(", ");
		}
		insert.append(" ?, ?, ?, null, null, CURRENT_DATE, ?, ?, ?, ?)");

		int[][] updateCounts = jdbcTemplate.batchUpdate(insert.toString(), lstMensualidadesSolicitante, batchSize,
				new ParameterizedPreparedStatementSetter<Mensualidad>() {
					public void setValues(PreparedStatement ps, Mensualidad mensualidad) throws SQLException {
						ps.setLong(1, mensualidad.getIdSolicitante());
						ps.setInt(2, mensualidad.getAnyo());
						ps.setInt(3, mensualidad.getMes());
						ps.setString(4, UtilProperties.Props.USER_PROCESS.val());
						ps.setBigDecimal(5, mensualidad.getImporte());
						ps.setString(6, mensualidad.getIdEjecucion());
						ps.setInt(7, modoPrueba ? ConstantesBatch.VAL_NUM_SI : ConstantesBatch.VAL_NUM_NO);
					}
				});

		return updateCounts.length;
	}

	@Override
	public int volcarMensualidadesEspejoAFinales(String idEjecucion) {
		StringBuilder insert = new StringBuilder("INSERT INTO ").append(T_MENSUALIDADES);
		insert.append(
				" (ID_MENSUALIDAD_89, ID_SOLICITANTE_89, ANYO_89, MES_89, GRUPO_IMPAGO_89, EXONERACION_89, F_ALTA_89, USU_ALTA_89, IMPORTE_89, ID_EJEC_PROCES_89) ")
				.append(" SELECT ")
				.append("ID_MENSUALIDAD_89, ID_SOLICITANTE_89, ANYO_89, MES_89, GRUPO_IMPAGO_89, EXONERACION_89, F_ALTA_89, USU_ALTA_89, IMPORTE_89, ID_EJEC_PROCES_89 ")
				.append(" FROM ").append(T_MENSUALIDADES_ESPEJO).append(" WHERE ID_EJEC_PROCES_89=?");

		return jdbcTemplate.update(insert.toString(), idEjecucion);
	}

	@Override
	public List<Solicitante> findSolicitantesConMensualidadEspejoByidEjecucion(String idEjecucion, int anyo, int mes) {

		String sql = SQL_SOLICITANTES_MENS_ESPEJO + " ORDER BY s.ID_SOLICITANTE_01";

		return jdbcTemplate.query(sql, new SolicitanteConMensualidadMapper(), idEjecucion, anyo, mes);
	}

	@Override
	public List<Solicitante> findSolicitantesConLiquidacionPendiente(String idProvincia) {
		StringBuilder sql = new StringBuilder(SQL_SOLICITANTES_PEN_LIQ);

		sql.append(" AND d.ID_PROVINCIA_06 = ? ");

		sql.append(" ORDER BY s.id_solicitante_01");

		return jdbcTemplate.query(sql.toString(), new SolicitanteLiquidacionPendienteMapper(), idProvincia);
	}

	@Override
	public List<Solicitante> findSolicitantesConLiquidacionPendientePorMensualidades(String idEjecucion) {
		StringBuilder sql = new StringBuilder(SQL_SOLICITANTES_PEN_LIQ);

		// Seleccion de id_mensualidad
		sql.append(" AND l1.COD_ORIGEN_00 IN ( "
				+ "		SELECT ID_MENSUALIDAD_89 FROM MENSUALIDADES WHERE ID_EJEC_PROCES_89 = ? ) ");

		sql.append("ORDER BY s.id_solicitante_01");

		return jdbcTemplate.query(sql.toString(), new SolicitanteLiquidacionPendienteMapper(), idEjecucion);
	}

	@Override
	@Transactional(readOnly = true)
	public Collection<String> comprobarMensualidadesGeneradas(String idEjecucion) {
		Collection<String> errors = new ArrayList<>();
		StringBuilder sql;
		Integer auxContador;

		// COMPROBAR REGISTRO UNICO POR SOLICITANTE-MES-AÑO EN LA EJECUCION
		sql = new StringBuilder("SELECT COUNT(1) FROM (");
		sql.append(" SELECT 1 FROM MENSUALIDADES_ESPEJO WHERE ID_EJEC_PROCES_89 = ? ");
		sql.append(" GROUP BY ID_EJEC_PROCES_89, ID_SOLICITANTE_89, ANYO_89, MES_89 HAVING COUNT(1) > 1 )");
		if ((auxContador = jdbcTemplate.queryForObject(sql.toString(), new Object[] { idEjecucion },
				Integer.class)) > 0) {
			errors.add(String.format("Existen %s duplicidades por solicitante-anyo-mes en las mensualidades generadas",
					auxContador));
		}
		
		/*- [jbhg] ¿Validar que la mensualidad para ese soliciante-año-mes no exista ya en la tabla final (con algun estado en concreto)? 
		 * 	Si hay más de una ejecución, la query de obtención de solicitantes-mediciones ya tiene en cuenta esta casuística...
		 */
		// ...¿mas?

		return errors;
	}

	/**
	 * Mapper Solicitantes para generar mensualidades
	 * 
	 * @author BICUGUAL
	 *
	 */
	private class SolicitanteMapper implements RowMapper<Solicitante> {

		public Solicitante mapRow(ResultSet rs, int rowNum) throws SQLException {

			Solicitante item = new Solicitante();
			item.setIdSolicitante(rs.getLong("ID_SOLICITANTE_01"));
			item.setfInicio(null != rs.getDate("F_INICIO_01") ? rs.getDate("F_INICIO_01").toLocalDate() : null);
			item.setfBaja(null != rs.getDate("F_BAJA_01") ? rs.getDate("F_BAJA_01").toLocalDate() : null);
			item.setnPreciosBeneficiario(rs.getInt("NPRECIOS"));
			item.setPisoTutelado(rs.getInt("NPISOTUTELADO"));

			return item;
		}
	}

	/**
	 * Mapper Solicitantes con mensualidad generada
	 * 
	 * @author BICUGUAL
	 *
	 */
	private class SolicitanteConMensualidadMapper implements RowMapper<Solicitante> {

		public Solicitante mapRow(ResultSet rs, int rowNum) throws SQLException {

			Solicitante item = new Solicitante();
			item.setIdSolicitante(rs.getLong("ID_SOLICITANTE_01"));
			item.setfInicio(null != rs.getDate("F_INICIO_01") ? rs.getDate("F_INICIO_01").toLocalDate() : null);
			item.setfBaja(null != rs.getDate("F_BAJA_01") ? rs.getDate("F_BAJA_01").toLocalDate() : null);
			item.setNumAbonado(rs.getString("NUM_ABONADO_01"));
			long idDireccion = rs.getLong("ID_DIRECCION_06");
			item.setIdDireccion(!rs.wasNull() ? idDireccion : null);
			item.setCalle(rs.getString("CALLE_06"));
			item.setPortal(rs.getString("PORTAL_06"));
			item.setEscalera(rs.getString("ESCALERA_06"));
			item.setPiso(rs.getString("PISO_06"));
			item.setLetra(rs.getString("LETRA_06"));
			long idProvincia = rs.getLong("ID_PROVINCIA_06");
			item.setIdProvincia(!rs.wasNull() ? idProvincia : null);
			long idMunicipio = rs.getLong("ID_MUNICIPIO_06");
			item.setIdMunicipio(!rs.wasNull() ? idMunicipio : null);
			item.setCp(rs.getString("CP_06"));
			long idCuenta = rs.getLong("ID_CUENTA_05");
			item.setIdCuenta(!rs.wasNull() ? idCuenta : null);
			item.setCodTipoIdenTitular(rs.getString("COD_TIPO_IDEN_TITULAR_05"));
			item.setIdenTitular(rs.getString("IDEN_TITULAR_05"));
			item.setNombreTitCuenta(rs.getString("NOMBRE_TIT_CUENTA_05"));
			item.setApellido1TitCuenta(rs.getString("APELLIDO1_TIT_CUENTA_05"));
			item.setApellido2TitCuenta(rs.getString("APELLIDO2_TIT_CUENTA_05"));
			item.setNumCuenta(rs.getString("NUM_CUENTA_05"));
			long idPerfil = rs.getLong("ID_PERFIL_01");
			item.setIdPerfil(!rs.wasNull() ? idPerfil : null);
			long idMensualidad = rs.getLong("ID_MENSUALIDAD_89");
			item.setIdMensualidad(!rs.wasNull() ? idMensualidad : null);
			BigDecimal importe = rs.getBigDecimal("IMPORTE_89");
			item.setImporte(!rs.wasNull() ? importe : null);
			item.setAnyoMesMensualidad(rs.getString("ANYO_MES"));
			item.setMandato(rs.getString("MANDATO_01"));

			return item;
		}
	}

	/**
	 * Mapper para consulta de liquidaciones pendientes
	 * 
	 * @author BICUGUAL
	 *
	 */
	private class SolicitanteLiquidacionPendienteMapper implements RowMapper<Solicitante> {

		public Solicitante mapRow(ResultSet rs, int rowNum) throws SQLException {

			Solicitante item = new Solicitante();
			item.setIdSolicitante(rs.getLong("ID_SOLICITANTE_01"));

			item.setfInicio(null != rs.getDate("F_INICIO_01") ? rs.getDate("F_INICIO_01").toLocalDate() : null);
			item.setfBaja(null != rs.getDate("F_BAJA_01") ? rs.getDate("F_BAJA_01").toLocalDate() : null);
			item.setNumAbonado(rs.getString("NUM_ABONADO_01"));
			long idDireccion = rs.getLong("ID_DIRECCION_06");
			item.setIdDireccion(!rs.wasNull() ? idDireccion : null);
			item.setCalle(rs.getString("CALLE_06"));
			item.setPortal(rs.getString("PORTAL_06"));
			item.setEscalera(rs.getString("ESCALERA_06"));
			item.setPiso(rs.getString("PISO_06"));
			item.setLetra(rs.getString("LETRA_06"));
			long idProvincia = rs.getLong("ID_PROVINCIA_06");
			item.setIdProvincia(!rs.wasNull() ? idProvincia : null);
			long idMunicipio = rs.getLong("ID_MUNICIPIO_06");
			item.setIdMunicipio(!rs.wasNull() ? idMunicipio : null);
			item.setCp(rs.getString("CP_06"));
			long idCuenta = rs.getLong("ID_CUENTA_05");
			item.setIdCuenta(!rs.wasNull() ? idCuenta : null);
			item.setCodTipoIdenTitular(rs.getString("COD_TIPO_IDEN_TITULAR_05"));
			item.setIdenTitular(rs.getString("IDEN_TITULAR_05"));
			item.setNombreTitCuenta(rs.getString("NOMBRE_TIT_CUENTA_05"));
			item.setApellido1TitCuenta(rs.getString("APELLIDO1_TIT_CUENTA_05"));
			item.setApellido2TitCuenta(rs.getString("APELLIDO2_TIT_CUENTA_05"));
			item.setNumCuenta(rs.getString("NUM_CUENTA_05"));
			long idPerfil = rs.getLong("ID_PERFIL_01");
			item.setIdPerfil(!rs.wasNull() ? idPerfil : null);
			long idMensualidad = rs.getLong("ID_MENSUALIDAD_89");
			item.setIdMensualidad(!rs.wasNull() ? idMensualidad : null);
			item.setAnyoMesMensualidad(rs.getString("ANYO_MES"));
			item.setMandato(rs.getString("MANDATO_01"));
			item.setnPreciosBeneficiario(rs.getInt("NPRECIOS_BENEFICIARIO"));
			item.setPisoTutelado(rs.getInt("NPISOTUTELADO"));

			return item;
		}
	}

	/**
	 * Obtiene la lista de solicitantes con fecha de alta y baja, el numero de
	 * precios beneficiario y ha estado en piso tutelado algun dia del periodo para
	 * el calculo de importes descartando aquellos que ya tienen mensualidad
	 * generada para la mensualidad a tratar.
	 * 
	 * @return
	 */
	private static String getSqlSolicitantes() {
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT s.ID_SOLICITANTE_01, " + "s.F_BAJA_01, " + "s.F_INICIO_01, ");
		sql.append("(SELECT count(1) FROM " + T_PRECIOS_BENEFICIARIO
				+ " pb WHERE pb.ID_SOLICITANTE_91 = s.ID_SOLICITANTE_01 "
				+ "AND pb.FECHA_INICIO_91 <= :fFinMensualidad AND (pb.FECHA_FIN_91 IS NULL OR pb.FECHA_FIN_91 > :fInicioMensualidad) ) AS NPRECIOS, ");
		sql.append("(SELECT count(1) FROM " + T_PISOS_TUTE_SOLI
				+ " ps WHERE ps.ID_SOLICITANTE_32 = s.ID_SOLICITANTE_01 "
				+ "AND ps.F_DESDE_32 <= :fFinMensualidad AND (ps.F_HASTA_32 IS NULL OR ps.F_HASTA_32 > :fInicioMensualidad )) AS NPISOTUTELADO ");
		sql.append("FROM " + T_SOLICITANTES + " s, " + T_CUENTAS + " c, " + T_DIRECCIONES + " d ");
		sql.append("WHERE s.ID_SOLICITANTE_01 = c.ID_SOLICITANTE_05 " + "AND s.ID_DIRECCION_01 = d.ID_DIRECCION_06 "
				+ "AND d.ID_PROVINCIA_06= :idProvincia " + "AND s.F_INICIO_01 <= :fFinMensualidad "
				+ "AND (s.F_BAJA_01 IS NULL OR s.F_BAJA_01 > :fInicioMensualidad) "
//				+ "AND s.id_cuenta_01 = c.id_cuenta_05 " + "AND c.NUM_CUENTA_05 IS NOT NULL "
				+ "AND s.id_cuenta_01 = c.id_cuenta_05 " // Se controla el NULL del NUM_CENTA en las validaciones del volcado
				+ "AND c.F_HISTORICO_05 IS NULL " + "AND NOT EXISTS ( " + "	SELECT 1 FROM " + T_MENSUALIDADES
				+ " m WHERE m.ANYO_89 = :anyo AND m.MES_89 = :mes AND m.ID_SOLICITANTE_89 = s.ID_SOLICITANTE_01 "
				+ ") ");
		sql.append(" ORDER BY s.ID_SOLICITANTE_01");
		return sql.toString();
	}

	/**
	 * Obtiene la lista de solicitantes on la informacion necesaria para un nuevo
	 * alta de liquidacion en base a mensualidades previamente creadas y obteniendo
	 * el importe a liquidar de la tabla de mensualidades, es decir, sin calcular de
	 * nuevo.
	 * 
	 * @return
	 */
	private static String getSqlSolicitantesConMensualidadEspejo() {

		StringBuilder sql = new StringBuilder();

		sql.append("SELECT s.ID_SOLICITANTE_01, " + "s.F_BAJA_01, " + "s.F_INICIO_01, " + "s.NUM_ABONADO_01, "
				+ "d.ID_DIRECCION_06, " + "d.CALLE_06, " + "d.PORTAL_06, " + "d.ESCALERA_06, " + "d.PISO_06, "
				+ "d.LETRA_06, " + "d.ID_PROVINCIA_06, " + "d.ID_MUNICIPIO_06, " + "d.ID_LOCALIDAD_06, " + "d.CP_06, "
				+ "c.ID_CUENTA_05, " + "c.COD_TIPO_IDEN_TITULAR_05, " + "c.IDEN_TITULAR_05, "
				+ "c.NOMBRE_TIT_CUENTA_05, " + "c.APELLIDO1_TIT_CUENTA_05, " + "c.APELLIDO2_TIT_CUENTA_05, "
				+ "c.NUM_CUENTA_05, " + "s.ID_PERFIL_01," + "s.MANDATO_01, " + "m.ID_MENSUALIDAD_89, "
				+ "m.IMPORTE_89, " + "m.ANYO_89|| LPAD(m.MES_89,2,0) AS ANYO_MES ");
		sql.append("FROM " + T_MENSUALIDADES_ESPEJO + " m, " + T_SOLICITANTES + " s, " + T_CUENTAS + " c, "
				+ T_DIRECCIONES + " d ");
		sql.append("WHERE m.ID_EJEC_PROCES_89 = ? " + "AND m.ANYO_89 = ? " + "AND m.MES_89 = ? "
				+ "AND m.ID_SOLICITANTE_89 = s.ID_SOLICITANTE_01 " + "AND s.ID_CUENTA_01 = c.ID_CUENTA_05 "
				+ "AND s.ID_DIRECCION_01 = d.ID_DIRECCION_06 ");

		return sql.toString();
	}

	/**
	 * Obtiene la lista de solicitantes con la informacion necesaria para un nuevo
	 * alta de liquidacion validando que el estado mas reciente de las liquidaciones
	 * a generar, es anulada.
	 * 
	 * @return
	 */
	private static String getSqlSolicitantesPendientesLiquidacion() {

		StringBuilder sql = new StringBuilder();

		sql.append("SELECT m.ID_MENSUALIDAD_89, " + "m.ANYO_89 || LPAD(m.MES_89,2,0) AS ANYO_MES,"
				+ "s.ID_SOLICITANTE_01, " + "s.F_BAJA_01,  " + "s.F_INICIO_01, " + "s.NUM_ABONADO_01, "
				+ "d.ID_DIRECCION_06, " + "d.CALLE_06, " + "d.PORTAL_06, " + "d.ESCALERA_06, " + "d.PISO_06, "
				+ "d.LETRA_06, " + "d.ID_PROVINCIA_06, " + "d.ID_MUNICIPIO_06, " + "d.ID_LOCALIDAD_06, " + "d.CP_06, "
				+ "c.ID_CUENTA_05, " + "c.COD_TIPO_IDEN_TITULAR_05, " + "c.IDEN_TITULAR_05, "
				+ "c.NOMBRE_TIT_CUENTA_05, " + "c.APELLIDO1_TIT_CUENTA_05, " + "c.APELLIDO2_TIT_CUENTA_05, "
				+ "c.NUM_CUENTA_05, " + "s.ID_PERFIL_01, " + "s.MANDATO_01, " + "(SELECT count(1) FROM "
				+ T_PISOS_TUTE_SOLI + " ps WHERE ps.ID_SOLICITANTE_32 = s.ID_SOLICITANTE_01 "
				+ "AND ps.F_DESDE_32 <=  LAST_DAY(TO_DATE(m.ANYO_89 || LPAD(m.MES_89,2,0), 'YYYYMM')) AND (ps.F_HASTA_32 IS NULL OR ps.F_HASTA_32 > TO_DATE(m.ANYO_89 || LPAD(m.MES_89,2,0),'YYYYMM') )) AS NPISOTUTELADO ,"
				+ "(SELECT count(1) FROM " + T_PRECIOS_BENEFICIARIO
				+ " pb WHERE pb.ID_SOLICITANTE_91 = s.ID_SOLICITANTE_01) AS NPRECIOS_BENEFICIARIO ");
		sql.append("FROM " + T_MENSUALIDADES + " m, " + T_SOLICITANTES + " s, " + T_CUENTAS + " c, " + T_DIRECCIONES
				+ " d, " + T_LIQUIDACIONES + " l1 ");
		sql.append("WHERE m.ID_SOLICITANTE_89 = s.ID_SOLICITANTE_01 " + " AND s.ID_CUENTA_01 = c.ID_CUENTA_05 "
				+ "	AND s.ID_DIRECCION_01 = d.ID_DIRECCION_06 " + " AND m.id_mensualidad_89 = l1.cod_origen_00 "
				// mensualidades que no estén exoneradas
				+ " AND (m.EXONERACION_89 = 0 OR m.EXONERACION_89 is null) "
				// Unicamente se tendran en cuenta aquellos beneficiarios que no tengan la marca
				// de "no relanzar"
				+ " AND (s.NO_REINTENTAR_01 = 0 OR s.NO_REINTENTAR_01 is null) " + " AND l1.id_liquidacion_00 = ");
		sql.append("	(SELECT max(l2.id_liquidacion_00) FROM " + T_LIQUIDACIONES + " l2 ");
		sql.append("	WHERE m.ID_MENSUALIDAD_89 = l2.cod_origen_00 ) ");
		// sql.append(" AND m.GRUPO_IMPAGO_89 IS NULL ");
		sql.append("	AND l1.ESTADO_LIQ_00 = 2 " + "		AND l1.id_tipo_ingreso_00=2 ");

		return sql.toString();
	}

}
