package com.ejie.ab79.service.inspecciones;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import javax.activation.MimetypesFileTypeMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.ab79.clientesWS.ab61WebService.Usuario;
import com.ejie.ab79.comun.Constantes;
import com.ejie.ab79.dao.RelEstInsDao;
import com.ejie.ab79.dao.expedientes.DatosDireccionesDao;
import com.ejie.ab79.dao.expedientes.DatosTercerosDao;
import com.ejie.ab79.dao.inspecciones.AgrupacionesDao;
import com.ejie.ab79.dao.inspecciones.CampainasInspeccionDao;
import com.ejie.ab79.dao.inspecciones.EstadosInspeccionDao;
import com.ejie.ab79.dao.inspecciones.InspeccionesDao;
import com.ejie.ab79.dao.inspecciones.ResultadosInspeccionDao;
import com.ejie.ab79.dao.procedimientos.ProcedimientosDao;
import com.ejie.ab79.model.Inspectores;
import com.ejie.ab79.model.RelEstIns;
import com.ejie.ab79.model.REST.servicioWeb.InspeccionDato;
import com.ejie.ab79.model.REST.servicioWeb.InspeccionDocumentacion;
import com.ejie.ab79.model.expedientes.DatosDirecciones;
import com.ejie.ab79.model.expedientes.DatosTerceros;
import com.ejie.ab79.model.expedientes.Expedientes;
import com.ejie.ab79.model.expedientes.RelExpTer;
import com.ejie.ab79.model.inspecciones.Agrupaciones;
import com.ejie.ab79.model.inspecciones.CampainasInspeccion;
import com.ejie.ab79.model.inspecciones.EstadosInspeccion;
import com.ejie.ab79.model.inspecciones.Inspecciones;
import com.ejie.ab79.model.inspecciones.ResultadosInspeccion;
import com.ejie.ab79.model.procedimientos.Procedimientos;
import com.ejie.ab79.model.protocolos.Protocolos;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * InspeccionesServiceImpl  
 * 
 *  
 */

@Service(value = "inspeccionesService")
public class InspeccionesServiceImpl implements InspeccionesService {

	private static final Logger logger = LoggerFactory.getLogger(InspeccionesServiceImpl.class);

	@Resource
	private ReloadableResourceBundleMessageSource appMessageSource;

	@Autowired
	private InspeccionesDao inspeccionesDao;

	@Autowired
	private RelEstInsDao relEstInsDao;

	@Autowired
	private EstadosInspeccionDao estadosInspeccionDao;

	@Autowired
	private ResultadosInspeccionDao resultadosInspeccionDao;

	@Autowired
	private DatosDireccionesDao datosDireccionesDao;

	@Autowired
	private DatosTercerosDao datosTercerosDao;

	@Autowired
	private CampainasInspeccionDao campainasInspeccionDao;

	@Autowired
	private AgrupacionesDao agrupacionesDao;

	@Autowired
	private ProcedimientosDao procedimientosDao;

	/**
	 * Inserts a single row in the Inspecciones table.
	 *
	 * @param inspecciones
	 *            Inspecciones
	 * @return Inspecciones
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public Inspecciones add(Inspecciones inspecciones) {
		return this.inspeccionesDao.add(inspecciones);
	}

	/**
	 * Updates a single row in the Inspecciones table.
	 *
	 * @param inspecciones
	 *            Inspecciones
	 * @return Inspecciones
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public Inspecciones update(Inspecciones inspecciones) {
		return this.inspeccionesDao.update(inspecciones);
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public Inspecciones updateDatosBasicos(Inspecciones inspecciones) {
		return this.inspeccionesDao.updateDatosBasicos(inspecciones);

	}

	/**
	 * Finds a single row in the Inspecciones table.
	 *
	 * @param inspecciones
	 *            Inspecciones
	 * @return Inspecciones
	 */
	@Override
	public Inspecciones find(Inspecciones inspecciones) {
		return this.inspeccionesDao.find(inspecciones);
	}

	@Override
	public Inspecciones findByIdInspeccionMovil(String idInspeccionMovil) {
		return this.inspeccionesDao.findByIdInspeccionMovil(idInspeccionMovil);
	}

	/**
	 * Deletes a single row in the Inspecciones table.
	 *
	 * @param inspecciones
	 *            Inspecciones
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void remove(Inspecciones inspecciones) {
		this.inspeccionesDao.remove(inspecciones);
	}

	/**
	 * Finds a list of rows in the Inspecciones table.
	 *
	 * @param inspecciones
	 *            Inspecciones
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @return List<Inspecciones>
	 */
	@Override
	public List<Inspecciones> findAll(Inspecciones inspecciones, TableRequestDto tableRequestDto) {
		return this.inspeccionesDao.findAll(inspecciones, tableRequestDto);
	}

	/**
	 * Finds rows in the Inspecciones table using like.
	 *
	 * @param inspecciones
	 *            Inspecciones
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<Inspecciones>
	 */
	@Override
	public List<Inspecciones> findAllLike(Inspecciones inspecciones, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.inspeccionesDao.findAllLike(inspecciones, tableRequestDto, startsWith);
	}

	@Override
	public List<InspeccionDato> findInspeccionesREST(String inspector) {
		return this.inspeccionesDao.findInspeccionesREST(inspector);
	}

	@Override
	public List<InspeccionDocumentacion> findDocumentacionInspeccionesREST(String inspector) {
		return this.inspeccionesDao.findDocumentacionInspeccionesREST(inspector);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the Inspecciones table.
	 *
	 * @param filterInspecciones
	 *            Inspecciones
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 */
	@Override
	public void removeMultiple(Inspecciones filterInspecciones, TableRequestDto tableRequestDto, Boolean startsWith) {
		this.inspeccionesDao.removeMultiple(filterInspecciones, tableRequestDto, startsWith);
	}

	/**
	 * Filter method in the Inspecciones table.
	 *
	 * @param filterInspecciones
	 *            Inspecciones
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return TableResponseDto<Inspecciones>
	 */
	@Override
	public TableResponseDto<Inspecciones> filter(Inspecciones filterInspecciones, TableRequestDto tableRequestDto,
			Boolean startsWith) {

		this.fncReordenarInspecciones(tableRequestDto);

		if (filterInspecciones.getIdsComboEstadoInspeccion() != null) {
			List<String> idsComboEstadoInspeccion = new ArrayList<String>();
			String[] str;
			if (!"".equals(filterInspecciones.getIdsComboEstadoInspeccion())) {
				str = filterInspecciones.getIdsComboEstadoInspeccion().split(",");
				idsComboEstadoInspeccion = Arrays.asList(str);
			}

			List<EstadosInspeccion> estadosInspeccion = this.estadosInspeccionDao
					.findByDesEstIns(idsComboEstadoInspeccion);
			if (!estadosInspeccion.isEmpty()) {
				String idsEstadoInspeccion = "";
				for (EstadosInspeccion estadoInspeccion : estadosInspeccion) {
					idsEstadoInspeccion += estadoInspeccion.getIdEstadoInspeccion() + ",";
				}

				idsEstadoInspeccion = idsEstadoInspeccion.substring(0, idsEstadoInspeccion.length() - 1);
				filterInspecciones.setIdsEstadoInspeccion(idsEstadoInspeccion);
			}

		}

		if (filterInspecciones.getResultadoInspeccion() != null
				&& filterInspecciones.getResultadoInspeccion().getDesResIns() != null) {
			List<ResultadosInspeccion> resultadosInspeccion = this.resultadosInspeccionDao
					.findByDesResIns(filterInspecciones.getResultadoInspeccion().getDesResIns());
			if (!resultadosInspeccion.isEmpty()) {
				String idsResultadoInspeccion = "";
				for (ResultadosInspeccion resultadoInspeccion : resultadosInspeccion) {
					idsResultadoInspeccion += resultadoInspeccion.getIdResultadoInspeccion() + ",";
				}

				idsResultadoInspeccion = idsResultadoInspeccion.substring(0, idsResultadoInspeccion.length() - 1);
				filterInspecciones.setIdsResultadoInspeccion(idsResultadoInspeccion);
			}
		}

		List<Inspecciones> listaInspecciones = this.inspeccionesDao.findAllLike(filterInspecciones, tableRequestDto,
				false);

		for (Inspecciones inspeccion : listaInspecciones) {
			if (Constantes.PROPUESTA_EN_TRAMITE.equals(filterInspecciones.getCasoPropuesta())) {
				inspeccion.setCasoPropuesta(Constantes.PROPUESTA_EN_TRAMITE);
			} else if (Constantes.PROPUESTA_ENVIADA.equals(filterInspecciones.getCasoPropuesta())) {
				inspeccion.setCasoPropuesta(Constantes.PROPUESTA_ENVIADA);
			} else if (Constantes.PROPUESTA_EXPEDIENTE_SANCIONADOR.equals(filterInspecciones.getCasoPropuesta())) {
				inspeccion.setCasoPropuesta(Constantes.PROPUESTA_EXPEDIENTE_SANCIONADOR);
			} else if (Constantes.PROPUESTA_SUBSANAR.equals(filterInspecciones.getCasoPropuesta())) {
				inspeccion.setCasoPropuesta(Constantes.PROPUESTA_SUBSANAR);
			} else {

				Inspecciones inspeccionPropuestaEnTramite = this.inspeccionesDao.findPropuestasEnTramite(inspeccion);
				if (inspeccionPropuestaEnTramite != null && inspeccionPropuestaEnTramite.getIdPropuesta() != null) {
					inspeccion.setCasoPropuesta(Constantes.PROPUESTA_EN_TRAMITE);
					inspeccion.setIdPropuesta(inspeccionPropuestaEnTramite.getIdPropuesta());
				} else {
					Inspecciones inspeccionPropuestaEnviada = this.inspeccionesDao.findPropuestasEnviadas(inspeccion);
					if (inspeccionPropuestaEnviada != null && inspeccionPropuestaEnviada.getIdPropuesta() != null) {
						inspeccion.setCasoPropuesta(Constantes.PROPUESTA_ENVIADA);
						inspeccion.setIdPropuesta(inspeccionPropuestaEnviada.getIdPropuesta());
					} else {
						Inspecciones inspeccionPropuestaExpedienteSancionador = this.inspeccionesDao
								.findPropuestasExpedienteSancionador(inspeccion);
						if (inspeccionPropuestaExpedienteSancionador != null
								&& inspeccionPropuestaExpedienteSancionador.getIdPropuesta() != null) {
							inspeccion.setCasoPropuesta(Constantes.PROPUESTA_EXPEDIENTE_SANCIONADOR);
							inspeccion.setIdPropuesta(inspeccionPropuestaExpedienteSancionador.getIdPropuesta());
						} else {
							Inspecciones inspeccionPropuestaSubsanacion = this.inspeccionesDao
									.findPropuestasSubsanacion(inspeccion);
							if (inspeccionPropuestaSubsanacion != null
									&& inspeccionPropuestaSubsanacion.getIdPropuesta() != null) {
								inspeccion.setCasoPropuesta(Constantes.PROPUESTA_SUBSANAR);
								inspeccion.setIdPropuesta(inspeccionPropuestaSubsanacion.getIdPropuesta());
							}
						}
					}
				}

			}
		}

		Long recordNum = this.inspeccionesDao
				.findAllLikeCount(filterInspecciones != null ? filterInspecciones : new Inspecciones(), false);

		TableResponseDto<Inspecciones> usuarioDto = new TableResponseDto<Inspecciones>(tableRequestDto, recordNum,
				listaInspecciones);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<Inspecciones>> reorderSelection = this.inspeccionesDao.reorderSelection(filterInspecciones,
					tableRequestDto, startsWith);
			usuarioDto.setReorderedSelection(reorderSelection);
			usuarioDto.addAdditionalParam("reorderedSelection", reorderSelection);
			usuarioDto.addAdditionalParam("selectedAll", tableRequestDto.getMultiselection().getSelectedAll());
		}
		if (tableRequestDto.getSeeker().getSelectedIds() != null) {
			tableRequestDto.setMultiselection(tableRequestDto.getSeeker());
			List<TableRowDto<Inspecciones>> reorderSeeker = this.inspeccionesDao.reorderSelection(filterInspecciones,
					tableRequestDto, startsWith);
			usuarioDto.setReorderedSeeker(reorderSeeker);
			usuarioDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}

		return usuarioDto;
	}

	/**
	 * Searches rows in the Inspecciones table.
	 *
	 * @param filterInspecciones
	 *            Inspecciones
	 * @param searchInspecciones
	 *            Inspecciones
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<Inspecciones>>
	 */
	@Override
	public List<TableRowDto<Inspecciones>> search(Inspecciones filterInspecciones, Inspecciones searchInspecciones,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.inspeccionesDao.search(filterInspecciones, searchInspecciones, tableRequestDto, startsWith);
	}

	/**
	 * Reorder the selection made in Inspecciones table.
	 *
	 * @param filterInspecciones
	 *            Inspecciones
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return Object
	 */
	@Override
	public Object reorderSelection(Inspecciones filterInspecciones, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.inspeccionesDao.reorderSelection(filterInspecciones, tableRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */

	/**
	 * Finder method in the hierarchical the Inspecciones table.
	 *
	 * @param filterInspecciones
	 *            Inspecciones
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return TableResponseDto<JerarquiaDto<Inspecciones>>
	 */
	@Override
	public TableResponseDto<JerarquiaDto<Inspecciones>> jerarquia(Inspecciones filterInspecciones,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<JerarquiaDto<Inspecciones>> listaInspecciones = this.inspeccionesDao
				.findAllLikeJerarquia(filterInspecciones, tableRequestDto);
		Long recordNum = this.inspeccionesDao.findAllLikeCountJerarquia(filterInspecciones, tableRequestDto);
		return new TableResponseDto<JerarquiaDto<Inspecciones>>(tableRequestDto, recordNum, listaInspecciones);
	}

	/**
	 * Finder method for siblings rows in the hierarchical the Inspecciones
	 * table.
	 *
	 * @param filterInspecciones
	 *            Inspecciones
	 * @param tableRequestDto
	 *            TableRequestDto
	 * @return TableResponseDto<JerarquiaDto<Inspecciones>>
	 */
	@Override
	public TableResponseDto<JerarquiaDto<Inspecciones>> jerarquiaChildren(Inspecciones filterInspecciones,
			TableRequestDto tableRequestDto) {
		TableResponseDto<JerarquiaDto<Inspecciones>> tableResponseDto = new TableResponseDto<JerarquiaDto<Inspecciones>>();
		tableResponseDto.addAdditionalParam(TableResponseDto.CHILDREN,
				this.inspeccionesDao.findAllChild(filterInspecciones, tableRequestDto));
		return tableResponseDto;
	}

	/**
	 * Exporta Datos al clipBoard
	 *
	 */
	@Override
	public List<Inspecciones> getMultiple(Inspecciones filterInspecciones, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.inspeccionesDao.getMultiple(filterInspecciones, tableRequestDto, startsWith);
	}

	@Override
	public Inspecciones updateProtocolos(Inspecciones inspecciones) {
		return this.inspeccionesDao.updateProtocolos(inspecciones);
	}

	@Override
	public void getExcel(List<Inspecciones> inspecciones, HttpServletResponse response) {

		Locale locale = LocaleContextHolder.getLocale();

		boolean castellano = false;
		boolean euskera = false;

		// Configuramos variables de idioma.
		if (locale.toString().equals(Constantes.CASTELLANO)) {
			castellano = true;
		} else if (locale.toString().equals(Constantes.EUSKERA)) {
			euskera = true;
		}

		try {

			// Nombre del archivo
			String fileName = appMessageSource.getMessage("excel.busquedaInspecciones.sheetName", null, locale)
					+ ".xls";

			// Creamos la hoja
			HSSFWorkbook workbook = new HSSFWorkbook();
			HSSFSheet sheet = workbook
					.createSheet(appMessageSource.getMessage("excel.busquedaInspecciones.sheetName", null, locale));

			// Definimos los estilos y fuentes de la hoja
			HSSFFont font = workbook.createFont();
			font.setFontName(HSSFFont.FONT_ARIAL);
			font.setFontHeightInPoints((short) 12);
			font.setBoldweight(Font.BOLDWEIGHT_BOLD);

			HSSFCellStyle headerStyle = workbook.createCellStyle();
			headerStyle.setBorderBottom(CellStyle.BORDER_MEDIUM);
			headerStyle.setFont(font);
			headerStyle.setAlignment(CellStyle.ALIGN_CENTER);

			HSSFCellStyle disabledStyle = workbook.createCellStyle();
			disabledStyle.setFillPattern(CellStyle.THIN_FORWARD_DIAG);

			// Creamos la fila cabecera
			HSSFRow rowHead = sheet.createRow(0);

			rowHead.createCell(0).setCellValue(
					appMessageSource.getMessage("excel.busquedaInspecciones.fechaRegistro", null, locale));
			rowHead.createCell(1).setCellValue(
					appMessageSource.getMessage("excel.busquedaInspecciones.identificadorInspeccion", null, locale));
			rowHead.createCell(2)
					.setCellValue(appMessageSource.getMessage("excel.busquedaInspecciones.expediente", null, locale));
			rowHead.createCell(3).setCellValue(
					appMessageSource.getMessage("excel.busquedaInspecciones.tituloExpediente", null, locale));
			rowHead.createCell(4)
					.setCellValue(appMessageSource.getMessage("excel.busquedaInspecciones.municipio", null, locale));
			rowHead.createCell(5)
					.setCellValue(appMessageSource.getMessage("excel.busquedaInspecciones.localidad", null, locale));
			rowHead.createCell(6)
					.setCellValue(appMessageSource.getMessage("excel.busquedaInspecciones.direccion", null, locale));
			rowHead.createCell(7)
					.setCellValue(appMessageSource.getMessage("excel.busquedaInspecciones.resultado", null, locale));
			rowHead.createCell(8).setCellValue(
					appMessageSource.getMessage("excel.busquedaInspecciones.fechaAsigInspeccion", null, locale));
			rowHead.createCell(9).setCellValue(
					appMessageSource.getMessage("excel.busquedaInspecciones.fechaLimInspeccion", null, locale));

			rowHead.getCell(0).setCellStyle(headerStyle);
			rowHead.getCell(1).setCellStyle(headerStyle);
			rowHead.getCell(2).setCellStyle(headerStyle);
			rowHead.getCell(3).setCellStyle(headerStyle);
			rowHead.getCell(4).setCellStyle(headerStyle);
			rowHead.getCell(5).setCellStyle(headerStyle);
			rowHead.getCell(6).setCellStyle(headerStyle);
			rowHead.getCell(7).setCellStyle(headerStyle);
			rowHead.getCell(8).setCellStyle(headerStyle);
			rowHead.getCell(9).setCellStyle(headerStyle);

			// Creamos el resto de filas con sus celdas
			int rowCount = 1;
			for (Inspecciones inspeccion : inspecciones) {

				HSSFRow inspeccionRow = sheet.createRow(rowCount++);

				if (inspeccion.getFechaRegistro() != null) {

					SimpleDateFormat sdf = new SimpleDateFormat();

					if (castellano) {
						sdf = new SimpleDateFormat(Constantes.FORMATO_FECHA_ES);
					} else if (euskera) {
						sdf = new SimpleDateFormat(Constantes.FORMATO_FECHA_EU);
					}

					String fechaComoCadena = sdf.format(inspeccion.getFechaRegistro());
					inspeccionRow.createCell(0).setCellValue(fechaComoCadena);
				}
				inspeccionRow.createCell(1).setCellValue(inspeccion.getIdentificadorInspeccion());
				inspeccionRow.createCell(2).setCellValue(inspeccion.getExpediente().getFolderNumber());
				inspeccionRow.createCell(3).setCellValue(inspeccion.getExpediente().getTitulo());
				inspeccionRow.createCell(4).setCellValue(inspeccion.getMunicipio().getDsO());
				inspeccionRow.createCell(5).setCellValue(inspeccion.getLocalidad().getDsO());
				inspeccionRow.createCell(6).setCellValue(inspeccion.getDatosDirecciones().getDireccion());
				if (castellano) {
					inspeccionRow.createCell(7).setCellValue(
							inspeccion.getResultadoInspeccion().getDesResIns().getDescripcionCastellano());
				} else if (euskera) {
					inspeccionRow.createCell(7)
							.setCellValue(inspeccion.getResultadoInspeccion().getDesResIns().getDescripcionEuskera());
				}
				if (inspeccion.getFechaAsigInspeccion() != null) {

					SimpleDateFormat formatoFecha = new SimpleDateFormat();

					if (castellano) {
						formatoFecha = new SimpleDateFormat(Constantes.FORMATO_FECHA_ES);
					} else if (euskera) {
						formatoFecha = new SimpleDateFormat(Constantes.FORMATO_FECHA_EU);
					}

					String fechaAsigInspeccion = formatoFecha.format(inspeccion.getFechaAsigInspeccion());

					inspeccionRow.createCell(8).setCellValue(fechaAsigInspeccion);
				} else {
					inspeccionRow.createCell(8).setCellValue("");
				}

				if (inspeccion.getFechaLimInspeccion() != null) {

					SimpleDateFormat formatoFechaLim = new SimpleDateFormat();

					if (castellano) {
						formatoFechaLim = new SimpleDateFormat(Constantes.FORMATO_FECHA_ES);
					} else if (euskera) {
						formatoFechaLim = new SimpleDateFormat(Constantes.FORMATO_FECHA_EU);
					}

					String fechaLimInspeccion = formatoFechaLim.format(inspeccion.getFechaLimInspeccion());

					inspeccionRow.createCell(9).setCellValue(fechaLimInspeccion);
				} else {
					inspeccionRow.createCell(9).setCellValue("");
				}
			}

			// Anchura de las columnas
			sheet.autoSizeColumn(0);
			sheet.autoSizeColumn(1);
			sheet.autoSizeColumn(2);
			sheet.autoSizeColumn(3);
			sheet.autoSizeColumn(4);
			sheet.autoSizeColumn(5);
			sheet.autoSizeColumn(6);
			sheet.autoSizeColumn(7);
			sheet.autoSizeColumn(8);
			sheet.autoSizeColumn(9);

			FileOutputStream fileOut = new FileOutputStream(fileName);
			workbook.write(fileOut);
			fileOut.close();

			InspeccionesServiceImpl.logger.info("[GET - exportarExcel] : Archivo generado");

			// Creamos el archivo a descargar
			File fileToDownload = new File(fileName);
			InputStream in = new FileInputStream(fileToDownload);

			// Recogemos el MIME type del fichero
			String mimeType = new MimetypesFileTypeMap().getContentType(fileName);

			if (mimeType == null) {
				// Si no se encuentra lo seteamos manualmente
				mimeType = "application/octet-stream";
			}
			InspeccionesServiceImpl.logger.info("[GET - exportarExcel] : MIME type: " + mimeType);

			// Seteamos el contentType de la response
			response.setContentType(mimeType);
			response.setContentLength((int) fileToDownload.length());

			// Descargamos el archivo
			response.setHeader("Content-Disposition", "attachment; filename=\"" + fileToDownload.getName() + "\"");

			// Obtenemos el outputStream de la response
			OutputStream outStream = response.getOutputStream();

			byte[] buffer = new byte[4096];
			int bytesRead = -1;

			while ((bytesRead = in.read(buffer)) != -1) {
				outStream.write(buffer, 0, bytesRead);
			}

			// Cerramos el InputStream y el OutputStream
			in.close();
			outStream.close();

			InspeccionesServiceImpl.logger.info("[GET - exportarExcel] : Archivo descargado con �xito");

		} catch (Exception e) {
			InspeccionesServiceImpl.logger.error(e.getMessage());
		}
	}

	/**
	 * Transformar los campos del ORDER BY cuando están dentro de un objeto
	 * 
	 * @param tableRequestDto
	 *            TableRequestDto
	 */
	private void fncReordenarInspecciones(TableRequestDto tableRequestDto) {

		if (tableRequestDto != null && tableRequestDto.getSidx() != null
				&& tableRequestDto.getSidx().equals("fechaRegistro")) {
			tableRequestDto.setSidx("FECHAREGIS");
		} else if (tableRequestDto != null && tableRequestDto.getSidx() != null
				&& tableRequestDto.getSidx().equals("identificadorInspeccion")) {
			tableRequestDto.setSidx("IDENTIFICADORINSPECCION");
		} else if (tableRequestDto != null && tableRequestDto.getSidx() != null
				&& tableRequestDto.getSidx().equals("expediente.folderNumber")) {
			tableRequestDto.setSidx("FOLDERNUM");
		} else if (tableRequestDto != null && tableRequestDto.getSidx() != null
				&& tableRequestDto.getSidx().equals("expediente.titulo")) {
			tableRequestDto.setSidx("TITULO");
		} else if (tableRequestDto != null && tableRequestDto.getSidx() != null
				&& tableRequestDto.getSidx().equals("municipio.dsO")) {
			tableRequestDto.setSidx("DSOMUNICIPIO");
		} else if (tableRequestDto != null && tableRequestDto.getSidx() != null
				&& tableRequestDto.getSidx().equals("localidad.dsO")) {
			tableRequestDto.setSidx("DSOLOCALIDAD");
		} else if (tableRequestDto != null && tableRequestDto.getSidx() != null
				&& tableRequestDto.getSidx().equals("datosDirecciones.direccion")) {
			tableRequestDto.setSidx("DIRECCION");
		} else if (tableRequestDto != null && tableRequestDto.getSidx() != null
				&& tableRequestDto.getSidx().equals("resultadoInspeccion.descripcionCastellano")) {
			tableRequestDto.setSidx("DESCCASTRESU");
		} else if (tableRequestDto != null && tableRequestDto.getSidx() != null
				&& tableRequestDto.getSidx().equals("resultadoInspeccion.descripcionEuskera")) {
			tableRequestDto.setSidx("DESCEUSKTRESU");
		}
	}

	@Override
	public List<Inspecciones> asignarInspector(List<Inspecciones> listaInspecciones) {
		return this.inspeccionesDao.asignarInspector(listaInspecciones);
	}

	@Override
	public List<Inspecciones> enviarTablet(List<Inspecciones> listaInspecciones, Integer enviar) {
		return this.inspeccionesDao.enviarTablet(listaInspecciones, enviar);
	}

	@Override
	@Transactional
	public Inspecciones generarInspeccion(Inspecciones inspeccion, Usuario usuario) {

		// La direccion de la inspeccion viene seleccionada desde el controlador
		// / pantalla
		inspeccion.setUsuarioRegistro(usuario.getUsuario());

		Procedimientos procedimiento = new Procedimientos();
		procedimiento.setIdProcedimiento(inspeccion.getProcedimiento().getIdProcedimiento());
		procedimiento = this.procedimientosDao.find(procedimiento);
		inspeccion.setDireccion(procedimiento.getDirecciones());
		inspeccion.setProcedimiento(procedimiento);

		inspeccion.setResultadoInspeccion(new ResultadosInspeccion());
		inspeccion.setExpediente(new Expedientes());
		inspeccion.setCampaina(new CampainasInspeccion());
		inspeccion.setIdOrigenInspeccion(Constantes.ORIGEN_INSPECCION_OFICIO);
		inspeccion.setIdProtocolo(new Protocolos());

		inspeccion.setProcedimiento(procedimiento);
		EstadosInspeccion estadoInspeccion = this.estadosInspeccionDao.findByOrigenDireccion(
				inspeccion.getIdOrigenInspeccion(), inspeccion.getDireccion().getIdDireccion(),
				Constantes.ESTADO_PENDIENTE);

		if (estadoInspeccion != null) {
			inspeccion.setEstadoInspeccion(estadoInspeccion);
		} else {
			inspeccion.setEstadoInspeccion(new EstadosInspeccion());
		}

		String identificadorInspeccion = null;

		identificadorInspeccion = this.crearIdentificadorInspeccion(inspeccion.getDireccion().getIdDireccion());

		inspeccion.setIdentificadorInspeccion(identificadorInspeccion);
		inspeccion.setEnviadoTablet(Constantes.ENVIADO_TABLET_NO);

		// Insert en AB7901T00
		Inspecciones inspeccionAux = this.inspeccionesDao.add(inspeccion);

		RelEstIns relEstIns = new RelEstIns();
		relEstIns.setInspeccionBD(inspeccionAux);
		relEstIns.setUsuarioRegistro(usuario.getUsuario());
		relEstIns.setProcedimiento(procedimiento);

		// Insert en AB7922T00
		this.relEstInsDao.add(relEstIns);

		return inspeccionAux;
	}

	@Override
	public String crearIdentificadorInspeccion(Integer idDireccion) {
		String direccionLetra = "";
		if (idDireccion == Constantes.ID_TURISMO_DIRECCION) {
			direccionLetra = Constantes.TURISMO_DIRECCION;
		} else {
			direccionLetra = Constantes.COMERCIO_DIRECCION;
		}

		String identificadorInspeccion = Constantes.IDENTIFICADOR_INSPECCION + "-" + direccionLetra + "-"
				+ Calendar.getInstance().get(Calendar.YEAR);

		Integer secuenciaIdentificador = this.inspeccionesDao
				.findUltimoIdentificadorByAnioDireccion(Calendar.getInstance().get(Calendar.YEAR), direccionLetra);
		if (secuenciaIdentificador != null) {
			secuenciaIdentificador += 1;
			identificadorInspeccion += "-" + secuenciaIdentificador;
		} else {
			identificadorInspeccion += "-" + Constantes.PRIMER_IDENTIFICADOR_ANIO;
		}

		return identificadorInspeccion;
	}

	@Override
	public Integer inspeccionesAsociadasDireccion(Integer provinciaPrecargada, Integer direccionPrecargada) {
		return this.inspeccionesDao.inspeccionesAsociadasDireccion(provinciaPrecargada, direccionPrecargada);
	}

	@Override
	public Integer inspeccionesAsociadas(Integer provinciaPrecargada) {
		return this.inspeccionesDao.inspeccionesAsociadas(provinciaPrecargada);
	}

	@Override
	public Inspecciones findByExpedienteOrigenInspeccion(Expedientes expediente) {
		return this.inspeccionesDao.findByExpedienteOrigenInspeccion(expediente);
	}

	@Override
	public Inspecciones findByIdentificadorInspeccion(String identificadorInspeccion) {
		return this.inspeccionesDao.findByIdentificadorInspeccion(identificadorInspeccion);
	}

	/**
	 * Buscar el inspector de una inspección
	 *
	 * @param idInspeccion
	 *            Integer
	 * @return Inspectores
	 */
	@Override
	public Inspectores comprobarInspectorInspeccion(Integer idInspeccion) {
		return this.inspeccionesDao.comprobarInspectorInspeccion(idInspeccion);
	}

	@Override
	public Inspecciones updateFechaFinInspeccion(Inspecciones inspecciones) {
		return this.inspeccionesDao.updateFechaFinInspeccion(inspecciones);
	}

	@Override
	public String crearTitulo(Inspecciones inspeccion, DatosTerceros datosTercero, DatosDirecciones datosDireccion) {
		String titulo = "";
		List<RelExpTer> listaTerceros = null;

		if (inspeccion != null) {
			if (inspeccion.getExpediente() != null && inspeccion.getExpediente().getIdExpediente() != null) {

				if (datosDireccion == null) {
					datosDireccion = this.datosDireccionesDao.findDomicilioUbicacion(
							inspeccion.getExpediente().getIdExpediente(), Constantes.ID_UBICACION_INVERSION);
				}

				if (datosTercero == null) {
					listaTerceros = this.datosTercerosDao
							.findByExpediente(inspeccion.getExpediente().getIdExpediente());
				}

			} else {

				if (datosDireccion == null) {
					datosDireccion = this.datosDireccionesDao.findDomicilioUbicacionSinExpediente(
							inspeccion.getIdInspeccion(), Constantes.ID_UBICACION_INVERSION);
				}
				if (datosTercero == null) {
					datosTercero = this.datosTercerosDao.findByInspeccion(inspeccion.getIdInspeccion());
				}

			}
		}
		if (datosDireccion != null && datosDireccion.getProvincia() != null
				&& datosDireccion.getProvincia().getId() != null) {

			String idProvincia = datosDireccion.getProvincia().getId();

			if (idProvincia.length() == Constantes.MAGIC_NUMBER_1) {
				idProvincia = String.valueOf(Constantes.MAGIC_NUMBER_0) + datosDireccion.getProvincia().getId();
			}

			if (!Constantes.COD_PROVINCIA_ARABA.equals(idProvincia)
					&& !Constantes.COD_PROVINCIA_BIZKAIA.equals(idProvincia)
					&& !Constantes.COD_PROVINCIA_GIPUZKOA.equals(idProvincia)) {
				idProvincia = Constantes.COD_PROVINCIA_ARABA;
			}

			titulo += "(" + idProvincia + ") ";

		}
		if (inspeccion != null && inspeccion.getCampaina() != null && inspeccion.getCampaina().getIdCampaina() != null
				&& inspeccion.getCampaina().getIdCampaina() != 0) {

			CampainasInspeccion campaina = this.campainasInspeccionDao.find(inspeccion.getCampaina());
			titulo += "[" + campaina.getIdentificadorCampaina() + "] ";
		}

		if (inspeccion != null && inspeccion.getAgrupacion() != null
				&& inspeccion.getAgrupacion().getIdAgrupacion() != null
				&& inspeccion.getAgrupacion().getIdAgrupacion() != 0) {
			Agrupaciones agrupacion = this.agrupacionesDao.find(inspeccion.getAgrupacion());
			titulo += "[" + agrupacion.getDescripcionCorta() + "] ";
		}

		if (datosDireccion != null && datosDireccion.getIdentificadorEstablecimiento() != null
				&& !"".equals(datosDireccion.getIdentificadorEstablecimiento())) {
			titulo += "[" + datosDireccion.getIdentificadorEstablecimiento() + "] ";
		}

		if (listaTerceros != null) {
			for (int i = 0; i < listaTerceros.size(); i++) {

				if ((listaTerceros.get(i) != null && listaTerceros.get(i).getSubtipoTercero() != null
						&& listaTerceros.get(i).getSubtipoTercero().getIdSubtipoTercero() != null && listaTerceros
								.get(i).getSubtipoTercero().getIdSubtipoTercero().equals(Constantes.PARTE_INCULPADA))
						|| listaTerceros.size() == 1) {

					if (listaTerceros.get(i).getDatosTerceros() != null) {

						if (i > 0) {
							titulo += " | ";
						}

						if (listaTerceros.get(i).getDatosTerceros().getNombre() != null) {
							titulo += listaTerceros.get(i).getDatosTerceros().getNombre() + " ";
						}
						if (listaTerceros.get(i).getDatosTerceros().getApellido1() != null) {
							titulo += listaTerceros.get(i).getDatosTerceros().getApellido1() + " ";
						}
						if (listaTerceros.get(i).getDatosTerceros().getApellido2() != null) {
							titulo += listaTerceros.get(i).getDatosTerceros().getApellido2();
						}

					}

				}

			}
		} else if (datosTercero != null) {

			if (datosTercero.getNombre() != null) {
				titulo += datosTercero.getNombre() + " ";
			}
			if (datosTercero.getApellido1() != null) {
				titulo += datosTercero.getApellido1() + " ";
			}
			if (datosTercero.getApellido2() != null) {
				titulo += datosTercero.getApellido2();
			}

		}

		return titulo;
	}
}
