package com.ejie.ab04b.service.tramitacion;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;

import com.ejie.ab04b.constantes.Constantes;
import com.ejie.ab04b.constantes.ConstantesDocumentos;
import com.ejie.ab04b.constantes.ConstantesNum;
import com.ejie.ab04b.constantes.ConstantesPlateaTramitacion;
import com.ejie.ab04b.constantes.ConstantesServicioCorrespondencia;
import com.ejie.ab04b.constantes.TipoDocumentoEnum;
import com.ejie.ab04b.constantes.TipoTareaFlujo;
import com.ejie.ab04b.constantes.TipoTareaPlatea;
import com.ejie.ab04b.constantes.TipoTramiteFlujo;
import com.ejie.ab04b.dao.temp.DocumentosAperturasTempDao;
import com.ejie.ab04b.exception.AB04BException;
import com.ejie.ab04b.model.ComunicacionApertura;
import com.ejie.ab04b.model.DatosEnvioPostal;
import com.ejie.ab04b.model.DatosLocalizacion;
import com.ejie.ab04b.model.DatosNotificacion;
import com.ejie.ab04b.model.DocumentoAperturas;
import com.ejie.ab04b.model.EstudioDocAperturas;
import com.ejie.ab04b.model.TareaAperturas;
import com.ejie.ab04b.model.TipoDocumento;
import com.ejie.ab04b.model.Tramite;
import com.ejie.ab04b.model.TramiteAperturas;
import com.ejie.ab04b.model.Venviospostales;
import com.ejie.ab04b.model.VosalanOs4Os6;
import com.ejie.ab04b.service.ComunicacionAperturaService;
import com.ejie.ab04b.service.DatosEnvioPostalService;
import com.ejie.ab04b.service.DatosLocalizacionService;
import com.ejie.ab04b.service.DatosNotificacionService;
import com.ejie.ab04b.service.DocumentoAperturasService;
import com.ejie.ab04b.service.GeneracionPDFCartaAperturaService;
import com.ejie.ab04b.service.GeneracionPDFComunicacionOS2OS3Service;
import com.ejie.ab04b.service.GeneracionPDFComunicacionOS2Service;
import com.ejie.ab04b.service.GeneracionPDFDocOS4Service;
import com.ejie.ab04b.service.GeneracionPDFDocOS6Service;
import com.ejie.ab04b.service.GeneracionPDFSubsanacionService;
import com.ejie.ab04b.service.TipoDocumentoService;
import com.ejie.ab04b.service.TramiteAperturasService;
import com.ejie.ab04b.service.TramiteService;
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.platea.PlateaTramitacionService;
import com.ejie.ab04b.service.serviciocorrespondencia.ServicioCorrespondenciaService;
import com.ejie.ab04b.util.PlateaTramitacionUtils;
import com.ejie.ab04b.util.PropertiesUtil;
import com.ejie.ab04b.util.ServicioCorrespondenciaUtils;
import com.ejie.ab04b.util.Utilities;
import com.ejie.ab04b.util.seguridad.UtilSeguridad;
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.mbt.xml.DeliveredNotificationTaskData;
import com.ejie.mbt.xml.Documents;
import com.ejie.mbt.xml.NotifyTaskData;
import com.ejie.mbt.xml.ObjectFactory;
import com.ejie.mbt.xml.RegistryTaskData;
import com.ejie.mbt.xml.StoredocumentTaskData;
import com.ejie.mbt.xml.StudyTaskData;
import com.ejie.mbt.xml.Task;
import com.ejie.t65.jaxb.beans.fsd.T65BDocumentIDType;

/**
 * @author GFI-NORTE
 * 
 */
@Service(value = "tramitacionAperturasService")
public class TramitacionAperturasService {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(TramitacionAperturasService.class);

	@Autowired()
	private ComunicacionAperturaService comunicacionAperturaService;
	@Autowired()
	private DatosNotificacionService datosNotificacionService;
	@Autowired()
	private DatosLocalizacionService datosLocalizacionService;
	@Autowired()
	private TramiteAperturasService tramiteAperturasService;
	@Autowired()
	private TramiteService tramiteService;
	@Autowired()
	private DocumentoAperturasService documentoAperturasService;
	@Autowired()
	private DocumentosAperturasTempDao documentosAperturasTempDao;
	@Autowired()
	private TipoDocumentoService tipoDocumentoService;
	@Autowired()
	private DatosEnvioPostalService datosEnvioPostalService;
	@Autowired()
	private VenviospostalesService venviospostalesService;

	@Autowired()
	private PlateaTramitacionService plateaTramitacionService;
	@Autowired()
	private DokusiService dokusiService;
	@Autowired()
	private PifService pifService;
	@Autowired()
	private ServicioCorrespondenciaService servicioCorrespondenciaService;
	@Autowired()
	private ReloadableResourceBundleMessageSource appMessageSource;
	@Autowired()
	private Properties appConfiguration;
	/****************************************/
	// @Autowired()
	// private ManejadorTareasAperturas manejadorTareaAperturas;
	/****************************************/

	@Autowired()
	private GeneracionPDFCartaAperturaService generacionPDFCartaAperturaService;

	@Autowired()
	private GeneracionPDFSubsanacionService generacionPDFSubsanacionService;

	@Autowired()
	private GeneracionPDFComunicacionOS2Service generacionPDFComunicacionOS2Service;

	@Autowired()
	private GeneracionPDFComunicacionOS2OS3Service GeneracionPDFComunicacionOS2OS3Service;

	@Autowired()
	private GeneracionPDFDocOS4Service GeneracionPDFDocOS4Service;
	@Autowired()
	private GeneracionPDFDocOS6Service GeneracionPDFDocOS6Service;

	/**
	 * estudio EstudioDocAperturas.
	 * 
	 * @param estudio
	 *            the estudio
	 */
	public void tramitarEstudioDocumentacion(EstudioDocAperturas estudio) {

		TareaAperturas tarea = estudio.getTareaAperturas();

		// Preparamos la tarea
		Task task = this.plateaTramitacionService.prepararTarea(
				tarea.getMailboxTaskId063(), TipoTareaPlatea.ESTDOCU);

		// Indicamos los datos propios de la tarea
		StudyTaskData studyTaskData = task.getTaskInfo().getStudyTaskData();
		studyTaskData
				.setResptarea(new ObjectFactory().createStudyTaskDataResptarea(
						UtilSeguridad.getInstance().getNif()));

		if (Constantes.ESTUDIO_DOC_RESULT_OK
				.equals(estudio.getResultado064())) {
			studyTaskData.setSituacionID(Constantes.ESTUDIO_DOC_CDT_RESULT_OK);
		} else if (Constantes.ESTUDIO_DOC_RESULT_REQ
				.equals(estudio.getResultado064())) {
			studyTaskData.setSituacionID(Constantes.ESTUDIO_DOC_CDT_RESULT_REQ);
		}
		studyTaskData
				.setAccion(ConstantesPlateaTramitacion.ESTDOC_ACCION_GRABAR);

		// Añadimos las notas del estudio al task
		task.setObservations(estudio.getNotas064());

		// Lanzamos la ejecución de la tarea
		this.plateaTramitacionService.estudiarDocumentacion(task);

	}

	/**
	 * tarea TareaAperturas.
	 * 
	 * @param tarea
	 *            the tarea
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	public void prepararDocRequerimiento(TareaAperturas tarea)
			throws AB04BException {
		try {

			// Obtenemos el tramite de aperturas para obtener la apertura
			TramiteAperturas tramiteRequerimiento = this.tramiteAperturasService
					.find(tarea.getTramiteAperturas());

			// Obtenemos el tramite estudio de aperturas para sacar su id
			// interno
			Tramite tipoTramiteEstudio = this.tramiteService
					.findByProceedingIdProcedureId(
							TipoTramiteFlujo.ESTUDIO.name(),
							Utilities.getInstance()
									.obtenerProcedureIdApertura());

			// Obtenemos el último tramite de aperturas de tipo estudio
			// TODO el tramite de estudio quizás lo necesitemos para obtener los
			// datos a insertar en el documento
			TramiteAperturas tramiteEstudio = this.tramiteAperturasService
					.findLastTramiteByTipo(tipoTramiteEstudio.getIdTramite089(),
							tramiteRequerimiento.getApertura());
			tramiteEstudio.toString(); // para que no de error

			// Generamos el documento
			String foldernumber = tarea.getTramiteAperturas().getApertura()
					.getNumExpediente();

			InputStream is = this.generacionPDFSubsanacionService.getPDF(
					foldernumber, ConstantesDocumentos.APERTURA_CENTRO,
					tramiteRequerimiento.getIdTramite062());

			// Lo subimos a PIF

			String rutaDokusi = this.appConfiguration.getProperty(
					PropertiesUtil.PIF_RUTA_DOKUSI) + "/requerimiento.pdf";
			String rutaDoc = this.pifService.uploadDocument(is, rutaDokusi,
					false);

			DocumentoAperturas documento = this.crearDocumentoAdjuntar(
					TipoDocumentoEnum.REQUERIMIENTO,
					Constantes.NOM_FICH_REQ_PDF, rutaDoc,
					tarea.getTramiteAperturas());

			this.prepararDocTramitar(tarea, documento);
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * tarea TareaAperturas.
	 * 
	 * @param tarea
	 *            the tarea
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	public void prepararDocCartaContratista(TareaAperturas tarea)
			throws AB04BException {
		try {

			// Generamos el documento
			// TODO estamos subiendo un documento de C:\

			// Lo subimos a PIF
			// InputStream is = new FileInputStream("C:\\prueba.pdf");
			// String rutaDokusi = this.appConfiguration
			// .getProperty(PropertiesUtil.PIF_RUTA_DOKUSI);
			// String rutaDoc = this.pifService.uploadDocument(is, rutaDokusi,
			// false);
			String rutaDoc = "/t65e/ab04b/prueba.pdf";

			DocumentoAperturas documento = this.crearDocumentoAdjuntar(
					TipoDocumentoEnum.CARTA_CONTRATISTA,
					Constantes.NOM_FICH_CARTA_CONTRATISTA_PDF, rutaDoc,
					tarea.getTramiteAperturas());

			this.prepararDocTramitar(tarea, documento);
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * tarea TareaAperturas.
	 * 
	 * @param tarea
	 *            the tarea
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	public void prepararDocComunicacionOS2(TareaAperturas tarea)
			throws AB04BException {
		try {

			// Generamos el documento

			String foldernumber = tarea.getTramiteAperturas().getApertura()
					.getNumExpediente();
			String[] listadoFolderNumber = new String[1];
			listadoFolderNumber[0] = foldernumber;
			InputStream is = this.generacionPDFComunicacionOS2Service
					.getPDF(listadoFolderNumber);

			// Lo subimos a PIF
			String rutaDokusi = this.appConfiguration.getProperty(
					PropertiesUtil.PIF_RUTA_DOKUSI) + "/comunicacion_os2.pdf";
			String rutaDoc = this.pifService.uploadDocument(is, rutaDokusi,
					false);

			DocumentoAperturas documento = this.crearDocumentoAdjuntar(
					TipoDocumentoEnum.CARTA_OS2,
					Constantes.NOM_FICH_COMUNICACION_OS2_PDF, rutaDoc,
					tarea.getTramiteAperturas());

			this.prepararDocTramitar(tarea, documento);
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * tarea TareaAperturas.
	 * 
	 * @param tarea
	 *            the tarea
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	public void prepararDocAdjuntarInformeInspeccion(TareaAperturas tarea,
			DocumentoAperturas documento) throws AB04BException {
		try {
			DocumentoAperturas doc = this.crearDocumentoAdjuntar(
					TipoDocumentoEnum.INFORME_INSPECCION,
					documento.getNombreDoc065(), documento.getRutaPif065(),
					tarea.getTramiteAperturas());
			this.prepararDocTramitar(tarea, doc);

			this.tramitarAdjuntarDoc(tarea, doc);

			DocumentoAperturas docFilter = new DocumentoAperturas();
			docFilter.setIdapetemp065(
					tarea.getTramiteAperturas().getApertura().getIdape056());

			// borrar los temporales
			this.documentosAperturasTempDao.removeByIdApertura(docFilter);

		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * tarea TareaAperturas.
	 * 
	 * @param tarea
	 *            the tarea
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	public void prepararDocComunicacionOS3(TareaAperturas tarea)
			throws AB04BException {
		try {
			// Generamos el documento
			String foldernumber = tarea.getTramiteAperturas().getApertura()
					.getNumExpediente();
			String[] listadoFolderNumber = new String[1];
			listadoFolderNumber[0] = foldernumber;
			InputStream is = this.GeneracionPDFComunicacionOS2OS3Service
					.getPDF(listadoFolderNumber);

			// Lo subimos a PIF
			String rutaDokusi = this.appConfiguration.getProperty(
					PropertiesUtil.PIF_RUTA_DOKUSI) + "/comunicacion_os3.pdf";
			String rutaDoc = this.pifService.uploadDocument(is, rutaDokusi,
					false);

			DocumentoAperturas documento = this.crearDocumentoAdjuntar(
					TipoDocumentoEnum.CARTA_OS3,
					Constantes.NOM_FICH_COMUNICACION_OS3_PDF, rutaDoc,
					tarea.getTramiteAperturas());

			this.prepararDocTramitar(tarea, documento);
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * tarea TareaAperturas.
	 * 
	 * @param tarea
	 *            the tarea
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	public void prepararDocCartaCambioCoordinador(TareaAperturas tarea)
			throws AB04BException {
		try {

			// Generamos el documento
			String[] foldernumber = new String[1];
			foldernumber[0] = tarea.getTramiteAperturas().getApertura()
					.getNumExpediente();
			InputStream is = this.generacionPDFCartaAperturaService
					.getPDF(foldernumber);

			// Lo subimos a PIF

			String rutaDokusi = this.appConfiguration.getProperty(
					PropertiesUtil.PIF_RUTA_DOKUSI) + "/apertura_centro.pdf";
			String rutaDoc = this.pifService.uploadDocument(is, rutaDokusi,
					false);

			DocumentoAperturas documento = this.crearDocumentoAdjuntar(
					TipoDocumentoEnum.CARTA_CAMBIO_COORDINADOR,
					Constantes.NOM_FICH_COMUNIC_CAMBIO_COORDINADOR_PDF, rutaDoc,
					tarea.getTramiteAperturas());

			this.prepararDocTramitar(tarea, documento);
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * tarea TareaAperturas visita VosalanOs4Os6.
	 * 
	 * @param tarea
	 *            the tarea
	 * @param visita
	 *            the visita
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	public void prepararDocVisitaOsalan(TareaAperturas tarea,
			VosalanOs4Os6 visita) throws AB04BException {
		try {

			// Generamos el documento

			String numExp = visita.getCodpro() + "-"
					+ visita.getCodano().toString() + "-"
					+ visita.getNumexp().toString();

			InputStream is = null;
			if (visita.getTipoos().equalsIgnoreCase("os4")) {
				is = this.GeneracionPDFDocOS4Service.getPDF(numExp,
						visita.getNumeje());
			} else {
				is = this.GeneracionPDFDocOS6Service.getPDF(numExp,
						visita.getNumeje());
			}

			// Lo subimos a PIF

			String rutaDokusi = this.appConfiguration.getProperty(
					PropertiesUtil.PIF_RUTA_DOKUSI) + "/visita_osalan.pdf";
			String rutaDoc = this.pifService.uploadDocument(is, rutaDokusi,
					false);

			DocumentoAperturas documento = this.crearDocumentoAdjuntar(
					TipoDocumentoEnum.INFORME_VISITA_OSALAN,
					Constantes.NOM_FICH_VISITA_OSALAN_PDF, rutaDoc,
					tarea.getTramiteAperturas());

			this.prepararDocTramitar(tarea, documento);
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * tipoDocumentoEnum TipoDocumentoEnum nombreDoc String rutaPif String
	 * tramite TramiteAperturas DocumentoAperturas.
	 * 
	 * @param tipoDocumentoEnum
	 *            the tipo documento enum
	 * @param nombreDoc
	 *            the nombre doc
	 * @param rutaPif
	 *            the ruta pif
	 * @param tramite
	 *            the tramite
	 * @return the documento aperturas
	 */
	private DocumentoAperturas crearDocumentoAdjuntar(
			TipoDocumentoEnum tipoDocumentoEnum, String nombreDoc,
			String rutaPif, TramiteAperturas tramite) {

		TipoDocumento tipoDocumento = new TipoDocumento(
				tipoDocumentoEnum.getIdTipoDoc());
		tipoDocumento = this.tipoDocumentoService.find(tipoDocumento);

		DocumentoAperturas documento = new DocumentoAperturas();
		documento.setNombreDoc065(nombreDoc);
		documento.setOrigen065(Constantes.DOCUMENTO_ORIGEN_ADMINISTRACION);
		documento.setRutaPif065(rutaPif);
		documento.setTipoDocumento(tipoDocumento);
		documento.setFechaDoc065(new Date());
		documento.setTramiteAperturas(tramite);
		documento.setFormatoAport065(Constantes.FORMATO_APORTACION_ELECTRONICO);

		return documento;
	}

	/**
	 * Sube el documento de la tramitación a Dokusi, lo guarda en BD y solicita
	 * su transformación a PDFA
	 * 
	 * tarea TareaAperturas documento DocumentoAperturas.
	 * 
	 * @param tarea
	 *            the tarea
	 * @param documento
	 *            the documento
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	private void prepararDocTramitar(TareaAperturas tarea,
			DocumentoAperturas documento) throws AB04BException {// TODO metodo
		// trampeado porque
		// no funciona la
		// subida a Dokusi
		try {
			// Lo subimos a Dokusi
			T65BDocumentIDType t65BDocumentIDType = this.dokusiService
					.almacenarDocumento(
							UtilSeguridad.getInstance().getAuditUserAuto(),
							documento);

			// Guardamos su OID
			documento.setOidDokusi065(t65BDocumentIDType.getId());
			// documento.setOidDokusi065("09f4240180813c47");

			// Guardamos el Id de la tarea que deberá continuar cuando recibamos
			// la confirmación de transformación a PDFA
			documento.setTareaAperturasContinuar(tarea);

			// Persistimos en BD
			DocumentoAperturas documentoAux = this.documentoAperturasService
					.add(documento);

			String taskId = tarea.getTipoTarea().getTaskId090();
			if (!TipoTareaFlujo.ADJUNTAR_INFORME_INSPECCION
					.esEquivalente(taskId)) {
				// Solicitamos su transformación a PDFA
				this.dokusiService.transformarPDFA(
						UtilSeguridad.getInstance().getAuditUserAuto(),
						t65BDocumentIDType);

				TramitacionAperturasService.LOGGER.info(
						"Se ha subido el documento {} a Dokusi, con OID {} y se ha solicitado su transformación a PDFA",
						documentoAux.getIdDocumento065(),
						documentoAux.getOidDokusi065());
			}

			/***********************************/

			// this.manejadorTareaAperturas.continuarEjecucionTareaEsperaTransformacion(tarea.getIdTarea063(),
			// documento.getIdDocumento065());

			/***********************************/
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}
	}

	/**
	 * tarea TareaAperturas documento Long.
	 * 
	 * @param tarea
	 *            the tarea
	 * @param documento
	 *            the documento
	 */
	public void tramitarAdjuntarDoc(TareaAperturas tarea,
			DocumentoAperturas documento) {

		// Preparamos la tarea
		Task task = this.plateaTramitacionService.prepararTarea(
				tarea.getMailboxTaskId063(), TipoTareaPlatea.APORDOCU);

		// Indicamos los datos propios de la tarea
		StoredocumentTaskData storedocumentTaskData = task.getTaskInfo()
				.getStoredocumentTaskData();

		String taskId = tarea.getTipoTarea().getTaskId090();

		if (TipoTareaFlujo.ADJUNTAR_INFORME.esEquivalente(taskId)) {
			// Sender
			storedocumentTaskData.setSenderManagingUnitID(
					Utilities.getInstance().obtenerManagingunitIdOsalan());
			storedocumentTaskData.setSenderManagingUnitName(
					PlateaTramitacionUtils.getInstance()
							.obtenerManagingunitNameDescriptionOsalan());
			storedocumentTaskData.setSenderDepartmentID(
					Utilities.getInstance().obtenerDepartmentIdOsalan());
			storedocumentTaskData.setSenderDepartmentName(PlateaTramitacionUtils
					.getInstance().obtenerDepartmentNameDescriptionOsalan());
			storedocumentTaskData.setSenderOrganismID(
					Utilities.getInstance().obtenerOrganismIdOsalan());
			storedocumentTaskData.setSenderOrganismName(PlateaTramitacionUtils
					.getInstance().obtenerOrganismNameDescriptionOsalan());

			storedocumentTaskData.setInternalExternal(
					ConstantesPlateaTramitacion.APORTACION_EXTERNAL);
		} else {
			// Sender
			storedocumentTaskData.setSenderManagingUnitID(
					Utilities.getInstance().obtenerManagingunitId());
			storedocumentTaskData.setSenderManagingUnitName(
					PlateaTramitacionUtils.getInstance()
							.obtenerManagingunitNameDescription());
			storedocumentTaskData.setSenderDepartmentID(
					Utilities.getInstance().obtenerDepartmentId());
			storedocumentTaskData.setSenderDepartmentName(PlateaTramitacionUtils
					.getInstance().obtenerDepartmentNameDescription());
			storedocumentTaskData.setSenderOrganismID(
					Utilities.getInstance().obtenerOrganismId());
			storedocumentTaskData.setSenderOrganismName(PlateaTramitacionUtils
					.getInstance().obtenerOrganismNameDescription());

			storedocumentTaskData.setInternalExternal(
					ConstantesPlateaTramitacion.APORTACION_INTERNAL);
		}

		// Receiver
		storedocumentTaskData.setReceiverManagingUnitID(
				Utilities.getInstance().obtenerManagingunitId());
		storedocumentTaskData.setReceiverManagingUnitName(PlateaTramitacionUtils
				.getInstance().obtenerManagingunitNameDescription());
		storedocumentTaskData.setReceiverDepartmentID(
				Utilities.getInstance().obtenerDepartmentId());
		storedocumentTaskData.setReceiverDepartmentName(PlateaTramitacionUtils
				.getInstance().obtenerDepartmentNameDescription());
		storedocumentTaskData.setReceiverOrganismID(
				Utilities.getInstance().obtenerOrganismId());
		storedocumentTaskData.setReceiverOrganismName(PlateaTramitacionUtils
				.getInstance().obtenerOrganismNameDescription());

		storedocumentTaskData.setStoreDate(PlateaTramitacionUtils.getInstance()
				.formatearTimestampPlatea(documento.getFechaDoc065()));
		storedocumentTaskData
				.setEntityID(Utilities.getInstance().obtenerEntityId());

		storedocumentTaskData.getDocuments().getDocument()
				.add(PlateaTramitacionUtils.getInstance()
						.construirDocument(documento));

		// Lanzamos la ejecución de la tarea
		this.plateaTramitacionService.aportarDocumentacion(task);

	}

	/**
	 * tarea TareaAperturas documento Long.
	 * 
	 * @param tarea
	 *            the tarea
	 * @param documento
	 *            the documento
	 */
	public void tramitarRegistrarDoc(TareaAperturas tarea,
			DocumentoAperturas documento) {

		// Preparamos la tarea
		Task task = this.plateaTramitacionService.prepararTarea(
				tarea.getMailboxTaskId063(), TipoTareaPlatea.REGISTRDOC);

		// Indicamos los datos propios de la tarea
		RegistryTaskData registryTaskData = task.getTaskInfo()
				.getRegistryTaskData();

		String taskId = tarea.getTipoTarea().getTaskId090();

		if (TipoTareaFlujo.REGISTRA_INFORME_SALIDA.esEquivalente(taskId)) {
			// Sender
			registryTaskData.setSenderManagingUnitID(
					Utilities.getInstance().obtenerManagingunitIdOsalan());
			registryTaskData.setSenderManagingUnitName(PlateaTramitacionUtils
					.getInstance().obtenerManagingunitNameDescriptionOsalan());
			registryTaskData.setSenderDepartmentID(
					Utilities.getInstance().obtenerDepartmentIdOsalan());
			registryTaskData.setSenderDepartmentName(PlateaTramitacionUtils
					.getInstance().obtenerDepartmentNameDescriptionOsalan());
			registryTaskData.setSenderOrganismID(
					Utilities.getInstance().obtenerOrganismIdOsalan());
			registryTaskData.setSenderOrganismName(PlateaTramitacionUtils
					.getInstance().obtenerOrganismNameDescriptionOsalan());

			registryTaskData.setEntryExitType(
					ConstantesPlateaTramitacion.REGISTRO_SALIDA);

			registryTaskData.getDocuments().getDocument()
					.add(PlateaTramitacionUtils.getInstance()
							.construirDocument(documento));

		} else {
			// Sender
			registryTaskData.setSenderManagingUnitID(
					Utilities.getInstance().obtenerManagingunitId());
			registryTaskData.setSenderManagingUnitName(PlateaTramitacionUtils
					.getInstance().obtenerManagingunitNameDescription());
			registryTaskData.setSenderDepartmentID(
					Utilities.getInstance().obtenerDepartmentId());
			registryTaskData.setSenderDepartmentName(PlateaTramitacionUtils
					.getInstance().obtenerDepartmentNameDescription());
			registryTaskData.setSenderOrganismID(
					Utilities.getInstance().obtenerOrganismId());
			registryTaskData.setSenderOrganismName(PlateaTramitacionUtils
					.getInstance().obtenerOrganismNameDescription());

			registryTaskData.setEntryExitType(
					ConstantesPlateaTramitacion.REGISTRO_ENTRADA);
		}

		// Receiver
		registryTaskData.setReceiverManagingUnitID(
				Utilities.getInstance().obtenerManagingunitId());
		registryTaskData.setReceiverManagingUnitName(PlateaTramitacionUtils
				.getInstance().obtenerManagingunitNameDescription());
		registryTaskData.setReceiverDepartmentID(
				Utilities.getInstance().obtenerDepartmentId());
		registryTaskData.setReceiverDepartmentName(PlateaTramitacionUtils
				.getInstance().obtenerDepartmentNameDescription());
		registryTaskData.setReceiverOrganismID(
				Utilities.getInstance().obtenerOrganismId());
		registryTaskData.setReceiverOrganismName(PlateaTramitacionUtils
				.getInstance().obtenerOrganismNameDescription());

		registryTaskData.setRequestFormatID("1");

		// Lanzamos la ejecución de la tarea
		this.plateaTramitacionService.registrarDocumentacion(task);

	}

	/**
	 * tarea TareaAperturas tramite TramiteAperturas.
	 * 
	 * @param tarea
	 *            the tarea
	 * @param tramite
	 *            the tramite
	 */
	public void tramitarAcuseRequerimiento(TareaAperturas tarea,
			TramiteAperturas tramite) {

		// Preparamos la tarea
		Task task = this.plateaTramitacionService.prepararTarea(
				tarea.getMailboxTaskId063(), TipoTareaPlatea.RECINOTI);

		ComunicacionApertura apertura = this.comunicacionAperturaService
				.find(tramite.getApertura());

		Venviospostales venvioPostal = new Venviospostales();
		venvioPostal.setIdTramite(tramite.getIdTramite062());
		venvioPostal.setTipoexp(Constantes.APE);

		venvioPostal = this.venviospostalesService.findByTipoExp(venvioPostal);

		DatosEnvioPostal datosEnvioPostal = venvioPostal.getDatosEnvioPostal();

		// Indicamos los datos propios de la tarea
		DeliveredNotificationTaskData deliveredNotificationTaskData = task
				.getTaskInfo().getDeliveredNotificationTaskData();

		com.ejie.mbt.xml.DescriptionType notifiedActDescription = null;

		notifiedActDescription = PlateaTramitacionUtils.getInstance()
				.construirMbtDescriptionType(
						this.appMessageSource.getMessage(
								ConstantesPlateaTramitacion.NOT_ACT_NAME_REQ_SUB,
								null, Constantes.LOCALE_ES),
						this.appMessageSource.getMessage(
								ConstantesPlateaTramitacion.NOT_ACT_NAME_REQ_SUB,
								null, Constantes.LOCALE_EU));

		// deliveredNotificationTaskData.setNotificationID();
		deliveredNotificationTaskData.setNotifiedActID(
				ConstantesPlateaTramitacion.NOT_ACT_ID_REQ_SUB);
		deliveredNotificationTaskData
				.setNotifiedActDescription(notifiedActDescription);

		String notificationFormat = PlateaTramitacionUtils.getInstance()
				.obtenerNotificationFormat(
						apertura.getDatosNotificacion().getCanalnotif066());

		deliveredNotificationTaskData.setNotificationFormat(notificationFormat);
		// deliveredNotificationTaskData.setAddresseeID(apertura.getNumdoc056());
		// deliveredNotificationTaskData.setAddresseeName(apertura.getNomemp056());
		deliveredNotificationTaskData
				.setDeliveryPersonID(apertura.getNumdoc056());
		deliveredNotificationTaskData
				.setDeliveryPersonName(apertura.getNomemp056());
		deliveredNotificationTaskData
				.setDeliveryStatus(datosEnvioPostal.getEstadoAcuse069());
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				Constantes.ES_DATE_MASK);

		deliveredNotificationTaskData.setDeliveryTimestamp(
				dateFormat.format(datosEnvioPostal.getFecnotificacion069()));
		deliveredNotificationTaskData.setReceptionTimestamp(
				dateFormat.format(datosEnvioPostal.getFecAcuse069()));

		// Lanzamos la ejecución de la tarea
		this.plateaTramitacionService.acuseRequerimiento(task);
	}

	/**
	 * task Task tramite TramiteAperturas tarea TareaAperturas tipoTramite
	 * TipoTramiteFlujo.
	 * 
	 * @param task
	 *            the task
	 * @param tramite
	 *            the tramite
	 * @param tarea
	 *            the tarea
	 * @param tipoTramite
	 *            the tipo tramite
	 */
	public void processEnviarNotificacion(Task task, TramiteAperturas tramite,
			TareaAperturas tarea, TipoTramiteFlujo tipoTramite) {

		ComunicacionApertura apertura = this.comunicacionAperturaService
				.find(tramite.getApertura());
		DatosNotificacion datosNotif = this
				.obtenerDatosNotificacionDestinatario(apertura, tipoTramite);

		String[] datosDestinatario = this.obtenerDatosDestinatario(apertura,
				tipoTramite);

		// Ya hemos preparado la tarea antes en SvtService.process()

		// Indicamos los datos propios de la tarea
		NotifyTaskData notifyTaskData = task.getTaskInfo().getNotifyTaskData();

		notifyTaskData = PlateaTramitacionUtils.getInstance()
				.rellenarDatosBasicosNotification(notifyTaskData, datosNotif,
						datosDestinatario[0], datosDestinatario[1]);

		notifyTaskData = this.rellenarNotificationInfo(notifyTaskData,
				tipoTramite);

		List<DocumentoAperturas> listaDocumentos = this
				.obtenerDocumentos(tipoTramite, tarea);
		notifyTaskData = this.rellenarDocumentos(notifyTaskData,
				listaDocumentos);

		// Lanzamos la ejecución de la tarea
		this.plateaTramitacionService.enviarComunicacion(task);

	}

	/**
	 * apertura ComunicacionApertura tipoTramite TipoTramiteFlujo
	 * DatosNotificacion.
	 * 
	 * @param apertura
	 *            the apertura
	 * @param tipoTramite
	 *            the tipo tramite
	 * @return the datos notificacion
	 */
	private DatosNotificacion obtenerDatosNotificacionDestinatario(
			ComunicacionApertura apertura, TipoTramiteFlujo tipoTramite) {

		DatosNotificacion datosNotificacion = null;
		if (TipoTramiteFlujo.REQUERIMIENTO.equals(tipoTramite)
				|| TipoTramiteFlujo.COMUNICACION_CONTRATISTA.equals(tipoTramite)
				|| TipoTramiteFlujo.COMUNICACION_OS2.equals(tipoTramite)
				|| TipoTramiteFlujo.COMUNICACION_OS2OS3.equals(tipoTramite)
				|| TipoTramiteFlujo.CAMBIAR_COORDINADOR.equals(tipoTramite)) {
			datosNotificacion = this.datosNotificacionService
					.find(apertura.getDatosNotificacion());
		}

		return datosNotificacion;
	}

	/**
	 * Devuelve en la posición 0 el Nif/Cif del destinatario y en la posición 1
	 * el Nombre/Razón Social del destinatario
	 * 
	 * apertura ComunicacionApertura tipoTramite TipoTramiteFlujo String[].
	 * 
	 * @param apertura
	 *            the apertura
	 * @param tipoTramite
	 *            the tipo tramite
	 * @return the string[]
	 */
	private String[] obtenerDatosDestinatario(ComunicacionApertura apertura,
			TipoTramiteFlujo tipoTramite) {

		// TODO falta poner el nombre y cif real del destinatario
		String[] datosDestinatario = new String[ConstantesNum.NUM_2];

		if (TipoTramiteFlujo.REQUERIMIENTO.equals(tipoTramite)
				|| TipoTramiteFlujo.COMUNICACION_CONTRATISTA.equals(tipoTramite)
				|| TipoTramiteFlujo.COMUNICACION_OS2.equals(tipoTramite)
				|| TipoTramiteFlujo.COMUNICACION_OS2OS3.equals(tipoTramite)
				|| TipoTramiteFlujo.CAMBIAR_COORDINADOR.equals(tipoTramite)) {

			if (apertura.getNumdocrepresentante056() != null) {
				datosDestinatario[0] = apertura.getNumdocrepresentante056();
				datosDestinatario[1] = apertura.getNombrerepresentante056();

			} else {
				datosDestinatario[0] = apertura.getNumdoc056();
				datosDestinatario[1] = apertura.getNomemp056();
			}

			if (TipoTramiteFlujo.COMUNICACION_CONTRATISTA.equals(tipoTramite)
					|| TipoTramiteFlujo.CAMBIAR_COORDINADOR
							.equals(tipoTramite)) {
				// Añadimos (Att. contratista) al nombre
				StringBuilder sb = new StringBuilder(datosDestinatario[1]);
				sb.append(Constantes.DEST_CARTA_CONTRATISTA);
				datosDestinatario[1] = sb.toString();
			}
		}

		return datosDestinatario;
	}

	/**
	 * task Task tramite TramiteAperturas tarea TareaAperturas tipoTramite
	 * TipoTramiteFlujo.
	 * 
	 * @param task
	 *            the task
	 * @param tramite
	 *            the tramite
	 * @param tarea
	 *            the tarea
	 * @param tipoTramite
	 *            the tipo tramite
	 * @throws Exception
	 */
	public void processRegistrarComunicacionPostal(Task task,
			TramiteAperturas tramite, TareaAperturas tarea,
			TipoTramiteFlujo tipoTramite) throws Exception {

		ComunicacionApertura apertura = this.comunicacionAperturaService
				.find(tramite.getApertura());
		DatosNotificacion datosNotif = this
				.obtenerDatosNotificacionDestinatario(apertura, tipoTramite);

		apertura.setDatosNotificacion(datosNotif);

		DatosLocalizacion datosLocalizacion = this.datosLocalizacionService
				.find(new DatosLocalizacion(datosNotif.getDatosLocalizacion()
						.getCodLocalizacion067()));

		apertura.getDatosNotificacion().setDatosLocalizacion(datosLocalizacion);

		List<DocumentoAperturas> listaDocumentos = this
				.obtenerDocumentos(tipoTramite, tarea);

		if (TipoTramiteFlujo.REQUERIMIENTO.equals(tipoTramite)) {
			// Cargamos el envío a la aplicación de Servicio de Correspondencia

			DocumentoAperturas documento = listaDocumentos.get(0);
			documento.getTramiteAperturas().setApertura(apertura);

			RemesaWs remesaEntrada = ServicioCorrespondenciaUtils.getInstance()
					.construirRemesaWs(documento, apertura.getUsuarioTram());
			RemesaOutWs remesaResult = this.servicioCorrespondenciaService
					.cargaMasiva(remesaEntrada);

			if (remesaResult.getErrores() == null
					|| remesaResult.getErrores().isEmpty()) {

				TramitacionAperturasService.LOGGER
						.error("### IDREMESA = " + remesaResult.getIdremesa());
				TramitacionAperturasService.LOGGER.error(
						"### CODIGOREMESA = " + remesaResult.getCodigoRemesa());
				TramitacionAperturasService.LOGGER.error(
						"### IDCOLECCION = " + remesaResult.getIdColeccion());
				TramitacionAperturasService.LOGGER.error("### CODCOLECCION = "
						+ remesaResult.getCodigoColeccion());
				if (remesaResult.getEnvios() != null
						&& !remesaResult.getEnvios().isEmpty()) {

					EnvioOutWs envio = remesaResult.getEnvios().get(0);
					TramitacionAperturasService.LOGGER
							.error("### IDENVIO = " + envio.getIdEnvio());
					TramitacionAperturasService.LOGGER
							.error("### CODENVIO = " + envio.getCodEnvio());
				} else {
					TramitacionAperturasService.LOGGER.error("### NO ENVIOS ");
				}

				// Guardamos el resultado de la carga
				DatosEnvioPostal datosEnvioPostal = ServicioCorrespondenciaUtils
						.getInstance().construirDatosEnvioPostal(remesaResult);
				datosEnvioPostal.setEstadoEnvio069(
						ConstantesServicioCorrespondencia.ESTADO_ENVIO_PTE_IMPRESION);
				datosEnvioPostal = this.datosEnvioPostalService
						.add(datosEnvioPostal);
				documento.setDatosEnvioPostal(datosEnvioPostal);
				this.documentoAperturasService.updateFilled(documento);
			} else {
				// Ha habido errores
				TramitacionAperturasService.LOGGER.error(
						"Han ocurrido errores al cargar envío a la remesa");
				for (ErrorWs error : remesaResult.getErrores()) {
					TramitacionAperturasService.LOGGER.error(
							"Descripción error: {} - {}",
							error.getCodigoError(),
							error.getDescripcionCastellano());
				}
			}

		}
		// Ya hemos preparado la tarea antes en SvtService.process()

		// Indicamos los datos propios de la tarea
		NotifyTaskData notifyTaskData = task.getTaskInfo().getNotifyTaskData();

		notifyTaskData = PlateaTramitacionUtils.getInstance()
				.rellenarDatosBasicosNotification(notifyTaskData, datosNotif,
						apertura.getNumdocrepresentante056(),
						apertura.getNomemp056());

		notifyTaskData = this.rellenarNotificationInfo(notifyTaskData,
				tipoTramite);

		notifyTaskData = this.rellenarDocumentos(notifyTaskData,
				listaDocumentos);

		// Lanzamos la ejecución de la tarea
		this.plateaTramitacionService.registraComunicacionPostal(task);

	}

	/**
	 * notifyTaskData NotifyTaskData tipoTramite TipoTramiteFlujo
	 * NotifyTaskData.
	 * 
	 * @param notifyTaskData
	 *            the notify task data
	 * @param tipoTramite
	 *            the tipo tramite
	 * @return the notify task data
	 */
	private NotifyTaskData rellenarNotificationInfo(
			NotifyTaskData notifyTaskData, TipoTramiteFlujo tipoTramite) {

		String notifiedActId = "";
		com.ejie.mbt.xml.DescriptionType notifiedActName = null;
		String notTextEs = "";
		String notTextEu = "";

		if (TipoTramiteFlujo.REQUERIMIENTO.equals(tipoTramite)) {
			notifiedActId = ConstantesPlateaTramitacion.NOT_ACT_ID_REQ_SUB;
			notifiedActName = PlateaTramitacionUtils.getInstance()
					.construirMbtDescriptionType(
							this.appMessageSource.getMessage(
									ConstantesPlateaTramitacion.NOT_ACT_NAME_REQ_SUB,
									null, Constantes.LOCALE_ES),
							this.appMessageSource.getMessage(
									ConstantesPlateaTramitacion.NOT_ACT_NAME_REQ_SUB,
									null, Constantes.LOCALE_EU));

			notTextEs = this.appMessageSource.getMessage(
					PropertiesUtil.NOTTEXT_APERTURAS_REQSUB, null,
					Constantes.LOCALE_ES);
			notTextEu = this.appMessageSource.getMessage(
					PropertiesUtil.NOTTEXT_APERTURAS_REQSUB, null,
					Constantes.LOCALE_EU);
		} else if (TipoTramiteFlujo.COMUNICACION_CONTRATISTA.equals(tipoTramite)
				|| TipoTramiteFlujo.CAMBIAR_COORDINADOR.equals(tipoTramite)) {
			notifiedActId = ConstantesPlateaTramitacion.NOT_ACT_ID_COMUNIC;
			notifiedActName = PlateaTramitacionUtils.getInstance()
					.construirMbtDescriptionType(
							this.appMessageSource.getMessage(
									ConstantesPlateaTramitacion.NOT_ACT_NAME_COMUNIC,
									null, Constantes.LOCALE_ES),
							this.appMessageSource.getMessage(
									ConstantesPlateaTramitacion.NOT_ACT_NAME_COMUNIC,
									null, Constantes.LOCALE_EU));

			notTextEs = this.appMessageSource.getMessage(
					PropertiesUtil.NOTTEXT_APERTURAS_COMUNIC_1, null,
					Constantes.LOCALE_ES);
			notTextEu = this.appMessageSource.getMessage(
					PropertiesUtil.NOTTEXT_APERTURAS_COMUNIC_1, null,
					Constantes.LOCALE_EU);

		} else if (TipoTramiteFlujo.COMUNICACION_OS2.equals(tipoTramite)
				|| TipoTramiteFlujo.COMUNICACION_OS2OS3.equals(tipoTramite)) {

			notifiedActId = ConstantesPlateaTramitacion.NOT_ACT_ID_COMUNIC;
			notifiedActName = PlateaTramitacionUtils.getInstance()
					.construirMbtDescriptionType(
							this.appMessageSource.getMessage(
									ConstantesPlateaTramitacion.NOT_ACT_NAME_COMUNIC,
									null, Constantes.LOCALE_ES),
							this.appMessageSource.getMessage(
									ConstantesPlateaTramitacion.NOT_ACT_NAME_COMUNIC,
									null, Constantes.LOCALE_EU));

			notTextEs = this.appMessageSource.getMessage(
					PropertiesUtil.NOTTEXT_APERTURAS_COMUNIC_2, null,
					Constantes.LOCALE_ES);
			notTextEu = this.appMessageSource.getMessage(
					PropertiesUtil.NOTTEXT_APERTURAS_COMUNIC_2, null,
					Constantes.LOCALE_EU);
		}

		notifyTaskData.setNotifiedActID(notifiedActId);
		notifyTaskData.setNotifiedActName(notifiedActName);
		notifyTaskData.setNotificationText(PlateaTramitacionUtils.getInstance()
				.construirMbtDescriptionType(notTextEs, notTextEu));

		return notifyTaskData;
	}

	/**
	 * tipoTramite TipoTramiteFlujo tarea TareaAperturas List
	 * <DocumentoAperturas>.
	 * 
	 * @param tipoTramite
	 *            the tipo tramite
	 * @param tarea
	 *            the tarea
	 * @return the list
	 */
	public List<DocumentoAperturas> obtenerDocumentos(
			TipoTramiteFlujo tipoTramite, TareaAperturas tarea) {

		List<DocumentoAperturas> listaDocumentos = null;
		DocumentoAperturas documentoFilter = new DocumentoAperturas();

		documentoFilter.setTramiteAperturas(tarea.getTramiteAperturas());
		// TODO Cogemos todos los documentos del trámite. Por ahora no es
		// necesario filtrar por el tipo de documento.
		// if (TipoTramiteFlujo.REQUERIMIENTO.equals(tipoTramite)) {
		// documentoFilter.setTipoDocumento(new TipoDocumento(
		// TipoDocumentoEnum.REQUERIMIENTO.getIdTipoDoc()));
		// }

		listaDocumentos = this.documentoAperturasService
				.findAll(documentoFilter, null);

		return listaDocumentos;
	}

	/**
	 * notifyTaskData NotifyTaskData listaDocumentos List
	 * <DocumentoAperturas> NotifyTaskData.
	 * 
	 * @param notifyTaskData
	 *            the notify task data
	 * @param listaDocumentos
	 *            the lista documentos
	 * @return the notify task data
	 */
	private NotifyTaskData rellenarDocumentos(NotifyTaskData notifyTaskData,
			List<DocumentoAperturas> listaDocumentos) {

		if (listaDocumentos != null && !listaDocumentos.isEmpty()) {
			Documents documents = new Documents();
			for (DocumentoAperturas doc : listaDocumentos) {
				documents.getDocument().add(PlateaTramitacionUtils.getInstance()
						.construirDocument(doc));
			}
			notifyTaskData.setDocuments(documents);
		}

		return notifyTaskData;
	}

}
