package com.ejie.ab39a.dao;

import com.ejie.x38.dao.RowNumResultSetExtractor;
import com.ejie.x38.dto.JQGridManager;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.TableRowDto;
import com.gfi.constants.Constants;
import com.gfi.utils.UtilSQL;
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.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.ab39a.constantes.Constantes;
import com.ejie.ab39a.constantes.SecuenciasSQL;
import com.ejie.ab39a.model.Entidades;
import com.ejie.ab39a.model.TecnicosEntidad;
import com.ejie.ab39a.model.TiposIdentif;

/**
 * TecnicosEntidadDaoImpl.
 * 
 *  
 */

@Repository
@Transactional
public class TecnicosEntidadDaoImpl implements TecnicosEntidadDao {

	private static final String[] ORDER_BY_WHITE_LIST = new String[] { "CODTECNICO", "BAJA", "DOCIDENTIFICACION",
			"NOMBRE", "APE1", "APE2", "TELEFONO1", "TELEFONO2", "EMAIL", "SEXO", "CALLE", "NUMCALLE", "CODPOSTAL",
			"MUNICIPIO", "PROVINCIA", "DIRECCIONESENTIDADES", "TIPOIDENTIF" };

	private JdbcTemplate jdbcTemplate;

	/*
	 * ROW_MAPPERS
	 */
	private RowMapper<TecnicosEntidad> rwMap = new RowMapper<TecnicosEntidad>() {
		@Override
		public TecnicosEntidad mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new TecnicosEntidad(resultSet.getInt("CODTECNICO"), resultSet.getInt("BAJA"),
					new TiposIdentif(resultSet.getLong("TIPOIDENTIF")), resultSet.getString("DOCIDENTIFICACION"),
					resultSet.getString("NOMBRE"), resultSet.getString("APE1"), resultSet.getString("APE2"),
					resultSet.getString("TELEFONO1"), resultSet.getString("TELEFONO2"), resultSet.getString("EMAIL"),
					resultSet.getString("SEXO"), resultSet.getString("CALLE"), resultSet.getString("NUMCALLE"),
					resultSet.getString("CODPOSTAL"), resultSet.getString("MUNICIPIO"),
					resultSet.getString("PROVINCIA"), "", resultSet.getString("LOCALIDAD"));
		}
	};

	private RowMapper<TecnicosEntidad> rwMapLike = new RowMapper<TecnicosEntidad>() {
		@Override
		public TecnicosEntidad mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new TecnicosEntidad(resultSet.getInt("CODTECNICO"), resultSet.getInt("BAJA"),
					new TiposIdentif(resultSet.getLong("TIPOIDENTIF")), resultSet.getString("DOCIDENTIFICACION"),
					resultSet.getString("NOMBRE"), resultSet.getString("APE1"), resultSet.getString("APE2"),
					resultSet.getString("TELEFONO1"), resultSet.getString("TELEFONO2"), resultSet.getString("EMAIL"),
					resultSet.getString("SEXO"), resultSet.getString("CALLE"), resultSet.getString("NUMCALLE"),
					resultSet.getString("CODPOSTAL"), resultSet.getString("MUNICIPIO"),
					resultSet.getString("PROVINCIA"), resultSet.getString("DIRECCIONESENTIDADES"),
					resultSet.getString("DESCPROVINCIA"), resultSet.getString("DESCMUNICIPIO"),
					resultSet.getString("LOCALIDAD"), resultSet.getString("DESCLOCALIDAD"));
		}
	};

	private RowMapper<TecnicosEntidad> rwMapPK = new RowMapper<TecnicosEntidad>() {
		@Override
		public TecnicosEntidad mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new TecnicosEntidad(resultSet.getInt("CODTECNICO"));
		}
	};

	/**
	 * 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 TecnicosEntidad table.
	 *
	 * @param tecnicosentidad
	 *            TecnicosEntidad
	 * @return TecnicosEntidad
	 */
	@Override
	public TecnicosEntidad add(TecnicosEntidad tecnicosentidad) {
		StringBuilder query = new StringBuilder(Constantes.STRING_BUILDER_INIT);
		query.append(
				"INSERT INTO TECNICOS_ENTIDAD (CODTECNICO, TIPOIDENTIF, DOCIDENTIFICACION, NOMBRE, APE1, APE2, TELEFONO1, TELEFONO2, EMAIL, SEXO, CALLE, NUMCALLE, CODPOSTAL, MUNICIPIO, PROVINCIA,LOCALIDAD) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");

		Integer idTecnico = SecuenciasSQL.TECNICOSENTIDAD.getNextInteger(jdbcTemplate);
		tecnicosentidad.setCodtecnico(idTecnico);

		this.jdbcTemplate.update(query.toString(), tecnicosentidad.getCodtecnico(),
				tecnicosentidad.getTipoIdentif().getCodigo(), tecnicosentidad.getDocidentificacion(),
				tecnicosentidad.getNombre(), tecnicosentidad.getApe1(), tecnicosentidad.getApe2(),
				tecnicosentidad.getTelefono1(), tecnicosentidad.getTelefono2(), tecnicosentidad.getEmail(),
				tecnicosentidad.getSexo(), tecnicosentidad.getCalle(), tecnicosentidad.getNumcalle(),
				tecnicosentidad.getCodpostal(), tecnicosentidad.getCodmun(), tecnicosentidad.getCodth(),
				tecnicosentidad.getCodloc());
		return tecnicosentidad;
	}

	/**
	 * Updates a single row in the TecnicosEntidad table.
	 *
	 * @param tecnicosentidad
	 *            TecnicosEntidad
	 * @return TecnicosEntidad
	 */
	@Override
	public TecnicosEntidad update(TecnicosEntidad tecnicosentidad) {
		StringBuilder query = new StringBuilder(
				"UPDATE TECNICOS_ENTIDAD SET TIPOIDENTIF=?, DOCIDENTIFICACION=?, NOMBRE=?, APE1=?, APE2=?, TELEFONO1=?, TELEFONO2=?, EMAIL=?, SEXO=?, CALLE=?, NUMCALLE=?, CODPOSTAL=?, MUNICIPIO=?, PROVINCIA=?,LOCALIDAD=? ");
		query.append(" WHERE CODTECNICO=?");
		this.jdbcTemplate.update(query.toString(), tecnicosentidad.getTipoIdentif().getCodigo(),
				tecnicosentidad.getDocidentificacion(), tecnicosentidad.getNombre(), tecnicosentidad.getApe1(),
				tecnicosentidad.getApe2(), tecnicosentidad.getTelefono1(), tecnicosentidad.getTelefono2(),
				tecnicosentidad.getEmail(), tecnicosentidad.getSexo(), tecnicosentidad.getCalle(),
				tecnicosentidad.getNumcalle(), tecnicosentidad.getCodpostal(), tecnicosentidad.getCodmun(),
				tecnicosentidad.getCodth(), tecnicosentidad.getCodloc(), tecnicosentidad.getCodtecnico());
		return tecnicosentidad;
	}

	/**
	 * Guarda las entidades del tecnico.
	 *
	 * @param tecnicosentidad
	 *            TecnicosEntidad
	 * @return TecnicosEntidad
	 */
	@Override
	public TecnicosEntidad guardarEntidadesTecnico(Entidades entidad) {
		TecnicosEntidad tecnicosentidad = new TecnicosEntidad();
		StringBuilder query = new StringBuilder("INSERT INTO ENTIDAD_TECNICO (CODENTIDAD, CODTECNICO) VALUES(?,?) ");
		query.append(" ");
		this.jdbcTemplate.update(query.toString(), entidad.getCodentidad(),
				entidad.getTecnicosEntidad().getCodtecnico());
		return tecnicosentidad;
	}

	/**
	 * Finds a single row in the TecnicosEntidad table.
	 *
	 * @param tecnicosentidad
	 *            TecnicosEntidad
	 * @return TecnicosEntidad
	 */
	@Override
	@Transactional(readOnly = true)
	public TecnicosEntidad find(TecnicosEntidad tecnicosentidad) {
		// SELECT - FROM
		StringBuilder query = new StringBuilder(
				"SELECT t1.CODTECNICO CODTECNICO, t1.BAJA BAJA, t1.TIPOIDENTIF TIPOIDENTIF, t1.DOCIDENTIFICACION DOCIDENTIFICACION, t1.NOMBRE NOMBRE, t1.APE1 APE1, t1.APE2 APE2, t1.TELEFONO1 TELEFONO1, t1.TELEFONO2 TELEFONO2, t1.EMAIL EMAIL, t1.SEXO SEXO, t1.CALLE CALLE, t1.NUMCALLE NUMCALLE, t1.CODPOSTAL CODPOSTAL, t1.MUNICIPIO MUNICIPIO, t1.PROVINCIA PROVINCIA,t1.LOCALIDAD LOCALIDAD ");
		// FROM
		query.append(" FROM TECNICOS_ENTIDAD t1 ");
		// WHERE
		query.append(" WHERE t1.CODTECNICO = ?  ");

		List<TecnicosEntidad> tecnicosentidadList = this.jdbcTemplate.query(query.toString(), this.rwMap,
				tecnicosentidad.getCodtecnico());
		return DataAccessUtils.uniqueResult(tecnicosentidadList);
	}

	/**
	 * Removes a single row in the TecnicosEntidad table.
	 *
	 * @param tecnicosentidad
	 *            TecnicosEntidad
	 */
	@Override
	public void remove(TecnicosEntidad tecnicosentidad) {
		String query = "UPDATE TECNICOS_ENTIDAD SET BAJA=? WHERE CODTECNICO=?";
		int estado = Constantes.BAJA_LOGICA;
		if (tecnicosentidad.getBaja() == Constantes.BAJA_LOGICA) {
			estado = Constantes.ALTA_LOGICA;
		} else if (tecnicosentidad.getBaja() == Constantes.ALTA_LOGICA) {
			estado = Constantes.BAJA_LOGICA;
		}
		this.jdbcTemplate.update(query, estado, tecnicosentidad.getCodtecnico());
	}

	/**
	 * 
	 * @param tecnicosentidad
	 */
	@Override
	public void borrarEntidadTecnico(Integer codtecnico, Integer codentidad) {
		String query = "DELETE FROM ENTIDAD_TECNICO WHERE CODTECNICO=? AND CODENTIDAD=?";
		this.jdbcTemplate.update(query, codtecnico, codentidad);
	}

	/**
	 * Finds a list of rows in the TecnicosEntidad table.
	 * 
	 * @param tecnicosEntidad
	 *            TecnicosEntidad
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<TecnicosEntidad>
	 */
	@Override
	@Transactional(readOnly = true)
	public List<TecnicosEntidad> findAll(TecnicosEntidad tecnicosEntidad, JQGridRequestDto jqGridRequestDto) {
		// SELECT - FROM
		boolean incluirDescripcionDireccion = true;

		StringBuilder query = new StringBuilder(this.getSelectFromQuery(true, incluirDescripcionDireccion));

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(tecnicosEntidad);
		StringBuilder where = new StringBuilder(Constantes.STRING_BUILDER_INIT);
		// " WHERE t5.CODTECNICO(+) = t1.CODTECNICO AND t5.CODENTIDAD =
		// t2.CODENTIDAD AND t3.ID_PROVINCIA(+) = t2.CODTH AND
		// t4.ID_MUNICIPIO(+) = t2.CODMUN AND t4.ID_PROVINCIA(+) = t2.CODTH ");

		where.append(" WHERE ");
		where.append(" t5.CODTECNICO(+) = t1.CODTECNICO  ");
		where.append(" AND t2.CODENTIDAD(+) = t5.CODENTIDAD ");

		where.append(" AND t10.ID_PROVINCIA(+)= t1.PROVINCIA  ");
		where.append(" AND t11.ID_PROVINCIA(+)= t1.PROVINCIA ");
		where.append(" AND t11.ID_MUNICIPIO(+)= t1.MUNICIPIO  ");
		where.append(" AND t1.PROVINCIA  = t13.ID_PROVINCIA(+)  ");
		where.append(" AND t1.MUNICIPIO  = t13.ID_MUNICIPIO(+)  ");
		where.append(" AND t1.LOCALIDAD  = t13.ID_LOCALIDAD(+) ");

		where.append(mapaWhere.get("query"));
		query.append(where);

		StringBuilder groupby = new StringBuilder(" GROUP BY ");
		groupby.append(
				" t1.CODTECNICO,t1.BAJA,t1.TIPOIDENTIF,t1.DOCIDENTIFICACION,t1.NOMBRE,t1.APE1,t1.APE2,t1.TELEFONO1,");
		groupby.append(
				" t1.TELEFONO2,t1.EMAIL,t1.SEXO,t1.CALLE,t1.NUMCALLE,t1.CODPOSTAL,t1.MUNICIPIO,t1.PROVINCIA, t1.LOCALIDAD ");

		if (incluirDescripcionDireccion) {
			groupby.append(", t10.DESC_OF, t11.DESC_OF,t13.DESC_OF");
		}

		query.append(groupby);

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

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

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

	/**
	 * Finds rows in the TecnicosEntidad table using like.
	 * 
	 * @param tecnicosEntidad
	 *            TecnicosEntidad
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TecnicosEntidad>
	 */
	@Override
	@Transactional(readOnly = true)
	public List<TecnicosEntidad> findAllLike(TecnicosEntidad tecnicosEntidad, JQGridRequestDto jqGridRequestDto,
			Boolean startsWith) {
		// SELECT - FROM
		StringBuilder query = new StringBuilder(this.getSelectFromQuery(true, true));

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(tecnicosEntidad, startsWith);
		// StringBuilder where = new StringBuilder(" WHERE t5.CODTECNICO(+) =
		// t1.CODTECNICO AND t5.CODENTIDAD = t2.CODENTIDAD(+) AND
		// t3.ID_PROVINCIA(+) = t2.CODTH AND t4.ID_MUNICIPIO(+) = t2.CODMUN AND
		// t4.ID_PROVINCIA(+) = t2.CODTH AND t10.ID_PROVINCIA(+) = t1.PROVINCIA
		// AND t11.ID_MUNICIPIO(+) = t1.MUNICIPIO AND t11.ID_PROVINCIA(+) =
		// t1.PROVINCIA AND t3.ID_PROVINCIA(+) = t12.ID_PROVINCIA AND
		// t4.ID_MUNICIPIO(+) = t12.ID_MUNICIPIO AND t1.PROVINCIA =
		// t13.ID_PROVINCIA(+) AND t1.MUNICIPIO = t13.ID_MUNICIPIO(+) AND
		// t1.LOCALIDAD = t13.ID_LOCALIDAD(+)");
		StringBuilder where = new StringBuilder(Constantes.STRING_BUILDER_INIT);

		where.append(" WHERE ");
		where.append(" t5.CODTECNICO(+) = t1.CODTECNICO  ");
		where.append(" AND t2.CODENTIDAD(+) = t5.CODENTIDAD ");
		where.append(" AND t10.ID_PROVINCIA(+)= t1.PROVINCIA  ");
		where.append(" AND t11.ID_PROVINCIA(+)= t1.PROVINCIA ");
		where.append(" AND t11.ID_MUNICIPIO(+)= t1.MUNICIPIO  ");
		where.append(" AND t1.PROVINCIA  = t13.ID_PROVINCIA(+)  ");
		where.append(" AND t1.MUNICIPIO  = t13.ID_MUNICIPIO(+)  ");
		where.append(" AND t1.LOCALIDAD  = t13.ID_LOCALIDAD(+) ");

		if (tecnicosEntidad.getCodPlane() != null) {
			if (tecnicosEntidad.getAsoc() == 0) {
				where.append(" AND t1.CODTECNICO NOT IN (SELECT CODTECNICO FROM PLANESESTR_TECNICOS WHERE CODPLANE = "
						+ tecnicosEntidad.getCodPlane() + ") ");
			} else if (tecnicosEntidad.getAsoc() == 1) {
				where.append(" AND t1.CODTECNICO IN (SELECT CODTECNICO FROM PLANESESTR_TECNICOS WHERE CODPLANE = "
						+ tecnicosEntidad.getCodPlane() + ") ");
			}
		}

		where.append(mapaWhere.get("query"));
		query.append(where);

		StringBuilder groupby = new StringBuilder(" GROUP BY ");
		groupby.append(
				" t1.CODTECNICO,  t1.BAJA,  t1.TIPOIDENTIF,  t1.DOCIDENTIFICACION,  t1.NOMBRE,  t1.APE1,  t1.APE2,  t1.TELEFONO1,  t1.TELEFONO2,  t1.EMAIL,");
		groupby.append(
				"t1.SEXO,  t1.CALLE,  t1.NUMCALLE,  t1.CODPOSTAL,  t1.MUNICIPIO,  t1.PROVINCIA,  t1.LOCALIDAD,  t10.DESC_OF,  t11.DESC_OF,  t13.DESC_OF ");
		query.append(groupby);

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

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

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

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Counts rows in the TecnicosEntidad table.
	 * 
	 * @param tecnicosEntidad
	 *            TecnicosEntidad
	 * @return Long
	 */
	@Override
	@Transactional(readOnly = true)
	public Long findAllCount(TecnicosEntidad tecnicosEntidad) {
		StringBuilder query = new StringBuilder("SELECT COUNT(1) FROM (SELECT COUNT(1) FROM TECNICOS_ENTIDAD t1 ");

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

		StringBuilder groupby = new StringBuilder(" GROUP BY ");
		groupby.append(
				" t1.CODTECNICO,t1.BAJA,t1.TIPOIDENTIF,t1.DOCIDENTIFICACION,t1.NOMBRE,t1.APE1,t1.APE2,t1.TELEFONO1,");
		groupby.append(
				"t1.TELEFONO2,t1.EMAIL,t1.SEXO,t1.CALLE,t1.NUMCALLE,t1.CODPOSTAL,t1.MUNICIPIO,t1.PROVINCIA, t1.LOCALIDAD ");
		query.append(groupby);
		query.append(") ");

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

		return this.jdbcTemplate.queryForObject(query.toString(), params.toArray(), Long.class);
	}

	/**
	 * Counts rows in the TecnicosEntidad table using like.
	 * 
	 * @param tecnicosEntidad
	 *            TecnicosEntidad
	 * @param startsWith
	 *            Boolean
	 * @return Long
	 */
	@Override
	@Transactional(readOnly = true)
	public Long findAllLikeCount(TecnicosEntidad tecnicosEntidad, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT COUNT(1) FROM (SELECT COUNT(1) FROM TECNICOS_ENTIDAD t1, ENTIDADES t2, ENTIDAD_TECNICO t5, PROVINCIA t10, MUNICIPIO t11, LOCALIDAD t13 ");
		// "SELECT COUNT(1) FROM (SELECT COUNT(1) FROM TECNICOS_ENTIDAD
		// t1,ENTIDADES t2,PROVINCIA t3,MUNICIPIO t4,ENTIDAD_TECNICO
		// t5,PROVINCIA t10,MUNICIPIO t11, LOCALIDAD t13 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(tecnicosEntidad, startsWith);
		// StringBuilder where = new StringBuilder(" WHERE t5.CODTECNICO(+) =
		// t1.CODTECNICO AND t5.CODENTIDAD(+) = t2.CODENTIDAD AND
		// t3.ID_PROVINCIA = t2.CODTH AND t4.ID_MUNICIPIO = t2.CODMUN AND
		// t4.ID_PROVINCIA = t2.CODTH AND t10.ID_PROVINCIA(+) = t1.PROVINCIA AND
		// t11.ID_MUNICIPIO(+) = t1.MUNICIPIO AND t11.ID_PROVINCIA(+) =
		// t1.PROVINCIA ");
		StringBuilder where = new StringBuilder(Constantes.STRING_BUILDER_INIT);
		// where.append(
		// " WHERE t5.CODTECNICO(+) = t1.CODTECNICO AND t5.CODENTIDAD(+) =
		// t2.CODENTIDAD AND t3.ID_PROVINCIA = t2.CODTH AND t4.ID_MUNICIPIO =
		// t2.CODMUN AND t4.ID_PROVINCIA = t2.CODTH AND t10.ID_PROVINCIA(+) =
		// t1.PROVINCIA AND t11.ID_MUNICIPIO(+) = t1.MUNICIPIO AND
		// t11.ID_PROVINCIA(+) = t1.PROVINCIA ");

		where.append(" WHERE ");
		where.append("t5.CODTECNICO(+) = t1.CODTECNICO  ");
		where.append("AND t2.CODENTIDAD(+) = t5.CODENTIDAD ");
		where.append("AND t10.ID_PROVINCIA(+)= t1.PROVINCIA  ");
		where.append("AND t11.ID_PROVINCIA(+)= t1.PROVINCIA ");
		where.append("AND t11.ID_MUNICIPIO(+)= t1.MUNICIPIO  ");
		where.append("AND t1.PROVINCIA  = t13.ID_PROVINCIA(+)  ");
		where.append("AND t1.MUNICIPIO  = t13.ID_MUNICIPIO(+)  ");
		where.append("AND t1.LOCALIDAD  = t13.ID_LOCALIDAD(+) ");

		where.append(mapaWhere.get("query"));
		query.append(where);

		StringBuilder groupby = new StringBuilder(" GROUP BY ");
		groupby.append(
				" t1.CODTECNICO,t1.BAJA,t1.TIPOIDENTIF,t1.DOCIDENTIFICACION,t1.NOMBRE,t1.APE1,t1.APE2,t1.TELEFONO1,");
		groupby.append(
				"t1.TELEFONO2,t1.EMAIL,t1.SEXO,t1.CALLE,t1.NUMCALLE,t1.CODPOSTAL,t1.MUNICIPIO,t1.PROVINCIA,t10.DESC_OF,t11.DESC_OF ");

		query.append(groupby);
		query.append(") ");

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

		return this.jdbcTemplate.queryForObject(query.toString(), params.toArray(), Long.class);
	}

	/**
	 * Reorder the data list of TecnicosEntidad selected for rup_table
	 * 
	 * @param tecnicosEntidad
	 *            TecnicosEntidad
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<TecnicosEntidad>>
	 */
	@Override
	public List<TableRowDto<TecnicosEntidad>> reorderSelection(TecnicosEntidad tecnicosEntidad,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		// SELECT - FROM
		StringBuilder query = new StringBuilder(this.getSelectFromQuery(true, false));

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

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

		// SQL para la reordenación
		StringBuilder sbReorderSelectionSQL = JQGridManager.getReorderQuery(query, jqGridRequestDto,
				TecnicosEntidad.class, filterParamList, "CODTECNICO");

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

	/**
	 * Remove multiple method for rup_table
	 * 
	 * @param filterTecnicosEntidad
	 *            TecnicosEntidad
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 */
	@Override
	public void removeMultiple(TecnicosEntidad filterTecnicosEntidad, JQGridRequestDto jqGridRequestDto,
			Boolean startsWith) {
		// SELECT - FROM
		/** TODO: select por clave */
		StringBuilder query = new StringBuilder(this.getSelectFromQuery(true, false));

		// WHERE
		Map<String, Object> mapaWhere = this.getWhereLikeMap(filterTecnicosEntidad, startsWith);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		where.append(mapaWhere.get("query"));
		query.append(where);

		@SuppressWarnings(value = "unchecked")
		List<Object> params = (List<Object>) mapaWhere.get("params");

		StringBuilder sbRemoveMultipleSQL = JQGridManager.getRemoveMultipleQuery(jqGridRequestDto,
				TecnicosEntidad.class, query, params, "CODTECNICO");
		this.jdbcTemplate.update(sbRemoveMultipleSQL.toString(), params.toArray());
	}

	/**
	 * Asociar tecnico
	 * 
	 * @param tecnicosEntidad
	 *            TecnicosEntidad tecnicosEntidad
	 */
	@Override
	public void asociarTecnico(TecnicosEntidad tecnicosEntidad) {
		// SELECT - FROM
		StringBuilder query = new StringBuilder("INSERT INTO PLANESESTR_TECNICOS (CODPLANE,CODTECNICO) VALUES("
				+ tecnicosEntidad.getCodPlane() + "," + tecnicosEntidad.getCodtecnico() + ")");

		this.jdbcTemplate.update(query.toString());
	}

	/**
	 * Desasociar tecnico
	 * 
	 * @param tecnicosEntidad
	 *            TecnicosEntidad tecnicosEntidad
	 */
	@Override
	public void desasociarTecnico(TecnicosEntidad tecnicosEntidad) {
		// SELECT - FROM
		StringBuilder query = new StringBuilder("DELETE FROM PLANESESTR_TECNICOS WHERE CODPLANE = "
				+ tecnicosEntidad.getCodPlane() + " AND CODTECNICO=" + tecnicosEntidad.getCodtecnico());

		this.jdbcTemplate.update(query.toString());
	}

	/*
	 * MÉTODOS PRIVADOS
	 */

	/**
	 * Devuelve la Select con todos los campos. Incluye el From si se indica.
	 * 
	 * @param includeFrom
	 *            boolean
	 * @return String
	 */
	private String getSelectFromQuery(boolean includeFrom, boolean includeDescripcionDireccion) {
		StringBuilder query = new StringBuilder(Constantes.STRING_BUILDER_INIT);
		query.append(
				"SELECT t1.CODTECNICO CODTECNICO, t1.BAJA BAJA, t1.TIPOIDENTIF TIPOIDENTIF, t1.DOCIDENTIFICACION DOCIDENTIFICACION, ");
		query.append(
				"t1.NOMBRE NOMBRE, t1.APE1 APE1, t1.APE2 APE2, t1.TELEFONO1 TELEFONO1, t1.TELEFONO2 TELEFONO2, t1.EMAIL EMAIL, t1.SEXO SEXO, ");
		query.append(
				"t1.CALLE CALLE, t1.NUMCALLE NUMCALLE, t1.CODPOSTAL CODPOSTAL, t1.MUNICIPIO MUNICIPIO, t1.PROVINCIA PROVINCIA,t1.LOCALIDAD LOCALIDAD, ");
		if (includeDescripcionDireccion) {
			query.append("t10.DESC_OF DESCPROVINCIA, t11.DESC_OF DESCMUNICIPIO,t13.DESC_OF DESCLOCALIDAD, ");
		}
		// query.append("(SELECT SUBSTR( rtrim (xmlagg (xmlelement(e,
		// (t6.DIRECCION||', '||t9.DESC_OF||'('||t8.DESC_OF||')')||' //
		// ')).extract ('//text()'), ' '),0,LENGTH(rtrim (xmlagg (xmlelement(e,
		// (t6.DIRECCION||', '||t9.DESC_OF||'('||t8.DESC_OF||')')||' //
		// ')).extract ('//text()'), ' '))-2) FROM ENTIDADES t6,ENTIDAD_TECNICO
		// t7,PROVINCIA t8,MUNICIPIO t9 WHERE t1.CODTECNICO = t7.CODTECNICO AND
		// t7.CODENTIDAD = t6.CODENTIDAD AND t8.ID_PROVINCIA = t6.CODTH AND
		// t9.ID_MUNICIPIO = t6.CODMUN AND t9.ID_PROVINCIA = t6.CODTH) AS
		// DIRECCIONESENTIDADES ");
		query.append(
				" (SELECT SUBSTR( rtrim (xmlagg (xmlelement(e, (t6.DESENTIDAD) ||' // ')).extract ('//text()'), ' '),0,LENGTH(rtrim (xmlagg (xmlelement(e, (t6.DESENTIDAD) ||' // ')).extract ('//text()'), ' '))-2) ");
		query.append(
				" FROM ENTIDADES t6,  ENTIDAD_TECNICO t7  WHERE t1.CODTECNICO = t7.CODTECNICO  AND t7.CODENTIDAD   = t6.CODENTIDAD) AS DIRECCIONESENTIDADES ");

		if (includeFrom) {
			// query.append(" FROM TECNICOS_ENTIDAD t1,ENTIDADES t2,PROVINCIA
			// t3,MUNICIPIO t4,ENTIDAD_TECNICO t5,LOCALIDAD t12 ");
			query.append(" FROM TECNICOS_ENTIDAD t1,ENTIDADES t2,ENTIDAD_TECNICO t5 ");
			if (includeDescripcionDireccion) {
				query.append(",PROVINCIA t10,MUNICIPIO t11, LOCALIDAD t13 ");
			}
		}
		return query.toString();
	}

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

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

		if (tecnicosEntidad != null) {
			if (tecnicosEntidad.getCodtecnico() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.CODTECNICO", tecnicosEntidad.getCodtecnico());
			}
			if (tecnicosEntidad.getBaja() != null && tecnicosEntidad.getBaja() != Constantes.TODOS_LOGICA) {
				UtilSQL.createFilterSQL(where, params, "t1.BAJA", tecnicosEntidad.getBaja());
			}
			if (tecnicosEntidad.getDocidentificacion() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.DOCIDENTIFICACION",
						tecnicosEntidad.getDocidentificacion().toUpperCase(), true);
			}
			if (tecnicosEntidad.getNombre() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.NOMBRE", tecnicosEntidad.getNombre());
			}
			if (tecnicosEntidad.getApe1() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.APE1", tecnicosEntidad.getApe1());
			}
			if (tecnicosEntidad.getApe2() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.APE2", tecnicosEntidad.getApe2());
			}
			if (tecnicosEntidad.getTelefono1() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.TELEFONO1", tecnicosEntidad.getTelefono1());
			}
			if (tecnicosEntidad.getTelefono2() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.TELEFONO2", tecnicosEntidad.getTelefono2());
			}
			if (tecnicosEntidad.getEmail() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.EMAIL", tecnicosEntidad.getEmail());
			}

			if (tecnicosEntidad.getSexo() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.SEXO", tecnicosEntidad.getSexo());
			}
			if (tecnicosEntidad.getCalle() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.CALLE", tecnicosEntidad.getCalle());
			}
			if (tecnicosEntidad.getNumcalle() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.NUMCALLE", tecnicosEntidad.getNumcalle());
			}
			if (tecnicosEntidad.getCodpostal() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.CODPOSTAL", tecnicosEntidad.getCodpostal());
			}
			if (tecnicosEntidad.getMunicipio() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.MUNICIPIO", tecnicosEntidad.getMunicipio());
			}
			if (tecnicosEntidad.getProvincia() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.PROVINCIA", tecnicosEntidad.getProvincia());
			}
			if (tecnicosEntidad.getLocalidad() != null) {
				UtilSQL.createFilterSQL(where, params, "t1.LOCALIDAD", tecnicosEntidad.getLocalidad());
			}
		}

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

		return mapWhere;
	}

	/**
	 * Returns a map with the needed value to create the conditions to filter by
	 * the TecnicosEntidad entity
	 * 
	 * @param tecnicosEntidad
	 *            TecnicosEntidad 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> getWhereLikeMap(TecnicosEntidad tecnicosEntidad, Boolean startsWith) {

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

		if (tecnicosEntidad != null) {
			if (tecnicosEntidad.getCodtecnico() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.CODTECNICO", tecnicosEntidad.getCodtecnico(),
						startsWith);
			}
			if (tecnicosEntidad.getBaja() != null
					&& !Constantes.VALUE_TODOS_NUM.equalsIgnoreCase(String.valueOf(tecnicosEntidad.getBaja()))) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.BAJA", tecnicosEntidad.getBaja(), startsWith);
			}
			if (tecnicosEntidad.getDocidentificacion() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.DOCIDENTIFICACION",
						tecnicosEntidad.getDocidentificacion(), startsWith);
			}
			if (tecnicosEntidad.getNombre() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.NOMBRE", tecnicosEntidad.getNombre(), startsWith);
			}
			if (tecnicosEntidad.getApe1() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.APE1", tecnicosEntidad.getApe1(), startsWith);
			}
			if (tecnicosEntidad.getApe2() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.APE2", tecnicosEntidad.getApe2(), startsWith);
			}
			if (tecnicosEntidad.getTelefono1() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.TELEFONO1", tecnicosEntidad.getTelefono1(), startsWith);
			}
			if (tecnicosEntidad.getTelefono2() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.TELEFONO2", tecnicosEntidad.getTelefono2(), startsWith);
			}
			if (tecnicosEntidad.getEmail() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.EMAIL", tecnicosEntidad.getEmail(), startsWith);
			}

			if (tecnicosEntidad.getSexo() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.SEXO", tecnicosEntidad.getSexo(), startsWith);
			}
			if (tecnicosEntidad.getCalle() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.CALLE", tecnicosEntidad.getCalle(), startsWith);
			}
			if (tecnicosEntidad.getNumcalle() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.NUMCALLE", tecnicosEntidad.getNumcalle(), startsWith);
			}
			if (tecnicosEntidad.getCodpostal() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.CODPOSTAL", tecnicosEntidad.getCodpostal(), startsWith);
			}
			if (tecnicosEntidad.getMunicipio() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.MUNICIPIO", tecnicosEntidad.getMunicipio(), startsWith);
			}
			if (tecnicosEntidad.getProvincia() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.PROVINCIA", tecnicosEntidad.getProvincia(), startsWith);
			}
			if (tecnicosEntidad.getLocalidad() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t1.LOCALIDAD", tecnicosEntidad.getLocalidad(), startsWith);
			}

			boolean codEntidadIsNotNullMetido = false;
			if (tecnicosEntidad.getCodth() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t2.CODTH", tecnicosEntidad.getCodth(), startsWith);
				where.append(" AND t5.CODENTIDAD IS NOT NULL ");
				codEntidadIsNotNullMetido = true;
			}
			if (tecnicosEntidad.getCodmun() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t2.CODMUN", tecnicosEntidad.getCodmun(), startsWith);
				if (!codEntidadIsNotNullMetido) {
					where.append(" AND t5.CODENTIDAD IS NOT NULL ");
				}
				codEntidadIsNotNullMetido = true;
			}

			if (tecnicosEntidad.getTipoEntidad() != null
					&& !Constantes.VALUE_TODOS_NUM.equalsIgnoreCase(String.valueOf(tecnicosEntidad.getTipoEntidad()))) {
				UtilSQL.createFilterLikeSQL(where, params, "t2.TIPO_ENTIDAD", tecnicosEntidad.getTipoEntidad(),
						startsWith);
				if (!codEntidadIsNotNullMetido) {
					where.append(" AND t5.CODENTIDAD IS NOT NULL ");
				}
			}

			if (tecnicosEntidad.getCodentidad() != null) {
				UtilSQL.createFilterLikeSQL(where, params, "t5.CODENTIDAD", tecnicosEntidad.getCodentidad(),
						startsWith);
			}

		}

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

		return mapWhere;
	}
}
