package com.ejie.ab61.dao.expedientes;

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.ab61.model.expedientes.Expedientes;
import com.ejie.ab61.model.expedientes.RelExpPla;
import com.ejie.ab61.model.plantillas.Plantillas;
import com.ejie.ab61.model.plantillas.TiposPlantilla;
import com.ejie.ab61.model.procedimientos.Procedimientos;
import com.ejie.x38.dao.RowNumResultSetExtractor;
import com.ejie.x38.dto.JQGridManager;
import com.ejie.x38.dto.JQGridManagerJerarquia;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * RelExpPlaDaoImpl  
 * 
 *  
 */

@Repository
@Transactional
public class RelExpPlaDaoImpl implements RelExpPlaDao {

	public static final String[] ORDER_BY_WHITE_LIST = new String[] { "IDRELEXPPLA", "IDPLANTILLA", "IDEXPEDIENTE",
			"RUTA", "FECHAREGISTRO", "USUARIOREGISTRO", "IDPROCEDIMIENTO" };

	private JdbcTemplate jdbcTemplate;

	/*
	 * ROW_MAPPERS
	 */
	private RowMapper<RelExpPla> rwMap = new RowMapper<RelExpPla>() {
		public RelExpPla mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new RelExpPla(resultSet.getInt("IDRELEXPPLA"), resultSet.getInt("IDPLANTILLA"),
					resultSet.getInt("IDEXPEDIENTE"), resultSet.getString("RUTA"), resultSet.getDate("FECHAREGISTRO"),
					resultSet.getString("USUARIOREGISTRO"), resultSet.getInt("IDPROCEDIMIENTO"));
		}
	};

	private RowMapper<RelExpPla> rwMapRuta = new RowMapper<RelExpPla>() {
		public RelExpPla mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			RelExpPla relExpPla = new RelExpPla();
			relExpPla.setIdRelExpPla(resultSet.getInt("IDRELEXPPLA"));
			relExpPla.setRuta(resultSet.getString("RUTA"));

			return relExpPla;
		}
	};

	private RowMapper<RelExpPla> rwMapAportarDocumento = new RowMapper<RelExpPla>() {
		public RelExpPla mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new RelExpPla(resultSet.getInt("IDRELEXPPLA"), resultSet.getString("RUTA"), null, new Plantillas(
					resultSet.getInt("IDPLANTILLA"), null, null, null, null, null, null, null, null, null,
					new TiposPlantilla(null, null, null, resultSet.getString("TASKID"),
							resultSet.getString("PROCEEDINGID"), resultSet.getString("TASKTYPE"),
							resultSet.getString("TITLE"), resultSet.getString("DOCUMENTROLEID"),
							resultSet.getString("DOCUMENTROLENAMECAS"), resultSet.getString("DOCUMENTROLENAMEEUS"),
							null, null, null, null, null),
					null, null), null);
		}
	};

	private RowMapper<RelExpPla> RowMapperAportarDocumentoDesdeProcedimiento = new RowMapper<RelExpPla>() {
		public RelExpPla mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new RelExpPla(resultSet.getInt("IDRELEXPPLA"), resultSet.getString("RUTA"),
					new Expedientes(null, null, null, null, null, null, null, null, new Procedimientos()),
					new Plantillas(resultSet.getInt("IDPLANTILLA"), null, null, null, null, null, null, null, null,
							null,
							new TiposPlantilla(null, null, null, resultSet.getString("TASKID"),
									resultSet.getString("PROCEEDINGID"), resultSet.getString("TASKTYPE"),
									resultSet.getString("TITLE"), resultSet.getString("DOCUMENTROLEID"),
									resultSet.getString("DOCUMENTROLENAMECAS"),
									resultSet.getString("DOCUMENTROLENAMEEUS"), null, null, null, null, null),
							null, null),
					new Procedimientos(resultSet.getInt("IDPROCEDIMIENTO"), resultSet.getString("CODPROCEDUREID"), null,
							null));
		}
	};

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

	/**
	 * Rowmapper para Jerarquía
	 *
	 * @param dataSource
	 *            DataSource
	 * @return
	 */
	private RowMapper<JerarquiaDto<RelExpPla>> rwMapJerarquia = new RowMapper<JerarquiaDto<RelExpPla>>() {
		public JerarquiaDto<RelExpPla> mapRow(ResultSet resultSet, int rowNum) throws SQLException {

			RelExpPla relexppla = new RelExpPla(resultSet.getInt("IDRELEXPPLA"), resultSet.getInt("IDPLANTILLA"),
					resultSet.getInt("IDEXPEDIENTE"), resultSet.getString("RUTA"), resultSet.getDate("FECHAREGISTRO"),
					resultSet.getString("USUARIOREGISTRO"), resultSet.getInt("IDPROCEDIMIENTO"));

			JerarquiaDto<RelExpPla> jerarquia = new JerarquiaDto<RelExpPla>();
			jerarquia.setModel(relexppla);
			jerarquia.setLevel(resultSet.getBigDecimal("LEVEL").intValue());
			jerarquia.setParentNodes(resultSet.getString("PARENTNODES"));
			jerarquia.setIsLeaf(Boolean.parseBoolean(resultSet.getString("ISLEAF")));
			jerarquia.setFilter(Boolean.parseBoolean(resultSet.getString("FILTER")));
			return jerarquia;
		}
	};

	/**
	 * 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 RelExpPla table.
	 * 
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @return RelExpPla
	 */
	public RelExpPla add(RelExpPla relexppla) {

		// Extraemos el siguiente id autoincremental a asignar.
		String nVQuery = "SELECT AB61.S_AB6133T00.NEXTVAL AS NEXTVAL FROM DUAL";
		int nextVal = this.jdbcTemplate.queryForObject(nVQuery, null, Integer.class);

		String query = "INSERT INTO REL_EXP_PLA (ID_REL_EXP_PLA, ID_PLANTILLA, ID_EXPEDIENTE, RUTA, FECHA_REGISTRO, USUARIO_REGISTRO, ID_PROCEDIMIENTO, IDENTIFICADOR) VALUES (?,?,?,?,?,?,?,?)";
		this.jdbcTemplate.update(query, nextVal, relexppla.getIdPlantilla(), relexppla.getIdExpediente(),
				relexppla.getRuta(), relexppla.getFechaRegistro(), relexppla.getUsuarioRegistro(),
				relexppla.getIdProcedimiento(), relexppla.getIdentificador());

		relexppla.setIdRelExpPla(nextVal);
		return relexppla;
	}

	/**
	 * Updates a single row in the RelExpPla table.
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @return RelExpPla
	 */
	public RelExpPla update(RelExpPla relexppla) {
		String query = "UPDATE REL_EXP_PLA SET ID_PLANTILLA=?, ID_EXPEDIENTE=?, RUTA=?, FECHA_REGISTRO=?, USUARIO_REGISTRO=?, ID_PROCEDIMIENTO=? WHERE ID_REL_EXP_PLA=?";
		this.jdbcTemplate.update(query, relexppla.getIdPlantilla(), relexppla.getIdExpediente(), relexppla.getRuta(),
				relexppla.getFechaRegistro(), relexppla.getUsuarioRegistro(), relexppla.getIdProcedimiento(),
				relexppla.getIdRelExpPla());
		return relexppla;
	}

	/**
	 * Finds a single row in the RelExpPla table.
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @return RelExpPla
	 */
	@Transactional(readOnly = true)
	public RelExpPla find(RelExpPla relexppla) {
		String query = "SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA, t1.ID_PLANTILLA IDPLANTILLA, t1.ID_EXPEDIENTE IDEXPEDIENTE, t1.RUTA RUTA, t1.FECHA_REGISTRO FECHAREGISTRO, t1.USUARIO_REGISTRO USUARIOREGISTRO, t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO FROM REL_EXP_PLA t1  WHERE t1.ID_REL_EXP_PLA = ?  ";

		List<RelExpPla> relexpplaList = this.jdbcTemplate.query(query, this.rwMap, relexppla.getIdRelExpPla());
		return (RelExpPla) DataAccessUtils.uniqueResult(relexpplaList);
	}

	@Transactional(readOnly = true)
	public RelExpPla obtenerDatosAportarDocumento(RelExpPla relexppla) {
		String query = "SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA, t1.RUTA RUTA, T2.ID_EXPEDIENTE IDEXPEDIENTE, t2.FOLDER_ID FOLDERID, t3.ID_PLANTILLA IDPLANTILLA, t4.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t4.COD_PROCEDURE_ID CODPROCEDUREID, t5.TASK_ID TASKID, t5.PROCEEDING_ID PROCEEDINGID, t5.TITLE TITLE, t5.DOCUMENT_ROLE_ID DOCUMENTROLEID, t5.DOCUMENT_ROLE_NAME_EUS DOCUMENTROLENAMEEUS, t5.DOCUMENT_ROLE_NAME_CAS DOCUMENTROLENAMECAS, t5.TASK_TYPE TASKTYPE FROM REL_EXP_PLA t1, EXPEDIENTES t2, PLANTILLAS t3, PROCEDIMIENTOS t4, TIPOS_PLANTILLA t5 WHERE t1.ID_PLANTILLA = ? AND t2.FOLDER_ID = ? AND T4.COD_PROCEDURE_ID = ? AND t1.ID_EXPEDIENTE = T2.ID_EXPEDIENTE AND t1.ID_PLANTILLA = t3.ID_PLANTILLA AND t1.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO AND t3.ID_TIPO_PLANTILLA = t5.ID_TIPO_PLANTILLA";

		Object getExpedienteFolderId = null;
		if (relexppla.getExpediente() != null && !"".equals(relexppla.getExpediente().getFolderId())) {
			getExpedienteFolderId = relexppla.getExpediente().getFolderId();
		}

		Object getProcedimiento = null;
		if (relexppla.getProcedimiento() != null && !"".equals(relexppla.getProcedimiento().getCodProcedureId())) {
			getProcedimiento = relexppla.getProcedimiento().getCodProcedureId();
		}

		List<RelExpPla> relexpplaList = this.jdbcTemplate.query(query, this.rwMapAportarDocumento,
				relexppla.getIdPlantilla(), getExpedienteFolderId, getProcedimiento);
		return (RelExpPla) DataAccessUtils.uniqueResult(relexpplaList);
	}

	/**
	 * obtener la ruta del archivo para poder modificar o aportar a tramitagune
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @return RelExpPla
	 */
	@Transactional(readOnly = true)
	public RelExpPla obtenerDatosAportarDocumentoNegocio(RelExpPla relexppla) {
		String query = "SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA, t1.RUTA RUTA, t3.ID_PLANTILLA IDPLANTILLA, t5.TASK_ID TASKID, t5.PROCEEDING_ID PROCEEDINGID, t5.TITLE TITLE, t5.DOCUMENT_ROLE_ID DOCUMENTROLEID, t5.DOCUMENT_ROLE_NAME_EUS DOCUMENTROLENAMEEUS, t5.DOCUMENT_ROLE_NAME_CAS DOCUMENTROLENAMECAS, t5.TASK_TYPE TASKTYPE FROM REL_EXP_PLA t1, PLANTILLAS t3, TIPOS_PLANTILLA t5 WHERE t1.ID_PLANTILLA = ? AND t1.IDENTIFICADOR = ? AND t1.ID_PLANTILLA = t3.ID_PLANTILLA AND t3.ID_TIPO_PLANTILLA = t5.ID_TIPO_PLANTILLA";

		String identificador = "";
		if (relexppla.getExpediente() != null && !"".equals(relexppla.getExpediente().getFolderId())) {
			identificador = relexppla.getExpediente().getFolderId();
		} else {
			identificador = relexppla.getProcedimiento().getCodProcedureId();
		}

		List<RelExpPla> relexpplaList = this.jdbcTemplate.query(query, this.rwMapAportarDocumento,
				relexppla.getIdPlantilla(), identificador);
		return (RelExpPla) DataAccessUtils.uniqueResult(relexpplaList);
	}

	@Override
	public RelExpPla obtenerRutaByIdentificador(RelExpPla relExpPla) {
		String query = "SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA, t1.RUTA RUTA FROM REL_EXP_PLA t1, PLANTILLAS t2, TIPOS_PLANTILLA t3 WHERE t1.ID_PLANTILLA = ? AND t1.IDENTIFICADOR = ? AND t1.ID_PLANTILLA = t2.ID_PLANTILLA AND t2.ID_TIPO_PLANTILLA = t3.ID_TIPO_PLANTILLA";

		List<RelExpPla> relexpplaList = this.jdbcTemplate.query(query, this.rwMapRuta, relExpPla.getIdPlantilla(),
				relExpPla.getIdentificador());
		return (RelExpPla) DataAccessUtils.uniqueResult(relexpplaList);
	}

	/**
	 * obtener la ruta del archivo para poder modificar o aportar a tramitagune
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @return RelExpPla
	 */
	@Transactional(readOnly = true)
	public RelExpPla obtenerDocumentoDesdeProcedimiento(RelExpPla relexppla) {

		String query = "SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA, t1.RUTA RUTA, t3.ID_PLANTILLA IDPLANTILLA, t4.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t4.COD_PROCEDURE_ID CODPROCEDUREID, t5.TASK_ID TASKID, t5.PROCEEDING_ID PROCEEDINGID, t5.TITLE TITLE, t5.DOCUMENT_ROLE_ID DOCUMENTROLEID, t5.DOCUMENT_ROLE_NAME_EUS DOCUMENTROLENAMEEUS, t5.DOCUMENT_ROLE_NAME_CAS DOCUMENTROLENAMECAS, t5.TASK_TYPE TASKTYPE FROM  REL_EXP_PLA t1, PLANTILLAS t3, PROCEDIMIENTOS t4, TIPOS_PLANTILLA t5 WHERE t1.ID_PLANTILLA   = ? AND T4.COD_PROCEDURE_ID = ? AND t1.ID_PLANTILLA     = t3.ID_PLANTILLA AND t1.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO AND t3.ID_TIPO_PLANTILLA = t5.ID_TIPO_PLANTILLA AND t1.ID_EXPEDIENTE   IS NULL";

		Object getProcedimiento = null;
		if (relexppla.getProcedimiento() != null && !"".equals(relexppla.getProcedimiento().getCodProcedureId())) {
			getProcedimiento = relexppla.getProcedimiento().getCodProcedureId();
		}

		List<RelExpPla> relexpplaList = this.jdbcTemplate.query(query, this.RowMapperAportarDocumentoDesdeProcedimiento,
				relexppla.getIdPlantilla(), getProcedimiento);
		return (RelExpPla) DataAccessUtils.uniqueResult(relexpplaList);
	}

	/**
	 * Obtener la ruta del archivo para poder modificar o aportar a tramitagune
	 * 
	 * @param relexppla
	 *            RelExpPla
	 * @return RelExpPla
	 */
	@Transactional(readOnly = true)
	public RelExpPla obtenerDocumentoDesdeInspeccion(RelExpPla relExpPla) {

		String query = "SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA, t1.RUTA RUTA, t3.ID_PLANTILLA IDPLANTILLA, t4.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t4.COD_PROCEDURE_ID CODPROCEDUREID, t5.TASK_ID TASKID, t5.PROCEEDING_ID PROCEEDINGID, t5.TITLE TITLE, t5.DOCUMENT_ROLE_ID DOCUMENTROLEID, t5.DOCUMENT_ROLE_NAME_EUS DOCUMENTROLENAMEEUS, t5.DOCUMENT_ROLE_NAME_CAS DOCUMENTROLENAMECAS, t5.TASK_TYPE TASKTYPE FROM REL_EXP_PLA t1, AB79.INSPECCIONES t2, PLANTILLAS t3, PROCEDIMIENTOS t4, TIPOS_PLANTILLA t5 WHERE t1.ID_PLANTILLA = ? AND t4.COD_PROCEDURE_ID = ? AND t2.IDENTIFICADOR_INSPECCION = ? AND t1.ID_INSPECCION = t2.ID_INSPECCION AND t1.ID_PLANTILLA = t3.ID_PLANTILLA AND t1.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO AND t3.ID_TIPO_PLANTILLA = t5.ID_TIPO_PLANTILLA AND t1.ID_EXPEDIENTE IS NULL";

		Object getProcedimiento = null;
		if (relExpPla.getProcedimiento() != null && !"".equals(relExpPla.getProcedimiento().getCodProcedureId())) {
			getProcedimiento = relExpPla.getProcedimiento().getCodProcedureId();
		}

		Object getInspeccion = null;
		if (relExpPla.getInspeccion() != null && !"".equals(relExpPla.getInspeccion().getIdentificadorInspeccion())) {
			getInspeccion = relExpPla.getInspeccion().getIdentificadorInspeccion();
		}

		List<RelExpPla> relExpPlaList = this.jdbcTemplate.query(query, this.RowMapperAportarDocumentoDesdeProcedimiento,
				relExpPla.getIdPlantilla(), getProcedimiento, getInspeccion);
		return (RelExpPla) DataAccessUtils.uniqueResult(relExpPlaList);
	}

	/**
	 * Removes a single row in the RelExpPla table.
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @return
	 */
	public void remove(RelExpPla relexppla) {
		String query = "DELETE FROM REL_EXP_PLA WHERE ID_REL_EXP_PLA=?";
		this.jdbcTemplate.update(query, relexppla.getIdRelExpPla());
	}

	/**
	 * Finds a list of rows in the RelExpPla table.
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<RelExpPla>
	 */
	@Transactional(readOnly = true)
	public List<RelExpPla> findAll(RelExpPla relexppla, JQGridRequestDto jqGridRequestDto) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.ID_REL_EXP_PLA IDRELEXPPLA,t1.ID_PLANTILLA IDPLANTILLA,t1.ID_EXPEDIENTE IDEXPEDIENTE,t1.RUTA RUTA,t1.FECHA_REGISTRO FECHAREGISTRO,t1.USUARIO_REGISTRO USUARIOREGISTRO,t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO ");
		query.append("FROM REL_EXP_PLA t1 ");

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

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

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

		return (List<RelExpPla>) this.jdbcTemplate.query(query.toString(), this.rwMap, params.toArray());
	}

	/**
	 * Finds rows in the RelExpPla table using like.
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<RelExpPla>
	 */
	@Transactional(readOnly = true)
	public List<RelExpPla> findAllLike(RelExpPla relexppla, JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT  t1.ID_REL_EXP_PLA IDRELEXPPLA,t1.ID_PLANTILLA IDPLANTILLA,t1.ID_EXPEDIENTE IDEXPEDIENTE,t1.RUTA RUTA,t1.FECHA_REGISTRO FECHAREGISTRO,t1.USUARIO_REGISTRO USUARIOREGISTRO,t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO ");
		query.append("FROM REL_EXP_PLA t1 ");

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

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

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

		return (List<RelExpPla>) this.jdbcTemplate.query(query.toString(), this.rwMap, params.toArray());
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

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

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(relexppla);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		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 RelExpPla table using like.
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @param startsWith
	 *            Boolean
	 * @return Long
	 */
	@Transactional(readOnly = true)
	public Long findAllLikeCount(RelExpPla relexppla, Boolean startsWith) {
		StringBuilder query = new StringBuilder("SELECT COUNT(1) FROM REL_EXP_PLA t1 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(relexppla, startsWith);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		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 RelExpPla selected for rup_table
	 *
	 * @param relexppla
	 *            RelExpPla
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<RelExpPla>>
	 */
	@Override
	public List<TableRowDto<RelExpPla>> reorderSelection(RelExpPla relexppla, JQGridRequestDto jqGridRequestDto,
			Boolean startsWith) {
		// SELECT
		StringBuilder query = new StringBuilder(
				"SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA,t1.ID_PLANTILLA IDPLANTILLA,t1.ID_EXPEDIENTE IDEXPEDIENTE,t1.RUTA RUTA,t1.FECHA_REGISTRO FECHAREGISTRO,t1.USUARIO_REGISTRO USUARIOREGISTRO,t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO ");
		// FROM
		query.append("FROM REL_EXP_PLA t1 ");
		// FILTRADO
		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(relexppla, startsWith);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		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, RelExpPla.class,
				filterParamList, "ID_REL_EXP_PLA");

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

	/**
	 * Search method for rup_table
	 *
	 * @param filterParams
	 *            RelExpPla
	 * @param searchParams
	 *            RelExpPla
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<RelExpPla>>
	 */
	@Override
	public List<TableRowDto<RelExpPla>> search(RelExpPla filterParams, RelExpPla searchParams,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		// SELECT
		StringBuilder query = new StringBuilder(
				"SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA,t1.ID_PLANTILLA IDPLANTILLA,t1.ID_EXPEDIENTE IDEXPEDIENTE,t1.RUTA RUTA,t1.FECHA_REGISTRO FECHAREGISTRO,t1.USUARIO_REGISTRO USUARIOREGISTRO,t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO ");
		// FROM
		query.append("FROM REL_EXP_PLA t1 ");
		// TABLAS_ALIAS
		List<String> from_alias = new ArrayList<String>();
		from_alias.add(" t1 ");

		// FILTRADO
		Map<String, ?> mapaWhereFilter = this.getWhereLikeMap(filterParams, startsWith);
		StringBuilder where = new StringBuilder(" WHERE 1=1 ");
		where.append(mapaWhereFilter.get("query"));
		query.append(where);
		// Filter params
		@SuppressWarnings("unchecked")
		List<Object> filterParamList = (List<Object>) mapaWhereFilter.get("params");

		// BUSQUEDA
		Map<String, Object> mapaWhereSearch = this.getWhereLikeMap(searchParams, startsWith);
		String searchSQL = ((StringBuilder) mapaWhereSearch.get("query")).toString();
		// Search params
		@SuppressWarnings("unchecked")
		List<Object> searchParamList = (List<Object>) mapaWhereSearch.get("params");

		// SQL
		StringBuilder sbReorderSelectionSQL = JQGridManager.getSearchQuery(query, jqGridRequestDto, RelExpPla.class,
				filterParamList, searchSQL, searchParamList, from_alias, "ID_REL_EXP_PLA");

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

	/**
	 * Remove multiple method for rup_table
	 *
	 * @param filterrelexppla
	 *            RelExpPla
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 */
	@Override
	public void removeMultiple(RelExpPla filterrelexppla, JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		// SELECT
		/** TODO: select por clave */
		StringBuilder query = new StringBuilder(
				"SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA,t1.ID_PLANTILLA IDPLANTILLA,t1.ID_EXPEDIENTE IDEXPEDIENTE,t1.RUTA RUTA,t1.FECHA_REGISTRO FECHAREGISTRO,t1.USUARIO_REGISTRO USUARIOREGISTRO,t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO ");
		// FROM
		query.append("FROM REL_EXP_PLA t1 ");

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

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

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

	/**
	 * Filter in the hierarchical RelExpPla table.
	 *
	 * @param filterRelExpPla
	 *            RelExpPla
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<JerarquiaDto<RelExpPla>>
	 */
	@Override
	public List<JerarquiaDto<RelExpPla>> findAllLikeJerarquia(RelExpPla filterRelExpPla,
			JQGridRequestDto jqGridRequestDto) {
		// SELECT
		StringBuilder query = new StringBuilder(
				"SELECT t1.ID_REL_EXP_PLA IDRELEXPPLA,t1.ID_PLANTILLA IDPLANTILLA,t1.ID_EXPEDIENTE IDEXPEDIENTE,t1.RUTA RUTA,t1.FECHA_REGISTRO FECHAREGISTRO,t1.USUARIO_REGISTRO USUARIOREGISTRO,t1.ID_PROCEDIMIENTO IDPROCEDIMIENTO ");
		// FROM
		// StringBuilder from = new StringBuilder("FROM REL_EXP_PLA t1 ");
		List<String> from = new ArrayList<String>();
		from.add("REL_EXP_PLA");
		// TABLAS_ALIAS
		List<String> from_alias = new ArrayList<String>();
		from_alias.add(" t1 ");

		// JOINS TABLAS
		/*
		 * Ejemplo de como indicar joins entre las tablas de la query
		 */
		/*
		 * StringBuilder joins = new StringBuilder("");
		 * joins.append("AND T1.ID=T2.ID_T1");
		 */

		// CONDICIONES (negocio)
		/*
		 * Ejemplo de como incluir condiciones de negocio en la consulta de la
		 * jerarquía
		 */
		/*
		 * StringBuilder businessFilters = new StringBuilder(); List<Object>
		 * businessParams = new ArrayList<Object>();
		 * businessFilters.append("   AND t1.EJIE = ?  ");
		 * businessParams.add("1");
		 */

		// FILTRO
		Map<String, ?> mapaWhere = this.getWhereLikeMap(filterRelExpPla, false);

		// JERARQUIA
		// Especificar la columna padre correspondiente en lugar de la generada
		// por defecto (ID_PADRE)
		query = JQGridManagerJerarquia.getQuery(jqGridRequestDto, query, mapaWhere, "ID_REL_EXP_PLA", "ID_PADRE",
				"NOMBRE", from, from_alias);

		/*
		 * Ejemplo de llamada en caso de indicar joins entre tablas y
		 * condiciones de negocio
		 */
		// query = JQGridManagerJerarquia.getQuery(jqGridRequestDto, query,
		// mapaWhere, "ID", "ID_PADRE", "NOMBRE", from, from_alias, joins,
		// businessFilters, businessParams);

		// PAGINACION
		if (jqGridRequestDto != null) {
			query = JQGridManagerJerarquia.getPaginationQuery(jqGridRequestDto, query,
					RelExpPlaDaoImpl.ORDER_BY_WHITE_LIST);
		}

		List<?> params = (List<?>) mapaWhere.get("params");
		return this.jdbcTemplate.query(query.toString(), this.rwMapJerarquia, params.toArray());
	}

	/**
	 * Count rows in hierarchy
	 *
	 * @param filterRelExpPla
	 *            RelExpPla
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return Long
	 */
	@Override
	public Long findAllLikeCountJerarquia(RelExpPla filterRelExpPla, JQGridRequestDto jqGridRequestDto) {
		// FROM
		// StringBuilder from = new StringBuilder("FROM REL_EXP_PLA t1 ");
		List<String> from = new ArrayList<String>();
		from.add("REL_EXP_PLA");

		// TABLAS_ALIAS
		List<String> from_alias = new ArrayList<String>();
		from_alias.add(" t1 ");

		// JOINS TABLAS
		/*
		 * Ejemplo de como indicar joins entre las tablas de la query
		 */
		/*
		 * StringBuilder joins = new StringBuilder("");
		 * joins.append("AND T1.ID=T2.ID_T1");
		 */

		// CONDICIONES (negocio)
		/*
		 * Ejemplo de como incluir condiciones de negocio en la consulta de la
		 * jerarquía
		 */
		/*
		 * StringBuilder businessFilters = new StringBuilder(); List<Object>
		 * businessParams = new ArrayList<Object>();
		 * businessFilters.append("   AND t1.EJIE = ?  ");
		 * businessParams.add("1");
		 */

		// FILTRO
		Map<String, ?> mapaWhere = this.getWhereLikeMap(filterRelExpPla, false);

		// JERARQUIA
		// Especificar la columna padre correspondiente en lugar de la generada
		// por defecto (ID_PADRE)
		StringBuilder query = JQGridManagerJerarquia.getQueryCount(jqGridRequestDto, mapaWhere, "ID_REL_EXP_PLA",
				"ID_PADRE", from, from_alias);

		/*
		 * Ejemplo de llamada en caso de indicar joins entre tablas y
		 * condiciones de negocio
		 */
		// StringBuilder query =
		// JQGridManagerJerarquia.getQueryCount(jqGridRequestDto, mapaWhere,
		// "ID", "ID_PADRE", from, from_alias, joins, businessFilters,
		// businessParams);

		List<?> params = (List<?>) mapaWhere.get("params");
		return this.jdbcTemplate.queryForLong(query.toString(), params.toArray());
	}

	/**
	 * Find dependent hierarchical rows
	 *
	 * @param filterRelExpPla
	 *            RelExpPla
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<TableRowDto<RelExpPla>>
	 */
	@Override
	public List<TableRowDto<RelExpPla>> findAllChild(RelExpPla filterRelExpPla, JQGridRequestDto jqGridRequestDto) {

		// FROM
		// StringBuilder from = new StringBuilder("FROM REL_EXP_PLA t1 ");
		List<String> from = new ArrayList<String>();
		from.add("REL_EXP_PLA");

		// TABLAS_ALIAS
		List<String> from_alias = new ArrayList<String>();
		from_alias.add(" t1 ");

		// JOINS TABLAS
		/*
		 * Ejemplo de como indicar joins entre las tablas de la query
		 */
		/*
		 * StringBuilder joins = new StringBuilder("");
		 * joins.append("AND T1.ID=T2.ID_T1");
		 */

		// CONDICIONES (negocio)
		/*
		 * Ejemplo de como incluir condiciones de negocio en la consulta de la
		 * jerarquía
		 */
		/*
		 * StringBuilder businessFilters = new StringBuilder(); List<Object>
		 * businessParams = new ArrayList<Object>();
		 * businessFilters.append("   AND t1.EJIE = ?  ");
		 * businessParams.add("1");
		 */

		// FILTRO
		Map<String, ?> mapaWhere = this.getWhereLikeMap(filterRelExpPla, false);

		// MULTISELECCION
		// Especificar la columna padre correspondiente en lugar de la generada
		// por defecto (ID_PADRE)
		StringBuilder query = JQGridManagerJerarquia.getQueryChildren(jqGridRequestDto, mapaWhere, "ID_REL_EXP_PLA",
				"ID_PADRE", from, from_alias);

		/*
		 * Ejemplo de llamada en caso de indicar joins entre tablas y
		 * condiciones de negocio
		 */
		// StringBuilder query =
		// JQGridManagerJerarquia.getQueryChildren(jqGridRequestDto, mapaWhere,
		// "ID", "ID_PADRE", from, from_alias, joins, businessFilters,
		// businessParams);

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

		return this.jdbcTemplate.query(query.toString(),
				new RowNumResultSetExtractor<RelExpPla>(this.rwMapPK, "ID_REL_EXP_PLA"), params.toArray());
	}

	/*
	 * MÉTODOS PRIVADOS
	 */

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

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

		if (relexppla != null && relexppla.getIdRelExpPla() != null) {
			where.append(" AND t1.ID_REL_EXP_PLA = ?");
			params.add(relexppla.getIdRelExpPla());
		}
		if (relexppla != null && relexppla.getIdPlantilla() != null) {
			where.append(" AND t1.ID_PLANTILLA = ?");
			params.add(relexppla.getIdPlantilla());
		}
		if (relexppla != null && relexppla.getIdExpediente() != null) {
			where.append(" AND t1.ID_EXPEDIENTE = ?");
			params.add(relexppla.getIdExpediente());
		}
		if (relexppla != null && relexppla.getRuta() != null) {
			where.append(" AND t1.RUTA = ?");
			params.add(relexppla.getRuta());
		}
		if (relexppla != null && relexppla.getFechaRegistro() != null) {
			where.append(" AND t1.FECHA_REGISTRO = ?");
			params.add(relexppla.getFechaRegistro());
		}
		if (relexppla != null && relexppla.getUsuarioRegistro() != null) {
			where.append(" AND t1.USUARIO_REGISTRO = ?");
			params.add(relexppla.getUsuarioRegistro());
		}
		if (relexppla != null && relexppla.getIdProcedimiento() != null) {
			where.append(" AND t1.ID_PROCEDIMIENTO = ?");
			params.add(relexppla.getIdProcedimiento());
		}

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

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

		if (relexppla != null && relexppla.getIdRelExpPla() != null) {
			where.append(" AND t1.ID_REL_EXP_PLA = ?");
			params.add(relexppla.getIdRelExpPla());
		}
		if (relexppla != null && relexppla.getIdPlantilla() != null) {
			where.append(" AND t1.ID_PLANTILLA = ?");
			params.add(relexppla.getIdPlantilla());
		}
		if (relexppla != null && relexppla.getIdExpediente() != null) {
			where.append(" AND t1.ID_EXPEDIENTE = ?");
			params.add(relexppla.getIdExpediente());
		}
		if (relexppla != null && relexppla.getRuta() != null) {
			where.append(" AND UPPER(t1.RUTA) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(relexppla.getRuta().toUpperCase() + "%");
			} else {
				params.add("%" + relexppla.getRuta().toUpperCase() + "%");
			}
			where.append(" AND t1.RUTA IS NOT NULL");
		}
		if (relexppla != null && relexppla.getFechaRegistro() != null) {
			where.append(" AND t1.FECHA_REGISTRO = ?");
			params.add(relexppla.getFechaRegistro());
		}
		if (relexppla != null && relexppla.getUsuarioRegistro() != null) {
			where.append(" AND UPPER(t1.USUARIO_REGISTRO) like ? ESCAPE  '\\'");
			if (startsWith) {
				params.add(relexppla.getUsuarioRegistro().toUpperCase() + "%");
			} else {
				params.add("%" + relexppla.getUsuarioRegistro().toUpperCase() + "%");
			}
			where.append(" AND t1.USUARIO_REGISTRO IS NOT NULL");
		}
		if (relexppla != null && relexppla.getIdProcedimiento() != null) {
			where.append(" AND t1.ID_PROCEDIMIENTO = ?");
			params.add(relexppla.getIdProcedimiento());
		}

		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;

}
