package com.ejie.m62fb.dao.registroVPP;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.m62fb.dao.ComboR09Dao;
import com.ejie.m62fb.dao.SQLGenericas;
import com.ejie.m62fb.dao.registroVPP.plsql.M62FuncionesPLSQL;
import com.ejie.m62fb.model.ContratoAlquilerActMasiva;
import com.ejie.m62fb.model.ContratoViviendaActMasiva;
import com.ejie.m62fb.model.ExpedienteVivienda;
import com.ejie.m62fb.model.InformacionSuelo;
import com.ejie.m62fb.model.RegistroPropiedad;
import com.ejie.m62fb.model.Vivienda;
import com.ejie.m62fb.model.ViviendaActMasiva;
import com.ejie.m62fb.model.tipos.RegimenAcceso;
import com.ejie.m62fb.model.tipos.RegimenTenencia;
import com.ejie.m62fb.model.tipos.TipoAcceso;
import com.ejie.m62fb.model.tipos.TipoAdjudicacion;
import com.ejie.m62fb.model.tipos.TipoComoAdjudicacion;
import com.ejie.m62fb.model.tipos.TipoElemento;
import com.ejie.m62fb.model.tipos.TipoIniciativa;
import com.ejie.m62fb.model.tipos.TipoPorqueAdjudicacion;
import com.ejie.m62fb.model.tipos.TipoPromotor;
import com.ejie.m62fb.model.tipos.TipoPropietarios;
import com.ejie.m62fb.model.tipos.TipoQuienAdjudicacion;
import com.ejie.m62fb.model.tipos.TipoRegulacion;
import com.ejie.m62fb.util.UtilSeguridad;
import com.ejie.m62fb.utils.constants.IberErrorsMsgConstants;
import com.ejie.m62fb.utils.error.UFException;
import com.ejie.m62fb.utils.sql.BDUtils;
import com.ejie.m62fb.utils.sql.UtilsResulSet;
import com.ejie.x38.dto.JQGridManager;
import com.ejie.x38.dto.JQGridRequestDto;

/**
 * ViviendaDaoImpl.
 * 
XXXX
 */
@Repository
@Transactional
public class ViviendaDaoImpl implements ViviendaDao {

	private JdbcTemplate jdbcTemplate;

	@Autowired
	ContratoAlquilerDao contratoAlquilerDao;
	@Autowired
	ContratoViviendaDao contratoViviendaDao;
	@Autowired
	ComboR09Dao comboR09Dao;
	/*
	 * ROW_MAPPERS
	 */
	private final RowMapper<Vivienda> rwMap = new RowMapper<Vivienda>() {
		@Override
		public Vivienda mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			Vivienda vivienda = populateRwMap(resultSet);
			return vivienda;
		}
	};
	private Vivienda populateRwMap(ResultSet resultSet) throws SQLException {
		Vivienda vivienda = new Vivienda();
//		//rowId
//		vivienda.setRowId(resultSet.getString("ROW_ID"));
		// NumVivienda
		vivienda.setNumVivienda(resultSet.getBigDecimal("NUMVIVIENDA"));
		// SuperficieUtil
		vivienda.setSuperficieUtil(resultSet.getBigDecimal("SUPUTILVIV"));
		// NumDormitorios
		vivienda.setNumDormitorios(UtilsResulSet.getLong(resultSet,
				"NUMDORMITORIOS"));
		// NumBanyos
		vivienda.setNumBanyos(UtilsResulSet.getLong(resultSet, "NUMBANYOS"));
		// IndVivAdaptada
		vivienda.setIndVivAdaptada(UtilsResulSet.getIndicadorSN(resultSet,
				"INDVIVADAPTADA"));
		// FecCalificacion
		vivienda.setFecCalificacion(resultSet
				.getTimestamp("FECCALIFICACION"));
		// FecDescalificacion
		vivienda.setFecDescalificacion(resultSet
				.getTimestamp("FECDESCALIFICA"));
		// NumPlazoCalificacion
		vivienda.setNumPlazoCalificacion(UtilsResulSet.getLong(resultSet,
				"NUMPLAZOCALIF"));

		// RegistroPropiedad
		RegistroPropiedad registro = new RegistroPropiedad();
		registro.setNombre(resultSet.getString("NOMREGISTROPROP"));
		registro.setNumero(UtilsResulSet.getLong(resultSet,
				"NUMREGISTROPROP"));
		registro.setTomo(resultSet.getString("DESTOMO"));
		registro.setLibro(resultSet.getString("DESLIBRO"));
		registro.setFolio(resultSet.getString("DESFOLIO"));
		registro.setFinca(resultSet.getString("DESFINCA"));
		registro.setInscripcion(resultSet.getString("DESINSCRIPCION"));
		vivienda.setRegistroPropiedad(registro);

		// TexObservaciones
		vivienda.setTexObservaciones(resultSet
				.getString("TEXOBSERVACIONES"));
		// NumFijoIbi
		vivienda.setNumFijoIbi(resultSet.getString("NUMFIJOIBI"));

		// Combo RegimenAcceso (P28)
		vivienda.setRegimenAcceso(new RegimenAcceso(resultSet
				.getString("CODREGACCESO")));

		// NumOrganoGestor
		vivienda.setNumOrganoGestor(UtilsResulSet.getLong(resultSet,
				"NUMORGANOGESTOR"));
		// FecIniGestion
		vivienda.setFecIniGestion(resultSet.getTimestamp("FECINIGESTION"));
		// FecFinGestion
		vivienda.setFecFinGestion(resultSet.getTimestamp("FECFINGESTION"));
		// FecEnvOrgGestor
		vivienda.setFecEnvOrgGestor(resultSet
				.getTimestamp("FECENVORGGESTOR"));
		// IndLocalEnViv
		vivienda.setIndLocalEnViv(UtilsResulSet.getIndicadorSN(resultSet,
				"INDLOCALENVIV"));

		// Combo TipoElemento (P28)
		vivienda.setTipoElemento(new TipoElemento(resultSet
				.getString("CODTIPOELEM")));

		// IdPromocion
		vivienda.setIdPromocion(UtilsResulSet.getInteger(resultSet,
				"IDPROMOCION"));
		// DescSituacionElemento
		vivienda.setDescSituacionElemento(resultSet.getString("DECSITELEM"));
		// IndUsoIndiv
		vivienda.setIndUsoIndiv(UtilsResulSet.getIndicadorSN(resultSet,
				"INDUSOINDIV"));
		// IndCalifPerman
		vivienda.setIndCalifPerman(UtilsResulSet.getIndicadorSN(resultSet,
				"INDCALIFPERMAN"));
		// IndBajaDensidad
		vivienda.setIndBajaDensidad(UtilsResulSet.getIndicadorSN(resultSet,
				"INDBAJADENSIDAD"));
		// IndVivConcer
		vivienda.setIndVivConcer(UtilsResulSet.getIndicadorSN(resultSet,
				"INDVIVCONCER"));

		// Tipo Regulacion (R09)
		vivienda.setTipoRegulacion(new TipoRegulacion(resultSet
				.getString("NUMTIPOREGULACION")));
		// Tipo Acceso (R09)
		vivienda.setTipoAcceso(new TipoAcceso(resultSet
				.getString("NUMTIPOREGACCESO")));
		// Tipo Iniciativa (R09)
		vivienda.setTipoIniciativa(new TipoIniciativa(resultSet
				.getString("NUMCLAINICIATIVA")));
		// Tipo Promotor (R09)
		vivienda.setTipoPromotor(new TipoPromotor(resultSet
				.getString("NUMTIPOPROMOTOR")));
		// Tipo Propietarios (R09)
		vivienda.setTipoPropietarios(new TipoPropietarios(resultSet
				.getString("NUMTIPOPROPIETARIO")));
		// Tipo Adjudicacion (R09)
		vivienda.setTipoAdjudicacion(new TipoAdjudicacion(resultSet
				.getString("NUMADJUDICACION")));
		// Tipo QuienAdjudicacion (R09)
		vivienda.setTipoQuienAdjudicacion(new TipoQuienAdjudicacion(
				resultSet.getString("NUMADJQUIEN")));
		// Tipo ComoAdjudicacion (R09)
		vivienda.setTipoComoAdjudicacion(new TipoComoAdjudicacion(resultSet
				.getString("NUMADJCOMO")));
		// Tipo PorqueAdjudicacion (R09)
		vivienda.setTipoPorqueAdjudicacion(new TipoPorqueAdjudicacion(
				resultSet.getString("NUMADJPORQUE")));

		// IndVivUnifamiliar
		vivienda.setIndVivUnifamiliar(UtilsResulSet.getIndicadorSN(
				resultSet, "INDVIVUNIFAMILIAR"));
		// CodRefCatastral
		vivienda.setCodRefCatastral(resultSet.getString("CODREFCATASTRAL"));
		// IndFamiliaNumer
		vivienda.setIndFamiliaNumer(UtilsResulSet.getIndicadorSN(resultSet,
				"INDFAMILIANUMER"));
		// FecInscripDerSup
		vivienda.setFecInscripDerSup(resultSet
				.getTimestamp("FECINSCRIPDERSUP"));
		// FecEscrituraSuel
		vivienda.setFecEscrituraSuel(resultSet
				.getTimestamp("FECESCRITURASUEL"));
		// IndAri
		vivienda.setIndAri(UtilsResulSet
				.getIndicadorSN(resultSet, "INDARI"));

		// Combo RegimenTenencia (P28)
		vivienda.setRegimenTenencia(new RegimenTenencia(resultSet
				.getString("CODREGTENENCIA")));

		// Direccion
		vivienda.setDireccion(UtilsResulSet.getDireccionCompleta(resultSet,
				ViviendasDaoSql.ALIAS_DIR));

		// AbstractM62FBModel
		UtilsResulSet.getAbstractClass(resultSet, vivienda,
				ViviendasDaoSql.ALIAS);

		// IndEliminarReserva (E33)
		vivienda.setIndEliminarReserva(UtilsResulSet.getIndicadorSN(
				resultSet, "INDELIMINARRESERVA"));

		// InformacionSuelo (R21)
		InformacionSuelo informacionSuelo = new InformacionSuelo();
		informacionSuelo.setCuotaParticipacion(resultSet
				.getBigDecimal("CUOTAPARTICIPACION"));
		vivienda.setInformacionSuelo(informacionSuelo);
		return vivienda;
	}	
	private final RowMapper<Vivienda> rwMapLupa = new RowMapper<Vivienda>() {
		@Override
		public Vivienda mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			Vivienda vivienda = populateRwMap(resultSet);
			vivienda.setExpedienteVivienda(new ExpedienteVivienda(resultSet.getString("NUMEXPEDIENTE")));
			return vivienda;
		}
	};	
	
	private final RowMapper<Vivienda> rwMapNumVivienda = new RowMapper<Vivienda>() {
		@Override
		public Vivienda mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {

			Vivienda vivienda = new Vivienda();
			vivienda.setNumVivienda(resultSet.getBigDecimal("NUMVIVIENDA"));

			return vivienda;
		}
	};
	/*
	 * ROW_MAPPERS
	 */
	private final RowMapper<Vivienda> rwMapSeleccionViviendas = new RowMapper<Vivienda>() {
		@Override
		public Vivienda mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {

			Vivienda vivienda = new Vivienda(UtilsResulSet.getBigDecimal(
					resultSet, "NUMVIVIENDA"));
			//rowId
			vivienda.setRowId(resultSet.getString("ROW_ID"));
			//numExpediente
			vivienda.setExpedienteVivienda(new ExpedienteVivienda(resultSet
					.getString("NUMEXPEDIENTE")));
			// Direccion
			vivienda.setDireccion(UtilsResulSet.getDireccionCompleta(resultSet,
					ViviendasDaoSql.ALIAS_DIR));

			vivienda.setFecCalificacion(resultSet
					.getTimestamp("FECCALIFICACION"));
			vivienda.setNumPlazoCalificacion(UtilsResulSet.getLong(resultSet,
					"NUMPLAZOCALIF"));
			vivienda.setFecDescalificacion(resultSet
					.getTimestamp("FECDESCALIFICA"));

			// FecFinCalif
			vivienda.setFecFinCalif(resultSet.getTimestamp("FECFINCALIF"));

			// Combo RegimenAcceso (P28)
			// vivienda.setRegimenAcceso(UtilsResulSet.getComboP28(resultSet,
			// ViviendasDaoSql.ALIAS_P28_ACCESO, RegimenAcceso.class));
			RegimenAcceso regimenAcceso = new RegimenAcceso();
			regimenAcceso.setCodTabla(resultSet.getString("CODREGACCESO"));
			regimenAcceso.setDescripcionEs(resultSet
					.getString("DESCREGACCESOES"));
			regimenAcceso.setDescripcionEu(resultSet
					.getString("DESCREGACCESOEU"));
			vivienda.setRegimenAcceso(regimenAcceso);

			// Combo RegimenTenencia (P28)
			// vivienda.setRegimenTenencia(UtilsResulSet.getComboP28(resultSet,
			// ViviendasDaoSql.ALIAS_P28_TENENC, RegimenTenencia.class));
			RegimenTenencia regimenTenencia = new RegimenTenencia();
			regimenTenencia.setCodTabla(resultSet.getString("CODREGTENENCIA"));
			regimenTenencia.setDescripcionEs(resultSet
					.getString("DESCREGTENENCIAES"));
			regimenTenencia.setDescripcionEu(resultSet
					.getString("DESCREGTENENCIAEU"));
			vivienda.setRegimenTenencia(regimenTenencia);

			// IndFamiliaNumer
			vivienda.setIndFamiliaNumer(UtilsResulSet.getIndicadorSN(resultSet,
					"INDFAMILIANUMER"));
			// IndUsoIndiv
			vivienda.setIndUsoIndiv(UtilsResulSet.getIndicadorSN(resultSet,
					"INDUSOINDIV"));
			// IndBajaDensidad
			vivienda.setIndBajaDensidad(UtilsResulSet.getIndicadorSN(resultSet,
					"INDBAJADENSIDAD"));
			// IndAri
			vivienda.setIndAri(UtilsResulSet
					.getIndicadorSN(resultSet, "INDARI"));
			// IndVivUnifamiliar
			vivienda.setIndVivUnifamiliar(UtilsResulSet.getIndicadorSN(
					resultSet, "INDVIVUNIFAMILIAR"));
			// CodRefCatastral
			vivienda.setCodRefCatastral(resultSet.getString("CODREFCATASTRAL"));
			// NumFijoIbi
			vivienda.setNumFijoIbi(resultSet.getString("NUMFIJOIBI"));
			// FecEscrituraSuel
			vivienda.setFecEscrituraSuel(resultSet
					.getTimestamp("FECESCRITURASUEL"));

			// Tipo Regulacion (R09)
			vivienda.setTipoRegulacion(new TipoRegulacion(resultSet
					.getString("NUMTIPOREGULACION")));
			// Tipo Acceso (R09)
			vivienda.setTipoAcceso(new TipoAcceso(resultSet
					.getString("NUMTIPOREGACCESO")));
			// Tipo Iniciativa (R09)
			vivienda.setTipoIniciativa(new TipoIniciativa(resultSet
					.getString("NUMCLAINICIATIVA")));
			// Tipo Promotor (R09)
			vivienda.setTipoPromotor(new TipoPromotor(resultSet
					.getString("NUMTIPOPROMOTOR")));
			// Tipo Propietarios (R09)
			vivienda.setTipoPropietarios(new TipoPropietarios(resultSet
					.getString("NUMTIPOPROPIETARIO")));
			// Tipo Adjudicacion (R09)
			vivienda.setTipoAdjudicacion(new TipoAdjudicacion(resultSet
					.getString("NUMADJUDICACION")));
			// Tipo QuienAdjudicacion (R09)
			vivienda.setTipoQuienAdjudicacion(new TipoQuienAdjudicacion(
					resultSet.getString("NUMADJQUIEN")));
			// Tipo ComoAdjudicacion (R09)
			vivienda.setTipoComoAdjudicacion(new TipoComoAdjudicacion(resultSet
					.getString("NUMADJCOMO")));
			// Tipo PorqueAdjudicacion (R09)
			vivienda.setTipoPorqueAdjudicacion(new TipoPorqueAdjudicacion(
					resultSet.getString("NUMADJPORQUE")));

			return vivienda;
		}
	};

	/*
	 * ROW_MAPPERS
	 */
	private final RowMapper<ViviendaActMasiva> rwMapSeleccionViviendasActMasiva = new RowMapper<ViviendaActMasiva>() {
		@Override
		public ViviendaActMasiva mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {

			ViviendaActMasiva viviendaActMasiva = new ViviendaActMasiva(
					UtilsResulSet.getBigDecimal(resultSet, "NUMVIVIENDA"));

			// Direccion
			viviendaActMasiva.setDireccion(UtilsResulSet.getDireccionCompleta(
					resultSet, ViviendasDaoSql.ALIAS_DIR));

			viviendaActMasiva.setFecCalificacion(resultSet
					.getTimestamp("FECCALIFICACION"));
			viviendaActMasiva.setNumPlazoCalificacion(UtilsResulSet.getLong(
					resultSet, "NUMPLAZOCALIF"));
			viviendaActMasiva.setFecDescalificacion(resultSet
					.getTimestamp("FECDESCALIFICA"));

			// Combo RegimenAcceso (P28)
			// viviendaActMasiva.setRegimenAcceso(UtilsResulSet.getComboP28(
			// resultSet, ViviendasDaoSql.ALIAS_P28_ACCESO,
			// RegimenAcceso.class));
			RegimenAcceso regimenAcceso = new RegimenAcceso();
			regimenAcceso.setCodTabla(resultSet.getString("CODREGACCESO"));
			regimenAcceso.setDescripcionEs(resultSet
					.getString("DESCREGACCESOES"));
			regimenAcceso.setDescripcionEu(resultSet
					.getString("DESCREGACCESOEU"));
			viviendaActMasiva.setRegimenAcceso(regimenAcceso);

			// Combo RegimenTenencia (P28)
			// viviendaActMasiva.setRegimenTenencia(UtilsResulSet.getComboP28(
			// resultSet, ViviendasDaoSql.ALIAS_P28_TENENC,
			// RegimenTenencia.class));
			RegimenTenencia regimenTenencia = new RegimenTenencia();
			regimenTenencia.setCodTabla(resultSet.getString("CODREGTENENCIA"));
			regimenTenencia.setDescripcionEs(resultSet
					.getString("DESCREGTENENCIAES"));
			regimenTenencia.setDescripcionEu(resultSet
					.getString("DESCREGTENENCIAEU"));
			viviendaActMasiva.setRegimenTenencia(regimenTenencia);

			// IndFamiliaNumer
			viviendaActMasiva.setIndFamiliaNumer(UtilsResulSet.getIndicadorSN(
					resultSet, "INDFAMILIANUMER"));
			// IndUsoIndiv
			viviendaActMasiva.setIndUsoIndiv(UtilsResulSet.getIndicadorSN(
					resultSet, "INDUSOINDIV"));
			// IndBajaDensidad
			viviendaActMasiva.setIndBajaDensidad(UtilsResulSet.getIndicadorSN(
					resultSet, "INDBAJADENSIDAD"));
			// IndAri
			viviendaActMasiva.setIndAri(UtilsResulSet.getIndicadorSN(resultSet,
					"INDARI"));
			// IndVivUnifamiliar
			viviendaActMasiva.setIndVivUnifamiliar(UtilsResulSet
					.getIndicadorSN(resultSet, "INDVIVUNIFAMILIAR"));
			// CodRefCatastral
			viviendaActMasiva.setCodRefCatastral(resultSet
					.getString("CODREFCATASTRAL"));
			// NumFijoIbi
			viviendaActMasiva.setNumFijoIbi(resultSet.getString("NUMFIJOIBI"));
			// FecEscrituraSuel
			viviendaActMasiva.setFecEscrituraSuel(resultSet
					.getTimestamp("FECESCRITURASUEL"));

			// Tipo Regulacion (R09)

//			viviendaActMasiva.setTipoRegulacion(new TipoRegulacion(resultSet
//					.getString("NUMTIPOREGULACION")));
//			System.out.println("resultSet.getString(NUMTIPOREGULACION):"+ resultSet
//					.getString("NUMTIPOREGULACION"));
			viviendaActMasiva.setTipoRegulacion(UtilsResulSet.getComboR09Tabla(
					 resultSet, "NUMTIPOREGULACION",comboR09Dao,
					 TipoRegulacion.class));
			// Tipo Acceso (R09)
//			viviendaActMasiva.setTipoAcceso(new TipoAcceso(resultSet
//					.getString("NUMTIPOREGACCESO")));
//			System.out.println("resultSet.getString(NUMTIPOREGACCESO):"+ resultSet
//					.getString("NUMTIPOREGACCESO"));
			viviendaActMasiva.setTipoAcceso(UtilsResulSet.getComboR09Tabla(
					 resultSet, "NUMTIPOREGACCESO",comboR09Dao,
					 TipoAcceso.class));
			// Tipo Iniciativa (R09)
//			viviendaActMasiva.setTipoIniciativa(new TipoIniciativa(resultSet
//					.getString("NUMCLAINICIATIVA")));
//			System.out.println("resultSet.getString(NUMCLAINICIATIVA):"+ resultSet
//					.getString("NUMCLAINICIATIVA"));
			viviendaActMasiva.setTipoIniciativa(UtilsResulSet.getComboR09Tabla(
					 resultSet, "NUMCLAINICIATIVA",comboR09Dao,
					 TipoIniciativa.class));
			// Tipo Promotor (R09)
//			viviendaActMasiva.setTipoPromotor(new TipoPromotor(resultSet
//					.getString("NUMTIPOPROMOTOR")));
//			System.out.println("resultSet.getString(NUMTIPOPROMOTOR):"+ resultSet
//					.getString("NUMTIPOPROMOTOR"));
			viviendaActMasiva.setTipoPromotor(UtilsResulSet.getComboR09Tabla(
					 resultSet, "NUMTIPOPROMOTOR",comboR09Dao,
					 TipoPromotor.class));
			// Tipo Propietarios (R09)
//			viviendaActMasiva.setTipoPropietarios(new TipoPropietarios(
//					resultSet.getString("NUMTIPOPROPIETARIO")));
//			System.out.println("resultSet.getString(NUMTIPOPROPIETARIO):"+ resultSet
//					.getString("NUMTIPOPROPIETARIO"));
			viviendaActMasiva.setTipoPropietarios(UtilsResulSet.getComboR09Tabla(
					 resultSet, "NUMTIPOPROPIETARIO",comboR09Dao,
					 TipoPropietarios.class));
			// Tipo Adjudicacion (R09)
//			viviendaActMasiva.setTipoAdjudicacion(new TipoAdjudicacion(
//					resultSet.getString("NUMADJUDICACION")));
//			System.out.println("resultSet.getString(NUMADJUDICACION):"+ resultSet
//					.getString("NUMADJUDICACION"));
			viviendaActMasiva.setTipoAdjudicacion(UtilsResulSet.getComboR09Tabla(
					 resultSet, "NUMADJUDICACION",comboR09Dao,
					 TipoAdjudicacion.class));
			// Tipo QuienAdjudicacion (R09)
//			viviendaActMasiva
//					.setTipoQuienAdjudicacion(new TipoQuienAdjudicacion(
//							resultSet.getString("NUMADJQUIEN")));
//			System.out.println("resultSet.getString(NUMADJQUIEN):"+ resultSet
//					.getString("NUMADJQUIEN"));
			viviendaActMasiva.setTipoQuienAdjudicacion(UtilsResulSet.getComboR09Tabla(
					 resultSet, "NUMADJQUIEN",comboR09Dao,
					 TipoQuienAdjudicacion.class));
			// Tipo ComoAdjudicacion (R09)
//			viviendaActMasiva.setTipoComoAdjudicacion(new TipoComoAdjudicacion(
//					resultSet.getString("NUMADJCOMO")));
//			System.out.println("resultSet.getString(NUMADJCOMO):"+ resultSet
//					.getString("NUMADJCOMO"));
			viviendaActMasiva.setTipoComoAdjudicacion(UtilsResulSet.getComboR09Tabla(
					 resultSet, "NUMADJCOMO",comboR09Dao,
					 TipoComoAdjudicacion.class));
			// Tipo PorqueAdjudicacion (R09)
//			viviendaActMasiva
//					.setTipoPorqueAdjudicacion(new TipoPorqueAdjudicacion(
//							resultSet.getString("NUMADJPORQUE")));
//			System.out.println("resultSet.getString(NUMADJPORQUE):"+ resultSet
//					.getString("NUMADJPORQUE"));
			viviendaActMasiva.setTipoPorqueAdjudicacion(UtilsResulSet.getComboR09Tabla(
					 resultSet, "NUMADJPORQUE",comboR09Dao,
					 TipoPorqueAdjudicacion.class));
			
			ContratoAlquilerActMasiva contratoAlquilerActMasivaFilter = new ContratoAlquilerActMasiva();
			contratoAlquilerActMasivaFilter.setVivienda(new Vivienda(
					viviendaActMasiva.getNumVivienda()));
			viviendaActMasiva.setContratosAlquiler(contratoAlquilerDao
					.findAllActMasiva(contratoAlquilerActMasivaFilter, null));
			// TODO contratos compras
			ContratoViviendaActMasiva contratoViviendaActMasivaFilter = new ContratoViviendaActMasiva();
			contratoViviendaActMasivaFilter.setVivienda(new Vivienda(
					viviendaActMasiva.getNumVivienda()));
			viviendaActMasiva.setContratosVivienda(contratoViviendaDao
					.findAllActMasiva(contratoViviendaActMasivaFilter, null));
			return viviendaActMasiva;
		}
	};

	// ContratoAlquilerDao contratoAlquilerDao;
	// ContratoAlquilerActMasiva contratoAlquilerActMasivaFilter = new
	// ContratoAlquilerActMasiva();
	// contratoAlquilerActMasivaFilter.setVivienda(new
	// Vivienda(vivienda.getNumVivienda()));
	// vivienda.
	// (contratoAlquilerDao.findAllActMasiva(contratoAlquilerActMasivaFilter,
	// null));
	// ContratoViviendaDao contratoViviendaDao;
	// TODO recuperar 4 contratos. Cuidado con el jsonIgnore
	// @JsonIgnore
	// private final List<ContratoVivienda> m62r03t0sList = new
	// ArrayList<ContratoVivienda>();
	// @JsonIgnore
	// private final List<ContratoAlquiler> m62r05t0sList = new
	// ArrayList<ContratoAlquiler>();
	/**
	 * Method use to set the datasource.
	 * 
	 * @param dataSource
	 *            DataSource
	 * @return
	 */
	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	/*
	 * OPERACIONES CRUD
	 */

	/**
	 * Inserts a single row in the Vivienda table.
	 * 
	 * @param vivienda
	 *            Vivienda
	 * @return Vivienda
	 */
	@Override
	public Vivienda add(final Vivienda vivienda) {
		KeyHolder keyHolder = new GeneratedKeyHolder();
		this.jdbcTemplate.update(new PreparedStatementCreator() {
			@Override
			public PreparedStatement createPreparedStatement(
					Connection connection) throws SQLException {
				// Sentencia SQL y array con ids que son primary key
				PreparedStatement ps = connection.prepareStatement(
						ViviendasDaoSql.SQL_INSERT,
						new String[] { "NUM_VIVIENDA" });

				// RegimenAcceso
				ps.setObject(1, vivienda.getRegimenAcceso() != null ? vivienda
						.getRegimenAcceso().getCodTabla() : null);
				// RegimenTenencia
				ps.setObject(2,vivienda.getRegimenTenencia() != null ? vivienda
						.getRegimenTenencia().getCodTabla() : null);
				// IndBajaDensidad
				ps.setObject(3,BDUtils.formatIndicadorToBD(vivienda.getIndBajaDensidad()));
				// IndAri
				ps.setObject(4,BDUtils.formatIndicadorToBD(vivienda.getIndAri()));
				// IndVivAdaptada
				ps.setObject(5,BDUtils.formatIndicadorToBD(vivienda.getIndVivAdaptada()));
				// IndFamiliaNumer
				ps.setObject(6,BDUtils.formatIndicadorToBD(vivienda.getIndFamiliaNumer()));
				// IndVivUnifamiliar
				ps.setObject(7,BDUtils.formatIndicadorToBD(vivienda.getIndVivUnifamiliar()));

				// NumDormitorios
				ps.setObject(8,vivienda.getNumDormitorios());
				// NumBanyos
				ps.setObject(9,vivienda.getNumBanyos());
				// SuperficieUtil
				ps.setObject(10,vivienda.getSuperficieUtil());
				// FecInscripDerSup
				ps.setDate(11,vivienda.getFecInscripDerSup()!=null?new java.sql.Date(vivienda.getFecInscripDerSup().getTime()) : null);

				// RegistroPropiedad.Nombre
				ps.setObject(12,vivienda.getRegistroPropiedad() != null ? vivienda
						.getRegistroPropiedad().getNombre() : null);
				// RegistroPropiedad.Numero
				ps.setObject(13,vivienda.getRegistroPropiedad() != null ? vivienda
						.getRegistroPropiedad().getNumero() : null);
				// RegistroPropiedad.Tomo
				ps.setObject(14,vivienda.getRegistroPropiedad() != null ? vivienda
						.getRegistroPropiedad().getTomo() : null);
				// RegistroPropiedad.Libro
				ps.setObject(15,vivienda.getRegistroPropiedad() != null ? vivienda
						.getRegistroPropiedad().getLibro() : null);
				// RegistroPropiedad.Folio
				ps.setObject(16,vivienda.getRegistroPropiedad() != null ? vivienda
						.getRegistroPropiedad().getFolio() : null);
				// RegistroPropiedad.Finca
				ps.setObject(17,vivienda.getRegistroPropiedad() != null ? vivienda
						.getRegistroPropiedad().getFinca() : null);
				// RegistroPropiedad.Inscripcion
				ps.setObject(18,vivienda.getRegistroPropiedad() != null ? vivienda
						.getRegistroPropiedad().getInscripcion() : null);

				// NumFijoIbi
				ps.setObject(19,vivienda.getNumFijoIbi());
				// CodRefCatastral
				ps.setObject(20,vivienda.getCodRefCatastral());
				// TipoElemento
				ps.setObject(21,TipoElemento.VIVIENDA);

				// FecCalificacion
				ps.setDate(22,vivienda.getFecCalificacion()!=null?new java.sql.Date(vivienda.getFecCalificacion().getTime()) : null);

				// NumPlazoCalificacion
				ps.setObject(23,vivienda.getNumPlazoCalificacion());
				// FecDescalificacion
				ps.setDate(24,vivienda.getFecDescalificacion()!=null?new java.sql.Date(vivienda.getFecDescalificacion().getTime()) : null);
				// FecEscrituraSuel
				ps.setDate(25,vivienda.getFecEscrituraSuel()!=null?new java.sql.Date(vivienda.getFecEscrituraSuel().getTime()) : null);
				// TexObservaciones
				ps.setObject(26,vivienda.getTexObservaciones());

				// TipoRegulacion
				ps.setObject(27,vivienda.getTipoRegulacion() != null ? vivienda
						.getTipoRegulacion().getIdElereg() : null);
				// TipoAcceso
				ps.setObject(28,vivienda.getTipoAcceso() != null ? vivienda.getTipoAcceso()
						.getIdElereg() : null);
				// TipoIniciativa
				ps.setObject(29,vivienda.getTipoIniciativa() != null ? vivienda
						.getTipoIniciativa().getIdElereg() : null);
				// TipoPromotor
				ps.setObject(30,vivienda.getTipoPromotor() != null ? vivienda
						.getTipoPromotor().getIdElereg() : null);
				// TipoPropietarios
				ps.setObject(31,vivienda.getTipoPropietarios() != null ? vivienda
						.getTipoPropietarios().getIdElereg() : null);
				// TipoAdjudicacion
				ps.setObject(32,vivienda.getTipoAdjudicacion() != null ? vivienda
						.getTipoAdjudicacion().getIdElereg() : null);
				// TipoQuienAdjudicacion
				ps.setObject(33,vivienda.getTipoQuienAdjudicacion() != null ? vivienda
						.getTipoQuienAdjudicacion().getIdElereg() : null);
				// TipoComoAdjudicacion
				ps.setObject(34,vivienda.getTipoComoAdjudicacion() != null ? vivienda
						.getTipoComoAdjudicacion().getIdElereg() : null);
				// TipoPorqueAdjudicacion
				ps.setObject(35,vivienda.getTipoPorqueAdjudicacion() != null ? vivienda
						.getTipoPorqueAdjudicacion().getIdElereg() : null);
				//descalle
				if(vivienda.getDireccion().getCalle().getId()== null){
					ps.setObject(36,vivienda.getDireccion().getCalle().getNombreEs());
				}else {
					ps.setObject(36,null);
				}
				int pos=37;
				// Direccion
				pos=SQLGenericas.getParamsDireccionKEyHolder(ps, vivienda.getDireccion(), pos);
				// AbstractM62FBModel (UsuarioConectado)
				ps.setString(pos, UtilSeguridad.getNombreUsuarioConectado());
				

				return ps;
			}
		}, keyHolder);

		// Obtener Pk generada por el trigger
		vivienda.setNumVivienda(new BigDecimal(keyHolder.getKeys().get("NUM_VIVIENDA").toString()));

		return vivienda;
//		String query = ViviendasDaoSql.SQL_INSERT;
//
//		// Preparar Parametros
//		List<Object> params = new ArrayList<Object>();
//
//		// RegimenAcceso
//		params.add(vivienda.getRegimenAcceso() != null ? vivienda
//				.getRegimenAcceso().getCodTabla() : null);
//		// RegimenTenencia
//		params.add(vivienda.getRegimenTenencia() != null ? vivienda
//				.getRegimenTenencia().getCodTabla() : null);
//
//		// IndBajaDensidad
//		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndBajaDensidad()));
//		// IndAri
//		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndAri()));
//		// IndVivAdaptada
//		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndVivAdaptada()));
//		// IndFamiliaNumer
//		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndFamiliaNumer()));
//		// IndVivUnifamiliar
//		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndVivUnifamiliar()));
//
//		// NumDormitorios
//		params.add(vivienda.getNumDormitorios());
//		// NumBanyos
//		params.add(vivienda.getNumBanyos());
//		// SuperficieUtil
//		params.add(vivienda.getSuperficieUtil());
//		// FecInscripDerSup
//		params.add(vivienda.getFecInscripDerSup());
//
//		// RegistroPropiedad.Nombre
//		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
//				.getRegistroPropiedad().getNombre() : null);
//		// RegistroPropiedad.Numero
//		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
//				.getRegistroPropiedad().getNumero() : null);
//		// RegistroPropiedad.Tomo
//		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
//				.getRegistroPropiedad().getTomo() : null);
//		// RegistroPropiedad.Libro
//		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
//				.getRegistroPropiedad().getLibro() : null);
//		// RegistroPropiedad.Folio
//		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
//				.getRegistroPropiedad().getFolio() : null);
//		// RegistroPropiedad.Finca
//		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
//				.getRegistroPropiedad().getFinca() : null);
//		// RegistroPropiedad.Inscripcion
//		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
//				.getRegistroPropiedad().getInscripcion() : null);
//
//		// NumFijoIbi
//		params.add(vivienda.getNumFijoIbi());
//		// CodRefCatastral
//		params.add(vivienda.getCodRefCatastral());
//		// TipoElemento
//		params.add(TipoElemento.VIVIENDA);
//
//		// FecCalificacion
//		params.add(vivienda.getFecCalificacion());
//		// NumPlazoCalificacion
//		params.add(vivienda.getNumPlazoCalificacion());
//		// FecDescalificacion
//		params.add(vivienda.getFecDescalificacion());
//		// FecEscrituraSuel
//		params.add(vivienda.getFecEscrituraSuel());
//		// TexObservaciones
//		params.add(vivienda.getTexObservaciones());
//
//		// TipoRegulacion
//		params.add(vivienda.getTipoRegulacion() != null ? vivienda
//				.getTipoRegulacion().getIdElereg() : null);
//		// TipoAcceso
//		params.add(vivienda.getTipoAcceso() != null ? vivienda.getTipoAcceso()
//				.getIdElereg() : null);
//		// TipoIniciativa
//		params.add(vivienda.getTipoIniciativa() != null ? vivienda
//				.getTipoIniciativa().getIdElereg() : null);
//		// TipoPromotor
//		params.add(vivienda.getTipoPromotor() != null ? vivienda
//				.getTipoPromotor().getIdElereg() : null);
//		// TipoPropietarios
//		params.add(vivienda.getTipoPropietarios() != null ? vivienda
//				.getTipoPropietarios().getIdElereg() : null);
//		// TipoAdjudicacion
//		params.add(vivienda.getTipoAdjudicacion() != null ? vivienda
//				.getTipoAdjudicacion().getIdElereg() : null);
//		// TipoQuienAdjudicacion
//		params.add(vivienda.getTipoQuienAdjudicacion() != null ? vivienda
//				.getTipoQuienAdjudicacion().getIdElereg() : null);
//		// TipoComoAdjudicacion
//		params.add(vivienda.getTipoComoAdjudicacion() != null ? vivienda
//				.getTipoComoAdjudicacion().getIdElereg() : null);
//		// TipoPorqueAdjudicacion
//		params.add(vivienda.getTipoPorqueAdjudicacion() != null ? vivienda
//				.getTipoPorqueAdjudicacion().getIdElereg() : null);
//
//		// Direccion
//		SQLGenericas.getParamsDireccion(params, vivienda.getDireccion());
//
//		// AbstractM62FBModel
//		SQLGenericas.getParamsAbstractClass(params, vivienda);
//
//		// Realizar insert
//		this.jdbcTemplate.update(query, params.toArray());
//		return vivienda;
	}
//	/**
//	 * Updates a single row in the Vivienda table.
//	 * 
//	 * @param vivienda
//	 *            Vivienda
//	 * @return Vivienda
//	 */
//	@Override
//	public void updateDesCalle(BigDecimal numVivienda,String desCalle) {
//		String query = ViviendasDaoSql.SQL_UPDATE_DES_CALLE;
//		// Preparar Parametros
//		List<Object> params = new ArrayList<Object>();
//		// desCalle
//		params.add(desCalle);
//		// NumVivienda
//		params.add(numVivienda);
//
//		// Realizar Update
//		this.jdbcTemplate.update(query, params.toArray());
//	}
	/**
	 * Updates a single row in the Vivienda table.
	 * 
	 * @param vivienda
	 *            Vivienda
	 * @return Vivienda
	 */
	@Override
	public Vivienda update(Vivienda vivienda) {

		String query = ViviendasDaoSql.SQL_UPDATE;

		// Preparar Parametros
		List<Object> params = new ArrayList<Object>();

		// RegimenAcceso
		params.add(vivienda.getRegimenAcceso() != null ? vivienda
				.getRegimenAcceso().getCodTabla() : null);
		// RegimenTenencia
		params.add(vivienda.getRegimenTenencia() != null ? vivienda
				.getRegimenTenencia().getCodTabla() : null);

		// IndBajaDensidad
		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndBajaDensidad()));
		// IndAri
		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndAri()));
		// IndVivAdaptada
		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndVivAdaptada()));
		// IndFamiliaNumer
		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndFamiliaNumer()));
		// IndVivUnifamiliar
		params.add(BDUtils.formatIndicadorToBD(vivienda.getIndVivUnifamiliar()));

		// NumDormitorios
		params.add(vivienda.getNumDormitorios());
		// NumBanyos
		params.add(vivienda.getNumBanyos());
		// SuperficieUtil
		params.add(vivienda.getSuperficieUtil());
		// FecInscripDerSup
		params.add(vivienda.getFecInscripDerSup());

		// RegistroPropiedad.Nombre
		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
				.getRegistroPropiedad().getNombre() : null);
		// RegistroPropiedad.Numero
		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
				.getRegistroPropiedad().getNumero() : null);
		// RegistroPropiedad.Tomo
		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
				.getRegistroPropiedad().getTomo() : null);
		// RegistroPropiedad.Libro
		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
				.getRegistroPropiedad().getLibro() : null);
		// RegistroPropiedad.Folio
		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
				.getRegistroPropiedad().getFolio() : null);
		// RegistroPropiedad.Finca
		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
				.getRegistroPropiedad().getFinca() : null);
		// RegistroPropiedad.Inscripcion
		params.add(vivienda.getRegistroPropiedad() != null ? vivienda
				.getRegistroPropiedad().getInscripcion() : null);

		// NumFijoIbi
		params.add(vivienda.getNumFijoIbi());
		// CodRefCatastral
		params.add(vivienda.getCodRefCatastral());

		// FecCalificacion
		params.add(vivienda.getFecCalificacion());
		// NumPlazoCalificacion
		params.add(vivienda.getNumPlazoCalificacion());
		// FecDescalificacion
		params.add(vivienda.getFecDescalificacion());
		// FecEscrituraSuel
		params.add(vivienda.getFecEscrituraSuel());
		// TexObservaciones
		params.add(vivienda.getTexObservaciones());

		// TipoRegulacion
		params.add(vivienda.getTipoRegulacion() != null ? vivienda
				.getTipoRegulacion().getIdElereg() : null);
		// TipoAcceso
		params.add(vivienda.getTipoAcceso() != null ? vivienda.getTipoAcceso()
				.getIdElereg() : null);
		// TipoIniciativa
		params.add(vivienda.getTipoIniciativa() != null ? vivienda
				.getTipoIniciativa().getIdElereg() : null);
		// TipoPromotor
		params.add(vivienda.getTipoPromotor() != null ? vivienda
				.getTipoPromotor().getIdElereg() : null);
		// TipoPropietarios
		params.add(vivienda.getTipoPropietarios() != null ? vivienda
				.getTipoPropietarios().getIdElereg() : null);
		// TipoAdjudicacion
		params.add(vivienda.getTipoAdjudicacion() != null ? vivienda
				.getTipoAdjudicacion().getIdElereg() : null);
		// TipoQuienAdjudicacion
		params.add(vivienda.getTipoQuienAdjudicacion() != null ? vivienda
				.getTipoQuienAdjudicacion().getIdElereg() : null);
		// TipoComoAdjudicacion
		params.add(vivienda.getTipoComoAdjudicacion() != null ? vivienda
				.getTipoComoAdjudicacion().getIdElereg() : null);
		// TipoPorqueAdjudicacion
		params.add(vivienda.getTipoPorqueAdjudicacion() != null ? vivienda
				.getTipoPorqueAdjudicacion().getIdElereg() : null);

		// Direccion
		SQLGenericas.getParamsDireccion(params, vivienda.getDireccion());

		// AbstractM62FBModel
		SQLGenericas.getParamsAbstractClass(params, vivienda);

		// NumVivienda
		params.add(vivienda.getNumVivienda());

		// Realizar Update
		this.jdbcTemplate.update(query, params.toArray());

		return vivienda;
	}

	/**
	 * Finds a single row in the Vivienda table.
	 * 
	 * @param vivienda
	 *            Vivienda
	 * @return Vivienda
	 */
	@Override
	@Transactional(readOnly = true)
	public Vivienda find(Vivienda vivienda) {
		String query = ViviendasDaoSql.SQL_FIND;
		List<Vivienda> viviendaList = this.jdbcTemplate.query(query,
				this.rwMap, vivienda.getNumVivienda());
		return DataAccessUtils.uniqueResult(viviendaList);
	}
	/**
	 * Finds a single row in the Vivienda table.
	 * 
	 * @param vivienda
	 *            Vivienda
	 * @return Vivienda
	 */
	@Override
	@Transactional(readOnly = true)
	public Vivienda findByRowid(String rowId) {
		String query = ViviendasDaoSql.SQL_FIND_NUMVIVIENDA;
		List<Vivienda> viviendaList = this.jdbcTemplate.query(query,
				this.rwMapNumVivienda, rowId);
		return DataAccessUtils.uniqueResult(viviendaList);
	}

	/**
	 * Removes a single row in the Vivienda table.
	 * 
	 * @param vivienda
	 *            Vivienda
	 */
	@Override
	public void remove(Vivienda vivienda) {
		/*****
		 * Llamada a function que implementa llamada a plsql
		 ****/
		M62FuncionesPLSQL m62FuncionesPLSQL = new M62FuncionesPLSQL(
				this.jdbcTemplate.getDataSource());
		m62FuncionesPLSQL.borrarVivienda(vivienda.getNumVivienda());
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Funcion encargada de buscar las viviendas para el mantenimiento de
	 * seleccion de viviendas
	 * 
	 * @param vivienda
	 *            Vivienda
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Booleanl
	 * @return List<Vivienda>
	 */
	@Override
	@Transactional(readOnly = true)
	public List<Vivienda> filterSeleccionViviendas(Vivienda vivienda,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {

		List<Object> params = new ArrayList<Object>();

		// Calculamos la Select a ejecutar
		StringBuilder query = new StringBuilder(
				this.getQueryFilterSeleccionViviendas(vivienda, startsWith,
						params, false));

		if (jqGridRequestDto != null) {
			query = JQGridManager.getPaginationQuery(jqGridRequestDto, query);
		}

		return this.jdbcTemplate.query(query.toString(),
				this.rwMapSeleccionViviendas, params.toArray());
	}

	/**
	 * Funcion encargada de buscar las viviendas para el mantenimiento de
	 * seleccion de viviendas para la actualización masiva
	 * 
	 * @param vivienda
	 *            Vivienda
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Booleanl
	 * @return List<Vivienda>
	 */
	@Override
	@Transactional(readOnly = true)
	public List<ViviendaActMasiva> filterSeleccionViviendasForActMasiva(
			Vivienda vivienda, JQGridRequestDto jqGridRequestDto,
			Boolean startsWith) {

		List<Object> params = new ArrayList<Object>();

		// Calculamos la Select a ejecutar
		StringBuilder query = new StringBuilder(
				this.getQueryFilterSeleccionViviendas(vivienda, startsWith,
						params, false));

		if (jqGridRequestDto != null) {
			query = JQGridManager.getPaginationQuery(jqGridRequestDto, query);
		}

		return this.jdbcTemplate.query(query.toString(),
				this.rwMapSeleccionViviendasActMasiva, params.toArray());
	}

	/**
	 * Funcion encargada de contar las viviendas para el mantenimiento de
	 * seleccion de viviendas
	 * 
	 * @param vivienda
	 *            Vivienda
	 * @param startsWith
	 *            Boolean
	 * @return Long
	 */
	@Override
	@Transactional(readOnly = true)
	public Long filterSeleccionViviendasCount(Vivienda vivienda,
			Boolean startsWith) {

		List<Object> params = new ArrayList<Object>();

		// Calculamos la Select a ejecutar
		StringBuilder query = new StringBuilder(
				ViviendasDaoSql.SQL_SELECT_COUNT);
		query.append(" FROM (");
		query.append(this.getQueryFilterSeleccionViviendas(vivienda,
				startsWith, params, false));
		query.append(") ");

		return this.jdbcTemplate.queryForLong(query.toString(),
				params.toArray());
	}

	private String getQueryFilterSeleccionViviendas(Vivienda vivienda,
			Boolean startsWith, List<Object> params, Boolean fromFindAllLike) {
		// Calculamos la Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMapSeleccionViviendas(
				vivienda, startsWith, fromFindAllLike);

		StringBuilder query;
		if (vivienda.getPersona() != null
				&& vivienda.getPersona().getIdPersona() != null) {
			// Con titular
			// INI -- QUERY PROPIETARIOS (COMPRA)
			query = new StringBuilder(
					ViviendasDaoSql.SQL_FIND_ALL_MANT_SELECCION_VIV_CON_TITULAR_COMPRA);
			query.append(ViviendasDaoSql.SQL_WHERE_ALL_MANT_SELECCION_VIV_CON_TITULAR_COMPRA);
			// Filtro persona
			query.append(" AND ").append(ViviendasDaoSql.ALIAS_PROP)
					.append(".ID_PERSONA = ?");
			params.add(vivienda.getPersona().getIdPersona());
			// Resto de Filtro
			query.append(mapaWhere.get("query"));
			params.addAll((List<?>) mapaWhere.get("params"));
			// FIN -- QUERY PROPIETARIOS (ALQUILER)
			// UNION
			query.append(" UNION ");
			// INI -- QUERY INQUILINOS (ALQUILER)
			query.append(ViviendasDaoSql.SQL_FIND_ALL_MANT_SELECCION_VIV_CON_TITULAR_ALQUILER);
			query.append(ViviendasDaoSql.SQL_WHERE_ALL_MANT_SELECCION_VIV_CON_TITULAR_ALQUILER);
			// Filtro persona
			query.append(" AND ").append(ViviendasDaoSql.ALIAS_INQ)
					.append(".ID_PERSONA = ?");
			params.add(vivienda.getPersona().getIdPersona());
			// Resto de Filtro
			query.append(mapaWhere.get("query"));
			params.addAll((List<?>) mapaWhere.get("params"));
			// FIN -- QUERY INQUILINOS (ALQUILER)
		} else {
			// Sin titular
			query = new StringBuilder(ViviendasDaoSql.STRING_BUILDER_INIT);
//			if (vivienda.getExpedienteVivienda() != null
//					&& vivienda.getExpedienteVivienda().getNumExpediente() != null) {
//				// Con NumExp
//				query.append(ViviendasDaoSql.SQL_FIND_ALL_MANT_SELECCION_VIV_SIN_TITULAR_CON_EXP);
//				query.append(ViviendasDaoSql.SQL_WHERE_ALL_MANT_SELECCION_VIV_SIN_TITULAR_CON_EXP);
//			} else {
				// Sin NumExp
				query.append(ViviendasDaoSql.SQL_FIND_ALL_MANT_SELECCION_VIV_SIN_TITULAR);
				query.append(ViviendasDaoSql.SQL_WHERE_ALL_MANT_SELECCION_VIV_SIN_TITULAR);
//			}
			// Resto de Filtro
			query.append(mapaWhere.get("query"));
			params.addAll((List<?>) mapaWhere.get("params"));
		}

		return query.toString();
	}

	/*
	 * MÉTODOS PRIVADOS
	 */

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the Vivienda entity
	 * 
	 * @param vivienda
	 *            Vivienda Bean with the criteria values to filter by.
	 * @param startsWith
	 *            Boolean
	 * @return Map created with two keys key query stores the sql query syntax
	 *         key params stores the parameter values to be used in the
	 *         condition sentence.
	 */
	private Map<String, Object> getWhereLikeMapSeleccionViviendas(
			Vivienda vivienda, Boolean startsWith, Boolean fromFindAllLike) {
		
		//TODO gazamago, pongo el parametro fromFindAllLike porque estaba muy lioso todo
		//y se utilizaba el getWhereLike desde un findAll normal
		StringBuilder where = new StringBuilder(
				ViviendasDaoSql.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		if (vivienda != null) {
			// NumVivienda
			if (vivienda.getNumVivienda() != null) {
				if(fromFindAllLike){
					BDUtils.crearFiltroLike(where, params, "VIV.NUM_VIVIENDA",
							BDUtils.formatComodinesFiltroToBD(vivienda.getNumVivienda().toString()),startsWith);
				}else{
					BDUtils.crearFiltroIgual(where, params, "VIV.NUM_VIVIENDA",
							vivienda.getNumVivienda());
				}
			}
			// ExpedienteVivienda
			if (vivienda.getExpedienteVivienda() != null) {
				// NumExpediente
				if (vivienda.getExpedienteVivienda().getNumExpediente() != null) {
					BDUtils.crearFiltroLike(
							where,
							params,
							"VIV.NUM_EXPEDIENTE",
							BDUtils.formatComodinesFiltroToBD(vivienda
									.getExpedienteVivienda().getNumExpediente()),
							startsWith);
				}
			}
			// RegistroPropiedad
			if (vivienda.getRegistroPropiedad() != null) {
				// Nombre
				if (vivienda.getRegistroPropiedad().getNombre() != null) {
					BDUtils.crearFiltroLike(where, params,
							"VIV.NOM_REGISTRO_PROP", vivienda
									.getRegistroPropiedad().getNombre(),
							startsWith);
				}
				// Numero
				if (vivienda.getRegistroPropiedad().getNumero() != null) {
					BDUtils.crearFiltroIgual(where, params,
							"VIV.NUM_REGISTRO_PROP", vivienda
									.getRegistroPropiedad().getNumero());
				}
				// Tomo
				if (vivienda.getRegistroPropiedad().getTomo() != null) {
					BDUtils.crearFiltroLike(where, params, "VIV.DES_TOMO",
							vivienda.getRegistroPropiedad().getTomo(),
							startsWith);
				}
				// Libro
				if (vivienda.getRegistroPropiedad().getLibro() != null) {
					BDUtils.crearFiltroLike(where, params, "VIV.DES_LIBRO",
							vivienda.getRegistroPropiedad().getLibro(),
							startsWith);
				}
				// Folio
				if (vivienda.getRegistroPropiedad().getFolio() != null) {
					BDUtils.crearFiltroLike(where, params, "VIV.DES_FOLIO",
							vivienda.getRegistroPropiedad().getFolio(),
							startsWith);
				}
				// Finca
				if (vivienda.getRegistroPropiedad().getFinca() != null) {
					BDUtils.crearFiltroLike(where, params, "VIV.DES_FINCA",
							vivienda.getRegistroPropiedad().getFinca(),
							startsWith);
				}
				// Inscripcion
				if (vivienda.getRegistroPropiedad().getInscripcion() != null) {
					BDUtils.crearFiltroLike(where, params,
							"VIV.DES_INSCRIPCION", vivienda
									.getRegistroPropiedad().getInscripcion(),
							startsWith);
				}
			}
			// Direcion
			if (vivienda.getDireccion() != null) {
				BDUtils.crearFiltroDireccion(where, params, "VIV",
						vivienda.getDireccion());
			}
			// Regimen Acceso
			if (vivienda.getRegimenAcceso() != null) {
				if (vivienda.getRegimenAcceso().getCodTabla() != null) {
					BDUtils.crearFiltroIgual(where, params,
							"VIV.COD_REG_ACCESO", vivienda.getRegimenAcceso()
									.getCodTabla());
				}
			}

			// FecCalificacion Desde
			if (vivienda.getFecCalificacionDesde() != null) {
				BDUtils.crearFiltroDesde(where, params, "VIV.FEC_CALIFICACION",
						vivienda.getFecCalificacionDesde());
			}

			// FecCalificacion Hasta
			if (vivienda.getFecCalificacionHasta() != null) {
				BDUtils.crearFiltroHasta(where, params, "VIV.FEC_CALIFICACION",
						vivienda.getFecCalificacionHasta());
			}
			// FecDesCalificacion Desde
			if (vivienda.getFecDescalificacionDesde() != null) {
				BDUtils.crearFiltroDesde(where, params, "VIV.FEC_DESCALIFICA",
						vivienda.getFecDescalificacionDesde());
			}

			// FecDesCalificacion Hasta
			if (vivienda.getFecDescalificacionHasta() != null) {
				BDUtils.crearFiltroHasta(where, params, "VIV.FEC_DESCALIFICA",
						vivienda.getFecDescalificacionHasta());
			}
		}

		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);

		return mapWhere;
	}

	/**
	 * Comprueba si se ha realizado algun cambio en BBDD, si es asi lanza una
	 * excecion.
	 * 
	 * @param vivienda
	 *            Vivienda(numVivienda, fecHorUltimaModif)
	 */
	@Override
	@Transactional(readOnly = true)
	public void checkForUpdate(Vivienda vivienda) {
		StringBuilder query = new StringBuilder(
				ViviendasDaoSql.SQL_CHECK_FOR_UPDATE);
		if (this.jdbcTemplate.queryForInt(query.toString(),
				vivienda.getNumVivienda(), vivienda.getFecHorUltimaModif()) == 0) {
			throw new UFException(IberErrorsMsgConstants.CONCURRENCY_MSG);
		}
	}

	@Override
	@Transactional(readOnly = true)
	public List<Vivienda> findAll(Vivienda vivienda, JQGridRequestDto jqGridRequestDto) {
		List<Object> params = new ArrayList<Object>();

		// Calculamos la Select a ejecutar
		StringBuilder query = new StringBuilder(
				this.getQueryFilterSeleccionViviendas(vivienda, false,
						params, false));

		if (jqGridRequestDto != null) {
			query = JQGridManager.getPaginationQuery(jqGridRequestDto, query);
		}

		return this.jdbcTemplate.query(query.toString(),
				this.rwMapSeleccionViviendas, params.toArray());
		
		
		
	}

	@Override
	public List<Vivienda> findAllLike(Vivienda vivienda, JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		List<Object> params = new ArrayList<Object>();

		// Calculamos la Select a ejecutar
		StringBuilder query = new StringBuilder(
				this.getQueryFilterSeleccionViviendas(vivienda, false,
						params, true));

		if (jqGridRequestDto != null) {
			query = JQGridManager.getPaginationQuery(jqGridRequestDto, query);
		}

		return this.jdbcTemplate.query(query.toString(),
				this.rwMapSeleccionViviendas, params.toArray());
	}

	@Override
	public Vivienda findForLupa(Vivienda vivienda) {
		String query = ViviendasDaoSql.SQL_FIND_LUPA;
		List<Vivienda> viviendaList = this.jdbcTemplate.query(query,
				this.rwMapLupa, vivienda.getNumVivienda());
		return DataAccessUtils.uniqueResult(viviendaList);	
	}
}