package com.ejie.u74a.dao;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
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.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.u74a.model.CriteriosBusqueda;
import com.ejie.u74a.model.Peticion;
import com.ejie.u74a.model.PeticionInforme;
import com.ejie.u74a.model.Ubicacion;
import com.ejie.u74a.model.UbicacionInforme;
import com.ejie.u74a.util.Constants;
import com.ejie.u74a.util.Utilidades;

/**
 * Clase que accede a la base de datos para obtener datos de peticiones. Tabla: PETICION.
 * 
 *  
 */
@Repository()
@Transactional()
public class PeticionDaoImpl implements PeticionDao {

	private JdbcTemplate jdbcTemplate;

	@Autowired()
	private ArticuloDao articuloDao;

	@Resource(name = "appMessageSource")
	private ReloadableResourceBundleMessageSource messageSource;

	public static final HashMap<String, String> ORDER_BY_SOLICITUDES = new HashMap<String, String>();
	static {
		ORDER_BY_SOLICITUDES.put("fechaPeticion", "P.FEPETICION");
		ORDER_BY_SOLICITUDES.put("descripcionEstado", "P.ESTADO");
		ORDER_BY_SOLICITUDES.put("descripcionSolicitante", "O.T02_NOOFI");
		ORDER_BY_SOLICITUDES.put("numPedido", "P.NUMPEDIDO");
		ORDER_BY_SOLICITUDES.put("descripcionTipo",
				new Locale("eu").equals(LocaleContextHolder.getLocale()) ? "TM.ABREVIATURA_EU" : "TM.ABREVIATURA");
		ORDER_BY_SOLICITUDES.put("descripcionMaterial",
				new Locale("eu").equals(LocaleContextHolder.getLocale()) ? "M.TITULO_EU" : "M.TITULO");
		ORDER_BY_SOLICITUDES.put("descripcionIdioma", "IDIOMA");
		ORDER_BY_SOLICITUDES.put("fechaEstado", "P.FEESTADO");
	}

	/**
	 * Clase que especifica el mapeo de las columnas de la tabla PETICION con los objetos de la clase Peticion
	 */
	private static final class PeticionRowMapper implements RowMapper<Peticion> {

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int)
		 */
		@Override()
		public Peticion mapRow(ResultSet rs, int rowNum) throws SQLException {

			Peticion peticion = new Peticion();

			peticion.setCodigoPeticion(rs.getInt("COPETICION"));
			peticion.setCodigoArticulo(rs.getInt("COARTICULO"));
			peticion.setFechaPeticion(rs.getDate("FEPETICION"));
			peticion.setNumPedido(rs.getInt("NUMPEDIDO"));
			peticion.setNumAceptado(rs.getInt("NUMACEPTADAS"));
			peticion.setNumEjemplaresCaja(rs.getInt("NUMEJEMCAJA"));
			peticion.setTextoPeticion(rs.getString("TEXTPETICION"));
			peticion.setCodigoSolicitante(rs.getString("COSOL"));
			peticion.setCodigoUbicacion(rs.getInt("COUBICA"));
			peticion.setTextoPuntoRecepcion(rs.getString("TEXTUBICA"));
			peticion.setFechaEstado(rs.getDate("FEESTADO"));
			peticion.setEstado(rs.getString("ESTADO"));
			peticion.setFechaModificacion(rs.getDate("FEMOD"));
			peticion.setCodigoUsuarioModificador(rs.getInt("COUSUMOD"));

			peticion.setTituloCastellano(rs.getString("TITULO"));
			peticion.setTituloEuskera(rs.getString("TITULO_EU"));

			return peticion;
		}
	}

	/**
	 * Clase que especifica el mapeo de las columnas de la tabla PETICION con los objetos de la clase PeticionInforme
	 */
	private static final class PeticionInformeRowMapper implements RowMapper<PeticionInforme> {

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int)
		 */
		@Override()
		public PeticionInforme mapRow(ResultSet rs, int rowNum) throws SQLException {

			PeticionInforme peticionInforme = new PeticionInforme();

			peticionInforme.setCodigoPeticion(rs.getInt("COPETICION"));
			peticionInforme.setCodigoArticulo(rs.getInt("COARTICULO"));
			peticionInforme.setEstado(rs.getString("ESTADO"));
			peticionInforme.setNumPedido(rs.getInt("NUMPEDIDO"));
			peticionInforme.setTituloCastellano(rs.getString("TITULO"));
			peticionInforme.setTituloEuskera(rs.getString("TITULO_EU"));
			peticionInforme.setCodigoAlmacen(rs.getString("COALMACEN"));
			peticionInforme.setNumAceptado(rs.getInt("NUMACEPTADAS"));
			peticionInforme.setTextoPeticion(rs.getString("TEXTPETICION"));
			peticionInforme.setTextoPuntoRecepcion(rs.getString("TEXTUBICA"));

			return peticionInforme;
		}
	}

	/**
	 * Clase que especifica el mapeo de las columnas de la tabla PETICION con los objetos de la clase Peticion
	 * 
	 *  
	 * 
	 */
	private static final class PeticionDetalleRowMapper implements RowMapper<Peticion> {

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int)
		 */
		@Override()
		public Peticion mapRow(ResultSet rs, int rowNum) throws SQLException {

			Peticion peticion = new Peticion();

			peticion.setCodigoPeticion(rs.getInt("COPETICION"));
			peticion.setCodigoArticulo(rs.getInt("COARTICULO"));
			peticion.setFechaPeticion(rs.getDate("FEPETICION"));

			peticion.setNumPedido(rs.getInt("NUMPEDIDO"));
			peticion.setNumAceptado(rs.getInt("NUMACEPTADAS"));
			peticion.setNumEjemplaresCaja(rs.getInt("NUMEJEMCAJA"));
			peticion.setTextoPeticion(rs.getString("TEXTPETICION"));
			peticion.setCodigoSolicitante(rs.getString("COSOL"));
			peticion.setTextoPuntoRecepcion(rs.getString("TEXTUBICA"));
			peticion.setFechaEstado(rs.getDate("FEESTADO"));
			peticion.setEstado(rs.getString("ESTADO"));

			// peticion.setFechaModificacion(rs.getDate("FEMOD"));
			// peticion.setCodigoUsuarioModificador(rs.getInt("COUSUMOD"));

			peticion.setTituloCastellano(rs.getString("TITULO"));
			peticion.setTituloEuskera(rs.getString("TITULO_EU"));

			if (new Locale("eu").equals(LocaleContextHolder.getLocale())) {
				peticion.setDescripcionMaterial(peticion.getTituloEuskera());
				peticion.setDescripcionTipo(rs.getString("NOTIPOMAT_EU"));
			} else {
				peticion.setDescripcionMaterial(peticion.getTituloCastellano());
				peticion.setDescripcionTipo(rs.getString("NOTIPOMAT"));
			}

			Ubicacion ubicacion = new Ubicacion();
			ubicacion.setNombreUbicacion(rs.getString("T07_NOUBICA"));
			ubicacion.setNombreDireccion(rs.getString("T07_NODIR"));
			ubicacion.setCodigoPostal(rs.getString("T07_COCP"));
			if (new Locale("eu").equals(LocaleContextHolder.getLocale())) {
				ubicacion.setNombreProvincia(rs.getString("NOMPROVINCE"));
			} else {
				ubicacion.setNombreProvincia(rs.getString("NOMPROVINC"));
			}
			ubicacion.setNombreMunicipio(rs.getString("NOMMUNICIP"));
			ubicacion.setNombreLocalidad(rs.getString("NOMLOCALID"));

			ubicacion.setExtranjero(rs.getInt("T07_EXTRANJERA"));
			ubicacion.setDireccionExtranjero(rs.getString("T07_NODIREXTRANJERA"));

			peticion.setUbicacion(ubicacion);

			return peticion;
		}
	}

	/**
	 * Clase que especifica el mapeo de las columnas de las tablas PETICION, UBICACION, con los objetos de la clase
	 * UbicacionInforme
	 */
	private static final class UbicacionInformeRowMapper implements RowMapper<UbicacionInforme> {

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int)
		 */
		@Override()
		public UbicacionInforme mapRow(ResultSet rs, int rowNum) throws SQLException {

			UbicacionInforme ubicacionInforme = new UbicacionInforme();

			ubicacionInforme.setCodigoUbicacion(rs.getInt("COUBICA"));
			ubicacionInforme.setNombreOficina(rs.getString("T02_NOOFI"));
			ubicacionInforme.setNombreUbicacion(rs.getString("T07_NOUBICA"));
			ubicacionInforme.setDireccion(rs.getString("T07_NODIR"));
			ubicacionInforme.setCodigoPostal(rs.getString("T07_COCP"));
			ubicacionInforme.setNombreProvincia(rs.getString("NOMPROVINC"));
			ubicacionInforme.setNombreMunicipio(rs.getString("NOMMUNICIP"));

			ubicacionInforme.setExtranjero(rs.getInt("T07_EXTRANJERA"));
			ubicacionInforme.setDireccionExtranjero(rs.getString("T07_NODIREXTRANJERA"));

			return ubicacionInforme;
		}
	}

	/**
	 * Método para establecer el datasource.
	 * 
	 * @param dataSource DataSource
	 */
	@Resource()
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ejie.u74a.dao.PeticionDao#insertPeticion(Peticion)
	 */
	@Override()
	public int insertPeticion(Peticion peticion) {

		Object[] insertObj = { peticion.getCodigoArticulo(), peticion.getFechaPeticion(), peticion.getNumPedido(),
				peticion.getNumEjemplaresCaja(), peticion.getTextoPeticion(), peticion.getCodigoSolicitante(),
				peticion.getCodigoUbicacion(), peticion.getTextoPuntoRecepcion(), peticion.getFechaEstado(),
				peticion.getEstado(), peticion.getFechaModificacion(), peticion.getCodigoUsuarioModificador() };

		this.jdbcTemplate
				.update("INSERT INTO PETICION (COPETICION,COARTICULO,FEPETICION,NUMPEDIDO,NUMEJEMCAJA,TEXTPETICION,COSOL,COUBICA,TEXTUBICA,FEESTADO,ESTADO,FEMOD,COUSUMOD) VALUES (U74A53Q00.NEXTVAL ,?,?,?,?,?,?,?,?,?,?,?,?)",
						insertObj);
		// TODO devolver el id?
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ejie.u74a.dao.PeticionDao#findByCodigo(int)
	 */
	@Transactional(readOnly = true)
	@Override()
	public Peticion findByCodigo(int codigoPeticion) {

		Peticion peticion = this.jdbcTemplate
				.queryForObject(
						"SELECT P.COPETICION,P.COARTICULO,P.FEPETICION,P.NUMPEDIDO, P.NUMACEPTADAS,P.NUMEJEMCAJA,P.TEXTPETICION,P.COSOL,P.COUBICA,P.TEXTUBICA,P.FEESTADO,P.ESTADO,P.FEMOD,P.COUSUMOD,M.TITULO,M.TITULO_EU FROM PETICION P INNER JOIN ARTICULO A ON P.COARTICULO=A.COARTICULO INNER JOIN MATERIAL M ON A.COMATERIAL=M.COMATERIAL WHERE COPETICION = ?",
						new PeticionRowMapper(), codigoPeticion);

		if (new Locale("eu").equals(LocaleContextHolder.getLocale())) {
			peticion.setDescripcionMaterial(peticion.getTituloEuskera());
		} else {
			peticion.setDescripcionMaterial(peticion.getTituloCastellano());
		}
		return peticion;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ejie.u74a.dao.PeticionDao#findByCriteria(CriteriosBusqueda)
	 */
	@Transactional(readOnly = true)
	@Override()
	public List<Peticion> findByCriteria(CriteriosBusqueda filtro) {

		StringBuilder query = new StringBuilder(
				"SELECT P.COPETICION,P.COARTICULO,P.FEPETICION,P.NUMPEDIDO, P.NUMACEPTADAS, P.NUMEJEMCAJA,P.FEESTADO,P.ESTADO,P.COSOL, P.TEXTPETICION, P.TEXTUBICA")
				.append(",M.TITULO,M.TITULO_EU,TM.ABREVIATURA,TM.ABREVIATURA_EU,O.T02_NOOFI, GET_DESC_IDIOMA(P.COARTICULO, '"
						+ LocaleContextHolder.getLocale() + "') IDIOMA ");

		Map<String, ?> mapaWhere = getWhereMapSolicitudesRecibidasByCriteria(filtro);
		query.append(mapaWhere.get("query"));
		List<?> argumentos = (List<?>) mapaWhere.get("params");

		// ordeno la tabla por la columna que haya clicado
		if (filtro.getSort() != null && !"".equals(filtro.getSort())) {
			query.append(" ORDER BY ").append(ORDER_BY_SOLICITUDES.get(filtro.getSort())).append(" ")
					.append(filtro.getOrder());
		} else {
			query.append(" ORDER BY P.FEPETICION DESC");
		}

		// Se obtiene la consulta final incluyendo la paginación.
		StringBuilder queryFinal = new StringBuilder(Utilidades.getPaginationQuery(query, filtro.getOffset(),
				filtro.getLimit(), null, null).toString());

		List<Map<String, Object>> rowsList = this.jdbcTemplate
				.queryForList(queryFinal.toString(), argumentos.toArray());

		List<Peticion> peticionesLst = new ArrayList<Peticion>();
		Locale localeEus = new Locale("eu");
		for (Map<String, Object> row : rowsList) {

			Peticion peticion = new Peticion();

			peticion.setCodigoPeticion(((BigDecimal) row.get("COPETICION")).intValue());
			peticion.setCodigoArticulo(((BigDecimal) row.get("COARTICULO")).intValue());
			peticion.setFechaPeticion((Date) row.get("FEPETICION"));
			peticion.setNumPedido(((BigDecimal) row.get("NUMPEDIDO")).intValue());
			if (row.get("NUMACEPTADAS") != null) {
				peticion.setNumAceptado(((BigDecimal) row.get("NUMACEPTADAS")).intValue());
			}
			peticion.setNumEjemplaresCaja(((BigDecimal) row.get("NUMEJEMCAJA")).intValue());
			peticion.setFechaEstado((Date) row.get("FEESTADO"));
			peticion.setEstado((String) row.get("ESTADO"));
			peticion.setCodigoSolicitante((String) row.get("COSOL"));

			peticion.setDescripcionSolicitante((String) row.get("T02_NOOFI"));

			peticion.setDescripcionEstado(this.messageSource.getMessage("solicitud.estado." + peticion.getEstado(),
					null, LocaleContextHolder.getLocale()));

			peticion.setDescripcionMaterial((String) row.get("TITULO"));
			if (localeEus.equals(LocaleContextHolder.getLocale())) {
				peticion.setDescripcionMaterial((String) row.get("TITULO_EU"));
			}

			peticion.setDescripcionTipo((String) row.get("ABREVIATURA"));
			if (localeEus.equals(LocaleContextHolder.getLocale())) {
				peticion.setDescripcionTipo((String) row.get("ABREVIATURA_EU"));
			}

			//
			// peticion.setDescripcionIdioma(this.articuloDao.getDescripcionIdiomasArticulo(peticion.getCodigoArticulo()));
			if (Constants.MULTILINGUE.equals(row.get("IDIOMA"))) {
				peticion.setDescripcionIdioma(this.messageSource.getMessage("comun.multilingue", null,
						LocaleContextHolder.getLocale()));
			} else if (Constants.SIN_IDIOMA.equals(row.get("IDIOMA"))) {
				peticion.setDescripcionIdioma(this.messageSource.getMessage("comun.sinIdioma", null,
						LocaleContextHolder.getLocale()));
			} else {
				peticion.setDescripcionIdioma((String) row.get("IDIOMA"));
			}

			peticion.setTextoPeticion((String) row.get("TEXTPETICION"));
			peticion.setTextoPuntoRecepcion((String) row.get("TEXTUBICA"));

			peticionesLst.add(peticion);
		}

		return peticionesLst;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ejie.u74a.dao.PeticionDao#findByCriteria(CriteriosBusqueda)
	 */
	@Transactional(readOnly = true)
	@Override()
	public int findByCountCriteria(CriteriosBusqueda filtro) {

		// De momento no recupero datos extras de temaMaterial ni tipoMaterial, solo los que se van a mostrar por
		// pantalla
		StringBuilder query = new StringBuilder("SELECT COUNT(COPETICION) ");

		Map<String, ?> mapaWhere = getWhereMapSolicitudesRecibidasByCriteria(filtro);
		query.append(mapaWhere.get("query"));
		List<?> argumentos = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForObject(query.toString(), argumentos.toArray(), Integer.class);
	}

	/**
	 * Devuelve un mapa con la query a ejecutar y los parámetros de búsqueda
	 * 
	 * @param filtro datos del filtro
	 * @return query a ejecutar
	 */
	private Map<String, ?> getWhereMapSolicitudesRecibidasByCriteria(CriteriosBusqueda filtro) {
		StringBuilder query = new StringBuilder();
		List<Object> argumentos = new ArrayList<Object>();

		query.append(" FROM PETICION P INNER JOIN ARTICULO A ON P.COARTICULO=A.COARTICULO INNER JOIN MATERIAL M ON A.COMATERIAL=M.COMATERIAL ");
		query.append("INNER JOIN TIPOMATERIAL TM ON M.COTIPOMAT=TM.COTIPOMAT INNER JOIN OFICINAS O ON P.COSOL=O.T02_COOR ");

		query.append(" WHERE 1=1 ");
		// Cuidado, si cambia algo del filtro en el método findByCriteria hay que cambiarlo también aquí.
		if (filtro.getTexto() != null && !"".equals(filtro.getTexto())) {
			query.append(" AND (UPPER(TITULO) LIKE UPPER(?) or UPPER(TITULO_EU) LIKE UPPER(?)) ");
			argumentos.add("%" + filtro.getTexto() + "%");
			argumentos.add("%" + filtro.getTexto() + "%");
		}
		if (filtro.getTipoMaterial() != null && !"".equals(filtro.getTipoMaterial())) {
			query.append(" AND TM.COTIPOMAT = ? ");
			argumentos.add(filtro.getTipoMaterial());
		}

		if (filtro.getIdioma() != null && !"".equals(filtro.getIdioma())) {
			query.append(" AND ")
					.append(" exists (SELECT IA.COIDIOMA FROM IDIOMASARTICULO IA WHERE IA.COARTICULO=A.COARTICULO AND A.COMATERIAL=M.COMATERIAL AND IA.COIDIOMA = ?) ");
			argumentos.add(filtro.getIdioma());
		}
		if (filtro.getFecha1() != null) {
			query.append(" AND TRUNC(P.FEPETICION) >= ? ");
			argumentos.add(filtro.getFecha1());
		}
		if (filtro.getFecha2() != null) {
			query.append(" AND TRUNC(P.FEPETICION) <= ? ");
			argumentos.add(filtro.getFecha2());
		}

		if (filtro.getEstado() != null && !"".equals(filtro.getEstado())) {
			query.append(" AND P.ESTADO = ? ");
			argumentos.add(filtro.getEstado());
		}

		// si estamos buscando por estado "Aceptadas"
		if (Constants.ESTADO_ACEPTADA.equals(filtro.getEstado())) {
			// tengo en cuenta el filtro por fecha de aceptación
			if (filtro.getFecha3() != null) {
				query.append(" AND TRUNC(P.FEESTADO) >= ? ");
				argumentos.add(filtro.getFecha3());
			}
			if (filtro.getFecha4() != null) {
				query.append(" AND TRUNC(P.FEESTADO) <= ? ");
				argumentos.add(filtro.getFecha4());
			}
		}

		if (filtro.getCodigos() != null && !filtro.getCodigos().isEmpty()) {
			String coma = "";
			StringBuffer codigos = new StringBuffer();
			for (int codigo : filtro.getCodigos()) {
				codigos.append(coma).append(codigo);
				coma = ",";
			}

			query.append(" AND P.COPETICION IN (").append(codigos).append(") ");

		}

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

		return mapWhere;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ejie.u74a.dao.PeticionDao#cambiarEstadoPeticion(int,String)
	 */
	@Transactional()
	@Override()
	public int cambiarEstadoPeticion(Peticion peticion) {
		Object[] updateObj = { peticion.getEstado(), peticion.getNumAceptado(), peticion.getCodigoPeticion() };
		return this.jdbcTemplate
				.update("UPDATE PETICION SET ESTADO = ?, NUMACEPTADAS = ?,  FEESTADO = SYSDATE WHERE COPETICION = ?",
						updateObj);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ejie.u74a.dao.PeticionDao#findUbicacionByCodigo(int)
	 */
	@Transactional(readOnly = true)
	@Override()
	public UbicacionInforme findUbicacionByCodigo(int codigoPeticion) {
		UbicacionInforme ubicacionInforme = this.jdbcTemplate
				.queryForObject(
						"SELECT P.COUBICA, U.T07_NOUBICA, U.T07_NODIR, U.T07_COCP, O.T02_NOOFI, PR.NOMPROVINC, M.NOMMUNICIP, U.T07_EXTRANJERA, U.T07_NODIREXTRANJERA "
								+ "FROM PETICION P INNER JOIN UBICACIONES U ON P.COUBICA=U.T07_COUBICA INNER JOIN OFICINAS O ON U.T07_COOR=O.T02_COOR LEFT JOIN PROVINCIA PR ON PR.CODPROVINC=U.T07_CODPROVINC LEFT JOIN MUNICIPIO M ON M.CODPROVINC=U.T07_CODPROVINC AND M.CODMUNICIP=U.T07_CODMUNICIP WHERE COPETICION = ?",
						new UbicacionInformeRowMapper(), codigoPeticion);

		return ubicacionInforme;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ejie.u74a.dao.PeticionDao#findPeticionInformeByCodigo(int)
	 */
	@Transactional(readOnly = true)
	@Override()
	public PeticionInforme findPeticionInformeByCodigo(int codigoPeticion) {
		StringBuilder query = new StringBuilder();
		query.append("SELECT P.COPETICION, P.COARTICULO, P.NUMPEDIDO, P.ESTADO, ")
				.append(" M.TITULO, M.TITULO_EU, A.COALMACEN, P.TEXTPETICION, P.TEXTUBICA, P.NUMACEPTADAS ")
				.append(" FROM PETICION P INNER JOIN ARTICULO A ON P.COARTICULO=A.COARTICULO INNER JOIN MATERIAL M ON A.COMATERIAL=M.COMATERIAL ")
				.append(" WHERE COPETICION = ? ");

		PeticionInforme peticionInforme = this.jdbcTemplate.queryForObject(query.toString(),
				new PeticionInformeRowMapper(), codigoPeticion);

		if (new Locale("eu").equals(LocaleContextHolder.getLocale())) {
			peticionInforme.setDescripcionMaterial(peticionInforme.getTituloEuskera());
		} else {
			peticionInforme.setDescripcionMaterial(peticionInforme.getTituloCastellano());
		}

		peticionInforme.setDescripcionIdioma(this.articuloDao.getDescripcionIdiomasArticulo(peticionInforme
				.getCodigoArticulo()));

		return peticionInforme;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ejie.u74a.dao.PeticionDao#findByCriteriaMisSolicitudes(com.ejie.u74a.model.CriteriosBusqueda)
	 */
	@Transactional(readOnly = true)
	@Override()
	public List<Peticion> findByCriteriaMisSolicitudes(CriteriosBusqueda filtro) {

		StringBuilder query = new StringBuilder();

		query.append("SELECT P.COPETICION,P.COARTICULO,P.FEPETICION,P.NUMPEDIDO,P.NUMEJEMCAJA,P.FEESTADO,P.ESTADO,P.COSOL");
		query.append(",M.TITULO,M.TITULO_EU,TM.ABREVIATURA,TM.ABREVIATURA_EU, GET_DESC_IDIOMA(P.COARTICULO, '"
				+ LocaleContextHolder.getLocale() + "') IDIOMA ");

		Map<String, ?> mapaWhere = getWhereMapMisSolicitudesByCriteria(filtro);
		query.append(mapaWhere.get("query"));
		List<?> argumentos = (List<?>) mapaWhere.get("params");

		// ordeno la tabla por la columna que haya clicado
		if (filtro.getSort() != null && !"".equals(filtro.getSort())) {
			query.append(" ORDER BY ").append(ORDER_BY_SOLICITUDES.get(filtro.getSort())).append(" ")
					.append(filtro.getOrder());
		} else {
			query.append(" ORDER BY P.FEPETICION DESC");
		}

		// query.append("ORDER BY FEPETICION DESC");

		// Se obtiene la consulta final incluyendo la paginación.
		StringBuilder queryFinal = new StringBuilder(Utilidades.getPaginationQuery(query, filtro.getOffset(),
				filtro.getLimit(), null, null).toString());

		List<Map<String, Object>> rowsList = this.jdbcTemplate
				.queryForList(queryFinal.toString(), argumentos.toArray());

		List<Peticion> peticionesLst = new ArrayList<Peticion>();
		Locale localeEus = new Locale("eu");
		for (Map<String, Object> row : rowsList) {

			Peticion peticion = new Peticion();

			peticion.setCodigoPeticion(((BigDecimal) row.get("COPETICION")).intValue());
			peticion.setCodigoArticulo(((BigDecimal) row.get("COARTICULO")).intValue());
			peticion.setFechaPeticion((Date) row.get("FEPETICION"));
			peticion.setNumPedido(((BigDecimal) row.get("NUMPEDIDO")).intValue());
			peticion.setNumEjemplaresCaja(((BigDecimal) row.get("NUMEJEMCAJA")).intValue());
			peticion.setFechaEstado((Date) row.get("FEESTADO"));
			peticion.setEstado((String) row.get("ESTADO"));

			peticion.setDescripcionEstado(this.messageSource.getMessage("solicitud.estado." + peticion.getEstado(),
					null, LocaleContextHolder.getLocale()));

			peticion.setDescripcionMaterial((String) row.get("TITULO"));
			if (localeEus.equals(LocaleContextHolder.getLocale())) {
				peticion.setDescripcionMaterial((String) row.get("TITULO_EU"));
			}

			peticion.setDescripcionTipo((String) row.get("ABREVIATURA"));
			if (localeEus.equals(LocaleContextHolder.getLocale())) {
				peticion.setDescripcionTipo((String) row.get("ABREVIATURA_EU"));
			}

			// peticion.setDescripcionIdioma(this.articuloDao.getDescripcionIdiomasArticulo(peticion.getCodigoArticulo()));
			if (Constants.MULTILINGUE.equals(row.get("IDIOMA"))) {
				peticion.setDescripcionIdioma(this.messageSource.getMessage("comun.multilingue", null,
						LocaleContextHolder.getLocale()));
			} else if (Constants.SIN_IDIOMA.equals(row.get("IDIOMA"))) {
				peticion.setDescripcionIdioma(this.messageSource.getMessage("comun.sinIdioma", null,
						LocaleContextHolder.getLocale()));
			} else {
				peticion.setDescripcionIdioma((String) row.get("IDIOMA"));
			}

			peticionesLst.add(peticion);
		}

		return peticionesLst;
	}

	@Transactional(readOnly = true)
	@Override()
	public int findByCountCriteriaMisSolicitudes(CriteriosBusqueda filtro) {

		StringBuilder query = new StringBuilder("SELECT COUNT(COPETICION) ");

		// Where clause & Params
		Map<String, ?> mapaWhere = getWhereMapMisSolicitudesByCriteria(filtro);
		query.append(mapaWhere.get("query"));
		List<?> argumentos = (List<?>) mapaWhere.get("params");

		return this.jdbcTemplate.queryForObject(query.toString(), Integer.class, argumentos.toArray());
	}

	/**
	 * Devuelve un mapa con la query a ejecutar y los parámetros de búsqueda
	 * 
	 * @param filtro datos del filtro
	 * @return query a ejecutar
	 */
	private Map<String, ?> getWhereMapMisSolicitudesByCriteria(CriteriosBusqueda filtro) {
		StringBuilder query = new StringBuilder();
		List<Object> argumentos = new ArrayList<Object>();

		query.append(" FROM PETICION P INNER JOIN ARTICULO A ON P.COARTICULO=A.COARTICULO INNER JOIN MATERIAL M ON A.COMATERIAL=M.COMATERIAL ");
		query.append(" INNER JOIN TIPOMATERIAL TM ON M.COTIPOMAT=TM.COTIPOMAT ");

		query.append(" WHERE P.COSOL = ? ");
		argumentos.add(Utilidades.getDetallesUsuario().getCodigoOficina());

		// Cuidado, si cambia algo del filtro, hay que cambiar en el método findByCountCriteria que devuelve el contador
		// de la consulta para la paginación.
		if (filtro.getTexto() != null && !"".equals(filtro.getTexto())) {
			query.append(" AND (UPPER(TITULO) LIKE UPPER(?) or UPPER(TITULO_EU) LIKE UPPER(?)) ");
			argumentos.add("%" + filtro.getTexto() + "%");
			argumentos.add("%" + filtro.getTexto() + "%");
		}
		if (filtro.getTipoMaterial() != null && !"".equals(filtro.getTipoMaterial())) {
			query.append((query.length() == 0 ? " WHERE " : " AND")).append(" TM.COTIPOMAT = ? ");
			argumentos.add(filtro.getTipoMaterial());
		}

		if (filtro.getIdioma() != null && !"".equals(filtro.getIdioma())) {
			query.append(" AND exists (SELECT IA.COIDIOMA FROM ARTICULO A,IDIOMASARTICULO IA WHERE A.COARTICULO = P.COARTICULO AND IA.COARTICULO=A.COARTICULO AND A.COMATERIAL=M.COMATERIAL AND IA.COIDIOMA = ?) ");
			argumentos.add(filtro.getIdioma());
		}
		if (filtro.getFecha1() != null) {
			query.append(" AND TRUNC(P.FEPETICION) >= ? ");
			argumentos.add(filtro.getFecha1());
		}
		if (filtro.getFecha2() != null) {
			query.append(" AND TRUNC(P.FEPETICION) <= ? ");
			argumentos.add(filtro.getFecha2());
		}

		if (filtro.getEstado() != null && !"".equals(filtro.getEstado())) {
			query.append(" AND P.ESTADO = ? ");
			argumentos.add(filtro.getEstado());
		}

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

		return mapWhere;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ejie.u74a.dao.PeticionDao#findDetalleByCodigo(int)
	 */
	@Transactional(readOnly = true)
	@Override()
	public Peticion findDetalleByCodigo(int codigoPeticion) {

		StringBuilder query = new StringBuilder();
		query.append("SELECT P.COPETICION,P.COARTICULO,P.FEPETICION,P.NUMPEDIDO, P.NUMACEPTADAS,P.NUMEJEMCAJA, ");
		query.append(" P.FEESTADO,P.ESTADO,P.COSOL, P.TEXTPETICION, P.TEXTUBICA, M.TITULO,M.TITULO_EU,TM.NOTIPOMAT,TM.NOTIPOMAT_EU, ");
		query.append(" UB.T07_NOUBICA, UB.T07_NODIR, UB.T07_COCP, P.NOMPROVINC, P.NOMPROVINCE, M.NOMMUNICIP, L.NOMLOCALID, ");
		query.append(" UB.T07_EXTRANJERA, UB.T07_NODIREXTRANJERA ");
		query.append(" FROM PETICION P ");
		query.append(" INNER JOIN ARTICULO A ON P.COARTICULO=A.COARTICULO ");
		query.append(" INNER JOIN MATERIAL M ON A.COMATERIAL=M.COMATERIAL ");
		query.append(" INNER JOIN TIPOMATERIAL TM ON M.COTIPOMAT=TM.COTIPOMAT ");
		query.append(" INNER JOIN UBICACIONES UB ON P.COUBICA = UB.T07_COUBICA ");
		query.append(" LEFT JOIN PROVINCIA P ON P.CODPROVINC=UB.T07_CODPROVINC ");
		query.append(" LEFT JOIN MUNICIPIO M ON M.CODPROVINC=UB.T07_CODPROVINC and M.CODMUNICIP=UB.T07_CODMUNICIP ");
		query.append(" LEFT JOIN LOCALIDAD L ON L.CODPROVINC=UB.T07_CODPROVINC and L.CODMUNICIP=UB.T07_CODMUNICIP AND L.CODLOCALID=UB.T07_COLO");
		query.append(" WHERE P.COPETICION = ? ");

		Peticion peticion = this.jdbcTemplate.queryForObject(query.toString(), new PeticionDetalleRowMapper(),
				codigoPeticion);

		peticion.setDescripcionEstado(this.messageSource.getMessage("solicitud.estado." + peticion.getEstado(), null,
				LocaleContextHolder.getLocale()));

		peticion.setDescripcionIdioma(this.articuloDao.getDescripcionIdiomasArticulo(peticion.getCodigoArticulo()));

		return peticion;
	}
}
