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.PersonaDao;
import com.ejie.m62fb.dao.SQLGenericas;
import com.ejie.m62fb.dao.registroVPP.plsql.M62FuncionesPLSQL;
import com.ejie.m62fb.model.ContratoAlquilerElemento;
import com.ejie.m62fb.model.CuentaBancaria;
import com.ejie.m62fb.model.Elemento;
import com.ejie.m62fb.model.persona.Persona;
import com.ejie.m62fb.model.tipos.TipoContratoAlquiler;
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;

/**
 * ContratoAlquilerElementoDaoImpl generated by UDA, 09-dic-2015 10:41:39.
 * 
XXXX
 */

@Repository
@Transactional
public class ContratoAlquilerElementoDaoImpl implements
		ContratoAlquilerElementoDao {
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private ReloadableResourceBundleMessageSource messageErrorsSource;

	@Autowired
	private PersonaDao personaDao;

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

			ContratoAlquilerElemento contratoAlquilerElemento = new ContratoAlquilerElemento();
			// Id Contrato Alquiler
			contratoAlquilerElemento.setIdContratoAlquiler(UtilsResulSet
					.getBigDecimal(resultSet, "IDCONTRATOALQ"));
			// Id Elemento
			contratoAlquilerElemento.setElemento(new Elemento());
			contratoAlquilerElemento.getElemento().setIdeElemento(
					resultSet.getBigDecimal("IDEELEMENTO"));
			// Persona (idPagador)
			Persona pagadorRenta = new Persona(
					resultSet.getBigDecimal("IDPAGADOR"));
			contratoAlquilerElemento.setPagador(personaDao.find(pagadorRenta));

			// Fecha Envio Contrato
			contratoAlquilerElemento.setFecEnvContrato(resultSet
					.getTimestamp("FECENVCONTRATO"));
			// Fecha Envio Fin Contrato
			contratoAlquilerElemento.setFecEnvFinContrato(resultSet
					.getTimestamp("FECENVFINCONTRATO"));
			// Fecha Inicio Fact
			contratoAlquilerElemento.setFecIniFac(resultSet
					.getTimestamp("FECINIFAC"));
			// Importe Precio Renta
			contratoAlquilerElemento.setImcPrecioRenta(resultSet
					.getBigDecimal("IMCPRECIORENTA"));
			// Importe Fianza
			contratoAlquilerElemento.setImcFianza(resultSet
					.getBigDecimal("IMCFIANZA"));
			// Fecha Entrada Contrato
			contratoAlquilerElemento.setFecEntContrato(resultSet
					.getTimestamp("FECENTCONTRATO"));
			// Fecha Inicio
			contratoAlquilerElemento.setFecInicio(resultSet
					.getTimestamp("FECINICIO"));
			// Fecha Fin
			contratoAlquilerElemento
					.setFecFin(resultSet.getTimestamp("FECFIN"));
			// Cuenta Bancaria
			contratoAlquilerElemento.setCuentaBancaria(new CuentaBancaria());
			contratoAlquilerElemento.getCuentaBancaria().setCodEntidad(
					resultSet.getString("CODENTIDAD"));
			contratoAlquilerElemento.getCuentaBancaria().setCodSucursal(
					resultSet.getString("CODSUCURSAL"));
			contratoAlquilerElemento.getCuentaBancaria().setCodDigitoControl(
					resultSet.getString("CODDIGITOCONTROL"));
			contratoAlquilerElemento.getCuentaBancaria().setCodCuenta(
					resultSet.getString("CODCUENTA"));
			// Indicador Visado
			contratoAlquilerElemento.setIndVisado(UtilsResulSet.getIndicadorSN(
					resultSet, "INDVISADO"));
			// Fecha Visado
			contratoAlquilerElemento.setFecVisado(resultSet
					.getTimestamp("FECVISADO"));
			// Fecha Empadronamiento
			contratoAlquilerElemento.setFecEmpadron(resultSet
					.getTimestamp("FECEMPADRON"));
			// Tipo Contrato Alquiler
			TipoContratoAlquiler tipoContratoAlquiler = new TipoContratoAlquiler(
					resultSet.getString("CODTIPOCONTRATO"));
			tipoContratoAlquiler.setDescripcionEs(resultSet
					.getString("DESCTIPOCONTRATOES"));
			tipoContratoAlquiler.setDescripcionEu(resultSet
					.getString("DESCTIPOCONTRATOEU"));
			contratoAlquilerElemento
					.setTipoContratoAlquiler(tipoContratoAlquiler);
			// Observaciones
			contratoAlquilerElemento.setTexObservaciones(resultSet
					.getString("TEXOBSERVACIONES"));
			// Direccion
			contratoAlquilerElemento.setDireccion(UtilsResulSet
					.getDireccionCompleta(resultSet, null));
			// Nif Pagador
			contratoAlquilerElemento.setNifPagadorRenta(resultSet
					.getString("NIFPAGADORRENTA"));

			// AbstractClass
			UtilsResulSet.getAbstractClass(resultSet, contratoAlquilerElemento,
					ContratoAlquilerElementoDaoSql.ALIAS_CONTRATOALQELEM);

			return contratoAlquilerElemento;
		}
	};

	private final RowMapper<ContratoAlquilerElemento> rwMapPK = new RowMapper<ContratoAlquilerElemento>() {
		@Override
		public ContratoAlquilerElemento mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			return new ContratoAlquilerElemento(
					resultSet.getBigDecimal("IDCONTRATOALQ"));
		}
	};

	private final RowMapper<ContratoAlquilerElemento> rwMapValidaciones = new RowMapper<ContratoAlquilerElemento>() {
		@Override
		public ContratoAlquilerElemento mapRow(ResultSet resultSet, int rowNum)
				throws SQLException {
			ContratoAlquilerElemento contratoAlquilerElemento = new ContratoAlquilerElemento();

			// Id Contrato Alquiler
			contratoAlquilerElemento.setIdContratoAlquiler(resultSet
					.getBigDecimal("IDCONTRATOALQ"));

			return contratoAlquilerElemento;
		}
	};

	/**
	 * 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 ContratoAlquilerElemento table.
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento
	 * @return ContratoAlquilerElemento
	 */
	@Override
	public ContratoAlquilerElemento add(
			ContratoAlquilerElemento contratoalquilerelemento) {
		String query = ContratoAlquilerElementoDaoSql.SQL_INSERT;
		// Campos para la generación del contrato vivienda
		// Id Elemento
		BigDecimal getIdElementoAux = null;
		if (contratoalquilerelemento.getElemento() != null
				&& contratoalquilerelemento.getElemento().getIdeElemento() != null) {
			getIdElementoAux = contratoalquilerelemento.getElemento()
					.getIdeElemento();
		}
		// Id Pagador
		BigDecimal getIdPagador = null;
		if (contratoalquilerelemento.getPagador() != null
				&& contratoalquilerelemento.getPagador().getIdPersona() != null) {
			getIdPagador = contratoalquilerelemento.getPagador().getIdPersona();
		}
		// Codigo Entidad
		String getCodEntidad = null;
		if (contratoalquilerelemento.getCuentaBancaria() != null
				&& contratoalquilerelemento.getCuentaBancaria().getCodEntidad() != null) {
			getCodEntidad = contratoalquilerelemento.getCuentaBancaria()
					.getCodEntidad();
		}
		// Codigo Sucursal
		String getCodSucursal = null;
		if (contratoalquilerelemento.getCuentaBancaria() != null
				&& contratoalquilerelemento.getCuentaBancaria()
						.getCodSucursal() != null) {
			getCodSucursal = contratoalquilerelemento.getCuentaBancaria()
					.getCodSucursal();
		}
		// Codigo Digito Control
		String getCodDigitoControl = null;
		if (contratoalquilerelemento.getCuentaBancaria() != null
				&& contratoalquilerelemento.getCuentaBancaria()
						.getCodDigitoControl() != null) {
			getCodDigitoControl = contratoalquilerelemento.getCuentaBancaria()
					.getCodDigitoControl();
		}
		// Codigo Cuenta
		String getCodCuenta = null;
		if (contratoalquilerelemento.getCuentaBancaria() != null
				&& contratoalquilerelemento.getCuentaBancaria().getCodCuenta() != null) {
			getCodCuenta = contratoalquilerelemento.getCuentaBancaria()
					.getCodCuenta();
		}
		// Tipo Contrato Alquiler (codigo)
		String getCodTipoContrato = null;
		if (contratoalquilerelemento.getTipoContratoAlquiler() != null
				&& contratoalquilerelemento.getTipoContratoAlquiler()
						.getCodTabla() != null) {
			getCodTipoContrato = contratoalquilerelemento
					.getTipoContratoAlquiler().getCodTabla();
		}

		// Preparar Parametros
		List<Object> params = new ArrayList<Object>();
		// Id Contrato Alquiler
		params.add(contratoalquilerelemento.getIdContratoAlquiler());
		// Id Elemento
		params.add(getIdElementoAux);
		// Id Pagador
		params.add(getIdPagador);
		// Fecha Envio Contrato
		params.add(contratoalquilerelemento.getFecEnvContrato());
		// Fecha Envio Fin Contrato
		params.add(contratoalquilerelemento.getFecEnvFinContrato());
		// Fecha Inicio Fact
		params.add(contratoalquilerelemento.getFecIniFac());
		// Importe Precio Renta
		params.add(contratoalquilerelemento.getImcPrecioRenta());
		// Importe Fianza
		params.add(contratoalquilerelemento.getImcFianza());
		// Fecha Entrada Contrato
		params.add(contratoalquilerelemento.getFecEntContrato());
		// Fecha Inicio
		params.add(contratoalquilerelemento.getFecInicio());
		// Fecha Fin
		params.add(contratoalquilerelemento.getFecFin());
		// Codigo Entidad
		params.add(getCodEntidad);
		// Codigo Sucursal
		params.add(getCodSucursal);
		// Codigo Digito Control
		params.add(getCodDigitoControl);
		// Codigo Cuenta
		params.add(getCodCuenta);
		// Indicador Visado
		params.add(contratoalquilerelemento.getIndVisado());
		// Fecha Visado
		params.add(contratoalquilerelemento.getFecVisado());
		// Fecha Empadronamiento
		params.add(contratoalquilerelemento.getFecEmpadron());
		// Tipo Contrato Alquiler (codigo)
		params.add(getCodTipoContrato);
		// Texto Observaciones
		params.add(contratoalquilerelemento.getTexObservaciones());

		// Direccion
		SQLGenericas.getParamsDireccion(params,
				contratoalquilerelemento.getDireccion());
		// CodUsuario
		SQLGenericas.getParamsAbstractClass(params, contratoalquilerelemento);

		this.jdbcTemplate.update(query, params.toArray());

		return contratoalquilerelemento;
	}

	/**
	 * Updates a single row in the ContratoAlquilerElemento table.
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento
	 * @return ContratoAlquilerElemento
	 */
	@Override
	public ContratoAlquilerElemento update(
			ContratoAlquilerElemento contratoalquilerelemento) {
		String query = ContratoAlquilerElementoDaoSql.SQL_UPDATE;
		// Campos para la generación del contrato vivienda
		// Id Elemento
		BigDecimal getIdElementoAux = null;
		if (contratoalquilerelemento.getElemento() != null
				&& contratoalquilerelemento.getElemento().getIdeElemento() != null) {
			getIdElementoAux = contratoalquilerelemento.getElemento()
					.getIdeElemento();
		}
		// Id Pagador
		BigDecimal getIdPagador = null;
		if (contratoalquilerelemento.getPagador() != null
				&& contratoalquilerelemento.getPagador().getIdPersona() != null) {
			getIdPagador = contratoalquilerelemento.getPagador().getIdPersona();
		}
		// Codigo Entidad
		String getCodEntidad = null;
		if (contratoalquilerelemento.getCuentaBancaria() != null
				&& contratoalquilerelemento.getCuentaBancaria().getCodEntidad() != null) {
			getCodEntidad = contratoalquilerelemento.getCuentaBancaria()
					.getCodEntidad();
		}
		// Codigo Sucursal
		String getCodSucursal = null;
		if (contratoalquilerelemento.getCuentaBancaria() != null
				&& contratoalquilerelemento.getCuentaBancaria()
						.getCodSucursal() != null) {
			getCodSucursal = contratoalquilerelemento.getCuentaBancaria()
					.getCodSucursal();
		}
		// Codigo Digito Control
		String getCodDigitoControl = null;
		if (contratoalquilerelemento.getCuentaBancaria() != null
				&& contratoalquilerelemento.getCuentaBancaria()
						.getCodDigitoControl() != null) {
			getCodDigitoControl = contratoalquilerelemento.getCuentaBancaria()
					.getCodDigitoControl();
		}
		// Codigo Cuenta
		String getCodCuenta = null;
		if (contratoalquilerelemento.getCuentaBancaria() != null
				&& contratoalquilerelemento.getCuentaBancaria().getCodCuenta() != null) {
			getCodCuenta = contratoalquilerelemento.getCuentaBancaria()
					.getCodCuenta();
		}
		// Tipo Contrato Alquiler (codigo)
		String getCodTipoContrato = null;
		if (contratoalquilerelemento.getTipoContratoAlquiler() != null
				&& contratoalquilerelemento.getTipoContratoAlquiler()
						.getCodTabla() != null) {
			getCodTipoContrato = contratoalquilerelemento
					.getTipoContratoAlquiler().getCodTabla();
		}

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

		// Id Elemento
		params.add(getIdElementoAux);
		// Id Pagador
		params.add(getIdPagador);
		// Fecha Envio Contrato
		params.add(contratoalquilerelemento.getFecEnvContrato());
		// Fecha Envio Fin Contrato
		params.add(contratoalquilerelemento.getFecEnvFinContrato());
		// Fecha Inicio Fact
		params.add(contratoalquilerelemento.getFecIniFac());
		// Importe Precio Renta
		params.add(contratoalquilerelemento.getImcPrecioRenta());
		// Importe Fianza
		params.add(contratoalquilerelemento.getImcFianza());
		// Fecha Entrada Contrato
		params.add(contratoalquilerelemento.getFecEntContrato());
		// Fecha Inicio
		params.add(contratoalquilerelemento.getFecInicio());
		// Fecha Fin
		params.add(contratoalquilerelemento.getFecFin());
		// Codigo Entidad
		params.add(getCodEntidad);
		// Codigo Sucursal
		params.add(getCodSucursal);
		// Codigo Digito Control
		params.add(getCodDigitoControl);
		// Codigo Cuenta
		params.add(getCodCuenta);
		// Indicador Visado
		params.add(contratoalquilerelemento.getIndVisado());
		// Fecha Visado
		params.add(contratoalquilerelemento.getFecVisado());
		// Fecha Empadronamiento
		params.add(contratoalquilerelemento.getFecEmpadron());
		// Tipo Contrato Alquiler (codigo)
		params.add(getCodTipoContrato);
		// Texto Observaciones
		params.add(contratoalquilerelemento.getTexObservaciones());

		// Direccion
		SQLGenericas.getParamsDireccion(params,
				contratoalquilerelemento.getDireccion());
		// CodUsuario
		SQLGenericas.getParamsAbstractClass(params, contratoalquilerelemento);

		// Id Contrato Alquiler
		params.add(contratoalquilerelemento.getIdContratoAlquiler());

		this.jdbcTemplate.update(query, params.toArray());

		return contratoalquilerelemento;
	}

	/**
	 * Finds a single row in the ContratoAlquilerElemento table.
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento
	 * @return ContratoAlquilerElemento
	 */
	@Override
	@Transactional(readOnly = true)
	public ContratoAlquilerElemento find(
			ContratoAlquilerElemento contratoalquilerelemento) {
		String query = ContratoAlquilerElementoDaoSql.SQL_FIND;

		List<ContratoAlquilerElemento> contratoalquilerelementoList = this.jdbcTemplate
				.query(query, this.rwMap,
						contratoalquilerelemento.getIdContratoAlquiler());
		return DataAccessUtils.uniqueResult(contratoalquilerelementoList);
	}

	/**
	 * FindForUpdate
	 * 
	 * @param contratoAlquilerElemento
	 *            ContratoAlquilerElemento
	 * @return ContratoAlquilerElemento
	 */
	@Override
	public ContratoAlquilerElemento findForUpdate(
			ContratoAlquilerElemento contratoAlquilerElemento) {
		ContratoAlquilerElemento contratoAlquilerElementoBD;
		try {
			contratoAlquilerElementoBD = this.jdbcTemplate.queryForObject(
					ContratoAlquilerElementoDaoSql.SQL_FIND_FOR_UPDATE,
					this.rwMap,
					contratoAlquilerElemento.getIdContratoAlquiler(),
					contratoAlquilerElemento.getFecHorUltimaModif());
		} catch (EmptyResultDataAccessException e) {
			throw new UFException(IberErrorsMsgConstants.CONCURRENCY_MSG);
		}
		if (contratoAlquilerElementoBD == null) {
			throw new UFException(IberErrorsMsgConstants.CONCURRENCY_MSG);
		}
		return contratoAlquilerElementoBD;
	}

	/**
	 * Removes a single row in the ContratoAlquilerElemento table.
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento
	 * @return
	 */
	@Override
	public void remove(ContratoAlquilerElemento contratoalquilerelemento) {
		/*****
		 * Llamada a function que implementa llamada a plsql
		 ****/
		M62FuncionesPLSQL m62FuncionesPLSQL = new M62FuncionesPLSQL(
				this.jdbcTemplate.getDataSource());
		m62FuncionesPLSQL.borrarContratoElemento(contratoalquilerelemento
				.getIdContratoAlquiler());
	}

	/**
	 * Finds a list of rows in the ContratoAlquilerElemento table.
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<ContratoAlquilerElemento>
	 */
	@Override
	@Transactional(readOnly = true)
	public List<ContratoAlquilerElemento> findAll(
			ContratoAlquilerElemento contratoalquilerelemento,
			JQGridRequestDto jqGridRequestDto) {
		StringBuilder query = new StringBuilder(
				ContratoAlquilerElementoDaoSql.SQL_FIND_ALL);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(contratoalquilerelemento);
		StringBuilder where = new StringBuilder(
				ContratoAlquilerElementoDaoSql.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());
	}

	/**
	 * Finds rows in the ContratoAlquilerElemento table using like.
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<ContratoAlquilerElemento>
	 */
	@Override
	@Transactional(readOnly = true)
	public List<ContratoAlquilerElemento> findAllLike(
			ContratoAlquilerElemento contratoalquilerelemento,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				ContratoAlquilerElementoDaoSql.SQL_FIND_ALL);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(
				contratoalquilerelemento, startsWith);
		StringBuilder where = new StringBuilder(
				ContratoAlquilerElementoDaoSql.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 ContratoAlquilerElemento table.
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento
	 * @return Long
	 */
	@Override
	@Transactional(readOnly = true)
	public Long findAllCount(ContratoAlquilerElemento contratoalquilerelemento) {
		StringBuilder query = new StringBuilder(
				ContratoAlquilerElementoDaoSql.SQL_FIND_ALL_COUNT);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(contratoalquilerelemento);
		StringBuilder where = new StringBuilder(
				ContratoAlquilerElementoDaoSql.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 ContratoAlquilerElemento table using like.
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento
	 * @param startsWith
	 *            Boolean
	 * @return Long
	 */
	@Override
	@Transactional(readOnly = true)
	public Long findAllLikeCount(
			ContratoAlquilerElemento contratoalquilerelemento,
			Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				ContratoAlquilerElementoDaoSql.SQL_FIND_ALL_COUNT);

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(
				contratoalquilerelemento, startsWith);
		StringBuilder where = new StringBuilder(
				ContratoAlquilerElementoDaoSql.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 ContratoAlquilerElemento selected for rup_table
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<ContratoAlquilerElemento>>
	 */
	@Override
	public List<TableRowDto<ContratoAlquilerElemento>> reorderSelection(
			ContratoAlquilerElemento contratoalquilerelemento,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		// SELECT
		StringBuilder query = new StringBuilder(
				ContratoAlquilerElementoDaoSql.SQL_FIND_ALL);

		// FILTRADO
		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(
				contratoalquilerelemento, startsWith);
		StringBuilder where = new StringBuilder(
				ContratoAlquilerElementoDaoSql.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, ContratoAlquilerElemento.class,
				filterParamList, ContratoAlquilerElementoDaoSql.PK);

		return this.jdbcTemplate.query(sbReorderSelectionSQL.toString(),
				new RowNumResultSetExtractor<ContratoAlquilerElemento>(
						this.rwMapPK, jqGridRequestDto), filterParamList
						.toArray());
	}

	/**
	 * Returns a BigDecimal. Máximo ID_CONTRATO_ALQ que hay para un elemento en
	 * la tabla CONTRATO_ALQUILER_ELEMENTO e incrementandolo en 1.
	 * 
	 * @param idElemento
	 *            BigDecimal
	 * @return BigDecimal
	 */
	@Override
	@Transactional(readOnly = true)
	public BigDecimal findIdContratoAlquilerMaxMasUno(BigDecimal idElemento) {
		StringBuilder query = new StringBuilder(
				ContratoAlquilerElementoDaoSql.SQL_FIND_IDCONTRATOALQ_MAX);
		Long registrosCount = this.jdbcTemplate.queryForLong(query.toString(),
				idElemento);
		return new BigDecimal(registrosCount);

	}

	/**
	 * 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 contratoAlquilerElemento
	 *            ContratoAlquilerElemento
	 * @return String
	 */
	@Override
	@Transactional(readOnly = true)
	public String validarFechasIniFin(
			ContratoAlquilerElemento contratoAlquilerElemento) {
		String resultado = null;
		String query = ContratoAlquilerElementoDaoSql.SQL_FIND_ULTIMO_CONTRATO;

		// Id Elemento
		BigDecimal getIdElementoAux = null;
		if (contratoAlquilerElemento.getElemento() != null
				&& contratoAlquilerElemento.getElemento().getIdeElemento() != null) {
			getIdElementoAux = contratoAlquilerElemento.getElemento()
					.getIdeElemento();
		}

		List<Object> params = new ArrayList<Object>();
		// Id Elemento
		params.add(getIdElementoAux);
		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 idContratoAlqModificado = 0;
		if (contratoAlquilerElemento.getIdContratoAlquiler() != null) {
			idContratoAlqModificado = contratoAlquilerElemento
					.getIdContratoAlquiler().intValue();
		}
		if (ultimoContrato == idContratoAlqModificado
				|| idContratoAlqModificado == 0) {
			// Ultimo contrato (o cuando estamos en el ALTA) -> la fecha inicio
			// debe ser mayor que la fecha inicio del resto de contratos
			String query2 = ContratoAlquilerElementoDaoSql.SQL_FECHA_INI_MAYOR;
			params = new ArrayList<Object>();
			// Fecha Inicio
			params.add(contratoAlquilerElemento.getFecInicio());
			// Id Contrato Alquiler
			params.add(contratoAlquilerElemento.getIdContratoAlquiler());
			// Id Elemento
			params.add(getIdElementoAux);
			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 = ContratoAlquilerElementoDaoSql.SQL_RANGO_FECHA_INI_FIN;
			params = new ArrayList<Object>();
			// Fecha Inicio
			params.add(contratoAlquilerElemento.getFecInicio());
			// Id Contrato Alquiler
			params.add(contratoAlquilerElemento.getIdContratoAlquiler());
			// Fecha Fin
			params.add(contratoAlquilerElemento.getFecFin());
			// Id Contrato Alquiler
			params.add(contratoAlquilerElemento.getIdContratoAlquiler());
			// Id Contrato Alquiler
			params.add(contratoAlquilerElemento.getIdContratoAlquiler());
			// Id Elemento
			params.add(getIdElementoAux);
			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 contratoAlquilerElemento
	 *            ContratoAlquilerElemento
	 * @return Integer
	 */
	@Override
	@Transactional(readOnly = true)
	public Integer validarFechaFinContrato(
			ContratoAlquilerElemento contratoAlquilerElemento) {
		Integer resultado = null;
		String query = ContratoAlquilerElementoDaoSql.SQL_FIND_CONTRATO_ANTERIOR;

		// Id Elemento
		BigDecimal getIdElementoAux = null;
		if (contratoAlquilerElemento.getElemento() != null
				&& contratoAlquilerElemento.getElemento().getIdeElemento() != null) {
			getIdElementoAux = contratoAlquilerElemento.getElemento()
					.getIdeElemento();
		}
		// Id Contrato Alquiler
		BigDecimal getIdContratoAlquilerAux = null;
		if (contratoAlquilerElemento.getIdContratoAlquiler() != null) {
			getIdContratoAlquilerAux = contratoAlquilerElemento
					.getIdContratoAlquiler();
		} else {
			getIdContratoAlquilerAux = this
					.findIdContratoAlquilerMaxMasUno(getIdElementoAux);
		}
		List<Object> params = new ArrayList<Object>();
		// Fecha Inicio
		params.add(contratoAlquilerElemento.getFecInicio());
		// Fecha Fin
		params.add(contratoAlquilerElemento.getFecFin());
		// Fecha Inicio
		params.add(contratoAlquilerElemento.getFecInicio());
		// Id Contrato Alquiler
		params.add(getIdContratoAlquilerAux);
		// Id Elemento
		params.add(getIdElementoAux);

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

		// Si la consulta realizada devuelve un ID_CONTRATO_ALQ 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)).getIdContratoAlquiler() != null
					&& !(resultadoQuery.get(0)).getIdContratoAlquiler().equals(
							"")) {
				resultado = ((resultadoQuery.get(0)).getIdContratoAlquiler())
						.intValue();
			}
		}
		return resultado;
	}

	/**
	 * Updates a single row in the ContratoAlquilerElemento table.
	 * 
	 * @param contratoAlquilerElemento
	 *            ContratoAlquilerElemento
	 * @param idContratoAlquiler
	 *            Integer
	 * @return ContratoAlquilerElemento
	 */
	@Override
	public ContratoAlquilerElemento updateFecFinContratoAnterior(
			ContratoAlquilerElemento contratoAlquilerElemento,
			Integer idContratoAlquiler) {
		String query = ContratoAlquilerElementoDaoSql.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(
				contratoAlquilerElemento.getFecInicio(), -1));
		// CodUsuario
		SQLGenericas.getParamsAbstractClass(params, contratoAlquilerElemento);

		// Id Contrato (idContrato obtenido en la consulta)
		params.add(idContratoAlquiler);

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

	/*
	 * MÉTODOS PRIVADOS
	 */

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the ContratoAlquilerElemento entity
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento 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(
			ContratoAlquilerElemento contratoalquilerelemento) {

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

		if (contratoalquilerelemento != null) {
			// Id Contrato Alquiler
			if (contratoalquilerelemento.getIdContratoAlquiler() != null) {
				BDUtils.crearFiltroIgual(where, params,
						"CONTRATOALQELEM.ID_CONTRATO_ALQ",
						contratoalquilerelemento.getIdContratoAlquiler());
			}
			// Id Elemento
			if (contratoalquilerelemento.getElemento() != null
					&& contratoalquilerelemento.getElemento().getIdeElemento() != null) {
				BDUtils.crearFiltroIgual(where, params,
						"CONTRATOALQELEM.IDE_ELEMENTO",
						contratoalquilerelemento.getElemento().getIdeElemento());
			}
		}

		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 ContratoAlquilerElemento entity
	 * 
	 * @param contratoalquilerelemento
	 *            ContratoAlquilerElemento 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(
			ContratoAlquilerElemento contratoalquilerelemento,
			Boolean startsWith) {

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

		if (contratoalquilerelemento != null) {
			// Id Contrato Alquiler
			if (contratoalquilerelemento.getIdContratoAlquiler() != null) {
				BDUtils.crearFiltroIgual(where, params,
						"CONTRATOALQELEM.ID_CONTRATO_ALQ",
						contratoalquilerelemento.getIdContratoAlquiler());
			}
			// Id Elemento
			if (contratoalquilerelemento.getElemento() != null
					&& contratoalquilerelemento.getElemento().getIdeElemento() != null) {
				BDUtils.crearFiltroIgual(where, params,
						"CONTRATOALQELEM.IDE_ELEMENTO",
						contratoalquilerelemento.getElemento().getIdeElemento());
			}
		}

		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;
}
