package com.ejie.ad74a.tareas.service;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
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.ad74a.dao.ExpedientesDao;
import com.ejie.ad74a.exceptions.Ad74aException;
import com.ejie.ad74a.exceptions.ManagerErrors;
import com.ejie.ad74a.jms.util.ModelApplicationParser;
import com.ejie.ad74a.model.DocumentosTarea;
import com.ejie.ad74a.model.Estados;
import com.ejie.ad74a.model.Expedientes;
import com.ejie.ad74a.model.MaestroTareas;
import com.ejie.ad74a.model.NotifPostales;
import com.ejie.ad74a.model.TareasTramite;
import com.ejie.ad74a.model.TramitesExpediente;
import com.ejie.ad74a.service.NotifPostalesService;
import com.ejie.ad74a.service.TareasTramiteService;
import com.ejie.ad74a.service.documentos.DocumentosService;
import com.ejie.ad74a.service.tramitacion.TramitacionService;
import com.ejie.ad74a.util.comun.UtilLiterales;
import com.ejie.ad74a.util.comun.UtilTokenXlnets;
import com.ejie.ad74a.util.comun.UtilidadesFecha;
import com.ejie.ad74a.util.constantes.Constantes;
import com.ejie.ad74a.util.constantes.EstadoNotificacionEnum;
import com.ejie.ad74a.util.constantes.EstadosExpedienteEnum;
import com.ejie.ad74a.util.constantes.TareasEnum;
import com.ejie.ad74a.util.constantes.TipoNotificacionComunicacionEnum;
import com.ejie.ad74a.util.constantes.TiposDocumentoRoleEnum;
import com.ejie.ad74a.util.documentos.DocumentosPlateaUtils;
import com.ejie.ad74a.ws.client.platea.expedienteElectronico.TGetTelActionDocumentList;
import com.ejie.ad74a.ws.client.platea.expedienteElectronico.TProcedingDocument;
import com.ejie.ad74a.ws.client.platea.expedienteElectronico.TTelActionProceding;
import com.ejie.ad74a.ws.client.platea.model.task.Task;
import com.ejie.ad74a.ws.client.platea.notificaciones.TDocField;
import com.ejie.ad74a.ws.client.platea.notificaciones.TDocFieldList;
import com.ejie.ad74a.ws.client.platea.notificaciones.TNotificationFilter;
import com.ejie.ad74a.ws.client.platea.notificaciones.TStringList;
import com.ejie.ad74a.ws.client.platea.service.PlateaService;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TBoolean;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TDocFormatType;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TDocNatureType;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TGenerateWait;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TGenerateWaitList;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TLanguage;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TNotice;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TNoticeChannel;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TNoticeList;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TNoticeType;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TNotification;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TNotificationList;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TNotificationType;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TParticipantType;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TPersonIDName;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TSignWhoType;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TStringI18N;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTask;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTaskInfoDocument;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTaskInfoDocumentList;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTaskNotification;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTaskType;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTerm;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTermType;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTextI18N;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TWaitOriginType;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TWaitResult;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TWaitResultList;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TWaitType;
import com.ejie.x38.dto.TableRequestDto;

/**
 * Gestión de la Tarea de Notificación
 * 
 * @author IBERMATICA
 */

@Service(value = "tareaNotificacionService")
public class TareaNotificacionServiceImpl implements TareaNotificacionService {

	private static final Logger logger = LoggerFactory.getLogger(TareaNotificacionServiceImpl.class);
	private static final String LITERAL_NOTIFICACION_LIQUIDACION = "informe.notificacionLiquidacion";
	private static final String TIPO_DOCUMENTO_LIQUIDACION = "Liquidación";

	@Autowired
	private TramitacionService tramitacionService;

	@Autowired
	private PlateaService plateaService;

	@Autowired
	private ExpedientesDao expedientesDao;

	@Autowired
	private NotifPostalesService notifPostalesService;

	@Autowired
	private TareasTramiteService tareasTramiteService;

	@Autowired
	private ReloadableResourceBundleMessageSource messageSource;

	@Autowired
	private DocumentosService documentosService;

	@Override
	public void tareaSugerida(Task task) throws Throwable {

		TareaNotificacionServiceImpl.logger.info("TareaNotificacionServiceImpl.tareaSugerida -{}-{}- inicio ",
				task.getTaskID(), task.getMailboxTaskID());

		TareaNotificacionServiceImpl.logger.info("TareaNotificacionServiceImpl.tareaSugerida #t0# ");

		String numRegistro = ModelApplicationParser.getNumRegistryFromTask(task);

		Expedientes expediente = new Expedientes();
		expediente.setFolderId00(task.getFolderID());
		List<Expedientes> listaExpedientes = expedientesDao.findExpedienteByFolderId(expediente);

		if (CollectionUtils.isNotEmpty(listaExpedientes)) {
			// se recuperan todos los datos del expediente
			expediente = expedientesDao.find(listaExpedientes.get(0));
		} else {
			ManagerErrors.manageError(
					"Error al sugerir la tarea de notificacion: no se ha encontrado el expediente FolderId: "
							+ task.getFolderID());
		}

		// almacenamos el tramite y la tarea
		this.tramitacionService.tratamientoTramiteTareaAutomaticaSugerida(task, numRegistro, expediente);

		// ** En función del ID de la tarea se especifica la acción ** //
		switch ((TareasEnum.getEnumByTaskId(task.getTaskID()))) {
		case NOTIFICACION_SUBSANACION:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_NOTIFICAR_REQUERIMIENTO.getId()));
			break;
		// ** Especificar acciones propias en función del tipo de tarea ** //
		// *****************************************************
		case NOTI_RESOL_DESISTIMIENTO:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_NOTIFICAR_RESOL_DESISTIMIENTO.getId()));
			break;
		case NOTI_RESOL_CONCESION:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_NOTIFICAR_RESOL_CONCESION.getId()));
			break;
		case NOTI_RESOL_DENEGACION:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_NOTIFICAR_RESOL_DENEGACION.getId()));
			break;
		case NOTI_TRAMITE_AUDIENCIA:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_NOTI_TRAMITE_AUDIENCIA.getId()));
			break;
		case NOTI_RESOL_DENEGACION_SERVICIO_AUDIENCIA:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_NOTIFICAR_RESOL_DENEGACION.getId()));
			break;
		case NOTI_LIQUIDACION:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_NOTIFICAR_LIQUIDACION.getId()));
			break;
		default:
			// Si no es ninguna de las tareas de notificaciono contempladas, no se actualiza
			// nada mas.
			return;
		}

		// Para todas las tareas de notificacion, se actualiza el estado del expediente
		// y se ejecuta la tarea.
		this.expedientesDao.updateEstado(expediente);

		this.prepararYEjecutarTareaNotificacion(expediente, task);

		TareaNotificacionServiceImpl.logger.info("TareaNotificacionServiceImpl.tareaSugerida -{}-{}- fin ",
				task.getTaskID(), task.getMailboxTaskID());
	}

	@Override
	public void tareaEjecutada(Task task) throws Throwable {
		TareaNotificacionServiceImpl.logger.info("TareaNotificacionServiceImpl.tareaEjecutada -{}-{}- inicio ",
				task.getTaskID(), task.getMailboxTaskID());

		Expedientes expediente = new Expedientes();
		expediente.setFolderId00(task.getFolderID());
		List<Expedientes> listaExpedientes = expedientesDao.findAll(expediente, null);

		if (CollectionUtils.isNotEmpty(listaExpedientes)) {
			expediente = listaExpedientes.get(0);
		} else {
			ManagerErrors
					.manageError("Error al sugerir la tarea de estudio: no se ha encontrado el expediente FolderId: "
							+ task.getFolderID());
		}

		// ** Actualizar trámite y tarea **/
		this.tramitacionService.tratamientoTramiteTareaEjecutada(task, true);

		expediente.setEstadoNotificacion00(EstadoNotificacionEnum.PENDIENTE_ACUSE.getId());
		this.expedientesDao.updateEstadoNotificacion(expediente);

		/*
		 * Si la notificacion es postal, se requiere guardar registro aparte para
		 * tratamiento con la pasarela de notificaciones postales
		 */
		notificacionPostalEjecutada(task);

		// ** En función del ID de la tarea se especifica la acción ** //
		switch ((TareasEnum.getEnumByTaskId(task.getTaskID()))) {
		case NOTIFICACION_SUBSANACION:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_ACUSE_RESOL_REQUERIMIENTO.getId()));
			this.expedientesDao.updateEstado(expediente);
			break;

		// ** Especificar acciones propias en función del tipo de tarea ** //
		// *****************************************************
		case NOTI_RESOL_DESISTIMIENTO:
			// grabar fecha resol de desistimiento con la fecha
			expediente.setfResolDesis00(UtilidadesFecha.parsearFechaPlatea(task.getDoTimestamp()));
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_ACUSE_RESOL_DESISTIMIENTO.getId()));
			this.expedientesDao.updateNotifResolDesis(expediente);

			break;
		case NOTI_RESOL_CONCESION:
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_ACUSE_RESOL_CONCESION.getId()));
			this.expedientesDao.updateNotifResolucion(expediente);
			break;
		case NOTI_RESOL_DENEGACION:
		case NOTI_RESOL_DENEGACION_SERVICIO_AUDIENCIA:
			// grabar fecha resol con la fecha, estado a pendiente de acuse
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_ACUSE_RESOL_DENEGACION.getId()));
			this.expedientesDao.updateNotifResolucion(expediente);

			break;
		case NOTI_TRAMITE_AUDIENCIA:
			// grabar fecha resol con la fecha, estado a pendiente de acuse
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_ACUSE_TRAMITE_AUDIENCIA.getId()));
			this.expedientesDao.updateEstado(expediente);

			break;
		case NOTI_LIQUIDACION:
			TareaNotificacionServiceImpl.logger.info("TareaNotificacionServiceImpl.cas NOTI_LIQUIDACION");
			// grabar fecha notificacion con la fecha, estado a pendiente de acuse
			expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_ACUSE_NOTI_LIQUIDACION.getId()));
			this.expedientesDao.updateNotifResolucion(expediente);

			break;
		default:
			break;
		}

		TareaNotificacionServiceImpl.logger.info("TareaNotificacionServiceImpl.tareaEjecutada -{}-{}- fin ",
				task.getTaskID(), task.getMailboxTaskID());
	}

	/*
	 * Ejecutar tarea sugerida de notificacion
	 */
	private TTask prepararYEjecutarTareaNotificacion(Expedientes expediente, Task task) throws Exception {

		// Recupera datos de la tarea de platea
		TTask taskDo = plateaService.prepareTask(task.getMailboxTaskID(), TTaskType.NOTIFICACION);

		// Prepara la generacion de esperas tal y como establece la guia
		taskDo.setGenerateWait(new TGenerateWaitList());

		// Informar datos de la espera
		informGenerateWaitNotificationObject(taskDo);

		// Informar datos de la persona a la que va dirigida la notificacion
		informAddresseeID(taskDo, expediente);

		/*-
		 * XXX [jbhg] de donde se deberia comprobar si hay que hacer una notificacion
		 * postal? de los datos del solicitante/representante en nuestra bbdd o de la
		 * información que devuelve platea para estos interesados?
		 * ¿Deberíamos notificar siempre con los datos que tenemos en bbdd?
		 */
		if (this.comprobarNotificacionPostal(taskDo)) {
			/*
			 * XXX [JBHG] En caso de notificacion postal, se debe agregar el buzon
			 * tramitador del técnico asociado al expediente.
			 */
			taskDo.getTaskNotification()
					.setPostalInboxID(UtilTokenXlnets.getPuestoUsuario(expediente.getTecnicoExpediente00()));
			taskDo.getTaskNotification().setNotificationFormat(TNotificationType.POSTAL);
			/*-
			 * XXX ATENCION se toma como principio que cualquier notificación sugerida manualmente será una retramitación de una notificación anterior 
			 * Comprobar si la tarea trae la lista de documentos informada (solo 
			 * vendrá informada si se ha sugerido automáticamente por flujo), sino
			 * es que quiere retramitar una notificacion anterior
			 */
			if (taskDo.getTaskNotification().getDocumentList() == null
					|| CollectionUtils.isEmpty(taskDo.getTaskNotification().getDocumentList().getDocument())) {
				informarDocumentosARenotificar(taskDo, expediente);
			}
		} else {
			taskDo.getTaskNotification().setNotificationFormat(TNotificationType.ELECTRONICA);
		}

		// SOLO para NOTID_LIQUID adjuntar el documento a notificar

		if (TareasEnum.NOTI_LIQUIDACION.getProceedingId().equals(task.getTaskID())) {
			logger.debug("Es una notificacion de liquidacion. IdTarea: {}", taskDo.getFolderID());
			asignarDocumentoNotLiq(taskDo);
		}

		// Ejecutar tarea de notificacion
		return plateaService.doTask(TareasEnum.getTaskType(taskDo.getTaskID()), taskDo);
	}

	/*
	 * Informa la lista de documentos en la notificacion. Esto sucede cuando se
	 * quiere retramitar una notificación que no ha sido sugerida por el flujo
	 * (después del APORDOCU), sino manualmente.
	 */
	private void informarDocumentosARenotificar(TTask taskDo, Expedientes expediente) {
		logger.debug("informarDocumentosARenotificar folderId:{} taskId:{} taskGUID:{}", taskDo.getFolderID(),
				taskDo.getTaskID(), taskDo.getTaskGUID());
		/*
		 * Recuperar última notificación de este mismo tipo en el expediente que se haya
		 * marcado para retramitar y obtener su lista de documentos
		 */
		NotifPostales notifPostales = getNotifPostalRetramitar(taskDo, expediente);

		///

		// Recuperar datos de la notificacion anterior en PLATEA
		TNotificationFilter filter = new TNotificationFilter();
		filter.setDocFieldList(new TDocFieldList());
		filter.getDocFieldList().getItem().add(TDocField.DOC_INFO);
		filter.setNotificationIDList(new TStringList());
		filter.getNotificationIDList().getItem().add(notifPostales.getTareasTramite().getIdNotificacion11());
		com.ejie.ad74a.ws.client.platea.notificaciones.TNotification not = plateaService.searchNotifications(filter)
				.get(0);
		// Se recupera el documento con el servicio de getTelactionDocuments, que
		// devuelve mas datos que el de notificaciones
		TProcedingDocument documento = getDocumentoPlateaRetramitar(taskDo, not);

		// Rellenar datos de la tarea con la info del último documento recuperado
		rellenarDocumentoTareaEjecutar(taskDo, not, documento);
		// Actualizar estado de retramitacion de la notificacion en bbdd
		notifPostales.setRetramitar(Constantes.NotifPostalesRetramitar.RETRAMITADA);
		notifPostalesService.update(notifPostales);
	}

	/*
	 * Informa los datos del documento de la tarea de notificacion
	 */
	private void rellenarDocumentoTareaEjecutar(TTask taskDo,
			com.ejie.ad74a.ws.client.platea.notificaciones.TNotification not, TProcedingDocument documento) {
		// Se inicializa el parámetro si estaba vacío
		if (taskDo.getTaskNotification().getDocumentList() == null) {
			taskDo.getTaskNotification().setDocumentList(new TTaskInfoDocumentList());

		}
		TTaskInfoDocument dNew = new TTaskInfoDocument();
		dNew.setTitle(documento.getTitle());
		dNew.setDokusiID(documento.getDokusiID());
		dNew.setDocumentRoleID(documento.getDocumentRoleID());
		// Manera "sencilla" de clonar objetos TTextI18N de diferentes esquemas
		TTextI18N i18n = new TTextI18N();
		dNew.setDocumentRoleName(i18n);
		try {
			BeanUtils.copyProperties(i18n, documento.getDocumentRoleName());
		} catch (IllegalAccessException | InvocationTargetException e) {
			logger.warn(
					"informarDocumentosARenotificar - Error al copiar los nombres del rolename del documento a notificar");
		}
		dNew.setSourceName(documento.getSourceName());
		dNew.setFormat(TDocFormatType.fromValue(documento.getDocumentFormat().value()));
		dNew.setExtension(not.getDocument().getExtension());
		taskDo.getTaskNotification().getDocumentList().getDocument().add(dNew);
	}

	/*
	 * Obtiene el documento en PLATEA asociado a la notificacion que se quiere
	 * retramitar.
	 */
	private TProcedingDocument getDocumentoPlateaRetramitar(TTask taskDo,
			com.ejie.ad74a.ws.client.platea.notificaciones.TNotification not) {
		TGetTelActionDocumentList docList = plateaService.getDocumentsTelAction(taskDo.getFolderID(),
				taskDo.getProcedureID());
		TProcedingDocument documento = null;
		for (TTelActionProceding proceeding : docList.getGeneratedList().getProceding()) {
			for (TProcedingDocument doc : proceeding.getDocumentList().getDocument()) {
				if (doc.getDokusiID().equalsIgnoreCase(not.getDocument().getDokusiID())) {
					documento = doc;
					break;
				}
			}
			if (documento != null) {
				break;
			}
		}
		if (documento == null) {
			throw new Ad74aException("notifpostales.error.noexistedocumentoretramitar",
					"No se ha encontrado el documento '" + not.getDocument().getDokusiID() + "' a retramitar");
		}
		return documento;
	}

	/*
	 * Recupera la notificacion postal que se quiere retramitar
	 */
	private NotifPostales getNotifPostalRetramitar(TTask taskDo, Expedientes expediente) {
		NotifPostales notifPostales = new NotifPostales();
		notifPostales.setRetramitar(Constantes.NotifPostalesRetramitar.RETRAMITANDO);
		TareasTramite tareasTramite = new TareasTramite();
		MaestroTareas maestroTareas = new MaestroTareas();
		maestroTareas.setTipoTarea38(taskDo.getTaskID());
		tareasTramite.setMaestroTareas(maestroTareas);
		TramitesExpediente tramitesExpediente = new TramitesExpediente();
		Expedientes exp = new Expedientes();
		exp.setIdExpediente00(expediente.getIdExpediente00());
		tramitesExpediente.setExpediente(exp);
		tareasTramite.setTramitesExpediente(tramitesExpediente);
		notifPostales.setTareasTramite(tareasTramite);
		notifPostales = notifPostalesService
				.findAllLike(notifPostales, new TableRequestDto(null, null, "IDNOTIFPOSTAL88", "DESC"), true).get(0);
		return notifPostales;
	}

	/*
	 * Comprueba si en la tarea hay alguna notificacion postal a realizar.
	 */
	private boolean comprobarNotificacionPostal(TTask taskDo) {
		boolean resultado = false;
		if (taskDo.getTaskNotification() != null && taskDo.getTaskNotification().getNotificationList() != null
				&& CollectionUtils.isNotEmpty(taskDo.getTaskNotification().getNotificationList().getNotification())) {
			for (TNotification not : taskDo.getTaskNotification().getNotificationList().getNotification()) {
				if (not != null && not.getNotify() != null && not.getNotify().getChannel() != null
						&& TNotificationType.POSTAL.equals(not.getNotify().getChannel().getChannelType())) {
					resultado = true;
					break;
					/*-
					 * Aqui Rellenar datos necesarios en caso de notificacion postal.
					 * XXX [jbhg] Los datos de notificacion ya los proporciona platea en el prepareTask, 
					 * si es necesario, se pueden sobreescribir aqui con lo que se tiene en la bbdd de ad74a. 
					 */
				}
			}
		}
		return resultado;
	}

	/*
	 * [jbhg] Tratamiento en caso de que sea una notificacion postal
	 */
	private void notificacionPostalEjecutada(Task task) {
		// Si tiene un id de envio postal de AA66, es una notificacion postal integrada
		// con la PNP.
		if (task.getTaskInfo().getNotifyTaskData() != null
				&& StringUtils.isNotBlank(task.getTaskInfo().getNotifyTaskData().getIdEnvioPostal())) {
			logger.debug("Es una notificacion postal. IdEnvio: {}",
					task.getTaskInfo().getNotifyTaskData().getIdEnvioPostal());
			// Buscar la pk de la tarea correspondiente en bbdd
			TareasTramite tBuscar = new TareasTramite();
			tBuscar.setTaskguid11(task.getMailboxTaskID());
			List<TareasTramite> listTareas = tareasTramiteService.findAll(tBuscar, null);
			if (CollectionUtils.isEmpty(listTareas)) {
				logger.warn("No se ha encontrado la tarea de notificacion postal '{}' en el sistema",
						task.getMailboxTaskID());
				return;
			}
			// Crear la notificacion postal
			NotifPostales notifPostales = new NotifPostales();
			notifPostales.setTareasTramite(listTareas.get(0));
			notifPostales.setTipoNot88(TipoNotificacionComunicacionEnum.NOTIFICACION.getValor());
			notifPostales
					.setIdEnvioPostal88(Integer.valueOf(task.getTaskInfo().getNotifyTaskData().getIdEnvioPostal()));
			notifPostales.setIdColeccionPostal88(
					Integer.valueOf(task.getTaskInfo().getNotifyTaskData().getIdColeccionPostal()));
			notifPostales.setPostalInboxId88(task.getTaskInfo().getNotifyTaskData().getPostalInboxID());
			notifPostales.setFinalizada88(Constantes.VAL_NUM_NO);
			// Se registra la notificacion postal para su gestion posterior por el
			// tramitador
			notifPostalesService.add(notifPostales);
		}
	}

	/*
	 * Genera el objeto TGenerateWait para una notificación, de la manera que se
	 * indica en la guia de PLATEA
	 */
	private void informGenerateWaitNotificationObject(TTask taskDo) {
		TGenerateWait g = new TGenerateWait();
		g.setOriginType(TWaitOriginType.CIUDADANO);
		g.setWaitType(TWaitType.NOTIFICACION_CIUDADANO);
		TTerm term = new TTerm();
		term.setValue(10);// 10 dias habiles
		term.setType(TTermType.DIA);
		g.setTerm(term);
		g.setIsInformConsultation(TBoolean.TRUE);
		g.setIsGenerateWait(TBoolean.TRUE);
		g.setResultList(new TWaitResultList());
		TWaitResult result = new TWaitResult();
		TStringI18N string18n = new TStringI18N();
		result.setDescription(new TTextI18N());
		result.setValue("0");// Codigo de espera aceptada
		string18n.setLocale(TLanguage.ES);
		string18n.setValue(messageSource.getMessage("resultadoespera.aceptada", null,
				com.ejie.ad74a.constantes.Constantes.LOCALE_ES));
		result.getDescription().getText().add(string18n);
		string18n = new TStringI18N();
		string18n.setLocale(TLanguage.EU);
		string18n.setValue(messageSource.getMessage("resultadoespera.aceptada", null,
				com.ejie.ad74a.constantes.Constantes.LOCALE_EU));
		result.getDescription().getText().add(string18n);
		g.getResultList().getResult().add(result);
		result = new TWaitResult();
		result.setDescription(new TTextI18N());
		result.setValue("1");// Codigo de espera rechazada
		string18n = new TStringI18N();
		string18n.setLocale(TLanguage.ES);
		string18n.setValue(messageSource.getMessage("resultadoespera.rechazada", null,
				com.ejie.ad74a.constantes.Constantes.LOCALE_ES));
		result.getDescription().getText().add(string18n);
		string18n = new TStringI18N();
		string18n.setLocale(TLanguage.EU);
		string18n.setValue(messageSource.getMessage("resultadoespera.rechazada", null,
				com.ejie.ad74a.constantes.Constantes.LOCALE_EU));
		result.getDescription().getText().add(string18n);
		g.getResultList().getResult().add(result);

		taskDo.getGenerateWait().getWait().add(g);
	}

	/*
	 * Informa el objeto addresseID en TaskNotification, con los datos del
	 * representante si hubiera, y si no del solicitante.
	 */
	private void informAddresseeID(TTask taskDo, Expedientes expediente) {
		// El solicitante siempre es persona fisica

		boolean esPersonaFisica = true;
		String dni = expediente.getSolicitantes().getIdentificador01();
		String nombre = expediente.getSolicitantes().getNombre01();
		String ape1 = expediente.getSolicitantes().getApellido101();
		String ape2 = expediente.getSolicitantes().getApellido201();
		if (Constantes.PresentaSolicitud.REPRESENTANTE.equals(expediente.getPresentaSol00())) {
			// Si el expediente tiene representante, se indican sus datos
			esPersonaFisica = Constantes.TIPO_PERSONA_FISICA_BBDD.equals(expediente.getTipoRep00());

			dni = expediente.getIdentificadorRep00();
			if (esPersonaFisica) {
				nombre = expediente.getNombreRep00();
			} else {
				nombre = expediente.getRazonSocialRep00();
			}

			ape1 = expediente.getApellido1Rep00();
			ape2 = expediente.getApellido2Rep00();
		}

		TTaskNotification n = taskDo.getTaskNotification();
		// Se crea el objeto AddresseeID
		n.setAddresseeID(new TPersonIDName());
		n.getAddresseeID().setID(dni);
		n.getAddresseeID().setName(nombre);
		if (esPersonaFisica) {
			n.getAddresseeID().setFirstLastName(ape1);
			n.getAddresseeID().setSecondLastName(ape2);
		}
	}

	/*
	 * Asigna documentos a la tarea de notificacion
	 */
	private void asignarDocumentoNotLiq(TTask tTask) throws Exception {
		TareaNotificacionServiceImpl.logger.info("TareaNotificacionServiceImpl.asignarDocumento -  inicio ");
		if (tTask.getTaskNotification() == null) {
			tTask.setTaskNotification(new TTaskNotification());
		}
		if (tTask.getTaskNotification().getDocumentList() == null) {
			tTask.getTaskNotification().setDocumentList(new TTaskInfoDocumentList());
		}

		Expedientes expediente = new Expedientes();
		expediente.setFolderId00(tTask.getFolderID());
		List<Expedientes> listaExpedientes = expedientesDao.findAll(expediente, null);

		if (null != listaExpedientes && !listaExpedientes.isEmpty()) {
			expediente = listaExpedientes.get(0);
		}

		/* ### NOTIFICATION INICIO ### */
		TNotification not = new TNotification();
		TPersonIDName personID = new TPersonIDName();
		// Siempre es afectado porque el procedimiento es de oficio y no hay solicitante
		not.setRoleName(TParticipantType.AFECTADO);
		if (expediente.getIdentificadorRep00() != null) {
			personID.setID(expediente.getIdentificadorRep00());
			personID.setName(expediente.getNombreCompletoRep());
		} else {
			personID.setID(expediente.getSolicitantes().getIdentificador01());
			personID.setName(expediente.getSolicitantes().getNombreCompleto());
		}
		not.setPersonID(personID);
		TNotificationList notList = new TNotificationList();
		notList.getNotification().add(not);
		tTask.getTaskNotification().setNotificationList(notList);
		/* ### NOTIFICATION FIN ### */
		/* ### TNoticeList INICIO ### */
		TNoticeList tNoticeList = new TNoticeList();
		if (Constantes.CanalNotificacion.CANAL_NOTIF_ALL.equals(expediente.getCanalNot00())
				|| Constantes.CanalNotificacion.CANAL_NOTIF_MAIL.equals(expediente.getCanalNot00())) {
			TNotice tNotice = new TNotice();
			TNoticeChannel tNoticeChannel = new TNoticeChannel();
			tNoticeChannel.setChannelType(TNoticeType.EMAIL);
			tNoticeChannel.setEmail(expediente.getEmailNot00());
			tNotice.setChannel(tNoticeChannel);
			tNotice.setAddresseeID(expediente.getSolicitantes().getIdentificador01());
			tNotice.setAddresseeName(expediente.getSolicitantes().getNombreCompleto());
			tNoticeList.getNotice().add(tNotice);

		} else if (Constantes.CanalNotificacion.CANAL_NOTIF_ALL.equals(expediente.getCanalNot00())
				|| Constantes.CanalNotificacion.CANAL_NOTIF_SMS.equals(expediente.getCanalNot00())) {

			TNoticeChannel tNoticeChannel = new TNoticeChannel();
			tNoticeChannel.setChannelType(TNoticeType.SMS);
			tNoticeChannel.setSms(expediente.getTfnoNot00());

			TNotice tNotice = new TNotice();
			tNotice.setChannel(tNoticeChannel);
			tNotice.setAddresseeID(expediente.getSolicitantes().getIdentificador01());
			tNotice.setAddresseeName(expediente.getSolicitantes().getNombreCompleto());

			tNoticeList.getNotice().add(tNotice);

		}
		tTask.getTaskNotification().setNoticeList(tNoticeList);
		/* ### TNoticeList FIN ### */
		tTask.getTaskNotification().setNotifiedActID(Constantes.NOTIFIEDACT_ID_NOTIFICATION);
		tTask.getTaskNotification().setOrganizationID(Constantes.PLATEA_ENTITY_ID);
		tTask.getTaskNotification().setOrganizationName(DocumentosPlateaUtils
				.setValueToText(Constantes.PLATEA_ENTITY_NAME_ES, Constantes.PLATEA_ENTITY_NAME_EU));
		tTask.getTaskNotification()
				.setNotifiedActName(DocumentosPlateaUtils.setValueToText(
						UtilLiterales.getLiteralMessage(messageSource, com.ejie.ad74a.constantes.Constantes.LOCALE_ES,
								LITERAL_NOTIFICACION_LIQUIDACION),
						UtilLiterales.getLiteralMessage(messageSource, com.ejie.ad74a.constantes.Constantes.LOCALE_EU,
								LITERAL_NOTIFICACION_LIQUIDACION)));
		tTask.getTaskNotification().setSignType(TSignWhoType.SERVIDOR);
		tTask.getTaskNotification().setCertificateID(Constantes.plateaCertificateID);
		tTask.getTaskNotification().setIsAllowAttachCitizenDocuments(TBoolean.FALSE);

		tTask.getTaskNotification().setAddresseeID(personID);

		HashMap<String, List<DocumentosTarea>> result = new HashMap<>();
		documentosService.recuperarDocExpedientes(expediente.getIdExpediente00(), result);
		List<DocumentosTarea> docs = result.get(Constantes.DOCUMENTOS_GENERADO);

		if (docs != null) {
			TareaNotificacionServiceImpl.logger
					.info("TareaNotificacionServiceImpl.asignarDocumento -  docs encontrados: {}", docs.size());
			prepararDocumentosNotLiq(tTask, docs);

		}
		TareaNotificacionServiceImpl.logger.info("TareaNotificacionServiceImpl.asignarDocumento -  fin ");
	}

	/*
	 * Prepara los documentos a añadir a la notificaion de liquidacion
	 */
	private void prepararDocumentosNotLiq(TTask tTask, List<DocumentosTarea> docs) throws Exception {
		for (DocumentosTarea doc : docs) {

			/* ### TTaskInfoDocument INICIO ### */
			TTaskInfoDocument docPlatea = new TTaskInfoDocument();
			docPlatea.setDokusiID(doc.getOiddokusi18());
			if (doc.getTipoDocumentoDescEs().equalsIgnoreCase(TIPO_DOCUMENTO_LIQUIDACION)) {
				docPlatea.setDocumentRoleID(TiposDocumentoRoleEnum.LIQUIDACION.getRoleID());
				docPlatea.setDocumentRoleName(
						DocumentosPlateaUtils.setValueToText(TiposDocumentoRoleEnum.LIQUIDACION.getLabelDesc(),
								TiposDocumentoRoleEnum.LIQUIDACION.getLabelDesc()));
				String[] auxNomFic = doc.getNombreDoc18().split("\\.");
				docPlatea.setSourceName(doc.getNombreDoc18());
				docPlatea.setExtension(auxNomFic[auxNomFic.length - 1]);
				docPlatea.setFormatName(auxNomFic[auxNomFic.length - 1]);
				docPlatea.setNature(TDocNatureType.ELECTRONICO);
				docPlatea.setLanguage(TLanguage.BI);
				docPlatea.setIsNotifiDocument(TBoolean.TRUE);
				Date fechaDoc = null;
				if (null != doc.getfModif18()) {
					fechaDoc = doc.getfModif18();
				} else if (null != doc.getfAlta18()) {
					fechaDoc = doc.getfAlta18();
				} else {
					fechaDoc = UtilidadesFecha.getFechaSistema();
				}

				docPlatea.setDocumentDate(UtilidadesFecha.formatearDateToStringMasc(fechaDoc,
						com.ejie.ad74a.constantes.Constantes.PLATEA_XML_EVENTS_DATE_FORMAT));
				docPlatea.setValidDate(UtilidadesFecha.formatearDateToStringMasc(fechaDoc,
						com.ejie.ad74a.constantes.Constantes.PLATEA_XML_EVENTS_DATE_FORMAT));

				tTask.getTaskNotification().getDocumentList().getDocument().add(docPlatea);
				// tTask.getTaskNotification().setDocumentOID(doc.getOiddokusi18());

				/* ### TTaskInfoDocument FIN ### */
			}

		}
		/*
		 * [jbhg] aqui habia bastante código comentado, se quita (revisar si se quiere
		 * versiones anteriores de svn)
		 */
	}
}
