package com.ejie.ab79.dao;

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.ab79.model.DocumentosSubidos;
import com.ejie.ab79.model.RelCamDoc;
import com.ejie.ab79.model.inspecciones.CampainasInspeccion;
import com.ejie.ab79.model.plantillas.Plantillas;
import com.ejie.ab79.model.plantillas.TiposPlantilla;
import com.ejie.ab79.model.procedimientos.Direcciones;
import com.ejie.ab79.model.procedimientos.Procedimientos;
import com.ejie.ab79.model.protocolos.Protocolos;
import com.ejie.x38.dao.RowNumResultSetExtractor;
import com.ejie.x38.dto.TableManager;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * RelCamDocDaoImpl  
 * 
 *  
 */

@Repository
@Transactional
public class RelCamDocDaoImpl implements RelCamDocDao {

	public static final String[] ORDER_BY_WHITE_LIST = new String[] { "IDRELCAMDOC", "IDCAMPAINA", "IDDOCUMENTOSUBIDO",
			"IDDOCUMENTOSUBIDO", "IDTIPOPLANTILLA", "IDACTUACION", "NOMBREDOCUMENTO", "OIDPID", "FECHAAPORTADOPID",
			"OIDDOKUSI", "APORTADOEXPEDIENTE", "TIPODOCUMENTODESCES", "TIPODOCUMENTODESCEU" };

	private JdbcTemplate jdbcTemplate;

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

			RelCamDoc retorno = new RelCamDoc();
			retorno.setIdRelCamDoc(
					(resultSet.getObject("IDRELCAMDOC") != null ? resultSet.getInt("IDRELCAMDOC") : null));

			DocumentosSubidos documentosSubidos = null;
			if (resultSet.getObject("IDDOCUMENTOSUBIDO") != null) {
				documentosSubidos = new DocumentosSubidos();
				documentosSubidos.setIdDocumentoSubido(resultSet.getInt("IDDOCUMENTOSUBIDO"));

				documentosSubidos.setIdActuacion(resultSet.getInt("IDACTUACION"));
				documentosSubidos.setNombreDocumento(resultSet.getString("NOMBREDOCUMENTO"));
				documentosSubidos.setOidPid(resultSet.getString("OIDPID"));
				documentosSubidos.setFechaAportadoPid(resultSet.getDate("FECHAAPORTADOPID"));
				documentosSubidos.setOidDokusi(resultSet.getString("OIDDOKUSI"));
				documentosSubidos.setAportadoExpediente(resultSet.getInt("APORTADOEXPEDIENTE"));
				documentosSubidos.setIdRelActDoc(resultSet.getInt("IDRELACTDOC"));
				documentosSubidos.setEnviadoProSan(resultSet.getInt("ENVIADOPROSAN"));

				TiposPlantilla tipoPlantilla = null;
				if (resultSet.getObject("IDTIPOPLANTILLA") != null) {
					tipoPlantilla = new TiposPlantilla();
					tipoPlantilla.setIdTipoPlantilla(resultSet.getLong("IDTIPOPLANTILLA"));
				}
				documentosSubidos.setTipoPlantilla(tipoPlantilla);

				Plantillas plantilla = null;
				if (resultSet.getObject("IDPLANTILLA") != null) {
					plantilla = new Plantillas();
					plantilla.setIdPlantilla(resultSet.getInt("IDPLANTILLA"));
					plantilla.setDescripcionCastellano(resultSet.getString("PLANTILLADESCES"));
					plantilla.setDescripcionEuskera(resultSet.getString("PLANTILLADESCEU"));
				}
				documentosSubidos.setPlantilla(plantilla);
			}
			retorno.setDocumentoSubido(documentosSubidos);

			CampainasInspeccion campaina = null;
			if (resultSet.getObject("IDCAMPAINA") != null) {
				campaina = new CampainasInspeccion();
				campaina.setIdCampaina(resultSet.getInt("IDCAMPAINA"));
				campaina.setDescripcionCastellano(resultSet.getString("DESCRIPCIONCASTELLANO"));
				campaina.setDescripcionEuskera(resultSet.getString("DESCRIPCIONEUSKERA"));
				campaina.setFechaInicio(resultSet.getDate("FECHAINICIO"));
				campaina.setFechaFin(resultSet.getDate("FECHAFIN"));
				campaina.setIdentificadorCampaina(resultSet.getString("IDENTIFICADORCAMPAINA"));

				Direcciones direccion = null;
				if (resultSet.getObject("IDDIRECCION") != null) {
					direccion = new Direcciones();
					direccion.setIdDireccion(resultSet.getInt("IDDIRECCION"));
					direccion.setDescripcionCastellano(resultSet.getString("DIRECCIONDESCES"));
					direccion.setDescripcionEuskera(resultSet.getString("DIRECCIONDESCEU"));
				}

				Procedimientos procedimiento = null;
				if (resultSet.getObject("IDPROCEDIMIENTO") != null) {
					procedimiento = new Procedimientos();
					procedimiento.setIdProcedimiento(resultSet.getInt("IDPROCEDIMIENTO"));
					procedimiento.setDescripcionEs(resultSet.getString("PROCEDIMIENTODESCES"));
					procedimiento.setDescripcionEu(resultSet.getString("PROCEDIMIENTODESCEU"));
					procedimiento.setCodProcedureId(resultSet.getString("CODPROCEDUREID"));
				}

				Protocolos protocoloAux = null;
				if (resultSet.getObject("IDPROTOCOLO") != null) {
					protocoloAux = new Protocolos();
					protocoloAux.setIdProtocolo(resultSet.getInt("IDPROTOCOLO"));
					protocoloAux.setDescripcionCastellano(resultSet.getString("PROTOCOLODESCES"));
					protocoloAux.setDescripcionEuskera(resultSet.getString("PROTOCOLODESCEU"));
				}

				campaina.setDireccion(direccion);
				campaina.setProcedimiento(procedimiento);
				campaina.setProtocolo(protocoloAux);
			}
			retorno.setCampainaInspeccion(campaina);

			return retorno;
		}
	};

	private RowMapper<RelCamDoc> rwMapPK = new RowMapper<RelCamDoc>() {
		@Override
		public RelCamDoc mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			return new RelCamDoc((resultSet.getObject("IDRELCAMDOC") != null ? resultSet.getInt("IDRELCAMDOC") : null));
		}
	};

	@Resource
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	@Override
	public RelCamDoc add(RelCamDoc relCamDoc) {

		int idRelCamDoc = this.jdbcTemplate.queryForObject("SELECT AB79.S_AB7941T00.NEXTVAL FROM DUAL", Integer.class);
		relCamDoc.setIdRelCamDoc(idRelCamDoc);

		String query = "INSERT INTO REL_CAM_DOC (ID_REL_CAM_DOC, ID_CAMPAINA, ID_DOCUMENTO_SUBIDO, FECHA_REGISTRO, USUARIO_REGISTRO) VALUES (?,?,?,SYSDATE,?)";
		this.jdbcTemplate.update(query, relCamDoc.getIdRelCamDoc(),
				(relCamDoc.getCampainaInspeccion() != null ? relCamDoc.getCampainaInspeccion().getIdCampaina() : null),
				(relCamDoc.getDocumentoSubido() != null ? relCamDoc.getDocumentoSubido().getIdDocumentoSubido() : null),
				relCamDoc.getUsuarioRegistro());
		return relCamDoc;
	}

	@Override
	@Transactional(readOnly = true)
	public RelCamDoc find(RelCamDoc relCamDoc) {
		String query = "SELECT t1.ID_REL_CAM_DOC IDRELCAMDOC, t1.ID_CAMPAINA IDCAMPAINA, t1.ID_DOCUMENTO_SUBIDO IDDOCUMENTOSUBIDO, "
				+ " t2.ID_DIRECCION IDDIRECCION, t2.DESCRIPCION_CASTELLANO DESCRIPCIONCASTELLANO, "
				+ " t2.DESCRIPCION_EUSKERA DESCRIPCIONEUSKERA , t2.FECHA_INICIO FECHAINICIO, t2.FECHA_FIN FECHAFIN, t2.IDENTIFICADOR_CAMPAINA IDENTIFICADORCAMPAINA, "
				+ " t2.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t2.ID_PROTOCOLO IDPROTOCOLO, "
				+ " t3.DESCRIPCION_CASTELLANO DIRECCIONDESCES, t3.DESCRIPCION_EUSKERA DIRECCIONDESCEU, "
				+ " t4.DESCRIPCION_CASTELLANO PROCEDIMIENTODESCES, t4.DESCRIPCION_EUSKERA PROCEDIMIENTODESCEU, t4.COD_PROCEDURE_ID CODPROCEDUREID, "
				+ " t5.DESCRIPCION_CASTELLANO PROTOCOLODESCES, t5.DESCRIPCION_EUSKERA PROTOCOLODESCEU, "
				+ " t6.ID_TIPO_PLANTILLA IDTIPOPLANTILLA, t6.NOMBRE_DOCUMENTO NOMBREDOCUMENTO, t6.OID_PID OIDPID, "
				+ " t6.FECHA_APORTADO_PID FECHAAPORTADOPID, t6.OID_DOKUSI OIDDOKUSI, t6.APORTADO_EXPEDIENTE APORTADOEXPEDIENTE, "
				+ " t7.ID_REL_ACT_DOC IDRELACTDOC, t7.ID_ACTUACION IDACTUACION, t7.ENVIADO_PRO_SAN ENVIADOPROSAN, "
				+ " t9.ID_PLANTILLA IDPLANTILLA, t9.DESCRIPCION_CASTELLANO PLANTILLADESCES, t9.DESCRIPCION_EUSKERA PLANTILLADESCEU "
				+ " FROM REL_CAM_DOC t1, CAMPAINAS_INSPECCION t2, DIRECCIONES t3, PROCEDIMIENTOS t4, PROTOCOLOS t5, DOCUMENTOS_SUBIDOS t6, REL_ACT_DOC t7, TIPOS_PLANTILLA t8, PLANTILLAS t9 "
				+ " WHERE 1=1 AND t1.ID_CAMPAINA = t2.ID_CAMPAINA(+) AND t1.ID_DOCUMENTO_SUBIDO = t6.ID_DOCUMENTO_SUBIDO(+) AND t2.ID_DIRECCION = t3.ID_DIRECCION(+) AND t2.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO(+) AND t2.ID_PROTOCOLO = t5.ID_PROTOCOLO(+) "
				+ " AND t6.ID_DOCUMENTO_SUBIDO = t7.ID_DOCUMENTO_SUBIDO(+) AND t6.ID_TIPO_PLANTILLA = t8.ID_TIPO_PLANTILLA(+) AND t6.ID_PLANTILLA = t9.ID_PLANTILLA(+) AND t1.ID_REL_CAM_DOC = ?  ";

		List<RelCamDoc> relCamDocList = this.jdbcTemplate.query(query, this.rwMap, relCamDoc.getIdRelCamDoc());
		return DataAccessUtils.uniqueResult(relCamDocList);
	}

	/**
	 * Removes a single row in the RelCamDoc table.
	 *
	 * @param relCamDoc
	 *            RelCamDoc
	 * @return
	 */
	@Override
	public void remove(RelCamDoc relCamDoc) {
		String query = "DELETE FROM REL_CAM_DOC WHERE ID_REL_CAM_DOC=?";
		this.jdbcTemplate.update(query, relCamDoc.getIdRelCamDoc());
	}

	@Override
	public void removeByIdDocumentoSubido(RelCamDoc relCamDoc) {
		String query = "DELETE FROM REL_CAM_DOC WHERE ID_DOCUMENTO_SUBIDO=?";
		this.jdbcTemplate.update(query, relCamDoc.getDocumentoSubido().getIdDocumentoSubido());
	}

	@Override
	@Transactional(readOnly = true)
	public List<RelCamDoc> findAll(RelCamDoc relCamDoc, TableRequestDto tableRequestDto) {
		StringBuilder query = new StringBuilder(
				"SELECT t1.ID_REL_CAM_DOC IDRELCAMDOC, t1.ID_CAMPAINA IDCAMPAINA, t1.ID_DOCUMENTO_SUBIDO IDDOCUMENTOSUBIDO, "
						+ " t2.ID_DIRECCION IDDIRECCION, t2.DESCRIPCION_CASTELLANO DESCRIPCIONCASTELLANO, "
						+ " t2.DESCRIPCION_EUSKERA DESCRIPCIONEUSKERA , t2.FECHA_INICIO FECHAINICIO, t2.FECHA_FIN FECHAFIN, t2.IDENTIFICADOR_CAMPAINA IDENTIFICADORCAMPAINA, "
						+ " t2.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t2.ID_PROTOCOLO IDPROTOCOLO, "
						+ " t3.DESCRIPCION_CASTELLANO DIRECCIONDESCES, t3.DESCRIPCION_EUSKERA DIRECCIONDESCEU, "
						+ " t4.DESCRIPCION_CASTELLANO PROCEDIMIENTODESCES, t4.DESCRIPCION_EUSKERA PROCEDIMIENTODESCEU, t4.COD_PROCEDURE_ID CODPROCEDUREID, "
						+ " t5.DESCRIPCION_CASTELLANO PROTOCOLODESCES, t5.DESCRIPCION_EUSKERA PROTOCOLODESCEU, "
						+ " t6.ID_TIPO_PLANTILLA IDTIPOPLANTILLA, t6.NOMBRE_DOCUMENTO NOMBREDOCUMENTO, t6.OID_PID OIDPID, "
						+ " t6.FECHA_APORTADO_PID FECHAAPORTADOPID, t6.OID_DOKUSI OIDDOKUSI, t6.APORTADO_EXPEDIENTE APORTADOEXPEDIENTE, "
						+ " t7.ID_REL_ACT_DOC IDRELACTDOC, t7.ID_ACTUACION IDACTUACION, t7.ENVIADO_PRO_SAN ENVIADOPROSAN, "
						+ " t9.ID_PLANTILLA IDPLANTILLA, t9.DESCRIPCION_CASTELLANO PLANTILLADESCES, t9.DESCRIPCION_EUSKERA PLANTILLADESCEU ");
		query.append(
				" FROM REL_CAM_DOC t1, CAMPAINAS_INSPECCION t2, DIRECCIONES t3, PROCEDIMIENTOS t4, PROTOCOLOS t5, DOCUMENTOS_SUBIDOS t6, REL_ACT_DOC t7, TIPOS_PLANTILLA t8, PLANTILLAS t9 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(relCamDoc);
		StringBuilder where = new StringBuilder(
				" WHERE 1=1 AND t1.ID_CAMPAINA = t2.ID_CAMPAINA(+) AND t1.ID_DOCUMENTO_SUBIDO = t6.ID_DOCUMENTO_SUBIDO(+) AND t2.ID_DIRECCION = t3.ID_DIRECCION(+) AND t2.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO(+) AND t2.ID_PROTOCOLO = t5.ID_PROTOCOLO(+) "
						+ " AND t6.ID_DOCUMENTO_SUBIDO = t7.ID_DOCUMENTO_SUBIDO(+) AND t6.ID_TIPO_PLANTILLA = t8.ID_TIPO_PLANTILLA(+) AND t6.ID_PLANTILLA = t9.ID_PLANTILLA(+) ");
		where.append(mapaWhere.get("query"));
		query.append(where);

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

		if (tableRequestDto != null) {
			query = TableManager.getPaginationQuery(tableRequestDto, query, RelCamDocDaoImpl.ORDER_BY_WHITE_LIST);
		}

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

	@Override
	@Transactional(readOnly = true)
	public List<RelCamDoc> findAllLike(RelCamDoc relCamDoc, TableRequestDto tableRequestDto, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT t1.ID_REL_CAM_DOC IDRELCAMDOC, t1.ID_CAMPAINA IDCAMPAINA, t1.ID_DOCUMENTO_SUBIDO IDDOCUMENTOSUBIDO, "
						+ " t2.ID_DIRECCION IDDIRECCION, t2.DESCRIPCION_CASTELLANO DESCRIPCIONCASTELLANO, "
						+ " t2.DESCRIPCION_EUSKERA DESCRIPCIONEUSKERA , t2.FECHA_INICIO FECHAINICIO, t2.FECHA_FIN FECHAFIN, t2.IDENTIFICADOR_CAMPAINA IDENTIFICADORCAMPAINA, "
						+ " t2.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t2.ID_PROTOCOLO IDPROTOCOLO, "
						+ " t3.DESCRIPCION_CASTELLANO DIRECCIONDESCES, t3.DESCRIPCION_EUSKERA DIRECCIONDESCEU, "
						+ " t4.DESCRIPCION_CASTELLANO PROCEDIMIENTODESCES, t4.DESCRIPCION_EUSKERA PROCEDIMIENTODESCEU, t4.COD_PROCEDURE_ID CODPROCEDUREID, "
						+ " t5.DESCRIPCION_CASTELLANO PROTOCOLODESCES, t5.DESCRIPCION_EUSKERA PROTOCOLODESCEU, "
						+ " t6.ID_TIPO_PLANTILLA IDTIPOPLANTILLA, t6.NOMBRE_DOCUMENTO NOMBREDOCUMENTO, t6.OID_PID OIDPID, "
						+ " t6.FECHA_APORTADO_PID FECHAAPORTADOPID, t6.OID_DOKUSI OIDDOKUSI, t6.APORTADO_EXPEDIENTE APORTADOEXPEDIENTE, "
						+ " t7.ID_REL_ACT_DOC IDRELACTDOC, t7.ID_ACTUACION IDACTUACION, t7.ENVIADO_PRO_SAN ENVIADOPROSAN, "
						+ " t9.ID_PLANTILLA IDPLANTILLA, t9.DESCRIPCION_CASTELLANO PLANTILLADESCES, t9.DESCRIPCION_EUSKERA PLANTILLADESCEU ");
		query.append(
				" FROM REL_CAM_DOC t1, CAMPAINAS_INSPECCION t2, DIRECCIONES t3, PROCEDIMIENTOS t4, PROTOCOLOS t5, DOCUMENTOS_SUBIDOS t6, REL_ACT_DOC t7, TIPOS_PLANTILLA t8, PLANTILLAS t9 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(relCamDoc, startsWith);
		StringBuilder where = new StringBuilder(
				" WHERE 1=1 AND t1.ID_CAMPAINA = t2.ID_CAMPAINA(+) AND t1.ID_DOCUMENTO_SUBIDO = t6.ID_DOCUMENTO_SUBIDO(+) AND t2.ID_DIRECCION = t3.ID_DIRECCION(+) AND t2.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO(+) AND t2.ID_PROTOCOLO = t5.ID_PROTOCOLO(+) "
						+ " AND t6.ID_DOCUMENTO_SUBIDO = t7.ID_DOCUMENTO_SUBIDO(+) AND t6.ID_TIPO_PLANTILLA = t8.ID_TIPO_PLANTILLA(+) AND t6.ID_PLANTILLA = t9.ID_PLANTILLA(+) ");
		where.append(mapaWhere.get("query"));
		query.append(where);

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

		if (tableRequestDto != null) {
			query = TableManager.getPaginationQuery(tableRequestDto, query, RelCamDocDaoImpl.ORDER_BY_WHITE_LIST);
		}

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

	@Override
	@Transactional(readOnly = true)
	public Long findAllCount(RelCamDoc relCamDoc) {
		StringBuilder query = new StringBuilder(
				"SELECT COUNT(1) FROM REL_CAM_DOC t1, CAMPAINAS_INSPECCION t2, DIRECCIONES t3, PROCEDIMIENTOS t4, PROTOCOLOS t5, DOCUMENTOS_SUBIDOS t6, REL_ACT_DOC t7, TIPOS_PLANTILLA t8, PLANTILLAS t9 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereMap(relCamDoc);
		StringBuilder where = new StringBuilder(
				"  WHERE 1=1 AND t1.ID_CAMPAINA = t2.ID_CAMPAINA(+) AND t1.ID_DOCUMENTO_SUBIDO = t6.ID_DOCUMENTO_SUBIDO(+) AND t2.ID_DIRECCION = t3.ID_DIRECCION(+) AND t2.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO(+) AND t2.ID_PROTOCOLO = t5.ID_PROTOCOLO(+) "
						+ " AND t6.ID_DOCUMENTO_SUBIDO = t7.ID_DOCUMENTO_SUBIDO(+) AND t6.ID_TIPO_PLANTILLA = t8.ID_TIPO_PLANTILLA(+) AND t6.ID_PLANTILLA = t9.ID_PLANTILLA(+) ");
		where.append(mapaWhere.get("query"));
		query.append(where);

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

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

	@Override
	@Transactional(readOnly = true)
	public Long findAllLikeCount(RelCamDoc relCamDoc, Boolean startsWith) {
		StringBuilder query = new StringBuilder(
				"SELECT COUNT(1) FROM REL_CAM_DOC t1, CAMPAINAS_INSPECCION t2, DIRECCIONES t3, PROCEDIMIENTOS t4, PROTOCOLOS t5, DOCUMENTOS_SUBIDOS t6, REL_ACT_DOC t7, TIPOS_PLANTILLA t8, PLANTILLAS t9 ");

		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(relCamDoc, startsWith);
		StringBuilder where = new StringBuilder(
				" WHERE 1=1 AND t1.ID_CAMPAINA = t2.ID_CAMPAINA(+) AND t1.ID_DOCUMENTO_SUBIDO = t6.ID_DOCUMENTO_SUBIDO(+) AND t2.ID_DIRECCION = t3.ID_DIRECCION(+) AND t2.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO(+) AND t2.ID_PROTOCOLO = t5.ID_PROTOCOLO(+) "
						+ " AND t6.ID_DOCUMENTO_SUBIDO = t7.ID_DOCUMENTO_SUBIDO(+) AND t6.ID_TIPO_PLANTILLA = t8.ID_TIPO_PLANTILLA(+) AND t6.ID_PLANTILLA = t9.ID_PLANTILLA(+) ");
		where.append(mapaWhere.get("query"));
		query.append(where);

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

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

	@Override
	public List<TableRowDto<RelCamDoc>> reorderSelection(RelCamDoc relCamDoc, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		// SELECT
		StringBuilder query = new StringBuilder(
				"SELECT t1.ID_REL_CAM_DOC IDRELCAMDOC, t1.ID_CAMPAINA IDCAMPAINA, t1.ID_DOCUMENTO_SUBIDO IDDOCUMENTOSUBIDO, "
						+ " t2.ID_DIRECCION IDDIRECCION, t2.DESCRIPCION_CASTELLANO DESCRIPCIONCASTELLANO, "
						+ " t2.DESCRIPCION_EUSKERA DESCRIPCIONEUSKERA , t2.FECHA_INICIO FECHAINICIO, t2.FECHA_FIN FECHAFIN, t2.IDENTIFICADOR_CAMPAINA IDENTIFICADORCAMPAINA, "
						+ " t2.ID_PROCEDIMIENTO IDPROCEDIMIENTO, t2.ID_PROTOCOLO IDPROTOCOLO, "
						+ " t3.DESCRIPCION_CASTELLANO DIRECCIONDESCES, t3.DESCRIPCION_EUSKERA DIRECCIONDESCEU, "
						+ " t4.DESCRIPCION_CASTELLANO PROCEDIMIENTODESCES, t4.DESCRIPCION_EUSKERA PROCEDIMIENTODESCEU, t4.COD_PROCEDURE_ID CODPROCEDUREID, "
						+ " t5.DESCRIPCION_CASTELLANO PROTOCOLODESCES, t5.DESCRIPCION_EUSKERA PROTOCOLODESCEU, "
						+ " t6.ID_TIPO_PLANTILLA IDTIPOPLANTILLA, t6.NOMBRE_DOCUMENTO NOMBREDOCUMENTO, t6.OID_PID OIDPID, "
						+ " t6.FECHA_APORTADO_PID FECHAAPORTADOPID, t6.OID_DOKUSI OIDDOKUSI, t6.APORTADO_EXPEDIENTE APORTADOEXPEDIENTE, "
						+ " t7.ID_REL_ACT_DOC IDRELACTDOC, t7.ID_ACTUACION IDACTUACION, t7.ENVIADO_PRO_SAN ENVIADOPROSAN, "
						+ " t9.ID_PLANTILLA IDPLANTILLA, t9.DESCRIPCION_CASTELLANO PLANTILLADESCES, t9.DESCRIPCION_EUSKERA PLANTILLADESCEU ");
		// FROM
		query.append(
				" FROM REL_CAM_DOC t1, CAMPAINAS_INSPECCION t2, DIRECCIONES t3, PROCEDIMIENTOS t4, PROTOCOLOS t5, DOCUMENTOS_SUBIDOS t6, REL_ACT_DOC t7, TIPOS_PLANTILLA t8, PLANTILLAS t9 ");
		// FILTRADO
		// Where clause & Params
		Map<String, ?> mapaWhere = this.getWhereLikeMap(relCamDoc, startsWith);
		StringBuilder where = new StringBuilder(
				" WHERE 1=1 AND t1.ID_CAMPAINA = t2.ID_CAMPAINA(+) AND t1.ID_DOCUMENTO_SUBIDO = t6.ID_DOCUMENTO_SUBIDO(+) AND t2.ID_DIRECCION = t3.ID_DIRECCION(+) AND t2.ID_PROCEDIMIENTO = t4.ID_PROCEDIMIENTO(+) AND t2.ID_PROTOCOLO = t5.ID_PROTOCOLO(+) "
						+ " AND t6.ID_DOCUMENTO_SUBIDO = t7.ID_DOCUMENTO_SUBIDO(+) AND t6.ID_TIPO_PLANTILLA = t8.ID_TIPO_PLANTILLA(+) AND t6.ID_PLANTILLA = t9.ID_PLANTILLA(+) ");
		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 = TableManager.getReorderQuery(query, tableRequestDto, RelCamDoc.class,
				filterParamList, "ID_REL_CAM_DOC");

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

	private Map<String, ?> getWhereMap(RelCamDoc relCamDoc) {

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

		if (relCamDoc != null && relCamDoc.getIdRelCamDoc() != null) {
			where.append(" AND t1.ID_REL_CAM_DOC = ?");
			params.add(relCamDoc.getIdRelCamDoc());
		}
		if (relCamDoc != null && relCamDoc.getCampainaInspeccion() != null
				&& relCamDoc.getCampainaInspeccion().getIdCampaina() != null) {
			where.append(" AND t1.ID_CAMPAINA = ?");
			params.add(relCamDoc.getCampainaInspeccion().getIdCampaina());
		}
		if (relCamDoc != null && relCamDoc.getDocumentoSubido() != null
				&& relCamDoc.getDocumentoSubido().getIdDocumentoSubido() != null) {
			where.append(" AND t1.ID_DOCUMENTO_SUBIDO = ?");
			params.add(relCamDoc.getDocumentoSubido().getIdDocumentoSubido());
		}

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

		return mapWhere;
	}

	private Map<String, Object> getWhereLikeMap(RelCamDoc relCamDoc, Boolean startsWith) {

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

		if (relCamDoc != null && relCamDoc.getIdRelCamDoc() != null) {
			where.append(" AND t1.ID_REL_CAM_DOC = ?");
			params.add(relCamDoc.getIdRelCamDoc());
		}
		if (relCamDoc != null && relCamDoc.getCampainaInspeccion() != null
				&& relCamDoc.getCampainaInspeccion().getIdCampaina() != null) {
			where.append(" AND t1.ID_CAMPAINA = ?");
			params.add(relCamDoc.getCampainaInspeccion().getIdCampaina());
		}
		if (relCamDoc != null && relCamDoc.getDocumentoSubido() != null
				&& relCamDoc.getDocumentoSubido().getIdDocumentoSubido() != null) {
			where.append(" AND t1.ID_DOCUMENTO_SUBIDO = ?");
			params.add(relCamDoc.getDocumentoSubido().getIdDocumentoSubido());
		}

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

		return mapWhere;
	}

	public static final int STRING_BUILDER_INIT = 4096;

}
