package com.ejie.ab04b.control;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.ejie.ab04b.constantes.Constantes;
import com.ejie.ab04b.constantes.ConstantesServicioCorrespondencia;
import com.ejie.ab04b.constantes.SituacionEntregaEnum;
import com.ejie.ab04b.dao.custom.TareaTramiteAperturasCustomDao;
import com.ejie.ab04b.dao.custom.TareaTramiteOS2CustomDao;
import com.ejie.ab04b.dao.custom.TareaTramiteOS3CustomDao;
import com.ejie.ab04b.exception.AB04BException;
import com.ejie.ab04b.exception.ErrorField;
import com.ejie.ab04b.exception.ErrorGenericoException;
import com.ejie.ab04b.model.DatosEnvioPostal;
import com.ejie.ab04b.model.TareaAperturas;
import com.ejie.ab04b.model.TareaOS2;
import com.ejie.ab04b.model.TareaOS3;
import com.ejie.ab04b.model.TramiteAperturas;
import com.ejie.ab04b.model.TramiteOS2;
import com.ejie.ab04b.model.TramiteOS3;
import com.ejie.ab04b.model.Venviospostales;
import com.ejie.ab04b.service.DatosEnvioPostalService;
import com.ejie.ab04b.service.VenviospostalesService;
import com.ejie.ab04b.service.dokusi.DokusiService;
import com.ejie.ab04b.service.pif.PifService;
import com.ejie.ab04b.service.serviciocorrespondencia.ServicioCorrespondenciaService;
import com.ejie.ab04b.service.tramitacion.TramitacionAperturasService;
import com.ejie.ab04b.service.tramitacion.TramitacionOS2Service;
import com.ejie.ab04b.service.tramitacion.TramitacionOS3Service;
import com.ejie.ab04b.util.ManejoSesion;
import com.ejie.ab04b.util.PropertiesUtil;
import com.ejie.ab04b.util.ServicioCorrespondenciaUtils;
import com.ejie.ab04b.util.seguridad.UtilSeguridad;
import com.ejie.ab04b.webservice.client.aa66.IdentTramitadorCondicionalWs;
import com.ejie.ab04b.webservice.client.aa66.IdentTramitadorWs;
import com.ejie.ab04b.webservice.client.aa66.SituacionEntregaWs;
import com.ejie.ab04b.webservice.client.aa66.ZipEnvioWs;
import com.ejie.t65.jaxb.beans.fsd.T65BDocumentType;
import com.ejie.t65.jaxb.beans.fsd.T65BStringListType;
//import com.ejie.ab04b.webservice.client.aa66.EnvioOutWs;
//import com.ejie.ab04b.webservice.client.aa66.ErrorWs;
//import com.ejie.ab04b.webservice.client.aa66.RemesaOutWs;
//import com.ejie.ab04b.webservice.client.aa66.RemesaWs;
import com.ejie.x38.control.bind.annotation.RequestJsonBody;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.security.UserCredentials;

/**
 * VenviospostalesController generated by UDA, 07-ago-2017 13:35:29.
 * 
 * @author UDA
 */

@Controller()
@RequestMapping(value = "/venviospostales")
public class GestionEnviosController {

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

	private static final String PARAM_SESSION_FILTER_FORM = "sessionFilterForm";
	// private static final String SEPARADOR_REMESA_COLECCION = "_";
	private static final String PARAM_COD_DEL = "codDel";
	private static final String PARAM_URL_REMESA = "urlRemesa";
	private static final String PARAM_URL_COLECCION = "urlColeccion";
	private static final String PARAM_URL_ENVIO = "urlEnvio";
	private static final String PARAM_PRUEBA_BYTES = "pruebaBytes";
	private static final String CHECK_FILE_NAME = "PruebaEnvio.zip";

	private static final String DATE_PATTERN_YEAR = "yyyy";
	private static final String DATE_PATTERN_CORREOS = Constantes.ES_DATE_MASK;

	private static final String PARAM_DOWNLOAD_FILE_PATH = "pathDownloadFile";
	private static final String PARAM_LIST_FILE_DELETE = "listFileDelete";

	private static final String FILE_DEST_SUFIX = "FINAL.pdf";

	@Autowired()
	private VenviospostalesService venviospostalesService;
	@Autowired()
	private DokusiService dokusiService;

	@Autowired()
	private PifService pifService;
	@Autowired()
	private DatosEnvioPostalService datosEnvioPostalService;
	@Autowired()
	private ServicioCorrespondenciaService servicioCorrespondenciaService;

	@Autowired()
	private TramitacionAperturasService tramitacionAperturasService;

	@Autowired()
	private TramitacionOS2Service tramitacionOS2Service;

	@Autowired()
	private TramitacionOS3Service tramitacionOS3Service;

	@Autowired()
	private TareaTramiteAperturasCustomDao tareaTramiteAperturasCustomDao;

	@Autowired()
	private TareaTramiteOS2CustomDao tareaTramiteOS2CustomDao;

	@Autowired()
	private TareaTramiteOS3CustomDao tareaTramiteOS3CustomDao;

	/**
	 * Usamos este mÃ©todo para indicarle a Spring el formato que debe usar para
	 * serializar las fechas cuando cargamos la entidad en el Model. En el resto
	 * de peticiones que devuelven un objeto con la anotaciÃ³n '@ResponseBody'
	 * se usan los serializadores de UDA
	 * 
	 * binder WebDataBinder
	 *
	 * @param binder
	 *            the binder
	 */
	@InitBinder()
	public void initBinder(WebDataBinder binder) {

		Locale locale = LocaleContextHolder.getLocale();
		DateFormat dateFormat = null;
		if (locale.equals(Constantes.LOCALE_ES)) {
			dateFormat = new SimpleDateFormat(Constantes.ES_DATE_MASK);
		} else {
			dateFormat = new SimpleDateFormat(Constantes.EU_DATE_MASK);
		}
		binder.registerCustomEditor(Date.class,
				new CustomDateEditor(dateFormat, true));
	}

	/*
	 * OPERACIONES CRUD (Create, Read, Update, Delete)
	 */

	/**
	 * Operacion CRUD Read. Devuelve el bean correspondiente al identificador
	 * indicado.
	 * 
	 * tipoexp the tipoexp idTramite Long
	 *
	 * @param tipoexp
	 *            the tipoexp
	 * @param idTramite
	 *            the id tramite Venviospostales Objeto correspondiente al
	 *            identificador indicado.
	 * @return the venviospostales
	 */
	@RequestMapping(value = "/{tipoexp}/{idTramite}", method = RequestMethod.GET)
	public @ResponseBody() Venviospostales get(@PathVariable() String tipoexp,
			@PathVariable() Long idTramite) {
		Venviospostales venvioPostal = new Venviospostales(tipoexp, idTramite);
		venvioPostal = this.venviospostalesService.find(venvioPostal);
		GestionEnviosController.logger
				.info("[GET - findBy_PK] : Obtener venvioPostal por PK");
		return venvioPostal;
	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * model Model request HttpServletRequest loadFilter String
	 *
	 * @param model
	 *            the model
	 * @param request
	 *            the request
	 * @param loadFilter
	 *            the load filter String
	 * @return the form edit
	 */
	@RequestMapping(value = "/maint", method = RequestMethod.GET)
	public String getFormEdit(Model model, HttpServletRequest request,
			@RequestParam(value = "f", required = false) String loadFilter) {
		GestionEnviosController.logger.info("[GET - View] : venviospostales");

		String codDel = UtilSeguridad.getInstance().obtenerDelegacionUsuario();
		Venviospostales filterForm = new Venviospostales();
		if (loadFilter != null && Boolean.valueOf(loadFilter)) {
			// pasamos filtro a model
			model.addAttribute(
					GestionEnviosController.PARAM_SESSION_FILTER_FORM,
					ManejoSesion.pasaDatosNavegacionModel(request, model,
							Venviospostales.class));
		} else {
			if (!codDel.equals(Constantes.DEL_LAKUA)) {
				filterForm.setTerritApertura(codDel);
			}

			filterForm.setAnoApertura((new SimpleDateFormat(
					GestionEnviosController.DATE_PATTERN_YEAR)
							.format(new Date())));

			model.addAttribute(
					GestionEnviosController.PARAM_SESSION_FILTER_FORM,
					filterForm);
		}
		model.addAttribute(GestionEnviosController.PARAM_COD_DEL, codDel);

		model.addAttribute(GestionEnviosController.PARAM_URL_REMESA,
				PropertiesUtil.getProperty(
						PropertiesUtil.GESTION_ENVIOS_URL_AA66_REMESA));
		model.addAttribute(GestionEnviosController.PARAM_URL_COLECCION,
				PropertiesUtil.getProperty(
						PropertiesUtil.GESTION_ENVIOS_URL_AA66_COLECCION));
		model.addAttribute(GestionEnviosController.PARAM_URL_ENVIO,
				PropertiesUtil.getProperty(
						PropertiesUtil.GESTION_ENVIOS_URL_AA66_ENVIO));

		return "venviospostales";
	}

	/**
	 * Operacion de filtrado del componente RUP_TABLE.
	 * 
	 * filterVenviospostales Venviospostales Bean que contiene los parametros de
	 * filtrado a emplear. jqGridRequestDto Dto que contiene los parametros de
	 * configuracion propios del RUP_TABLE a aplicar en el filtrado. request
	 * HttpServletRequest
	 *
	 * @param filterVenviospostales
	 *            the filter venviospostales
	 * @param jqGridRequestDto
	 *            the jq grid request dto
	 * @param request
	 *            the request JQGridResponseDto<Venviospostales> Dto que
	 *            contiene el resultado del filtrado realizado por el componente
	 *            RUP_TABLE.
	 * @return the JQ grid response dto
	 */
	@RequestMapping(value = "/filter", method = RequestMethod.POST)
	public @ResponseBody() JQGridResponseDto<Venviospostales> filter(
			@RequestJsonBody(param = "filter") Venviospostales filterVenviospostales,
			@RequestJsonBody() JQGridRequestDto jqGridRequestDto,
			HttpServletRequest request) {
		GestionEnviosController.logger
				.info("[POST - filter] : Obtener Venviospostales");

		Venviospostales filterVenviospostalesAux = filterVenviospostales;
		Object datosFiltroSesion = ManejoSesion.recuperaDatosFiltro(request,
				jqGridRequestDto, Venviospostales.class);
		if (datosFiltroSesion != null) {
			filterVenviospostalesAux = (Venviospostales) datosFiltroSesion;
		} else {
			// guarda filtro
			ManejoSesion.guardaFiltro(request, filterVenviospostalesAux,
					jqGridRequestDto);
		}
		if (filterVenviospostales.getTiposexp() == null
				|| filterVenviospostales.getTiposexp().length == 0) {
			UserCredentials userCredentials = null;
			userCredentials = (UserCredentials) SecurityContextHolder
					.getContext().getAuthentication().getCredentials();

			List<String> perfiles = userCredentials.getUserProfiles();
			String[] array = null;
			if (perfiles.contains(Constantes.ROL_TRAMITADOR_OSALAN_ALAVA)
					|| perfiles
							.contains(Constantes.ROL_TRAMITADOR_OSALAN_GIPUZKOA)
					|| perfiles.contains(Constantes.ROL_TRAMITADOR_BIZKAIA)) {
				array = new String[2];
				array[0] = "OS2";
				array[1] = "OS3";
				filterVenviospostales.setTiposexp(array);
			} else {
				array = new String[1];
				array[0] = "APE";
				filterVenviospostales.setTiposexp(array);
			}
		}
		return this.venviospostalesService.findEnvios(filterVenviospostalesAux,
				jqGridRequestDto);
	}

	/**
	 * Generar documento completo imprimir.
	 * 
	 * request HttpServletRequest listaPk the lista pk
	 *
	 * @param request
	 *            the request
	 * @param listaPk
	 *            the lista pk String
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	/*
	 * @RequestMapping(value = "/cargarEnviosRemesa", method =
	 * RequestMethod.POST) public @ResponseBody() String cargarEnviosRemesa(
	 * 
	 * @RequestParam(value = "listaIdsTramites[]") List<Long> listaIdsTramites,
	 * HttpServletRequest request) {
	 * 
	 * StringBuilder idsRemesaColeccion = new StringBuilder();
	 * List<TramiteAperturas> listaTramites = new ArrayList<TramiteAperturas>();
	 * List<Mensaje> listaMensajes = new ArrayList<Mensaje>(); if
	 * (listaIdsTramites != null && !listaIdsTramites.isEmpty()) { for (Long id
	 * : listaIdsTramites) { TramiteAperturas tra = this.venviospostalesService
	 * .find(new TramiteAperturas(id)); if (tra.getIdRemesa062() != null) {
	 * listaMensajes.add(new Mensaje("error.envioYaEstaEnRemesa",
	 * tra.getIdTramite062().toString())); } else { // Buscamos la empresa (está
	 * dentro de la apertura) tra.setApertura(
	 * this.comunicacionAperturaService.find(tra.getApertura())); /* // Buscamos
	 * el solicitante Personas personaSolicitante = this.personasService
	 * .findPersonaDestinatario( tra.getExpedientes().getCodexpediente001(),
	 * Constantes.DESTINATARIO_TRAMITE_EMPRESA); tra.getExpedientes()
	 * .setPersonaSolicitante(personaSolicitante); / listaTramites.add(tra); } }
	 * }
	 * 
	 * if (!listaMensajes.isEmpty()) { List<ErrorField> listaErrorField = new
	 * ArrayList<ErrorField>(); listaErrorField.add( new
	 * ErrorField("error.tituloCargarRemesa", listaMensajes)); throw new
	 * ErrorGenericoException(listaErrorField); } if (!listaTramites.isEmpty())
	 * { try { RemesaWs remesaEntrada = ServicioCorrespondenciaUtils
	 * .getInstance().construirRemesaWs(listaTramites, request,
	 * this.delegacionesService);
	 * 
	 * RemesaOutWs result = this.servicioCorrespondenciaService
	 * .cargaMasiva(remesaEntrada); if (result != null && (result.getErrores()
	 * == null || result.getErrores().isEmpty())) { for (TramiteAperturas
	 * tramite : listaTramites) { tramite.setIdRemesa062(result.getIdremesa());
	 * tramite.setCodRemesa062(result.getCodigoRemesa());
	 * tramite.setIdColeccion062(result.getIdColeccion());
	 * tramite.setCodColeccion062(
	 * Integer.parseInt(result.getCodigoColeccion())); Object[] infoEnvio =
	 * this.obtenerIdEnvioTramite(tramite, result.getEnvios());
	 * tramite.setIdEnvio062( (Integer)
	 * infoEnvio[GestionEnviosController.INFO_ENVIO_POS_ID_ENVIO]);
	 * tramite.setCodEnvio062( (String)
	 * infoEnvio[GestionEnviosController.INFO_ENVIO_POS_COD_ENVIO]);
	 * tramite.setCodSituacionEnvio062( SituacionEntregaEnum.NO_SITUACION
	 * .getCodSituacionEntrega()); this.tramiteAperturasService
	 * .updateDatosEnvioPostal(tramite); }
	 * idsRemesaColeccion.append(result.getCodigoRemesa());
	 * idsRemesaColeccion.append(
	 * GestionEnviosController.SEPARADOR_REMESA_COLECCION);
	 * idsRemesaColeccion.append(result.getCodigoColeccion()); } else { if
	 * (result == null || result.getErrores() == null) {
	 * GestionEnviosController.logger.error(
	 * "Error al crear remesa. La llamada no falla pero el resultado no es correcto."
	 * ); throw new ErrorGenericoException("error.crearRemesa"); } else {
	 * List<ErrorField> listaErrores = new ArrayList<ErrorField>(); for (ErrorWs
	 * error : result.getErrores()) { listaErrores.add(new ErrorField( "Envio "
	 * + error.getIdErroneo(), error.getCodigoError() + " - " + error
	 * .getDescripcionCastellano())); } throw new
	 * ErrorGenericoException(listaErrores); } } } catch
	 * (ServicioCorrespondenciaException sce) {
	 * GestionEnviosController.logger.error(
	 * "Error en la llamada al servicio web de crear remesa", sce); throw new
	 * ErrorGenericoException("error.titulo", "error.crearRemesa"); } catch
	 * (Exception e) { if (e instanceof ErrorGenericoException) { throw
	 * (ErrorGenericoException) e; } GestionEnviosController.logger.error(
	 * "Error al crear remesa", e); throw new
	 * ErrorGenericoException("error.titulo", "error.crearRemesa"); }
	 * 
	 * return idsRemesaColeccion.toString(); } else { throw new
	 * ErrorGenericoException("error.envioNoSeleccionado"); } }
	 */

	/**
	 * De toda la lista de envíos cargados a la remesa, devuelve el Id de envío
	 * que corresponde a nuestro Id de trámite
	 * 
	 * tramite TramiteAperturas listaEnvios List<EnvioOutWs> Object[] pos0:
	 * idEnvio, pos1: codEnvio
	 */
	/*
	 * private Object[] obtenerIdEnvioTramite(TramiteAperturas tramite,
	 * List<EnvioOutWs> listaEnvios) { Object[] infoEnvio = new Object[2]; if
	 * (listaEnvios != null && !listaEnvios.isEmpty()) { for (EnvioOutWs envio :
	 * listaEnvios) { if (envio != null && envio.getIdInterno()
	 * .equals(tramite.getIdTramite062().toString())) {
	 * infoEnvio[GestionEnviosController.INFO_ENVIO_POS_ID_ENVIO] = envio
	 * .getIdEnvio();
	 * infoEnvio[GestionEnviosController.INFO_ENVIO_POS_COD_ENVIO] = envio
	 * .getCodEnvio(); return infoEnvio; } } }
	 * GestionEnviosController.logger.warn(
	 * "No se encuentra envio correspondiente al trámite {}",
	 * tramite.getIdTramite062()); return null; }
	 */

	/**
	 * request HttpServletRequest listaPk Long[]
	 * 
	 * @throws AB04BException
	 */
	@ResponseStatus(value = HttpStatus.OK)
	@RequestMapping(value = "/generarDocImprimir", method = RequestMethod.POST)
	public void generarDocumentoCompletoImprimir(HttpServletRequest request,
			@RequestParam(value = "listaTramites[]") List<String> listaPk)
			throws AB04BException {

		List<String> listaDocsError = new ArrayList<String>();
		boolean error = false;
		if (listaPk != null && !listaPk.isEmpty()) {

			OutputStream outStream = null;
			PDFMergerUtility merger = new PDFMergerUtility();

			String auditUser = UtilSeguridad.getInstance().getAuditUser();

			List<String> listaFicherosBorrar = new ArrayList<String>();

			for (String pk : listaPk) {
				String[] tipo = pk.split("~");
				T65BDocumentType documentType = new T65BDocumentType();
				try {

					documentType = this.dokusiService.recuperarDocumentoConOid(
							auditUser, tipo[tipo.length - 1],
							new T65BStringListType());

					if (documentType == null) {
						// Si el documento recuperado es nulo,
						// añadimos
						// error
						listaDocsError.add(tipo[tipo.length - 1]);
					} else {

						// Copiamos contenido a un fichero temporal
						InputStream is = pifService.downloadDocument(
								documentType.getContent().getPifId());

						byte[] buffer = IOUtils.toByteArray(is);
						is.close();

						StringBuilder fileName = new StringBuilder();
						fileName.append(PropertiesUtil.getProperty(
								PropertiesUtil.RUTA_PLANTILLA_EST_TEMP));
						fileName.append(documentType.getDocumentID().getId());
						fileName.append(
								Long.toString(System.currentTimeMillis()));
						fileName.append(Constantes.PUNTO)
								.append(Constantes.EXT_PDF);
						File targetFile = new File(fileName.toString());
						outStream = new FileOutputStream(targetFile);
						outStream.write(buffer);

						// Añadimos el documento al merge
						merger.addSource(targetFile);

						// Añadimos el fichero para ser borrado al
						// final
						listaFicherosBorrar.add(fileName.toString());
					}
				} catch (Exception e) {

					GestionEnviosController.logger.error("ERROR: ",
							e.getMessage());
					error = true;
				} finally {
					try {
						outStream.close();
					} catch (IOException e) {
						GestionEnviosController.logger.error("ERROR: ",
								e.getMessage());
					}
				}

				if (!listaDocsError.isEmpty()) {
					// Si la lista contiene algún documento con error,
					// los guardamos en el mapa junto con el Id del
					// trámite
					error = true;
				}
			}

			StringBuilder destFile = new StringBuilder();
			destFile.append(PropertiesUtil
					.getProperty(PropertiesUtil.RUTA_PLANTILLA_EST_TEMP));
			destFile.append(Long.toString(System.currentTimeMillis()));
			destFile.append(GestionEnviosController.FILE_DEST_SUFIX);
			merger.setDestinationFileName(destFile.toString());

			if (!error) {
				try {
					merger.mergeDocuments(null);
					request.getSession().setAttribute(
							GestionEnviosController.PARAM_DOWNLOAD_FILE_PATH,
							destFile.toString());

					// Añadimos el documento resultante para ser borrado al
					// final
					listaFicherosBorrar.add(destFile.toString());
					request.getSession().setAttribute(
							GestionEnviosController.PARAM_LIST_FILE_DELETE,
							listaFicherosBorrar);

					// Marcamos los trámites como imprimidos (pdte. acuse)
					for (String pk : listaPk) {
						String[] tipo = pk.split("~");
						Venviospostales envioPostal = new Venviospostales(
								tipo[0], new Long(tipo[1]));
						envioPostal = this.venviospostalesService
								.findByTipoExp(envioPostal);
						DatosEnvioPostal denviop = envioPostal
								.getDatosEnvioPostal();
						denviop.setEstadoEnvio069(
								ConstantesServicioCorrespondencia.ESTADO_ENVIO_PTE_ACUSE_RECIBO);
						datosEnvioPostalService.update(denviop);
					}

				} catch (IOException ioe) {
					GestionEnviosController.logger.error(
							"Error al hacer merge de los documentos", ioe);
					throw new ErrorGenericoException("error.titulo",
							"error.mergeEnvios");
				}
			} else {

				throw new ErrorGenericoException("error.titulo",
						"error.imprimirdoc");
			}

		}
	}

	/**
	 * Descargar documento completo imprimir.
	 * 
	 * request HttpServletRequest response HttpServletResponse
	 *
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 */
	@RequestMapping(value = "/descargarDocImprimir", produces = "application/pdf; charset=utf-8")
	@ResponseStatus(value = HttpStatus.OK)
	public void descargarDocumentoCompletoImprimir(HttpServletRequest request,
			HttpServletResponse response) {

		String destFile = (String) request.getSession()
				.getAttribute(GestionEnviosController.PARAM_DOWNLOAD_FILE_PATH);
		request.getSession().removeAttribute(this.PARAM_DOWNLOAD_FILE_PATH);

		List<String> listaFicherosBorrar = (List<String>) request.getSession()
				.getAttribute(GestionEnviosController.PARAM_LIST_FILE_DELETE);
		request.getSession().removeAttribute(
				GestionEnviosController.PARAM_LIST_FILE_DELETE);

		File fDestFile = new File(destFile);
		try {
			InputStream is = new FileInputStream(fDestFile);
			byte[] bytes = IOUtils.toByteArray(is);
			response.setContentType("application/pdf");
			response.setHeader("content-disposition",
					"inline; filename=\"" + fDestFile.getName() + "\"");
			FileCopyUtils.copy(bytes, response.getOutputStream());
			is.close();

			for (String fileDelete : listaFicherosBorrar) {
				try {
					File file = new File(fileDelete);
					file.delete();
				} catch (Exception e) {
					GestionEnviosController.logger.error(
							"Se ha producido un error al borrar el temporal {0}. No se hace nada.",
							fileDelete);
				}
			}

		} catch (Exception e) {
			GestionEnviosController.logger
					.error("Error al descargar el documento a imprimir", e);
		}
	}

	/**
	 * Registrar acuse recibo.
	 * 
	 * tipoexp the tipoexp idTramite Long fecAcuse Date
	 *
	 * @param tipoexp
	 *            the tipoexp
	 * @param idTramite
	 *            the id tramite
	 * @param fecAcuse
	 *            the fec acuse
	 */
	@RequestMapping(value = "/registrarAcuse", method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public void registrarAcuseRecibo(
			@RequestParam(value = "tipoexp") String tipoexp,
			@RequestParam(value = "idTramite") Long idTramite,
			@RequestParam(value = "fecAcuse") Date fecAcuse,
			@RequestParam(value = "estadoAcuse") String estadoAcuse) {

		Venviospostales envioPostal = new Venviospostales(tipoexp, idTramite);

		if (fecAcuse == null) {
			throw new ErrorGenericoException("error.titulo",
					"error.noPerteneceRemesa");
		} else {
			envioPostal = this.venviospostalesService
					.findByTipoExp(envioPostal);

			DatosEnvioPostal datosEnvioPostal = envioPostal
					.getDatosEnvioPostal();

			if (!datosEnvioPostal.getEstadoEnvio069().equals(
					ConstantesServicioCorrespondencia.ESTADO_ENVIO_PTE_ACUSE_RECIBO)) {
				throw new ErrorGenericoException("error.titulo",
						"error.envioNoPdtAcuse");
			} else {

				// Actualizamos la fecha de acuse y el estado del envío
				datosEnvioPostal.setFecAcuse069(fecAcuse);
				datosEnvioPostal.setEstadoEnvio069(
						ConstantesServicioCorrespondencia.ESTADO_ENVIO_REG_ACUSE_RECIBO);
				datosEnvioPostal.setEstadoAcuse069(estadoAcuse);
				this.datosEnvioPostalService.update(datosEnvioPostal);

				// llamada a la tarea "acuse_requerimiento" del flujo de
				// tramitación
				try {
					// this.plateaTramitacionService.crearTarea(proceding,
					// TipoTramiteFlujo.REQUERIMIENTO.name(),
					// TipoTareaFlujo.ACUSE_REQUERIMIENTO_POSTAL
					// .getTaskId(),
					// folderId,
					// UtilSeguridad.getInstance().getUserCredentials()
					// .getPosition(),
					// UtilSeguridad.getInstance().getNombre());

					if (Constantes.APE.equals(tipoexp)) {
						TareaAperturas tareaApe = new TareaAperturas();
						tareaApe.setEstado063(new Long(0));
						tareaApe.setTramiteAperturas(
								new TramiteAperturas(idTramite));
						List<TareaAperturas> listtareaApe = tareaTramiteAperturasCustomDao
								.vfindAll(tareaApe, null);
						if (listtareaApe != null && listtareaApe.size() > 0) {
							tareaApe = listtareaApe.get(0);
						}
						tramitacionAperturasService.tramitarAcuseRequerimiento(
								tareaApe, tareaApe.getTramiteAperturas());
					} else if (Constantes.OS2.equals(tipoexp)) {
						TareaOS2 tareaOS2 = new TareaOS2();
						tareaOS2.setEstado093(new Long(0));
						tareaOS2.setTramiteOS2(new TramiteOS2(idTramite));
						List<TareaOS2> listtareaOS2 = tareaTramiteOS2CustomDao
								.vfindAll(tareaOS2, null);
						if (listtareaOS2 != null && listtareaOS2.size() > 0) {
							tareaOS2 = listtareaOS2.get(0);
						}
						tramitacionOS2Service.tramitarAcuseRequerimiento(
								tareaOS2, tareaOS2.getTramiteOS2());
					} else if (Constantes.OS3.equals(tipoexp)) {
						TareaOS3 tareaOS3 = new TareaOS3();
						tareaOS3.setEstado096(new Long(0));
						tareaOS3.setTramiteOS3(new TramiteOS3(idTramite));
						List<TareaOS3> listtareaOS3 = tareaTramiteOS3CustomDao
								.vfindAll(tareaOS3, null);
						if (listtareaOS3 != null && listtareaOS3.size() > 0) {
							tareaOS3 = listtareaOS3.get(0);
						}
						tramitacionOS3Service.tramitarAcuseRequerimiento(
								tareaOS3, tareaOS3.getTramiteOS3());
					}

				} catch (Exception e) {
					DatosEnvioPostal datosEnvioPostal2 = envioPostal
							.getDatosEnvioPostal();
					datosEnvioPostal.setEstadoEnvio069(
							ConstantesServicioCorrespondencia.ESTADO_ENVIO_FINALIZADO_KAO);
					this.datosEnvioPostalService.update(datosEnvioPostal2);
					throw new ErrorGenericoException("error.titulo", "error");
				}

				/*
				 * //Expedientes expediente =
				 * this.expedientesService.find(tramite.getExpedientes());
				 * 
				 * ComunicacionApertura apertura =
				 * this.comunicacionAperturaService.find(new
				 * ComunicacionApertura(tramite.getApertura().getTerape056(),
				 * tramite.getApertura().getAnoape056(),
				 * tramite.getApertura().getNumape056()));
				 * 
				 * String auditUser =
				 * UtilSeguridad.getInstance().getAuditUser();
				 * 
				 * try {
				 * this.starterService.sendMessageAcuseReciboPostal(expediente,
				 * tramite, auditUser); } catch (Exception e) {
				 * GestionEnviosController.logger.error(
				 * "Error al encolar el trámite tras informar la fecha de acuse"
				 * , e); datosEnvioPostal.setEstadoEnvio069(
				 * ConstantesServicioCorrespondencia.ESTADO_ENVIO_FINALIZADO_KAO
				 * ); this.datosEnvioPostalService.update(datosEnvioPostal);
				 * 
				 * throw new ErrorGenericoException("error.titulo",
				 * "error.encolarTramiteAcuse"); }
				 */
			}
		}
	}

	/**
	 * Actualizar situacion envio.
	 * 
	 * idEnvio Integer response HttpServletResponse
	 *
	 * @param idEnvio
	 *            the id envio
	 * @param response
	 *            the response
	 */
	@RequestMapping(value = "/actualizarSituacionEnvio", method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public void actualizarSituacionEnvio(
			@RequestParam(value = "idEnvio") Integer idEnvio,
			HttpServletResponse response) {

		if (idEnvio != null) {
			IdentTramitadorCondicionalWs identTramitador = ServicioCorrespondenciaUtils
					.getInstance()
					.construirIdentTramitadorCondicionalWs(idEnvio);
			try {
				SituacionEntregaWs situacionEntrega = this.servicioCorrespondenciaService
						.actualizarSituacionEnvio(identTramitador);
				if (situacionEntrega != null) {
					if (situacionEntrega.getError() != null) {
						StringBuilder sb = new StringBuilder();
						sb.append(situacionEntrega.getError().getCodigoError());
						sb.append(" - ");
						if (LocaleContextHolder.getLocale()
								.equals(Constantes.LOCALE_ES)) {
							sb.append(situacionEntrega.getError()
									.getDescripcionCastellano());
						} else {
							sb.append(situacionEntrega.getError()
									.getDescripcionEuskera());
						}
						GestionEnviosController.logger.error(
								"Se ha obtenido la situación de envío con error {}",
								sb.toString());
						throw new ErrorGenericoException("error.titulo",
								sb.toString());
					} else {
						DatosEnvioPostal datosEnvioPostal = new DatosEnvioPostal();
						datosEnvioPostal.setIdEnvio069(idEnvio);
						datosEnvioPostal.setCodSituacionEnvio069(
								situacionEntrega.getCodigoSituacion());
						datosEnvioPostal.setDescSituacionEnvioEs069(
								situacionEntrega.getDescripcionCastellano());
						datosEnvioPostal.setDescSituacionEnvioEu069(
								situacionEntrega.getDescripcionEuskera());
						DateFormat df = new SimpleDateFormat(
								GestionEnviosController.DATE_PATTERN_CORREOS);
						datosEnvioPostal.setFecSituacionEnvio069(
								df.parse(situacionEntrega.getFechaSituacion()));
						this.datosEnvioPostalService
								.updateSituacionEnvio(datosEnvioPostal);
					}
				} else {
					GestionEnviosController.logger.error(
							"Se ha obtenido la situacion de envío pero la respuesta es nula");
					throw new ErrorGenericoException("error.titulo",
							"error.obtenerSituacion");
				}
			} catch (Exception e) {
				if (e instanceof ErrorGenericoException) {
					throw (ErrorGenericoException) e;
				} else {
					GestionEnviosController.logger.error(
							"Se ha producido una excepción al obtener la situacion de envío");
					throw new ErrorGenericoException("error.titulo",
							"error.obtenerSituacion");
				}
			}
		} else {
			GestionEnviosController.logger.error(
					"No se puede actualizar la situación de envío ya que no se ha cargado a ninguna remesa");
			throw new ErrorGenericoException("error.titulo",
					"error.noPerteneceRemesa");
		}
	}

	/**
	 * Gestionar situacion entrega envio.
	 * 
	 * tipoexp the tipoexp idTramite Long
	 *
	 * @param tipoexp
	 *            the tipoexp
	 * @param idTramite
	 *            the id tramite String
	 * @return the string
	 */
	@RequestMapping(value = "gestionarSituacionEntrega")
	public @ResponseBody() String gestionarSituacionEntregaEnvio(
			@RequestParam(value = "tipoexp") String tipoexp,
			@RequestParam(value = "idTramite") Long idTramite) {

		Venviospostales envioPostal = new Venviospostales(tipoexp, idTramite);

		envioPostal = this.venviospostalesService.findByTipoExp(envioPostal);

		SituacionEntregaEnum sitEntrega = SituacionEntregaEnum
				.getByCodSituacion(envioPostal.getDatosEnvioPostal()
						.getCodSituacionEnvio069());
		if (sitEntrega.esSituacionFinal()) {
			// Si es situación final, la gestionamos
			if (sitEntrega.getEnvioCorrecto()) {
				// Si el envío es correcto, guardamos fecha y continuamos el
				// trámite (como si fuese un registro de acuse
				// manual hecho por el usuario)
				this.registrarAcuseRecibo(tipoexp, idTramite, envioPostal
						.getDatosEnvioPostal().getFecSituacionEnvio069(), "2");
			} else { // Si el envío es erroneo, marcamos el trámite como

				DatosEnvioPostal datosEnvioPostal = envioPostal
						.getDatosEnvioPostal();
				datosEnvioPostal.setEstadoEnvio069(
						ConstantesServicioCorrespondencia.ESTADO_ENVIO_NO_ENTREGADO);
				this.datosEnvioPostalService.update(datosEnvioPostal);
			}

		} else {
			// Si no es situación final, informamos al usuario
			List<ErrorField> listaErrores = new ArrayList<ErrorField>();
			listaErrores.add(
					new ErrorField("error.titulo", "error.sitEntregaNoFinal"));
			throw new ErrorGenericoException(listaErrores);
		}

		return "";

	}

	/**
	 * Obtener prueba envio.
	 * 
	 * idEnvio Integer request HttpServletRequest response HttpServletResponse
	 *
	 * @param idEnvio
	 *            the id envio
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 */
	@RequestMapping(value = "/obtenerPrueba", method = RequestMethod.POST)
	public void obtenerPruebaEnvio(
			@RequestParam(value = "idEnvio") Integer idEnvio,
			HttpServletRequest request, HttpServletResponse response) {

		if (idEnvio != null) {
			IdentTramitadorWs identTramitador = ServicioCorrespondenciaUtils
					.getInstance().construirIdentTramitadorWs(idEnvio);
			try {
				ZipEnvioWs zipEnvio = this.servicioCorrespondenciaService
						.obtenerPruebaEnvio(identTramitador);
				if (zipEnvio != null) {
					if (zipEnvio.getError() != null) {
						StringBuilder sb = new StringBuilder();
						sb.append(zipEnvio.getError().getCodigoError());
						sb.append(" - ");
						if (LocaleContextHolder.getLocale()
								.equals(Constantes.LOCALE_ES)) {
							sb.append(zipEnvio.getError()
									.getDescripcionCastellano());
						} else {
							sb.append(zipEnvio.getError()
									.getDescripcionEuskera());
						}
						GestionEnviosController.logger.error(
								"Se ha obtenido la prueba de envío con error {}",
								sb.toString());
						throw new ErrorGenericoException("error.titulo",
								sb.toString());
					} else {
						if (!zipEnvio.getFicheroZip().isEmpty()) {
							byte[] bytes = zipEnvio.getFicheroZip().get(0);
							request.getSession().setAttribute(
									GestionEnviosController.PARAM_PRUEBA_BYTES,
									bytes);
						}
					}
				} else {
					GestionEnviosController.logger.error(
							"Se ha obtenido la prueba de envío pero la respuesta es nula");
					throw new ErrorGenericoException("error.titulo",
							"error.obtenerPrueba");
				}
			} catch (Exception e) {
				if (e instanceof ErrorGenericoException) {
					throw (ErrorGenericoException) e;
				} else {
					GestionEnviosController.logger.error(
							"Se ha producido una excepción al obtener la prueba de envío");
					throw new ErrorGenericoException("error.titulo",
							"error.obtenerPrueba");
				}
			}
		} else {
			GestionEnviosController.logger.error(
					"No se puede obtener prueba de envío ya que no se ha cargado a ninguna remesa");
			throw new ErrorGenericoException("error.titulo",
					"error.noPerteneceRemesa");
		}
	}

	/**
	 * Descargar prueba.
	 * 
	 * request HttpServletRequest response HttpServletResponse
	 *
	 * @param request
	 *            the request
	 * @param response
	 *            the response
	 */
	@RequestMapping(value = "/descargarPrueba", method = RequestMethod.GET)
	@ResponseStatus(value = HttpStatus.OK)
	public void descargarPrueba(HttpServletRequest request,
			HttpServletResponse response) {
		byte[] bytes = (byte[]) request.getSession()
				.getAttribute(GestionEnviosController.PARAM_PRUEBA_BYTES);

		response.setContentLength(bytes.length);
		response.setContentType("application/zip");
		response.setHeader("Content-Disposition",
				String.format("attachment; filename=\"%s\"",
						GestionEnviosController.CHECK_FILE_NAME));
		try {
			FileCopyUtils.copy(bytes, response.getOutputStream());
		} catch (Exception e) {
			GestionEnviosController.logger.error(
					"Error al copiar la prueba de envío al objeto Response", e);
		} finally {
			request.getSession().removeAttribute(
					GestionEnviosController.PARAM_PRUEBA_BYTES);
		}
	}

}
