package com.ejie.m62fb.dao.registroVPP;

import java.math.BigDecimal;
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.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.m62fb.utils.constants.IberErrorsMsgConstants;
import com.ejie.m62fb.utils.error.UFException;
import com.ejie.m62fb.utils.format.FormatUtils;
import com.ejie.m62fb.dao.ComboP28Dao;
import com.ejie.m62fb.dao.PersonaDao;
import com.ejie.m62fb.dao.SQLGenericas;
import com.ejie.m62fb.dao.registroVPP.plsql.M62FuncionesPLSQL;
import com.ejie.m62fb.model.AlojamientoDotacional;
import com.ejie.m62fb.model.ContratoAlquilerad;
import com.ejie.m62fb.model.CuentaBancaria;
import com.ejie.m62fb.model.persona.Persona;
import com.ejie.m62fb.model.tipos.TipoSiNo;
import com.ejie.m62fb.utils.sql.BDUtils;
import com.ejie.m62fb.utils.sql.UtilsResulSet;
import com.ejie.x38.dao.RowNumResultSetExtractor;
import com.ejie.x38.dto.JQGridManager;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * ContratoAlquileradDaoImpl generated by UDA, 08-oct-2015 9:02:54.
XXXX
 */
 
@Repository
@Transactional
public class ContratoAlquileradDaoImpl implements ContratoAlquileradDao {
    private JdbcTemplate jdbcTemplate;
    
    @SuppressWarnings("rawtypes")
	@Autowired
	private ComboP28Dao<TipoSiNo> comboP28Dao;
	@Autowired
	DireccionesDao direccionesDao;
	@Autowired
	PersonaDao personaDao;
	@Autowired
	AlojamientoDotacionalDao alojamientoDotacionalDao;
	@Autowired
	private ReloadableResourceBundleMessageSource messageErrorsSource;
    
	
	/*
	 * ROW_MAPPERS
	 */
	private RowMapper<ContratoAlquilerad> rwMap = new RowMapper<ContratoAlquilerad>() {
		public ContratoAlquilerad mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			
			//Id Contrato
			ContratoAlquilerad contratoAlquilerAd = new ContratoAlquilerad(
					resultSet.getInt("IDCONTRATO"));

			
			//Alojamiento Dotacional
//			contratoAlquilerAd.setAlojamientoDotacional(
//					new AlojamientoDotacional() );
//            contratoAlquilerAd.getAlojamientoDotacional().setIdAlojamiento(
//            		resultSet.getInt("IDALOJREG"));
           
            AlojamientoDotacional alojamientoDotacional = new AlojamientoDotacional(resultSet.getInt("IDALOJREG"));
            contratoAlquilerAd.setAlojamientoDotacional(
            		alojamientoDotacionalDao.find(alojamientoDotacional));
            
            //Numero de contrato
            contratoAlquilerAd.setNumContrato(
            		resultSet.getLong("NUMCONTRATO"));
            
            //Fecha entrada eontrato
            contratoAlquilerAd.setFecEntContrato(
            		resultSet.getTimestamp("FECENTCONTRATO"));
            
            //Fecha de inicio
            contratoAlquilerAd.setFecInicio(
            		resultSet.getTimestamp("FECINICIO"));
            
            //FEcha de fin
            contratoAlquilerAd.setFecFin(
            		resultSet.getTimestamp("FECFIN"));
            
            
         // Indicador Visado
			TipoSiNo indVisado = new TipoSiNo(resultSet.getString("INDVISADO"));
			contratoAlquilerAd.setIndVisado((TipoSiNo) comboP28Dao
					.find(indVisado));
            
            //Fecha de Visado
            contratoAlquilerAd.setFecVisado(
            		resultSet.getTimestamp("FECVISADO"));
            
            //Fecha de padrón
            contratoAlquilerAd.setFecEmpadron(
            		resultSet.getTimestamp("FECEMPADRON"));
            
			// ID Pagador Renta
			Persona pagadorRenta = new Persona(
					resultSet.getBigDecimal("IDPAGADORRENTA"));
			contratoAlquilerAd.setPagadorRenta(personaDao.find(pagadorRenta));

            
            //Importe precio de renta
//            contratoAlquilerAd.setImpPrecioRenta(
//					resultSet.getBigDecimal("IMPPRECIORENTA"));
            
            //Importe precio de renta
            contratoAlquilerAd.setImcPrecioRenta(
					resultSet.getBigDecimal("IMCPRECIORENTA"));
            
            //Importe de la fianza
//            contratoAlquilerAd.setImpFianza(
//					resultSet.getBigDecimal("IMPFIANZA"));
            
            //Importe de la fianza
            contratoAlquilerAd.setImcFianza(
            		resultSet.getBigDecimal("IMCFIANZA"));
            
         // Datos Cuenta Bancaria
            contratoAlquilerAd.setCuentaBancaria(new CuentaBancaria());
          //Código ENTIDAD BANCARIA
            contratoAlquilerAd.getCuentaBancaria().setCodEntidad(
					resultSet.getString("CODENTIDAD"));
          //CODIGO SUCURSAL
            contratoAlquilerAd.getCuentaBancaria().setCodSucursal(
					resultSet.getString("CODSUCURSAL"));
          //Codigo dígito de control
            contratoAlquilerAd.getCuentaBancaria().setCodDigitoControl(
					resultSet.getString("CODDIGITOCONTROL"));
		  //Codigo cuenta bancaria
            contratoAlquilerAd.getCuentaBancaria().setCodCuenta(
					resultSet.getString("CODCUENTA"));
            
            //Texto observaciones
            contratoAlquilerAd.setTexObservaciones(
					resultSet.getString("TEXOBSERVACIONES"));
            
            //Fecha envío contrato
            contratoAlquilerAd.setFecEnvContrato(
					resultSet.getTimestamp("FECENVCONTRATO"));
            
            //Fecha envío fin de contrato
            contratoAlquilerAd.setFecEnvFinContrato(
					resultSet.getTimestamp("FECENVFINCONTRATO"));
            
            //Fecha inicio facturacion renta
            contratoAlquilerAd.setFecIniFac(
					resultSet.getTimestamp("FECINIFAC"));
            
         // DIRECCION
            contratoAlquilerAd.setDireccion(UtilsResulSet.getDireccionCompleta(
					resultSet, ContratoAlquileradDaoSql.ALIAS_CONTRATOALQAD,
					direccionesDao));
            
			// AbstractClass
			UtilsResulSet.getAbstractClass(resultSet, contratoAlquilerAd,
					ContratoAlquileradDaoSql.ALIAS_CONTRATOALQAD);
            
           return contratoAlquilerAd; 
		}
	};
           
	private RowMapper<ContratoAlquilerad> rwMapPK = new RowMapper<ContratoAlquilerad>() {
		public ContratoAlquilerad mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new ContratoAlquilerad(
				resultSet.getInt("IDCONTRATO")
           ); } } ;
           
           
   	private final RowMapper<ContratoAlquilerad> rwMapValidaciones = new RowMapper<ContratoAlquilerad>() {
		@Override
		public ContratoAlquilerad mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			ContratoAlquilerad contratoAlquilerad = new ContratoAlquilerad();
			
			// Id Alojamniento Dotacional
            AlojamientoDotacional alojamientoDotacional = new AlojamientoDotacional(resultSet.getInt("IDALOJREG"));
            contratoAlquilerad.setAlojamientoDotacional(
            		alojamientoDotacionalDao.find(alojamientoDotacional));
          //id de contrato
            contratoAlquilerad.setIdContrato(resultSet.getInt("IDCONTRATO"));
            //Numero de contrato
            contratoAlquilerad.setNumContrato(
            		resultSet.getLong("NUMCONTRATO"));

			return contratoAlquilerad;
		}
	};


	/**
     * 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 ContratoAlquilerad table.
     *
     * @param contratoalquilerad ContratoAlquilerad
     * @return ContratoAlquilerad
     */
	public ContratoAlquilerad add(ContratoAlquilerad contratoalquilerad) {
		
		String query = ContratoAlquileradDaoSql.SQL_INSERT;
		
		// Alojamiento dotacional
		Integer getIdAlojRegAux = null;
		if (contratoalquilerad.getAlojamientoDotacional() != null && 
				contratoalquilerad.getAlojamientoDotacional().getIdAlojReg() != null ) {
			getIdAlojRegAux = contratoalquilerad.getAlojamientoDotacional().getIdAlojReg();
		}
		// Codigo Entidad
		String getCodEntidad = null;
		if (contratoalquilerad.getCuentaBancaria() != null
				&& contratoalquilerad.getCuentaBancaria().getCodEntidad() != null) {
			getCodEntidad = contratoalquilerad.getCuentaBancaria()
					.getCodEntidad();
		}
		// Codigo Sucursal
		String getCodSucursal = null;
		if (contratoalquilerad.getCuentaBancaria() != null
				&& contratoalquilerad.getCuentaBancaria().getCodSucursal() != null) {
			getCodSucursal = contratoalquilerad.getCuentaBancaria()
					.getCodSucursal();
		}
		// Codigo Digito Control
		String getCodDigitoControl = null;
		if (contratoalquilerad.getCuentaBancaria() != null
				&& contratoalquilerad.getCuentaBancaria().getCodDigitoControl() != null) {
			getCodDigitoControl = contratoalquilerad.getCuentaBancaria()
					.getCodDigitoControl();
		}
		// Codigo Cuenta
		String getCodCuenta = null;
		if (contratoalquilerad.getCuentaBancaria() != null
				&& contratoalquilerad.getCuentaBancaria().getCodCuenta() != null) {
			getCodCuenta = contratoalquilerad.getCuentaBancaria().getCodCuenta();
		}
		// Id Pagador Renta
		BigDecimal getIdPagadorRenta = null;
		if (contratoalquilerad.getPagadorRenta() != null
				&& contratoalquilerad.getPagadorRenta().getIdPersona() != null) {
			getIdPagadorRenta = contratoalquilerad.getPagadorRenta()
					.getIdPersona();
		}
		
		
		// Campos para la generación del contrato alquiler dotacional
		// Preparar Parametros
		List<Object> params = new ArrayList<Object>();
		
		//Id AlojReg
		params.add(getIdAlojRegAux);
		
		
		//Ya me llega el num_contrato del formulario. 
		params.add(contratoalquilerad.getNumContrato());
		// Num Contrato: maximo NUM_CONTRATO de la tabla CONTRATO_ALQUILERAD
		// incrementandolo en 1. Si no hay contratos es 1.
//		params.add(this.findNumContratoMaxMasUno(getIdAlojRegAux));
		
		// Fecha Entrada Contrato
		params.add(contratoalquilerad.getFecEntContrato());		
		// Fecha Inicio
		params.add(contratoalquilerad.getFecInicio());
		// Fecha Fin
		params.add(contratoalquilerad.getFecFin());
		// Indicador Visado
		if (contratoalquilerad.getIndVisado() != null) {
			params.add(contratoalquilerad.getIndVisado().getCodTabla());
		} else {
			params.add(BDUtils.FALSE);
		}
		
		// Fecha Visado
		params.add(contratoalquilerad.getFecVisado());
		// Fecha Empadronamiento
		params.add(contratoalquilerad.getFecEmpadron());
		// Id pagador de la renta
		params.add(getIdPagadorRenta);
//		//1
//		params.add(contratoalquilerad.get);
//		//2 
//		params.add(contratoalquilerad.get);
//		//3
//		params.add(contratoalquilerad.get);
		// Importe renta 
//		params.add(contratoalquilerad.getImpPrecioRenta());
		// Importe renta 
		params.add(contratoalquilerad.getImcPrecioRenta());
		// Importe fianza
//		params.add(contratoalquilerad.getImpFianza());
		// Importe fianza
		params.add(contratoalquilerad.getImcFianza());
		// Codigo Entidad
		params.add(getCodEntidad);
		// Codigo Sucursal
		params.add(getCodSucursal);
		// Codigo Digito Control
		params.add(getCodDigitoControl);
		// Codigo Cuenta
		params.add(getCodCuenta);
		// Texto Observaciones
		params.add(contratoalquilerad.getTexObservaciones());
		// Fecha Envio Contrato
		params.add(contratoalquilerad.getFecEnvContrato());
		// Fecha Envio Fin Contrato
		params.add(contratoalquilerad.getFecEnvFinContrato());
		// Fecha Inicio Factura
		params.add(contratoalquilerad.getFecIniFac());
		
		// Direccion
		SQLGenericas
				.getParamsDireccion(params, contratoalquilerad.getDireccion());
		
		// CodUsuario
		SQLGenericas.getParamsAbstractClass(params, contratoalquilerad);

		this.jdbcTemplate.update(query, params.toArray());
    	
		return contratoalquilerad;
	}

    /**
     * Updates a single row in the ContratoAlquilerad table.
     *
     * @param contratoalquilerad ContratoAlquilerad
     * @return ContratoAlquilerad
     */
    public ContratoAlquilerad update(ContratoAlquilerad contratoalquilerad) {
    	
		String query = ContratoAlquileradDaoSql.SQL_UPDATE;

		// Campos para la generación del contrato alojamiento dotacional
		// Id Contrato
		Integer getIdContratoAux = null;
		if (contratoalquilerad.getIdContrato() != null) {
			getIdContratoAux = contratoalquilerad.getIdContrato();
		}
		// Num contrato
		Long getNumContratoAux = null;
		if (contratoalquilerad.getNumContrato() != null) {
			getNumContratoAux = contratoalquilerad.getNumContrato();
		}
		
		// Alojamiento dotacional
		Integer getIdAlojRegAux = null;
		if (contratoalquilerad.getAlojamientoDotacional() != null && 
				contratoalquilerad.getAlojamientoDotacional().getIdAlojReg() != null ) {
			getIdAlojRegAux = contratoalquilerad.getAlojamientoDotacional().getIdAlojReg();
		}
		// Codigo Entidad
		String getCodEntidad = null;
		if (contratoalquilerad.getCuentaBancaria() != null
				&& contratoalquilerad.getCuentaBancaria().getCodEntidad() != null) {
			getCodEntidad = contratoalquilerad.getCuentaBancaria()
					.getCodEntidad();
		}
		// Codigo Sucursal
		String getCodSucursal = null;
		if (contratoalquilerad.getCuentaBancaria() != null
				&& contratoalquilerad.getCuentaBancaria().getCodSucursal() != null) {
			getCodSucursal = contratoalquilerad.getCuentaBancaria()
					.getCodSucursal();
		}
		// Codigo Digito Control
		String getCodDigitoControl = null;
		if (contratoalquilerad.getCuentaBancaria() != null
				&& contratoalquilerad.getCuentaBancaria().getCodDigitoControl() != null) {
			getCodDigitoControl = contratoalquilerad.getCuentaBancaria()
					.getCodDigitoControl();
		}
		// Codigo Cuenta
		String getCodCuenta = null;
		if (contratoalquilerad.getCuentaBancaria() != null
				&& contratoalquilerad.getCuentaBancaria().getCodCuenta() != null) {
			getCodCuenta = contratoalquilerad.getCuentaBancaria().getCodCuenta();
		}
		// Id Pagador Renta
		BigDecimal getIdPagadorRenta = null;
		if (contratoalquilerad.getPagadorRenta() != null
				&& contratoalquilerad.getPagadorRenta().getIdPersona() != null) {
			getIdPagadorRenta = contratoalquilerad.getPagadorRenta()
					.getIdPersona();
		}
		
		
		// Campos para la generación del contrato alquiler dotacional
		// Preparar Parametros
		List<Object> params = new ArrayList<Object>();

		//Id AlojReg
		params.add(getIdAlojRegAux);
		// Num Contrato
		params.add(getNumContratoAux);
		// Fecha Entrada Contrato
		params.add(contratoalquilerad.getFecEntContrato());		
		// Fecha Inicio
		params.add(contratoalquilerad.getFecInicio());
		// Fecha Fin
		params.add(contratoalquilerad.getFecFin());
		// Indicador Visado
		if (contratoalquilerad.getIndVisado() != null) {
			params.add(contratoalquilerad.getIndVisado().getCodTabla());
		} else {
			params.add(BDUtils.FALSE);
		}
		// Fecha Visado
		params.add(contratoalquilerad.getFecVisado());
		// Fecha Empadronamiento
		params.add(contratoalquilerad.getFecEmpadron());
		// Id pagador de la renta
		params.add(getIdPagadorRenta);
		// Importe renta 
//		params.add(contratoalquilerad.getImpPrecioRenta());
		// Importe renta 
		params.add(contratoalquilerad.getImcPrecioRenta());
		// Importe fianza
//		params.add(contratoalquilerad.getImpFianza());
		// Importe fianza
		params.add(contratoalquilerad.getImcFianza());
		// Codigo Entidad
		params.add(getCodEntidad);
		// Codigo Sucursal
		params.add(getCodSucursal);
		// Codigo Digito Control
		params.add(getCodDigitoControl);
		// Codigo Cuenta
		params.add(getCodCuenta);
		// Texto Observaciones
		params.add(contratoalquilerad.getTexObservaciones());
		// Fecha Envio Contrato
		params.add(contratoalquilerad.getFecEnvContrato());
		// Fecha Envio Fin Contrato
		params.add(contratoalquilerad.getFecEnvFinContrato());
		// Fecha Inicio Factura
		params.add(contratoalquilerad.getFecIniFac());
		
		// Direccion
		SQLGenericas
				.getParamsDireccion(params, contratoalquilerad.getDireccion());
		
		// CodUsuario
		SQLGenericas.getParamsAbstractClass(params, contratoalquilerad);
		
		
		//Id contrato alojamiento dotacional ha actualizar
		params.add(getIdContratoAux);
		
		this.jdbcTemplate.update(query, params.toArray());
		
		return contratoalquilerad;
	}
    
    /**
	 * Returns a Integer. Máximo NUM_CONTRATO que hay para un alojamiento en
	 * la tabla CONTRATO_ALQUILERAD e incrementandolo en 1.
	 * 
	 * @param idAlojReg
	 *            Integer
	 * @return Integer Siguiente n&uacute;mero de contrato
	 */
	@Override
	@Transactional(readOnly = true)
	public Integer findNumContratoMaxMasUno(Integer idAlojReg) {
		StringBuilder query = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_GET_NEXT_NUM_CONTRATO);
		Integer numContrato = this.jdbcTemplate.queryForInt(query.toString(),idAlojReg);
				
		return numContrato;
	}

    /**
     * Finds a single row in the ContratoAlquilerad table.
     *
     * @param contratoalquilerad ContratoAlquilerad
     * @return ContratoAlquilerad
     */
    @Transactional (readOnly = true)
    public ContratoAlquilerad find(ContratoAlquilerad contratoalquilerad) {
		String query = ContratoAlquileradDaoSql.SQL_FIND;

		List<ContratoAlquilerad> contratoAlquilerAdList = this.jdbcTemplate.query(
				query, this.rwMap, contratoalquilerad.getIdContrato());
		
		return (ContratoAlquilerad) DataAccessUtils.uniqueResult(contratoAlquilerAdList);
		
    }

    /**
     * Removes a single row in the ContratoAlquilerad table.
     *
     * @param contratoalquilerad ContratoAlquilerad
     * @return
     */
    public void remove(ContratoAlquilerad contratoalquilerad) {
		BigDecimal idContrato = null;
		
		if(contratoalquilerad.getIdContrato()!=null){
			idContrato = new BigDecimal(contratoalquilerad.getIdContrato());
		}
		/*****
		 * Llamada a function que implementa llamada a plsql
		 ****/
		M62FuncionesPLSQL m62FuncionesPLSQL = new M62FuncionesPLSQL(
				this.jdbcTemplate.getDataSource());
		m62FuncionesPLSQL.borrarContratoAlojDotacional(idContrato);
		
    }
    
   /**
    * Finds a list of rows in the ContratoAlquilerad table.
    * 
    * @param contratoalquilerad ContratoAlquilerad
    * @param jqGridRequestDto JQGridRequestDto
    * @return List<ContratoAlquilerad> 
    */
	@Transactional (readOnly = true)
    public List<ContratoAlquilerad> findAll(ContratoAlquilerad contratoalquilerad, JQGridRequestDto jqGridRequestDto) {
		
		StringBuilder query = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_FIND_ALL);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(contratoalquilerad);
		StringBuilder where = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

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

		return (List<ContratoAlquilerad>) this.jdbcTemplate.query(query.toString(), this.rwMap,
				params.toArray());
		
	}
	
	/**
	 * Finds rows in the ContratoAlquilerad table using like.
     * 
     * @param contratoalquilerad ContratoAlquilerad
     * @param jqGridRequestDto JQGridRequestDto
     * @param startsWith Boolean
     * @return List<ContratoAlquilerad>
     */
	@Transactional (readOnly = true)
    public List<ContratoAlquilerad> findAllLike(ContratoAlquilerad contratoalquilerad, JQGridRequestDto jqGridRequestDto, Boolean startsWith) {

		StringBuilder query = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_FIND_ALL);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(contratoalquilerad,
				startsWith);
		StringBuilder where = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

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

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

	/*
	 * OPERACIONES RUP_TABLE
	 */
	
    /**
     * Counts rows in the ContratoAlquilerad table.
     * 
     * @param contratoalquilerad ContratoAlquilerad
     * @return Long
     */
    @Transactional (readOnly = true)
    public Long findAllCount(ContratoAlquilerad contratoalquilerad){
    
    	StringBuilder query = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_FIND_ALL_COUNT);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(contratoalquilerad);
		StringBuilder where = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForLong(query.toString(),
				params.toArray());
		
	}	
	
	/**
	 * Counts rows in the ContratoAlquilerad table using like.
     * 
     * @param contratoalquilerad ContratoAlquilerad
     * @param startsWith Boolean
     * @return Long 
     */
	@Transactional (readOnly = true)
    public Long findAllLikeCount(ContratoAlquilerad contratoalquilerad, Boolean startsWith) {
		
		StringBuilder query = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_FIND_ALL_COUNT);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(contratoalquilerad,
				startsWith);
		StringBuilder where = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		List<?> params = (List<?>) mapaWhere.get("params");

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

	/**
	 * Reorder the data list of ContratoAlquilerad selected for rup_table
     * 
     * @param contratoalquilerad ContratoAlquilerad
     * @param jqGridRequestDto JQGridRequestDto
     * @param startsWith Boolean
     * @return List<TableRowDto<ContratoAlquilerad>> 
     */
	@Override 
	public List<TableRowDto<ContratoAlquilerad>> reorderSelection(ContratoAlquilerad contratoalquilerad, JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		
		// SELECT
		StringBuilder query = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_FIND_ALL);

		// FILTRADO
		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(contratoalquilerad,
				startsWith);
		StringBuilder where = new StringBuilder(
				ContratoAlquileradDaoSql.SQL_WHERE_ALL);
		where.append(mapaWhere.get("query"));
		query.append(where);

		// Parámetros de filtrado
		@SuppressWarnings("unchecked")
		List<Object> filterParamList = (List<Object>) mapaWhere.get("params");

		// SQL para la reordenación
		StringBuilder sbReorderSelectionSQL = JQGridManager.getReorderQuery(
				query, jqGridRequestDto, ContratoAlquilerad.class,
				filterParamList, ContratoAlquileradDaoSql.PK);

		return this.jdbcTemplate.query(sbReorderSelectionSQL.toString(),
				new RowNumResultSetExtractor<ContratoAlquilerad>(this.rwMapPK,
						jqGridRequestDto), filterParamList.toArray());
		
		
	}
	
	
	
	/**
	 * Funcion que valida la coherencia entre las fechas inicio y fin. Consulta
	 * si estamos en el ultimo contrato. Si estamos en el ultimo contrato, la
	 * fecha inicio debe ser mayor que la fecha inicio del resto de contratos.
	 * Si no estamos en el ultimo contrato, hay que comprobar el rango de fechas
	 * inicio/fin.
	 * 
	 * @param contratoAlquileraAd
	 *            ContratoAlquilerad
	 * @return String
	 */
	@Override
	@Transactional(readOnly = true)
	public String validarFechasIniFin(ContratoAlquilerad contratoAlquilerAd) {
		String resultado = null;
		String query = ContratoAlquileradDaoSql.SQL_FIND_ULTIMO_CONTRATO;
		
		// Id contrato
		Integer getIdContratoAux = null;
		if (contratoAlquilerAd.getIdContrato() != null ) {
			getIdContratoAux = contratoAlquilerAd.getIdContrato();
		}

		// Id Alojamiento Registrado
		Integer getIdAlojRegAux = null;
		if (contratoAlquilerAd.getAlojamientoDotacional() != null 
				&& contratoAlquilerAd.getAlojamientoDotacional().getIdAlojReg() !=null) {
			getIdAlojRegAux = contratoAlquilerAd.getAlojamientoDotacional().getIdAlojReg();
		}
		
		List<Object> params = new ArrayList<Object>();
		// Id Alojamiento Registrado
		params.add(getIdAlojRegAux);
		int ultimoContrato = this.jdbcTemplate.queryForInt(query,
				params.toArray());

		// Si el valor devuelto por la query coincide con el de nuestro
		// contrato, estamos en el ultimo contrato. Si no, no.
		int numContratoModificado = 0;
		if (contratoAlquilerAd.getNumContrato() != null) {
			numContratoModificado = contratoAlquilerAd.getNumContrato().intValue();
		}
		
		
		if (ultimoContrato <= numContratoModificado) {
			params = new ArrayList<Object>();
			// Fecha Inicio
			params.add(contratoAlquilerAd.getFecInicio());
			// Ultimo contrato -> la fecha inicio debe ser mayor que la fecha
			// inicio del resto de contratos
			String query2;
			if (getIdContratoAux==null){
				query2 = ContratoAlquileradDaoSql.SQL_FECHA_INI_MAYOR_ON_ADD;
			}else{
				query2 = ContratoAlquileradDaoSql.SQL_FECHA_INI_MAYOR_ON_UPDATE;
				// ID Contrato
				params.add(getIdContratoAux);
			}
			// Id Alojamiento Registrado
			params.add(getIdAlojRegAux);
			int resultadoQuery2 = this.jdbcTemplate.queryForInt(query2,
					params.toArray());
			if (resultadoQuery2 > 0) {
				resultado = IberErrorsMsgConstants.FECHA_INICIO_MAYOR;
			}
		} else {
			// No ultimo -> el rango de fechas inicio/fin introducidos debe ser
			// valido
			String query2 = ContratoAlquileradDaoSql.SQL_RANGO_FECHA_INI_FIN;
			params = new ArrayList<Object>();
			// Fecha Inicio
			params.add(contratoAlquilerAd.getFecInicio());
			// Numero contrato del contrato modificado
			params.add(numContratoModificado);
			// Fecha Fin
			params.add(contratoAlquilerAd.getFecFin());
			// Num Contrato
			params.add(numContratoModificado);
			// Id Contrato
			params.add(getIdContratoAux);
			// Id Alojamiento Registrado
			params.add(getIdAlojRegAux);
			int resultadoQuery2 = this.jdbcTemplate.queryForInt(query2,
					params.toArray());
			
			if (resultadoQuery2 > 0) {
				resultado = messageErrorsSource.getMessage(
						IberErrorsMsgConstants.RANGO_FECHAS_NO_VALIDO, null,
						LocaleContextHolder.getLocale());
			}
		}
		return resultado;
	}

	/**
	 * Si estamos modificando el ultimo contrato de la vivienda, se valida si
	 * debemos modificar la fecha fin del contrato anterior, bien porque este
	 * sea nulo o sea superior a la fecha inicio de nuestro contrato, con el día
	 * anterior a la fecha de inicio de nuestro contrato.
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 * @return Integer
	 */
	@Override
	@Transactional(readOnly = true)
	public Integer validarFechaFinContrato(ContratoAlquilerad contratoAlquilerad) {
		Integer resultado = null;
		String query = ContratoAlquileradDaoSql.SQL_FIND_CONTRATO_ANTERIOR;

		// Num Contrato alojamiento dotacional --> 
		Long getNumContratoAux = null;
		if (contratoAlquilerad.getNumContrato() != null	) {
			getNumContratoAux = contratoAlquilerad.getNumContrato();
		}
		
		// Id Alojamiento Registrado
		Integer getIdAlojRegAux = null;
		if (contratoAlquilerad.getAlojamientoDotacional() != null &&
				contratoAlquilerad.getAlojamientoDotacional().getIdAlojReg()!= null) {
			getIdAlojRegAux = contratoAlquilerad.getAlojamientoDotacional().getIdAlojReg();
		}
		
		List<Object> params = new ArrayList<Object>();
		// Fecha Inicio
		params.add(contratoAlquilerad.getFecInicio());
		// Fecha Fin
		params.add(contratoAlquilerad.getFecFin());
		// Fecha Inicio
		params.add(contratoAlquilerad.getFecInicio());
		// Num contrato
		params.add(getNumContratoAux);
		// Id Alojamiento registrado
		params.add(getIdAlojRegAux);

		List<ContratoAlquilerad> resultadoQuery = this.jdbcTemplate.query(
				query.toString(), this.rwMapValidaciones, params.toArray());

		// Si la consulta realizada devuelve un ID_CONTRATO es cuando
		// preguntaremos al usuario sobre la modificacion de la fecha fin del
		// contrato, por lo tanto devolvemos true.
		if (!resultadoQuery.isEmpty()) {
			if ((resultadoQuery.get(0)).getIdContrato() != null
					&& !(resultadoQuery.get(0)).getNumContrato().equals("")) {
				resultado = ((resultadoQuery.get(0)).getNumContrato()).intValue();
			}
		}
		return resultado;
	}

	/**
	 * Updates a single row in the ContratoAlquilerad table.
	 * 
	 * @param contratoAlquilerad
	 *            ContratoAlquilerad
	 * @return ContratoAlquilerad
	 */
	@Override
	public ContratoAlquilerad updateFecFinContratoAnterior(
			ContratoAlquilerad contratoAlquilerad, Integer numContrato) {
		String query = ContratoAlquileradDaoSql.SQL_UPDATE_CONTR_ANTERIOR;

		// Preparar Parametros
		List<Object> params = new ArrayList<Object>();
		// Fecha Fin (restamos un día a la Fecha Inicio del contrato que estamos
		// modificando)
		params.add(FormatUtils.addRemoveDaysToDate(
				contratoAlquilerad.getFecInicio(), -1));
		// CodUsuario
		SQLGenericas.getParamsAbstractClass(params, contratoAlquilerad);
		// num Contrato (numContrato obtenido en la consulta)
		params.add(numContrato);
		// Id Alojamiento registrado
		params.add(contratoAlquilerad.getAlojamientoDotacional().getIdAlojReg());
		this.jdbcTemplate.update(query, params.toArray());
		return contratoAlquilerad;
	}
	
	
	/**
	 * FindForUpdate
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 * @return ContratoAlquiler
	 */
	@Override
	public ContratoAlquilerad findForUpdate(ContratoAlquilerad contratoAlquilerad) {
		ContratoAlquilerad contratoAlquileradBD;
		try {
			contratoAlquileradBD = this.jdbcTemplate.queryForObject(
					ContratoAlquileradDaoSql.SQL_FIND_FOR_UPDATE, this.rwMap,
					contratoAlquilerad.getIdContrato(),
					contratoAlquilerad.getFecHorUltimaModif());
		} catch (EmptyResultDataAccessException e) {
			throw new UFException(IberErrorsMsgConstants.CONCURRENCY_MSG);
		}
		if (contratoAlquileradBD == null) {
			throw new UFException(IberErrorsMsgConstants.CONCURRENCY_MSG);
		}
		return contratoAlquileradBD;
	}
	


	/*
	 * MÉTODOS PRIVADOS
	 */
	 	
	/**
	 * Returns a map with the needed value to create the conditions to filter by 
	 * the ContratoAlquilerad entity 
	 * 
	 * @param contratoalquilerad ContratoAlquilerad
	 *            Bean with the criteria values to filter by.
	 * @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.
	 */
	// CHECKSTYLE:OFF CyclomaticComplexity - Generación de código de UDA
	private Map<String, ?> getWhereMap (ContratoAlquilerad contratoalquilerad){
		
		StringBuilder where = new StringBuilder(
				ContratoAlquileradDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		//TODO verificar este código
		if (contratoalquilerad != null) {
			if (contratoalquilerad.getAlojamientoDotacional() != null) {
				// ALOJ_REG
				if (contratoalquilerad.getAlojamientoDotacional().getIdAlojReg() != null) {
					BDUtils.crearFiltroIgual(
							where,
							params,
							ContratoAlquileradDaoSql.ALIAS_CONTRATOALQAD+".ID_ALOJ_REG",
							contratoalquilerad.getAlojamientoDotacional().getIdAlojReg()
							);
				}
				// NUM_CONTRATO
				if (contratoalquilerad.getNumContrato()>0) {
					BDUtils.crearFiltroIgual(
							where,
							params,
							ContratoAlquileradDaoSql.ALIAS_CONTRATOALQAD+".NUM_CONTRATO",
							contratoalquilerad.getNumContrato()
							);
				}
			}
		}
		
		Map<String, Object> mapWhere = new HashMap<String, Object>();
		mapWhere.put("query", where);
		mapWhere.put("params", params);

		return mapWhere;
	}
	
	
	// CHECKSTYLE:ON CyclomaticComplexity - Generación de código de UDA
	
	/**
	 * Returns a map with the needed value to create the conditions to filter by  
	 * the ContratoAlquilerad entity 
	 * 
	 * @param contratoalquilerad ContratoAlquilerad
	 *            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.
	 */
	// CHECKSTYLE:OFF CyclomaticComplexity - Generación de código de UDA
	private Map<String, Object> getWhereLikeMap (ContratoAlquilerad contratoalquilerad, Boolean startsWith){

		StringBuilder where = new StringBuilder(
				ContratoAlquileradDaoImpl.STRING_BUILDER_INIT);
		List<Object> params = new ArrayList<Object>();

		//TODO verificar como va este método.
		if (contratoalquilerad != null) {
			if (contratoalquilerad.getAlojamientoDotacional() != null) {
				// ALOJ_REG
				if (contratoalquilerad.getAlojamientoDotacional().getIdAlojReg() != null) {
					BDUtils.crearFiltroIgual(
							where,
							params,
							ContratoAlquileradDaoSql.ALIAS_CONTRATOALQAD+".ID_ALOJ_REG",
							contratoalquilerad.getAlojamientoDotacional().getIdAlojReg()
					);
				}
			}
		}

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

		return mapWhere;
		
	}
	// CHECKSTYLE:ON CyclomaticComplexity - Generación de código de UDA
	
	/**
	 * StringBuilder initilization value
	 */
	 public static final int STRING_BUILDER_INIT = 4096;}

