package com.ejie.ad74a.tareas.service;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.lang.exception.ExceptionUtils;
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.AvisosDao;
import com.ejie.ad74a.dao.DependenciaDao;
import com.ejie.ad74a.dao.DireccionesDao;
import com.ejie.ad74a.dao.DiscapacidadDao;
import com.ejie.ad74a.dao.ExpedientesDao;
import com.ejie.ad74a.dao.InformesDao;
import com.ejie.ad74a.dao.PisosSolicitantesDao;
import com.ejie.ad74a.dao.PreciosBeneficiarioDao;
import com.ejie.ad74a.dao.SolicitantesDao;
import com.ejie.ad74a.dao.TareasTramiteDao;
import com.ejie.ad74a.dao.TramitesExpedienteDao;
import com.ejie.ad74a.exceptions.ManagerErrors;
import com.ejie.ad74a.jms.util.ModelApplicationParser;
import com.ejie.ad74a.model.Avisos;
import com.ejie.ad74a.model.DatosTareaEstudio;
import com.ejie.ad74a.model.DatosTareaEstudioAlta;
import com.ejie.ad74a.model.DatosTareaEstudioModDireccion;
import com.ejie.ad74a.model.DatosTareaEstudioRevision;
import com.ejie.ad74a.model.Dependencia;
import com.ejie.ad74a.model.Direcciones;
import com.ejie.ad74a.model.Discapacidad;
import com.ejie.ad74a.model.ErroresTelevida;
import com.ejie.ad74a.model.Estados;
import com.ejie.ad74a.model.Expedientes;
import com.ejie.ad74a.model.Informes;
import com.ejie.ad74a.model.MaestroActores;
import com.ejie.ad74a.model.MaestroSubtiposAviso;
import com.ejie.ad74a.model.MaestroTiposAviso;
import com.ejie.ad74a.model.PisosSolicitantes;
import com.ejie.ad74a.model.PreciosBeneficiario;
import com.ejie.ad74a.model.Solicitantes;
import com.ejie.ad74a.model.TareasTramite;
import com.ejie.ad74a.model.TramitesExpediente;
import com.ejie.ad74a.scheduler.JobSchedulerService;
import com.ejie.ad74a.scheduler.SchedulerJobType;
import com.ejie.ad74a.service.ErroresTelevidaService;
import com.ejie.ad74a.service.tramitacion.TramitacionService;
import com.ejie.ad74a.util.comun.Utilidades;
import com.ejie.ad74a.util.comun.UtilidadesFecha;
import com.ejie.ad74a.util.constantes.ActoresEnum;
import com.ejie.ad74a.util.constantes.Constantes;
import com.ejie.ad74a.util.constantes.EstadoInformesEnum;
import com.ejie.ad74a.util.constantes.EstadosExpedienteEnum;
import com.ejie.ad74a.util.constantes.FinalizacionEstudioEnum;
import com.ejie.ad74a.util.constantes.ProcedimientosEnum;
import com.ejie.ad74a.util.constantes.SubTipoAvisoEnum;
import com.ejie.ad74a.util.constantes.TareasEnum;
import com.ejie.ad74a.util.constantes.TipoAvisoEnum;
import com.ejie.ad74a.util.constantes.TipoInformesEnum;
import com.ejie.ad74a.util.constantes.TramitesEnum;
import com.ejie.ad74a.ws.client.platea.model.task.Task;
import com.ejie.ad74a.ws.client.platea.service.PlateaService;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTask;
import com.ejie.ad74a.ws.client.platea.tareasTramitacion.TTaskType;
import com.ejie.ad74a.ws.client.prestadorWS.data.TipoComunicacionEnum;
import com.ejie.ad74a.ws.client.prestadorWS.service.PrestadorWSService;

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

@Service(value = "tareaEstudioService")
public class TareaEstudioServiceImpl implements TareaEstudioService {

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

	@Autowired
	private TramitacionService tramitacionService;

	@Autowired
	private PlateaService plateaService;

	@Autowired
	private ExpedientesDao expedientesDao;

	@Autowired
	private TareasTramiteDao tareasTramiteDao;

	@Autowired
	private DependenciaDao dependenciaDao;

	@Autowired
	private DireccionesDao direccionesDao;

	@Autowired
	private DiscapacidadDao discapacidadDao;

	@Autowired
	private SolicitantesDao solicitantesDao;

	@Autowired
	private PisosSolicitantesDao pisosSolicitantesDao;

	@Autowired
	private PreciosBeneficiarioDao preciosBeneficiarioDao;

	@Autowired
	private AvisosDao avisosDao;

	@Autowired
	private InformesDao informesDao;

	@Autowired
	private TramitesExpedienteDao tramitesExpedienteDao;

	@javax.annotation.Resource
	private ReloadableResourceBundleMessageSource appMessageSource;

	@Autowired
	private PrestadorWSService prestadorWsService;

	@Autowired
	private ErroresTelevidaService erroresTelevidaService;

	@Autowired
	private JobSchedulerService jobSchedulerService;

	/**
	 * Método que gestiona el evento de Tarea Sugerida
	 * 
	 */
	public void tareaSugerida(Task task) throws Throwable {
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaSugerida -" + task.getTaskID() + "-"
				+ task.getMailboxTaskID() + "- inicio ");

		String numRegistro = ModelApplicationParser.getNumRegistryFromTask(task);

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

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

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

		// actualizamos el estado del expediente a Pendiente de estudio por apertura si
		// el estado es pendiente apertura (Sólo se cambia en los estudios de apertura,
		// no en los de Aportacion/Subsanción)
		if (EstadosExpedienteEnum.PEND_APERTURA.getId().equals(expediente.getEstados().getIdEstado30())) {
			expediente.getEstados().setIdEstado30(EstadosExpedienteEnum.PEND_ESTUDIO.getId());
			this.expedientesDao.updateEstado(expediente);
		} else if (EstadosExpedienteEnum.PEND_ALEGACIONES.getId().equals(expediente.getEstados().getIdEstado30())) {
			// En las alegaciones
			this.tramitacionService.finalizarTareaEstudio(expediente.getFolderId00(),
					FinalizacionEstudioEnum.RESOLUCION_DENEGACION_ALEGACIONES.getId());
		}

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaSugerida -" + task.getTaskID() + "-"
				+ task.getMailboxTaskID() + "- fin ");
	}

	/**
	 * Método que gestiona el evento de Tarea Ejecutada
	 */
	public void tareaCancelada(Task task) throws Throwable {
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaCancelada -" + task.getTaskID() + "-"
				+ task.getMailboxTaskID() + "- inicio ");

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

		if (null != listaExpedientes && listaExpedientes.size() > 0) {
			expedienteOrigen = listaExpedientes.get(0);
		} else {
			ManagerErrors
					.manageError("Error al ejecutar la tarea de estudio: no se ha encontrado el expediente FolderId: "
							+ task.getFolderID());
		}

		// ** Gestión de la finalización de la tarea de Estudio * //
		if (null != task.getTaskInfo() && null != task.getTaskInfo().getStudyTaskData()
				&& !Utilidades.esBlancoNulo(task.getTaskInfo().getStudyTaskData().getSituacionID())) {

			List<TareasTramite> listaTareas = this.tareasTramiteDao
					.getLastNotExecutedTask(expedienteOrigen.getIdExpediente00(), TramitesEnum.ESTUDIO_DOCUMENTACION);

			if (!listaTareas.isEmpty()) {
				TramitesExpediente tramiteEstudio = this.tramitesExpedienteDao
						.find(new TramitesExpediente(listaTareas.get(0).getTramitesExpediente().getIdTramiteExp10()));

				TareasTramite tareaEstudio = listaTareas.get(0);
				DatosTareaEstudio datosTareaEstudio = new DatosTareaEstudio();

				datosTareaEstudio.setTramitesExpediente(tramiteEstudio);
				datosTareaEstudio.setExpediente(expedienteOrigen);
				datosTareaEstudio
						.setSituacioneFinalTarea(Long.parseLong(FinalizacionEstudioEnum.NO_HACER_NADA.getId()));
				datosTareaEstudio.setResultadoEstudio(Constantes.ResultadoDocumentacion.COMPLETO.getId());
				tareaEstudio.setDatosTarea(datosTareaEstudio);
				this.tareasTramiteDao.update(tareaEstudio);

				// EJECUTAR TAREA DE ESTUDIO ** //
				this.tramitacionService.finalizarTareaEstudio(expedienteOrigen.getFolderId00(),
						FinalizacionEstudioEnum.NO_HACER_NADA.getId());
			}

			this.tramitacionService.tratamientoTramiteTareaEjecutada(task, false);

			TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaCancelada -" + task.getTaskID() + "-"
					+ task.getMailboxTaskID() + "- fin ");
		}
	}

	/**
	 * Método que gestiona el evento de Tarea Ejecutada
	 */
	public void tareaEjecutada(Task task) throws Throwable {
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaEjecutada -" + task.getTaskID() + "-"
				+ task.getMailboxTaskID() + "- inicio ");

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

		if (null != listaExpedientes && listaExpedientes.size() > 0) {
			expedienteOrigen = listaExpedientes.get(0);
		} else {
			ManagerErrors
					.manageError("Error al ejecutar la tarea de estudio: no se ha encontrado el expediente FolderId: "
							+ task.getFolderID());
		}

		// ** Gestión de la finalización de la tarea de Estudio * //
		if (null != task.getTaskInfo() && null != task.getTaskInfo().getStudyTaskData()
				&& !Utilidades.esBlancoNulo(task.getTaskInfo().getStudyTaskData().getSituacionID())) {
			String resultado = task.getTaskInfo().getStudyTaskData().getSituacionID();
			// el resultado viene en formato -> COD-Texto Descritivo
			String[] valores = resultado.split("-");

			String procedureId = task.getProcedureID();
			// ** En función del ID de la tarea se especifica la acción ** //
			switch (ProcedimientosEnum.getById(procedureId)) {

			case ALTA:
				/***************************/

				if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.REQUERIMIENTO_SUBSANACION.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - ALTA. REQUERIMIENTO SUBSANACION");
					// actualizamos el estado del expediente a Pendiente de subsanacion
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_REQ_SUBSANACION.getId()));
					this.expedientesDao.updateEstado(expedienteOrigen);

					// sugerir tramite de requerimiento de subsanacion
					this.tramitacionService.sugerirTarea(task, TareasEnum.REQUERIMIENTO_SUBSANACION);
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.NO_HACER_NADA.getId())) {
					TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaEjecutada - ALTA. NO HACER NADA");
					// No se hace nada
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.RESOLUCION_CONCESION.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - ALTA. RESOLUCION DE CONCESION");

					// actualizamos el estado del expediente a Pendiente de subsanacion y el
					// resultado del estudio
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_RESOLUCION_CONCESION.getId()));
					expedienteOrigen.setResultadoEstudio00(
							Integer.valueOf(FinalizacionEstudioEnum.RESOLUCION_CONCESION.getId()));
					this.expedientesDao.updateEstadoAndResultadoEstudio(expedienteOrigen);

					// actualizamos datos de dependencia y discapacidad, fechas de resolucion,
					// urgencia ,exoneracion y precioPrivado/exoneracion
					this.updateDatosAltaResolConc(expedienteOrigen, task.getMailboxTaskID(), task.getSenderID());

					// Paso a historico del piso tutelado en caso de haber y se crea nuevo registro
					Long idBeneficiario = expedienteOrigen.getIdSolicitante00();
					tratamientoPisosHistorico(expedienteOrigen, idBeneficiario, true,
							expedienteOrigen.getfResolucion00());

					// sugerir tramite de resolucion de concesion
					this.tramitacionService.sugerirTarea(task, TareasEnum.RESOL_CONCESION);
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.RESOLUCION_DENEGACION.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - ALTA. RESOLUCION DE DENEGACION");
					// actualizamos el estado del expediente a Pendiente de subsanacion
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_RESOLUCION_DENEGACION.getId()));
					expedienteOrigen.setResultadoEstudio00(
							Integer.valueOf(FinalizacionEstudioEnum.RESOLUCION_DENEGACION.getId()));
					this.expedientesDao.updateEstadoAndResultadoEstudio(expedienteOrigen);

					// sugerir tramite de resolucion de concesion
					this.tramitacionService.sugerirTarea(task, TareasEnum.RESOL_DENEGACION);
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.DESISTIMIENTO.getId())) {
					TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaEjecutada - ALTA. DESISTIMIENTO");

					// Sugerir tramite de resolución de desistimiento
					this.tramitacionService.sugerirTarea(task, TareasEnum.RESOL_DESISTIMIENTO);
				} else {
					ManagerErrors.manageError(
							"La situación final del estudio no esta controlada : " + procedureId + "," + valores[0]);
				}
				break;
			case BAJA:
				/***************************/
				if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.RESOLUCION_CONCESION.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - BAJA. RESOLUCION DE CONCESION");
					// actualizamos el estado del expediente a Pendiente de cerrar y el
					// resultado del estudio
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_RESOLUCION_CONCESION.getId()));
					expedienteOrigen.setResultadoEstudio00(
							Integer.valueOf(FinalizacionEstudioEnum.RESOLUCION_CONCESION.getId()));
					this.expedientesDao.updateEstadoAndResultadoEstudio(expedienteOrigen);

					// Paso a historico del piso tutelado en caso de haber y se crea nuevo registro
					Long idBeneficiario = solicitantesDao
							.findBeneficiarioPorIdSolicitante(expedienteOrigen.getSolicitantes()).getIdSolicitante01();
					tratamientoPisosHistorico(expedienteOrigen, idBeneficiario, false,
							expedienteOrigen.getSolicitantes().getfBaja01());

					// actualizamos datos de baja del solicitante
					this.updateBajaConcesion(expedienteOrigen, task.getMailboxTaskID(), task.getSenderID(),
							idBeneficiario);

					// se sugiere la tarea de resolucion de concesion
					this.tramitacionService.sugerirTarea(task, TareasEnum.RESOL_CONCESION);
				} else if (valores[0]
						.equalsIgnoreCase(FinalizacionEstudioEnum.RESOLUCION_DENEGACION_ALEGACIONES.getId())) {
					TareaEstudioServiceImpl.logger.info(
							"TareaEstudioServiceImpl.tareaEjecutada - BAJA. RESOLUCION_DENEGACION_SERVICIO_AUDIENCIA");
					// actualizamos el estado del expediente a Pendiente de cerrar y el
					// resultado del estudio
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_RESOLUCION_CONCESION.getId()));
					expedienteOrigen.setResultadoEstudio00(
							Integer.valueOf(FinalizacionEstudioEnum.RESOLUCION_DENEGACION_ALEGACIONES.getId()));
					this.expedientesDao.updateEstadoAndResultadoEstudio(expedienteOrigen);

					// Paso a historico del piso tutelado en caso de haber y se crea nuevo registro
					Long idBeneficiario = solicitantesDao
							.findBeneficiarioPorIdSolicitante(expedienteOrigen.getSolicitantes()).getIdSolicitante01();
					tratamientoPisosHistorico(expedienteOrigen, idBeneficiario, false,
							expedienteOrigen.getSolicitantes().getfBaja01());

					// se sugiere la tarea de resolucion de concesion
					this.tramitacionService.sugerirTarea(task, TareasEnum.RESOL_DENEGACION_SERVICIO_AUDIENCIA);
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.NO_HACER_NADA.getId())) {
					TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaEjecutada - BAJA. NO HACER NADA");
					// No se hace nada
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.TRAMITE_DE_AUDIENCIA.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - BAJA. TRAMITE DE AUDIENCIA");

					// actualizamos el estado del expediente a Pendiente de subsanacion
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_NOTI_TRAMITE_AUDIENCIA.getId()));
					expedienteOrigen.setResultadoEstudio00(
							Integer.valueOf(FinalizacionEstudioEnum.TRAMITE_DE_AUDIENCIA.getId()));
					this.expedientesDao.updateEstadoAndResultadoEstudio(expedienteOrigen);
					// sugerir tramite de Notificacion del tramite de audiencia
					this.tramitacionService.sugerirTarea(task, TareasEnum.AUDIENCIA);

				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.DESISTIMIENTO.getId())) {
					TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaEjecutada - ALTA. DESISTIMIENTO");

					// Sugerir tramite de resolución de desistimiento
					this.tramitacionService.sugerirTarea(task, TareasEnum.RESOL_DESISTIMIENTO);
				} else {
					ManagerErrors.manageError(
							"La situación final del estudio no esta controlada : " + procedureId + "," + valores[0]);
				}
				break;
			case INFORME:
				/***************************/
				if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.REQUERIMIENTO_SUBSANACION.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - INFORME INTERVENCION. REQ. SUBSANACION");
					// actualizamos el estado del expediente a Pendiente de subsanacion
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_SUBSANACION.getId()));
					this.expedientesDao.updateEstado(expedienteOrigen);

					// sugerir tramite de requerimiento de subsanacion
					this.tramitacionService.sugerirTarea(task, TareasEnum.REQUERIMIENTO_SUBSANACION);
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.NO_HACER_NADA.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - INFORME INTERVENCION. NO HACER NADA");
					// No se hace nada
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.SOLICITAR_INFORME.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - INFORME INTERVENCION. SOLICITAR INFORME");
					// actualizamos el estado del expediente a Pendiente de solicitar informe
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_APORTAR_INFORME.getId()));
					expedienteOrigen
							.setResultadoEstudio00(Integer.valueOf(FinalizacionEstudioEnum.SOLICITAR_INFORME.getId()));
					this.expedientesDao.updateEstadoAndResultadoEstudio(expedienteOrigen);

					// crear informe
					Informes informe = generarInforme(expedienteOrigen);
					informe = this.informesDao.add(informe);

					// Recuperamos el comentario que se guarda en el estudio de documentación
					TramitesExpediente tramite = new TramitesExpediente();

					TareasTramite tareaTramite = new TareasTramite();
					tareaTramite.setTaskguid11(task.getMailboxTaskID());

					tramite.setTareaTramite(tareaTramite);

					tramite = this.tramitesExpedienteDao.findTramiteByTaskGUID(tramite);
					expedienteOrigen.setTramitesExpediente(tramite);

					// crear aviso de informe de intervencion
					Avisos aviso = getAvisoInformeIntervencion(expedienteOrigen);
					aviso.setIdInforme20(informe.getIdInforme16());
					aviso = this.avisosDao.add(aviso);

					// Se sugiere la solicitud informe intervencion
					this.tramitacionService.sugerirTarea(task, TareasEnum.SOLICITUD_INFORME_INTERVENCION);

				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.NO_SOLICITAR_INFORME.getId())) {
					TareaEstudioServiceImpl.logger.info(
							"TareaEstudioServiceImpl.tareaEjecutada - INFORME INTERVENCION REQ. NO SOLICITAR INFORME");
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_CERRAR.getId()));
					expedienteOrigen.setResultadoEstudio00(
							Integer.valueOf(FinalizacionEstudioEnum.NO_SOLICITAR_INFORME.getId()));
					this.expedientesDao.updateEstadoAndResultadoEstudio(expedienteOrigen);

					// Se sugiere el cierre del expediente
					this.tramitacionService.sugerirTarea(task, TareasEnum.CIERRE);
				} else {
					ManagerErrors.manageError(
							"La situación final del estudio no esta controlada : " + procedureId + "," + valores[0]);
				}
				break;
			case MODIFICACION:
				/***************************/
				if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.REQUERIMIENTO_SUBSANACION.getId())) {
					TareaEstudioServiceImpl.logger.info(
							"TareaEstudioServiceImpl.tareaEjecutada - MODIFICACION DE DIRECCION. REQUERIMIENTO SUBSANACION");
					// actualizamos el estado del expediente a Pendiente de subsanacion
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_SUBSANACION.getId()));
					this.expedientesDao.updateEstado(expedienteOrigen);

					// sugerir tramite de requerimiento de subsanacion
					this.tramitacionService.sugerirTarea(task, TareasEnum.REQUERIMIENTO_SUBSANACION);
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.NO_HACER_NADA.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - MODIFICACION DE DIRECCION. NO HACER NADA");
					// No se hace nada
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.CAMBIO_ACEPTADO.getId())) {
					TareaEstudioServiceImpl.logger.info(
							"TareaEstudioServiceImpl.tareaEjecutada - MODIFICACION DE DIRECCION. CAMBIO ACEPTADO");

					Solicitantes solicitante = new Solicitantes(
							expedienteOrigen.getSolicitantes().getIdSolicitante01());

					actualizarDirecciones(task, expedienteOrigen);

					// Se actualiza el estado a pendiente de cierre
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_CERRAR.getId()));
					this.expedientesDao.updateEstado(expedienteOrigen);

					// Paso a historico del piso tutelado en caso de haber y se crea nuevo registro
					Long idBeneficiario = solicitantesDao
							.findBeneficiarioPorIdSolicitante(expedienteOrigen.getSolicitantes()).getIdSolicitante01();

					DatosTareaEstudioModDireccion datTar = getDatosTareaModificacion(task.getMailboxTaskID());
					Date fEjecucionEstudi = null;
					if (null != datTar) {
						fEjecucionEstudi = getDatosTareaModificacion(task.getMailboxTaskID()).getfCambio();
					} else {
						fEjecucionEstudi = Calendar.getInstance().getTime();
					}
					tratamientoPisosHistorico(expedienteOrigen, idBeneficiario, true, fEjecucionEstudi);

					// Se sugiere el cierre del expediente
					this.tramitacionService.sugerirTarea(task, TareasEnum.CIERRE);

					long initPrestador = System.currentTimeMillis();
					try {
						this.prestadorWsService.enviarCambioDomicilio(solicitante, expedienteOrigen);

					} catch (Exception e) {
						e.printStackTrace();
						TareaEstudioServiceImpl.logger.error(
								"TareaEstudioServiceImpl.tareaEjecutada - MODIFICACION DE DIRECCION - CAMBIO_ACEPTADO  - error al llamar al WS del prestador: "
										+ e.getMessage());
						ErroresTelevida errorPS = new ErroresTelevida();
						errorPS.setErrormsg51(getErrorMessage(ExceptionUtils.getStackTrace(e)));
						errorPS.setEstado51(com.ejie.ad74a.util.constantes.Constantes.EstadoErrores.ESTADO_ERRONEO);
						errorPS.setFecrecep51(new Date());
						errorPS.setTipomensaje51(TipoComunicacionEnum.DOMICILIO.value());
						errorPS.setSentido51(Constantes.UNO);
						errorPS.setError51("-1");
						try {
							errorPS.setMensaje51("#".concat(solicitante.getIdSolicitante01().toString()).concat("#")
									.concat(expedienteOrigen.getIdExpediente00().toString()));
						} catch (Exception e2) {
							e2.printStackTrace();
						}
						errorPS = erroresTelevidaService.add(errorPS);

						try {
							// ** Programar RE-Ejecución en diferido ** //
							HashMap<String, String> params = new HashMap<String, String>();
							params.put("id", errorPS.getIdError51().toString());
							this.jobSchedulerService.programarEjecucion(SchedulerJobType.ERROR_TELEVIDA, params);
						} catch (Exception e2) {
							// Solo para que no haga rollback
							TareaEstudioServiceImpl.logger
									.error("Error programando re-ejecución: " + ExceptionUtils.getStackTrace(e2));
						}
					}
					long endPrestador = System.currentTimeMillis();
					TareaEstudioServiceImpl.logger.info(
							"llamada al WS del prestador :" + (endPrestador - initPrestador) / 1000 + " segundos");

				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.CAMBIO_NO_ACEPTADO.getId())) {
					TareaEstudioServiceImpl.logger.info(
							"TareaEstudioServiceImpl.tareaEjecutada - MODIFICACION DE DIRECCION. CAMBIO NO ACEPTADO");
					/**
					 * Si el estudio de documentación finaliza con ‘Cambio no aceptado’, se solicita
					 * la fecha de rechazo y el motivo. Así mismo se finaliza el plazo para subsanar
					 * documentación que hubiera pendiente
					 */

					// Se actualiza el estado a pendiente de cierre
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_CERRAR.getId()));
					this.expedientesDao.updateEstado(expedienteOrigen);

					// Se sugiere el cierre del expediente
					this.tramitacionService.sugerirTarea(task, TareasEnum.CIERRE);
				} else {
					ManagerErrors.manageError(
							"La situación final del estudio no esta controlada : " + procedureId + "," + valores[0]);
				}
				break;
			case REVISION_PRECIO:
				/***************************/
				if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.REQUERIMIENTO_SUBSANACION.getId())) {
					TareaEstudioServiceImpl.logger.info(
							"TareaEstudioServiceImpl.tareaEjecutada - REVISION DE PRECIO. REQUERIMIENTO SUBSANACION");
					// actualizamos el estado del expediente a Pendiente de subsanacion
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_SUBSANACION.getId()));
					this.expedientesDao.updateEstado(expedienteOrigen);

					// sugerir tramite de requerimiento de subsanacion
					this.tramitacionService.sugerirTarea(task, TareasEnum.REQUERIMIENTO_SUBSANACION);
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.RESOLUCION_CONCESION.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - REVISION DE PRECIO. RESOLUCION_CONCESION");
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_RESOLUCION_CONCESION.getId()));
					expedienteOrigen.setResultadoEstudio00(
							Integer.valueOf(FinalizacionEstudioEnum.RESOLUCION_CONCESION.getId()));
					this.expedientesDao.updateEstadoAndResultadoEstudio(expedienteOrigen);

					Long idBeneficiario = solicitantesDao
							.findBeneficiarioPorIdSolicitante(expedienteOrigen.getSolicitantes()).getIdSolicitante01();

					// actualizamos datos de dependencia y discapacidad, fechas de resolucion,
					// urgencia, exoneracion precio privado/exoneracion
					this.updateDatosRevisionResolConc(expedienteOrigen, task.getMailboxTaskID(), task.getSenderID(),
							idBeneficiario);

					// sugerir tramite de resolucion de concesion
					this.tramitacionService.sugerirTarea(task, TareasEnum.RESOL_CONCESION);

				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.RESOLUCION_DENEGACION.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - REVISION DE PRECIO. RESOLUCION_DENEGACION");

					// actualizamos el estado del expediente a Pendiente de subsanacion
					expedienteOrigen.setEstados(new Estados(EstadosExpedienteEnum.PEND_RESOLUCION_DENEGACION.getId()));
					expedienteOrigen.setResultadoEstudio00(
							Integer.valueOf(FinalizacionEstudioEnum.RESOLUCION_DENEGACION.getId()));
					this.expedientesDao.updateEstadoAndResultadoEstudio(expedienteOrigen);

					// sugerir tramite de resolucion de concesion
					this.tramitacionService.sugerirTarea(task, TareasEnum.RESOL_DENEGACION);

				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.NO_HACER_NADA.getId())) {
					TareaEstudioServiceImpl.logger
							.info("TareaEstudioServiceImpl.tareaEjecutada - REVISION DE PRECIO. NO HACER NADA");
					// No se hace nada
				} else if (valores[0].equalsIgnoreCase(FinalizacionEstudioEnum.DESISTIMIENTO.getId())) {
					TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaEjecutada - ALTA. DESISTIMIENTO");

					// Sugerir tramite de resolución de desistimiento
					this.tramitacionService.sugerirTarea(task, TareasEnum.RESOL_DESISTIMIENTO);
				} else {
					ManagerErrors.manageError(
							"La situación final del estudio no esta controlada : " + procedureId + "," + valores[0]);
				}
				break;

			default:
				break;
			}
		}
		this.tramitacionService.tratamientoTramiteTareaEjecutada(task, false);

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tareaEjecutada -" + task.getTaskID() + "-"
				+ task.getMailboxTaskID() + "- fin ");
	}

	private void tratamientoPisosHistorico(Expedientes expedienteOrigen, Long idBeneficiario, Boolean nuevoReg,
			Date fecha) {

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tratamientoPisosHistorico - expedienteOrigen "
				+ expedienteOrigen.getIdExpediente00() + "- idBeneficiario " + idBeneficiario + " - nuevoReg "
				+ nuevoReg + " - inicio ");

		if (expedienteOrigen.getPerfiles() != null) {
			PisosSolicitantes pisosSolFilter = new PisosSolicitantes();
			pisosSolFilter.setIdSolicitante32(idBeneficiario);
			PisosSolicitantes pisosSolicitantesActivo = this.pisosSolicitantesDao.findBySolActivo(pisosSolFilter);
			if (null != pisosSolicitantesActivo && null != pisosSolicitantesActivo.getIdPiso32()) {
				TareaEstudioServiceImpl.logger.info(
						"TareaEstudioServiceImpl.tratamientoPisosHistorico - pisosSolicitantesActivo {}",
						pisosSolicitantesActivo.getIdPiso32());

				pisosSolicitantesActivo.setFHasta32(fecha);
				this.pisosSolicitantesDao.update(pisosSolicitantesActivo);
			}
			if (nuevoReg && Constantes.VAL_NUM_SI.equals(expedienteOrigen.getPerfiles().getPisoTutelado07())) {
				PisosSolicitantes pisosSolicitantesNuevo = new PisosSolicitantes();
				pisosSolicitantesNuevo.setFDesde32(fecha);
				pisosSolicitantesNuevo.setIdSolicitante32(idBeneficiario);
				pisosSolicitantesNuevo.setIdPiso32(expedienteOrigen.getPerfiles().getPisosTutelados().getIdPiso32());
				this.pisosSolicitantesDao.add(pisosSolicitantesNuevo);

			}
			Solicitantes beneficiario = this.solicitantesDao.find(new Solicitantes(idBeneficiario));
			if (beneficiario != null) {
				beneficiario.setPerfiles(expedienteOrigen.getPerfiles());
				this.solicitantesDao.updatePerfil(beneficiario);
			}
		}
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.tratamientoPisosHistorico - expedienteOrigen "
				+ expedienteOrigen.getIdExpediente00() + "- idBeneficiario " + idBeneficiario + " - nuevoReg "
				+ nuevoReg + "- fin ");
	}

	private void tratamientoPreciosBenficiarioHistorico(Expedientes expedienteOrigen, Long idBeneficiario,
			Boolean nuevoReg, DatosTareaEstudio datosTareaEstudio, String usuario) {

		TareaEstudioServiceImpl.logger
				.info("TareaEstudioServiceImpl.tratamientoPreciosBenficiarioHistorico - expedienteOrigen "
						+ expedienteOrigen.getIdExpediente00() + "- idBeneficiario" + idBeneficiario + " - nuevoReg "
						+ nuevoReg + " - inicio ");

		if (expedienteOrigen != null) {
			PreciosBeneficiario preciosBeneficiarioFilter = new PreciosBeneficiario();
			preciosBeneficiarioFilter.setIdSolicitante91(idBeneficiario);
			PreciosBeneficiario pisosSolicitantesActivo = this.preciosBeneficiarioDao
					.findBySolActivo(preciosBeneficiarioFilter);
			if (null != pisosSolicitantesActivo) {
				TareaEstudioServiceImpl.logger.debug(
						"TareaEstudioServiceImpl.tratamientoPreciosBenficiarioHistorico - PrecioBeneficiarioActivo "
								+ pisosSolicitantesActivo.getIdPrecioBeneficiario91());

				pisosSolicitantesActivo.setFechaFin91(datosTareaEstudio.getExpediente().getfResolucion00());
				this.preciosBeneficiarioDao.update(pisosSolicitantesActivo);
			}
			if (Boolean.TRUE.equals(nuevoReg)
					&& Constantes.VAL_NUM_SI.equals(expedienteOrigen.getPerfiles().getPisoTutelado07())) {
				PreciosBeneficiario preciosBeneficiarioNuevo = new PreciosBeneficiario();
				preciosBeneficiarioNuevo.setFechaInicio91(datosTareaEstudio.getExpediente().getfResolucion00());
				preciosBeneficiarioNuevo.setIdSolicitante91(idBeneficiario);
				if (ProcedimientosEnum.REVISION_PRECIO.getId()
						.equalsIgnoreCase(datosTareaEstudio.getIdProcedimiento00())) {
					DatosTareaEstudioRevision datosTareaEstudioRevision = (DatosTareaEstudioRevision) datosTareaEstudio;
					if (Constantes.TIPOPRECIO_PRIVADO.equals(datosTareaEstudioRevision.getTipoPrecio())) {
						preciosBeneficiarioNuevo.setPrecioPrivado91(expedienteOrigen.getPrecioFinal00());
					}
				} else if (ProcedimientosEnum.ALTA.getId().equalsIgnoreCase(datosTareaEstudio.getIdProcedimiento00())) {
					DatosTareaEstudioAlta datosTareaEstudioAlta = (DatosTareaEstudioAlta) datosTareaEstudio;
					if (Constantes.TIPOPRECIO_PRIVADO.equals(datosTareaEstudioAlta.getTipoPrecio())) {
						preciosBeneficiarioNuevo.setPrecioPrivado91(expedienteOrigen.getPrecioFinal00());
					}
				}

				preciosBeneficiarioNuevo.setIndExento91(expedienteOrigen.getExencionRes00());
				preciosBeneficiarioNuevo.setUsuAlta91(usuario);
				this.preciosBeneficiarioDao.add(preciosBeneficiarioNuevo);

			}
		}
		TareaEstudioServiceImpl.logger
				.info("TareaEstudioServiceImpl.tratamientoPreciosBenficiarioHistorico - expedienteOrigen "
						+ expedienteOrigen.getIdExpediente00() + "- idBeneficiario" + idBeneficiario + " - nuevoReg "
						+ nuevoReg + "- fin ");
	}

	private void updateBajaDenegacion(Expedientes expediente, String taskGUID, String senderID) {

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateBajaDenegacion -" + taskGUID + "- Inicio");

		TareasTramite tarea = new TareasTramite();
		tarea.setTaskguid11(taskGUID);
		tarea = this.tareasTramiteDao.findAll(tarea, null).get(0);
		if (null != tarea && null != tarea.getDatosTareaEstudio()
				&& !Utilidades.esBlancoNulo(tarea.getDatosTareaEstudio().getIdProcedimiento00())
				&& tarea.getDatosTareaEstudio().getIdProcedimiento00().equalsIgnoreCase(ProcedimientosEnum.BAJA.getId())
				&& null != tarea.getDatosTarea11() && null != tarea.getDatosTareaEstudioBaja()
				&& null != tarea.getDatosTareaEstudioBaja().getfDenegacionBaja()) {

			Solicitantes solicitanteBaja = expediente.getSolicitantes();
			solicitanteBaja.setfBaja01(tarea.getDatosTareaEstudioBaja().getfDenegacionBaja());
			this.solicitantesDao.updateBajaBeneficiario(solicitanteBaja);
		}

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateBajaDenegacion -" + taskGUID + "- Fin");

	}

	private void actualizarDirecciones(Task task, Expedientes expedienteOrigen) {
		Solicitantes sol = this.solicitantesDao
				.findBeneficiarioPorIdSolicitante(new Solicitantes(expedienteOrigen.getIdSolicitante00()));

		this.pasarDireccionHistorico(expedienteOrigen, task.getSenderID(), sol);

		this.grabarNuevaDireccion(expedienteOrigen, sol);
	}

	/**
	 * Obtenemos la direccion asociada al expediente facilitado y se lo asignamos al
	 * solicitante beneficiario
	 * 
	 * @param MailboxTaskID
	 * @param expediente
	 * @param solicitanteBeneficiario
	 */
	private void grabarNuevaDireccion(Expedientes expediente, Solicitantes solicitanteBeneficiario) {
		try {
			// Se añade la nueva dirección
			Direcciones direccionExp = this.direccionesDao.find(expediente.getDirecciones());

			solicitanteBeneficiario.setDirecciones(direccionExp);
			this.solicitantesDao.update(solicitanteBeneficiario);

		} catch (Exception e) {

			TareaEstudioServiceImpl.logger.error("TareaEstudioServiceImpl.grabarNuevaDireccion causa -" + e.toString());
			ManagerErrors
					.manageError("TareaEstudioServiceImpl.grabarNuevaDireccion Error al grabar la nueva dirección.");
		}
	}

	/**
	 * Recuperamos la dirección asociada con el registro de solicitante
	 * beneficiario, actualizamos los datos de pase a historico y actualizamos esa
	 * dirección
	 * 
	 * @param expediente
	 * @param senderID
	 */
	private void pasarDireccionHistorico(Expedientes expediente, String senderID,
			Solicitantes solicitanteBeneficiario) {
		try {

			// Recuperamos la dirección solicitante beneficiario
			Direcciones direccionFilter = new Direcciones();
			direccionFilter.setIdDireccion06(solicitanteBeneficiario.getIdDireccion01());
			Direcciones direccionActual;
			List<Direcciones> resultadoListDireccion = this.direccionesDao.findAll(direccionFilter, null);
			if (!resultadoListDireccion.isEmpty()) {
				direccionActual = resultadoListDireccion.get(0);
				direccionActual.setfHistorico06(Calendar.getInstance().getTime());
				direccionActual.setUsuHistorico06(senderID);
				direccionActual.setIdSolicitante06(solicitanteBeneficiario.getIdSolicitante01());
				this.direccionesDao.update(direccionActual);
			}
		} catch (NullPointerException e) {
			TareaEstudioServiceImpl.logger.error(
					"TareaEstudioServiceImpl.pasarDireccionHistorico Error al pasar a historicos ¿No esta dado de alta como beneficiario el solicitante?");
		} catch (Exception e) {
			TareaEstudioServiceImpl.logger
					.error("TareaEstudioServiceImpl.pasarDireccionHistorico Error al pasar a historicos.");
		}
	}

	/**
	 * Preparación de la tarea
	 */
	public TTask prepararTarea(String taskGUID) throws Throwable {

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.prepararTarea -" + taskGUID + "- inicio ");
		// preparamos tarea de Platea

		TTask tTask = plateaService.prepareTask(taskGUID, TTaskType.ESTDOCU);

		TareaEstudioServiceImpl.logger
				.info("TareaEstudioServiceImpl.prepararTarea -" + tTask.getTaskID() + "-" + taskGUID + "- fin ");
		return tTask;

	}

	/**
	 * Ejecución de la tarea
	 */
	public TTask ejecutarTarea(TTask tTask) throws Throwable {
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.ejecutarTarea -" + tTask.getTaskID() + "-"
				+ tTask.getMailboxTaskID() + "- Inicio");

		tTask = plateaService.doTask(TareasEnum.getTaskType(tTask.getTaskID()), tTask);

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.ejecutarTarea -" + tTask.getTaskID() + "-"
				+ tTask.getMailboxTaskID() + "- Inicio");
		return tTask;
	}

	/**
	 * Ejecución de la tarea de forma automática
	 */
	public void ejecutarTareaAutomatica(String taskGUID) throws Throwable {
		TareaEstudioServiceImpl.logger
				.info("TareaEstudioServiceImpl.ejecutarTareaAutomatica -" + taskGUID + "- Inicio");

		// tTask.setSenderID(TareasUtils.getSenderIdAutomatico());

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.ejecutarTareaAutomatica -" + taskGUID + "- Fin");
	}

	private void updateDatosAltaResolConc(Expedientes expediente, String taskGUID, String senderID) {

		TareaEstudioServiceImpl.logger
				.info("TareaEstudioServiceImpl.updateDatosAltaResolConc -" + taskGUID + "- Inicio");

		TareasTramite tarea = new TareasTramite();
		tarea.setTaskguid11(taskGUID);
		tarea = this.tareasTramiteDao.findAll(tarea, null).get(0);
		if (null != tarea && null != tarea.getDatosTareaEstudio()
				&& !Utilidades.esBlancoNulo(tarea.getDatosTareaEstudio().getIdProcedimiento00())
				&& tarea.getDatosTareaEstudio().getIdProcedimiento00().equalsIgnoreCase(ProcedimientosEnum.ALTA.getId())
				&& null != tarea.getDatosTarea11() && null != tarea.getDatosTareaEstudioAlta()
				&& null != tarea.getDatosTareaEstudioAlta().getExpediente()) {

			updateAltaFResol(expediente, senderID, tarea.getDatosTareaEstudioAlta().getExpediente().getfResolucion00(),
					taskGUID);
			if (tarea.getDatosTareaEstudioAlta().getDiscapacidad() != null) {
				updateDiscapacidad(expediente, senderID, tarea.getDatosTareaEstudioAlta().getDiscapacidad(), taskGUID);
			}
			if (tarea.getDatosTareaEstudioAlta().getDependencia() != null) {
				updateDependecia(expediente, senderID, tarea.getDatosTareaEstudioAlta().getDependencia(), taskGUID);
			}
			if (tarea.getDatosTareaEstudioAlta().getExpediente() != null) {
				updateDatosExpediente(expediente, senderID, tarea.getDatosTareaEstudioAlta().getExpediente(), taskGUID);
			}
			if (Constantes.VAL_NUM_SI.equals(expediente.getExencionRes00())
					|| Constantes.TIPOPRECIO_PRIVADO.equals(tarea.getDatosTareaEstudioAlta().getTipoPrecio())) {
				tratamientoPreciosBenficiarioHistorico(expediente, expediente.getIdSolicitante00(), true,
						tarea.getDatosTareaEstudioAlta(), senderID);
			}

		}

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateDatosAltaResolConc -" + taskGUID + "- Fin");

	}

	private DatosTareaEstudioModDireccion getDatosTareaModificacion(String taskGUID) {
		TareasTramite tarea = new TareasTramite();
		tarea.setTaskguid11(taskGUID);
		tarea = this.tareasTramiteDao.findAll(tarea, null).get(0);
		if (null != tarea && null != tarea.getDatosTareaEstudio()
				&& !Utilidades.esBlancoNulo(tarea.getDatosTareaEstudio().getIdProcedimiento00())
				&& tarea.getDatosTareaEstudio().getIdProcedimiento00()
						.equalsIgnoreCase(ProcedimientosEnum.MODIFICACION.getId())
				&& null != tarea.getDatosTarea11() && null != tarea.getDatosTareaEstudioModDireccion()) {
			return tarea.getDatosTareaEstudioModDireccion();

		}
		return null;
	}

	private void updateDatosRevisionResolConc(Expedientes expediente, String taskGUID, String senderID,
			Long idBeneficiario) {

		TareaEstudioServiceImpl.logger
				.info("TareaEstudioServiceImpl.updateDatosRevisionResolConc -" + taskGUID + "- Inicio");

		TareasTramite tarea = new TareasTramite();
		tarea.setTaskguid11(taskGUID);
		tarea = this.tareasTramiteDao.findAll(tarea, null).get(0);
		if (null != tarea && null != tarea.getDatosTareaEstudio()
				&& !Utilidades.esBlancoNulo(tarea.getDatosTareaEstudio().getIdProcedimiento00())
				&& tarea.getDatosTareaEstudio().getIdProcedimiento00()
						.equalsIgnoreCase(ProcedimientosEnum.REVISION_PRECIO.getId())
				&& null != tarea.getDatosTarea11() && null != tarea.getDatosTareaEstudioRevision()
				&& null != tarea.getDatosTareaEstudioRevision().getExpediente()) {

			updateAltaFResol(expediente, senderID,
					tarea.getDatosTareaEstudioRevision().getExpediente().getfResolucion00(), taskGUID);
			updateDatosExpediente(expediente, senderID, tarea.getDatosTareaEstudioRevision().getExpediente(), taskGUID);

			PreciosBeneficiario preciosBeneficiarioFilter = new PreciosBeneficiario();
			preciosBeneficiarioFilter.setIdSolicitante91(idBeneficiario);
			PreciosBeneficiario preciosBeneActual = this.preciosBeneficiarioDao
					.findBySolActivo(preciosBeneficiarioFilter);
			if (Constantes.VAL_NUM_SI.equals(expediente.getExencionRes00())
					|| Constantes.TIPOPRECIO_PRIVADO.equals(tarea.getDatosTareaEstudioRevision().getTipoPrecio())
					|| (preciosBeneActual != null && (Constantes.VAL_NUM_SI.equals(preciosBeneActual.getIndExento91())
							&& Constantes.VAL_NUM_NO.equals(expediente.getExencionRes00())))
					|| (Constantes.TIPOPRECIO_PUBLICO.equals(tarea.getDatosTareaEstudioRevision().getTipoPrecio())
							&& (preciosBeneActual != null && (preciosBeneActual.getPrecioPrivado91() != null
									&& (BigDecimal.ZERO.compareTo(preciosBeneActual.getPrecioPrivado91()) != 0))))) {
				tratamientoPreciosBenficiarioHistorico(expediente, idBeneficiario, true,
						tarea.getDatosTareaEstudioRevision(), senderID);
			}
		}

		TareaEstudioServiceImpl.logger
				.info("TareaEstudioServiceImpl.updateDatosRevisionResolConc -" + taskGUID + "- Fin");

	}

	private void updateDependecia(Expedientes expediente, String senderID, Dependencia newDependecia, String taskGUID) {
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateDependecia -" + taskGUID + "- Inicio");

		// Si existe se actualiza y si no se crea una nueva
		Dependencia dependencia = new Dependencia();
		dependencia.setIdExpediente04(expediente.getIdExpediente00());
		dependencia.setIsHistorico(Boolean.FALSE);
		List<Dependencia> dependenciaList = this.dependenciaDao.findAll(dependencia, null);
		if (dependenciaList.isEmpty()) {
			// No existe dependdencia. Crear una nueva
			TareaEstudioServiceImpl.logger
					.debug("TareaEstudioServiceImpl.updateDependecia - Damos de alta la nueva dependencia");
			dependencia = this.dependenciaDao.add(newDependecia);
		} else {
			// Existe dependencia. Actualizarla
			dependencia = dependenciaList.get(0);
			dependencia.setBaremo04(newDependecia.getBaremo04());
			dependencia.setIdGradoDependencia04(newDependecia.getIdGradoDependencia04());
			dependencia.setDescOtraDependencia04(newDependecia.getDescOtraDependencia04());
			this.dependenciaDao.updateOnApertura(dependencia);
		}

//		Dependencia curseDependecia = new Dependencia();
//		curseDependecia.setIdExpediente04(expediente.getIdExpediente00());
//		List<Dependencia> listaDepe = this.dependenciaDao.findAll(curseDependecia, null);
//		boolean esNuevaDependencia = true;
//		if (null != listaDepe && listaDepe.size() > 1) {
//			ManagerErrors.manageError("Hay más de una dependecia grabada");
//		} else if (null != listaDepe && listaDepe.size() > 0) {
//			TareaEstudioServiceImpl.logger.info("DocumentosServiceImpl.updateDependecia - Hay dependencia previa");
//			curseDependecia = listaDepe.get(0);
//			// pasar a historico si es necesario
//			if (esPasoHistorico(curseDependecia.getfResolucion04(), newDependecia.getfResolucion04())) {
//				TareaEstudioServiceImpl.logger.debug(
//						"TareaEstudioServiceImpl.updateDependecia - Pasamos a historico la dependencia anterior");
//				this.dependenciaDao.pasarHistorico(listaDepe.get(0), senderID);
//			} else {
//				esNuevaDependencia = false;
//			}
//
//		}
//		if (esNuevaDependencia && newDependecia != null) {
//			TareaEstudioServiceImpl.logger
//					.debug("TareaEstudioServiceImpl.updateDependecia - Damos de alta la nueva dependencia");
//			newDependecia.setIdExpediente04(expediente.getIdExpediente00());
//			newDependecia.setIdSolicitante04(expediente.getIdSolicitante00());
//			newDependecia.setUsuAlta04(senderID);
//			this.dependenciaDao.add(newDependecia);
//		}
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateDependecia -" + taskGUID + "- Fin");
	}

	private void updateAltaFResol(Expedientes expediente, String senderID, Date fResolucion00, String taskGUID) {
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateAltaFResol -" + taskGUID + "- Inicio");
		expediente.setfResolucion00(fResolucion00);
		this.expedientesDao.updateFResolucion(expediente, senderID);
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateAltaFResol -" + taskGUID + "- Fin");
	}

	private void updateDatosExpediente(Expedientes expediente, String senderID, Expedientes expedienteTarea,
			String taskGUID) {
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateDatosExpediente -" + taskGUID + "- Inicio");
		// expediente.setUrgencia00(expedienteTarea.getUrgencia00());
		expediente.setExencionRes00(expedienteTarea.getExencionRes00());
		expediente.setPrecioFinal00(expedienteTarea.getPrecioFinal00());

		this.expedientesDao.updateDatosAltaResolConc(expediente, senderID);
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateDatosExpediente -" + taskGUID + "- Fin");
	}

	private void updateDiscapacidad(Expedientes expediente, String senderID, Discapacidad newDiscapacidad,
			String taskGUID) {
		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateDiscapacidad -" + taskGUID + "- Inicio");
		Discapacidad curseDiscapacidad = new Discapacidad();
		curseDiscapacidad.setIdExpediente71(expediente.getIdExpediente00());
		List<Discapacidad> listaDis = this.discapacidadDao.findAll(curseDiscapacidad, null);
		boolean esNuevaDiscapacidad = true;
		if (null != listaDis && listaDis.size() > 1) {
			ManagerErrors.manageError("Hay más de una discapacidad grabada");
		} else if (null != listaDis && listaDis.size() > 0) {
			TareaEstudioServiceImpl.logger.info("DocumentosServiceImpl.updateDiscapacidad - Hay discapacidad previa");
			curseDiscapacidad = listaDis.get(0);
			// pasar a historico si es necesario
			if (esPasoHistorico(curseDiscapacidad.getfResolucion71(), newDiscapacidad.getfResolucion71())) {
				TareaEstudioServiceImpl.logger.debug(
						"TareaEstudioServiceImpl.updateDiscapacidad - Pasamos a historico la discapacidad anterior");
				this.discapacidadDao.pasarHistorico(listaDis.get(0), senderID);
			} else {
				esNuevaDiscapacidad = false;
			}

		}
		if (esNuevaDiscapacidad && newDiscapacidad != null) {
			TareaEstudioServiceImpl.logger
					.debug("TareaEstudioServiceImpl.updateDiscapacidad - Damos de alta la nueva dependencia");
			newDiscapacidad.setIdExpediente71(expediente.getIdExpediente00());
			newDiscapacidad.setIdSolicitante71(expediente.getIdSolicitante00());
			newDiscapacidad.setUsuAlta71(senderID);
			this.discapacidadDao.add(newDiscapacidad);
		}

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateDependecia -" + taskGUID + "- Fin");
	}

	private void updateBajaConcesion(Expedientes expediente, String taskGUID, String senderID, Long idBeneficiario) {

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateBajaConcesion -" + taskGUID + "- Inicio");

		TareasTramite tarea = new TareasTramite();
		tarea.setTaskguid11(taskGUID);
		tarea = this.tareasTramiteDao.findAll(tarea, null).get(0);
		if (null != tarea && null != tarea.getDatosTareaEstudio()
				&& !Utilidades.esBlancoNulo(tarea.getDatosTareaEstudio().getIdProcedimiento00())
				&& tarea.getDatosTareaEstudio().getIdProcedimiento00().equalsIgnoreCase(ProcedimientosEnum.BAJA.getId())
				&& null != tarea.getDatosTarea11() && null != tarea.getDatosTareaEstudioBaja()
				&& null != tarea.getDatosTareaEstudioBaja().getfConcesionBaja()) {

			Solicitantes solicitanteBaja = this.solicitantesDao.find(new Solicitantes(idBeneficiario));
			solicitanteBaja.setfBaja01(tarea.getDatosTareaEstudioBaja().getfConcesionBaja());
			solicitanteBaja.setIdMotivoBaja01(tarea.getDatosTareaEstudioBaja().getIdMotivoBaja());
			this.solicitantesDao.updateBajaBeneficiario(solicitanteBaja);

			expediente.setfBaja00(tarea.getDatosTareaEstudioBaja().getfConcesionBaja());
			this.expedientesDao.updateResolucionBaja(expediente);

			tratamientoPreciosBenficiarioHistorico(expediente, idBeneficiario, false, tarea.getDatosTareaEstudioBaja(),
					senderID);
		}

		TareaEstudioServiceImpl.logger.info("TareaEstudioServiceImpl.updateBajaConcesion -" + taskGUID + "- Fin");

	}

	private boolean esPasoHistorico(Date curseFResolucionDate, Date newFResolucionDate) {
		String newFResol = "";
		try {
			newFResol = UtilidadesFecha.formatearDateToStringMasc(newFResolucionDate,
					Constantes.DATE_FORMAT_TIMESTAMP_NOTIME);
		} catch (Exception e) {
			TareaEstudioServiceImpl.logger.error(
					"TareaEstudioServiceImpl.esPasoHistorico Error al transformar la ultima fecha de resolucion");
		}

		String curseFResol = "";
		try {
			curseFResol = UtilidadesFecha.formatearDateToStringMasc(curseFResolucionDate,
					Constantes.DATE_FORMAT_TIMESTAMP_NOTIME);
		} catch (Exception e) {
			TareaEstudioServiceImpl.logger
					.error("TareaEstudioServiceImpl.esPasoHistorico Error al transformar la fecha de resolucion");
		}

		if (!curseFResol.equalsIgnoreCase(newFResol)) {
			return true;
		}
		return false;
	}

	private Avisos getAvisoInformeIntervencion(Expedientes expediente) {
		Avisos aviso = new Avisos();
		MaestroActores origen = new MaestroActores();
		origen.setIdActor42(ActoresEnum.DSS.getId());
		aviso.setMaestroActoresByOrigen20(origen);
		MaestroActores destino = new MaestroActores();
		destino.setIdActor42(ActoresEnum.PS.getId());
		aviso.setMaestroActoresByDestino20(destino);
		aviso.setObservaciones20(expediente.getMotivoInforme00());
		MaestroTiposAviso tipoAviso = new MaestroTiposAviso();
		tipoAviso.setIdTipoAviso40(TipoAvisoEnum.INFINT.getIdLongValue());
		aviso.setMaestroTiposAviso(tipoAviso);
		MaestroSubtiposAviso subtipoAviso = new MaestroSubtiposAviso();
		subtipoAviso.setIdSubTipoAviso41(SubTipoAvisoEnum.SOLICPS.getIdLongValue());
		aviso.setMaestroSubtiposAviso(subtipoAviso);
		aviso.setIdSolicitante20(expediente.getSolicitantes().getIdSolicitante01());
		aviso.setIdexpedienteAsociado(expediente.getIdExpediente00());
		aviso.setUsuAlta20(com.ejie.ad74a.constantes.Constantes.COD_APLICACION);
		if (null != expediente.getUrgencia00() && expediente.getUrgencia00() == 1) {
			aviso.setUrgencia20(true);
		} else {
			aviso.setUrgencia20(false);
		}
		return aviso;
	}

	private Informes generarInforme(Expedientes expediente) {
		Informes informes = new Informes();

		informes.setTipoInforme16(TipoInformesEnum.INFINT.getId());
		Solicitantes solicitante = new Solicitantes();
		solicitante.setIdSolicitante01(expediente.getSolicitantes().getIdSolicitante01());
		informes.setSolicitantes(solicitante);
		informes.setIdExpediente16(expediente.getIdExpediente00());
		informes.setOculto16(0);
		informes.setObservaciones16(expediente.getMotivoInforme00());
		informes.setUsuAlta16(com.ejie.ad74a.constantes.Constantes.USER_PROCESADO_AUTOMATICO);
		informes.setEstado16(EstadoInformesEnum.SOLICITADO_PROVEEDOR.getId());

		return informes;
	}

	private String getErrorMessage(String error) {
		if (null != error && error.length() > 800) {
			error = error.substring(0, 799);
		}
		return error;
	}
}
