package com.ejie.ad74a.control;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;

import com.ejie.ad74a.dao.TareasTramiteDao;
import com.ejie.ad74a.exceptions.Ad74aException;
import com.ejie.ad74a.exceptions.ManagerErrors;
import com.ejie.ad74a.model.BandejaEntradas;
import com.ejie.ad74a.model.Combo;
import com.ejie.ad74a.model.Contactos;
import com.ejie.ad74a.model.DatosEconomicos;
import com.ejie.ad74a.model.Dependencia;
import com.ejie.ad74a.model.Discapacidad;
import com.ejie.ad74a.model.DocumentosTarea;
import com.ejie.ad74a.model.Estados;
import com.ejie.ad74a.model.Expedientes;
import com.ejie.ad74a.model.Informes;
import com.ejie.ad74a.model.MaestroMotDenegacion;
import com.ejie.ad74a.model.MotivosBaja;
import com.ejie.ad74a.model.PisosTutelados;
import com.ejie.ad74a.model.Solicitantes;
import com.ejie.ad74a.model.TramiteTareaDto;
import com.ejie.ad74a.model.TramitesExpediente;
import com.ejie.ad74a.model.ae01b.Liquidaciones;
import com.ejie.ad74a.service.BandejaEntradasService;
import com.ejie.ad74a.service.ContactosService;
import com.ejie.ad74a.service.DependenciaService;
import com.ejie.ad74a.service.DiscapacidadService;
import com.ejie.ad74a.service.ExpedientesService;
import com.ejie.ad74a.service.InformesService;
import com.ejie.ad74a.service.MaestroMotDenegacionService;
import com.ejie.ad74a.service.MotivosBajaService;
import com.ejie.ad74a.service.PisosTuteladosService;
import com.ejie.ad74a.service.SolicitantesService;
import com.ejie.ad74a.service.ae01b.LiquidacionesService;
import com.ejie.ad74a.service.tramitacion.TramitacionService;
import com.ejie.ad74a.util.comun.UtilLiterales;
import com.ejie.ad74a.util.comun.UtilSeguridad;
import com.ejie.ad74a.util.comun.UtilTokenXlnets;
import com.ejie.ad74a.util.comun.Utilidades;
import com.ejie.ad74a.util.comun.UtilidadesMail;
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.MotivoBajaEnum;
import com.ejie.ad74a.util.constantes.ProcedimientosEnum;
import com.ejie.ad74a.util.constantes.RequerimientosEnum;
import com.ejie.ad74a.util.constantes.TareasEnum;
import com.ejie.ad74a.util.constantes.TipoCanalOrigenEnum;
import com.ejie.ad74a.util.constantes.TipoIdentificadorEnum;
import com.ejie.ad74a.util.constantes.TipoInformesEnum;
import com.ejie.ad74a.util.constantes.TramitesEnum;
import com.ejie.ad74a.util.constantes.modelos.TipoExpedientes;
import com.ejie.ad74a.ws.client.platea.service.PlateaService;
import com.ejie.x38.control.bind.annotation.RequestJsonBody;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;
import com.ejie.x38.util.DateTimeManager;

import es.redsara.intermediacion.scsp.esquemas.datosespecificos.Retorno;

/**
 * ExpedientesController generated by UDA, 10-feb-2023 12:13:21.
 * 
 * @author UDA
 */

@Controller
@RequestMapping(value = "/expedientes")

public class ExpedientesController {

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

	@Autowired
	private ExpedientesService expedientesService;

	@Autowired
	private PisosTuteladosService pisosTuteladosService;

	@Autowired
	private MotivosBajaService motivosBajaService;

	@Autowired
	private PlateaService plateaService;

	@Autowired
	private InformesService informesService;

	@Autowired
	private ContactosService contactosService;

	@Autowired
	private BandejaEntradasService bandejaEntradasService;

	@Autowired
	private TramitacionService tramitacionService;

	@Autowired
	private MaestroMotDenegacionService maestroMotDenegacionService;

	@Autowired
	private DiscapacidadService discapacidadService;

	@Autowired
	private TareasTramiteDao tareasTramiteDao;

	@Autowired
	private DependenciaService dependenciaService;

	@Autowired
	private ReloadableResourceBundleMessageSource appMessageSource;

	@Autowired
	private Properties appConfiguration;

	@Autowired
	private SolicitantesService solicitantesService;

	@Autowired
	private LiquidacionesService liquidacionesService;

	@InitBinder
	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws ServletException {
		binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
		// XXX [JBHG] Cuando se quiere utilizar campos <form:input> de tipo "DateTime"
		// (fecha con
		// hora) se debe utilizar la funcion de x38 getTimestampFormat para que devuelva
		// el formato
		// correcto incluyendo horas, minutos y segundos
		// binder.registerCustomEditor(Date.class,
		// new
		// CustomDateEditor(DateTimeManager.getDateTimeFormat(LocaleContextHolder.getLocale()),
		// true));
		binder.registerCustomEditor(Date.class,
				new CustomDateEditor(DateTimeManager.getTimestampFormat(LocaleContextHolder.getLocale()), true));
	}

	private Object validarUsuarioAcceso(HttpServletRequest request) {
		String[] perfilesAcceso = { UtilSeguridad.Props.PERFIL_SEGURIDAD_ADMINISTRADOR.getValue(),
				UtilSeguridad.Props.PERFIL_SEGURIDAD_TECNICO_DSS.getValue(),
				UtilSeguridad.Props.PERFIL_SEGURIDAD_DIRECTOR_DSS.getValue() };
		Boolean tieneAcceso;
		tieneAcceso = UtilSeguridad.tienePerfilSeguridad(perfilesAcceso);

		return tieneAcceso;
	}

	private Boolean isSoloLecturaSoilicitud(Expedientes exp) {

		Boolean isSoloLectura;

		String[] perfilesNoEdicion = { UtilSeguridad.Props.PERFIL_SEGURIDAD_DIRECTOR_DSS.getValue() };

		BandejaEntradas bandejaEntradas = new BandejaEntradas();
		bandejaEntradas.setIdexpediente(exp.getIdExpediente00());
		bandejaEntradas.setEstado(Constantes.EstadosBandejaPapel0.PENDIENTE);

		isSoloLectura = UtilSeguridad.tienePerfilSeguridad(perfilesNoEdicion)
				|| EstadosExpedienteEnum.CERRADO.getId().equals(exp.getEstados().getIdEstado30())
				|| (this.bandejaEntradasService.findAll(bandejaEntradas, null).size() > 0)
				|| (ProcedimientosEnum.X87_TEA_1.getId().equalsIgnoreCase(exp.getIdProcedimiento00())
						|| ProcedimientosEnum.X87_TEA_2.getId().equalsIgnoreCase(exp.getIdProcedimiento00())
						|| ProcedimientosEnum.X87_TEA_4.getId().equalsIgnoreCase(exp.getIdProcedimiento00()));

		return isSoloLectura;

	}

	private Boolean validarUsuarioModificacion(HttpServletRequest request) {
		// TODO
		return false;

	}

	private Boolean validarUsuarioAdmDSS() {

		Boolean tieneAcceso;

		String[] perfilesAcceso = { UtilSeguridad.Props.PERFIL_SEGURIDAD_ADMINISTRADOR.getValue(),
				UtilSeguridad.Props.PERFIL_SEGURIDAD_TECNICO_DSS.getValue() };
		tieneAcceso = UtilSeguridad.tienePerfilSeguridad(perfilesAcceso);

		return tieneAcceso;

	}

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

	/**
	 * Operacion CRUD Read. Devuelve el bean correspondiente al identificador
	 * indicado.
	 * 
	 * @param idExpediente00 Long
	 * @return Expedientes Objeto correspondiente al identificador indicado.
	 */
	@RequestMapping(value = "/{idExpediente00}", method = RequestMethod.GET)
	public @ResponseBody Expedientes get(@PathVariable Long idExpediente00) {
		Expedientes expedientes = new Expedientes();
		expedientes.setIdExpediente00(idExpediente00);
		expedientes = this.expedientesService.find(expedientes);
		ExpedientesController.logger.info("[GET - findBy_PK] : Obtener Expedientes por PK");
		return expedientes;
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 *
	 * @param filterExpedientes Expedientes Objeto que contiene los parametros de
	 *                          filtrado utilizados en la busqueda.
	 * @return List<Expedientes> Lista de objetos correspondientes a la busqueda
	 *         realizada.
	 */
	@RequestMapping(method = RequestMethod.GET)
	public @ResponseBody List<Expedientes> getAll(@ModelAttribute Expedientes filterExpedientes) {
		ExpedientesController.logger.info("[GET - find_ALL] : Obtener Expedientes por filtro");
		return this.expedientesService.findAll(filterExpedientes, null);
	}

	/**
	 * Operacion CRUD Edit. Modificacion del bean indicado.
	 *
	 * @param expedientes Expedientes Bean que contiene la informacion a modificar.
	 * @return Expedientes Bean resultante de la modificacion.
	 */
	@RequestMapping(value = "/edit", method = RequestMethod.PUT)
	public @ResponseBody Expedientes edit(@RequestBody Expedientes expedientes) {
		Expedientes expedientesAux = this.expedientesService.update(expedientes);
		ExpedientesController.logger.info("[PUT] : Expedientes actualizado correctamente");
		return expedientesAux;
	}

	/**
	 * Operacion CRUD Create. Creacion de un nuevo registro a partir del bean
	 * indicado.
	 *
	 * @param expedientes Expedientes Bean que contiene la informacion con la que se
	 *                    va a crear el nuevo registro.
	 * @return Expedientes Bean resultante del proceso de creacion.
	 */
	@RequestMapping(value = "/add", method = RequestMethod.POST)
	public @ResponseBody Expedientes add(@RequestBody Expedientes expedientes) {
		Expedientes expedientesAux = this.expedientesService.add(expedientes);
		ExpedientesController.logger.info("[POST] : Expedientes insertado correctamente");
		return expedientesAux;
	}

	/**
	 * Operacion CRUD Delete. Borrado del registro correspondiente al identificador
	 * especificado.
	 *
	 * @param idExpediente00 Long Identificador del objeto que se desea eliminar.
	 * @return Expedientes Bean eliminado.
	 */
	@RequestMapping(value = "/{idExpediente00}", method = RequestMethod.DELETE)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody Expedientes remove(@PathVariable Long idExpediente00) {
		Expedientes expedientes = new Expedientes();
		expedientes.setIdExpediente00(idExpediente00);
		this.expedientesService.remove(expedientes);
		ExpedientesController.logger.info("[DELETE] : Expedientes borrado correctamente");
		return expedientes;
	}

	/*
	 * METODOS COMPONENTE RUP_TABLE
	 * 
	 */

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * @param model Model
	 * @return String
	 */
	@RequestMapping(value = "/maint", method = RequestMethod.GET)
	public String getFormEdit(Model model) {
		ExpedientesController.logger.info("[GET - View] : expedientes");
		model.addAttribute("expedientes", new Expedientes());
		return "expedientes";
	}

	/**
	 * Operacion de filtrado del componente RUP_TABLE.
	 * 
	 * @param filterExpedientes Expedientes Bean que contiene los parametros de
	 *                          filtrado a emplear.
	 * @param tableRequestDto   Dto que contiene los parametros de configuracion
	 *                          propios del RUP_TABLE a aplicar en el filtrado.
	 * @return TableResponseDto<Expedientes> Dto que contiene el resultado del
	 *         filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/filter", method = RequestMethod.POST)
	public @ResponseBody TableResponseDto<Expedientes> filter(
			@RequestJsonBody(param = "filter") Expedientes filterExpedientes,
			@RequestJsonBody TableRequestDto tableRequestDto) {
		ExpedientesController.logger.info("[POST - filter] : Obtener Expedientess");
		return this.expedientesService.filter(filterExpedientes, tableRequestDto, false);
	}

	/**
	 * Operacion de busqueda del componente RUP_TABLE.
	 * 
	 * @param filterExpedientes Expedientes Bean que contiene los parametros de
	 *                          filtrado a emplear.
	 * @param searchExpedientes Expedientes Bean que contiene los parametros de
	 *                          busqueda a emplear.
	 * @param tableRequestDto   Dto que contiene los parametros de configuracion
	 *                          propios del RUP_TABLE a aplicar en la búsqueda.
	 * @return TableRowDto<Expedientes> Dto que contiene el resultado de la busqueda
	 *         realizada por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/search", method = RequestMethod.POST)
	public @ResponseBody List<TableRowDto<Expedientes>> search(
			@RequestJsonBody(param = "filter") Expedientes filterExpedientes,
			@RequestJsonBody(param = "search") Expedientes searchExpedientes,
			@RequestJsonBody TableRequestDto tableRequestDto) {
		ExpedientesController.logger.info("[POST - search] : Buscar Expedientess");
		return this.expedientesService.search(filterExpedientes, searchExpedientes, tableRequestDto, false);
	}

	/**
	 * Borrado multiple de registros
	 * 
	 * @param filterExpedientes Expedientes Bean que contiene los parametros de
	 *                          filtrado a emplear.
	 * @param tableRequestDto   Dto que contiene los parametros de configuracion
	 *                          propios del RUP_TABLE a aplicar en la busqueda.
	 * @return List<String> Lista de los identificadores de los registros
	 *         eliminados.
	 * 
	 */
	@RequestMapping(value = "/deleteAll", method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody List<String> removeMultiple(@RequestJsonBody TableRequestDto tableRequestDto) {
		ExpedientesController.logger.info("[POST - removeMultiple] : Eliminar multiples Expedientess");
		this.expedientesService.removeMultiple(tableRequestDto);
		ExpedientesController.logger.info("All entities correctly deleted!");

		return tableRequestDto.getMultiselection().getSelectedIds();
	}

	/*
	 * METODOS COMPONENTE RUP_TABLE - JERARQUIA
	 */

	/**
	 * Operacion de filtrado del componente RUP_TABLE para presentar los registros
	 * mediante visualizacion jerarquica.
	 * 
	 * @param filterExpedientes Expedientes Bean que contiene los parametros de
	 *                          filtrado a emplear.
	 * @param tableRequestDto   Dto que contiene los parametros de configuracion
	 *                          propios del RUP_TABLE a aplicar en el filtrado.
	 * @return TableResponseDto<JerarquiaDto<Expedientes>> Dto que contiene el
	 *         resultado del filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/jerarquia/filter", method = RequestMethod.POST)
	public @ResponseBody TableResponseDto<JerarquiaDto<Expedientes>> jerarquia(
			@RequestJsonBody(param = "filter") Expedientes filterExpedientes,
			@RequestJsonBody TableRequestDto tableRequestDto) {
		ExpedientesController.logger.info("[POST - jerarquia] : Obtener Expedientess jerarquia");
		return this.expedientesService.jerarquia(filterExpedientes, tableRequestDto, false);
	}

	/**
	 * Recupera los hijos de los registros desplegados en la visualizacion
	 * jerarquica.
	 * 
	 * @param filterExpedientes Expedientes Bean que contiene los parametros de
	 *                          filtrado a emplear.
	 * @param tableRequestDto   Dto que contiene los parametros de configuracion
	 *                          propios del RUP_TABLE a aplicar en el filtrado.
	 * @return TableResponseDto<JerarquiaDto<Expedientes>> Dto que contiene el
	 *         resultado del filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/jerarquiaChildren", method = RequestMethod.POST)
	public @ResponseBody TableResponseDto<JerarquiaDto<Expedientes>> jerarquiaChildren(
			@RequestJsonBody(param = "filter") Expedientes filterExpedientes,
			@RequestJsonBody TableRequestDto tableRequestDto) {
		ExpedientesController.logger.info("[POST - jerarquia] : Obtener Expedientess jerarquia - Hijos");
		return this.expedientesService.jerarquiaChildren(filterExpedientes, tableRequestDto);
	}

	/**
	 * EXPORTERS
	 */
	/**
	 * Devuelve los datos exportados de la tabla y los copia al Portapapeles.
	 *
	 * @param filterExpedientes Expedientes
	 * @param tableRequestDto   TableRequestDto
	 */
	@RequestMapping(value = "/clipboardReport", method = RequestMethod.POST)
	protected @ResponseBody List<Expedientes> getClipboardReport(
			@RequestJsonBody(param = "filter") Expedientes filterExpedientes,
			@RequestJsonBody TableRequestDto tableRequestDto) {
		ExpedientesController.logger.info("[POST - clipboardReport] : : Copiar en Portapapeles");
		return this.expedientesService.getMultiple(filterExpedientes, tableRequestDto, false);
	}

	/**
	 * Devuelve un fichero excel que contiene los datos exportados de la tabla.
	 *
	 * @param filter          Expedientes
	 * @param columns         String[]
	 * @param fileName        String
	 * @param sheetTitle      String
	 * @param tableRequestDto TableRequestDto
	 * @param request         HttpServletRequest
	 * @param response        HttpServletResponse
	 */
	@RequestMapping(value = { "/xlsReport",
			"/xlsxReport" }, method = RequestMethod.POST, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
	protected @ResponseBody void generateExcelReport(
			@RequestJsonBody(param = "filter", required = false) Expedientes filter,
			@RequestJsonBody(param = "columns", required = false) String[] columns,
			@RequestJsonBody(param = "columnsName", required = false) String[] columnsName,
			@RequestJsonBody(param = "fileName", required = false) String fileName,
			@RequestJsonBody(param = "sheetTitle", required = false) String sheetTitle,
			@RequestJsonBody TableRequestDto tableRequestDto, HttpServletRequest request, HttpServletResponse response)
			throws ServletException {
		ExpedientesController.logger.info("[POST - generateExcelReport] : Devuelve un fichero excel");

		this.expedientesService.generateReport(filter, columns, columnsName, fileName, sheetTitle, tableRequestDto,
				request, response);
	}

	/**
	 * Devuelve un fichero pdf que contiene los datos exportados de la tabla.
	 *
	 * @param filter          Expedientes
	 * @param columns         String[]
	 * @param fileName        String
	 * @param sheetTitle      String
	 * @param tableRequestDto TableRequestDto
	 * @param request         HttpServletRequest
	 * @param response        HttpServletResponse
	 */
	@RequestMapping(value = "pdfReport", method = RequestMethod.POST, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
	protected @ResponseBody void generatePDFReport(
			@RequestJsonBody(param = "filter", required = false) Expedientes filter,
			@RequestJsonBody(param = "columns", required = false) String[] columns,
			@RequestJsonBody(param = "columnsName", required = false) String[] columnsName,
			@RequestJsonBody(param = "fileName", required = false) String fileName,
			@RequestJsonBody(param = "sheetTitle", required = false) String sheetTitle,
			@RequestJsonBody TableRequestDto tableRequestDto, HttpServletRequest request,
			HttpServletResponse response) {
		ExpedientesController.logger.info("[POST - generatePDFReport] : Devuelve un fichero pdf");

		this.expedientesService.generateReport(filter, columns, columnsName, fileName, sheetTitle, tableRequestDto,
				request, response);
	}

	/**
	 * Devuelve un fichero ods que contiene los datos exportados de la tabla.
	 *
	 * @param filter          Expedientes
	 * @param columns         String[]
	 * @param fileName        String
	 * @param sheetTitle      String
	 * @param tableRequestDto TableRequestDto
	 * @param request         HttpServletRequest
	 * @param response        HttpServletResponse
	 */
	@RequestMapping(value = "odsReport", method = RequestMethod.POST, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
	protected @ResponseBody void generateODSReport(
			@RequestJsonBody(param = "filter", required = false) Expedientes filter,
			@RequestJsonBody(param = "columns", required = false) String[] columns,
			@RequestJsonBody(param = "columnsName", required = false) String[] columnsName,
			@RequestJsonBody(param = "fileName", required = false) String fileName,
			@RequestJsonBody(param = "sheetTitle", required = false) String sheetTitle,
			@RequestJsonBody TableRequestDto tableRequestDto, HttpServletRequest request,
			HttpServletResponse response) {
		ExpedientesController.logger.info("[POST - generateODSReport] : Devuelve un fichero ods");

		this.expedientesService.generateReport(filter, columns, columnsName, fileName, sheetTitle, tableRequestDto,
				request, response);
	}

	/**
	 * Devuelve un fichero csv que contiene los datos exportados de la tabla.
	 *
	 * @param filter          Expedientes
	 * @param columns         String[]
	 * @param fileName        String
	 * @param sheetTitle      String
	 * @param tableRequestDto TableRequestDto
	 * @param request         HttpServletRequest
	 * @param response        HttpServletResponse
	 */
	@RequestMapping(value = "csvReport", method = RequestMethod.POST, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
	protected @ResponseBody void generateCSVReport(
			@RequestJsonBody(param = "filter", required = false) Expedientes filter,
			@RequestJsonBody(param = "columns", required = false) String[] columns,
			@RequestJsonBody(param = "columnsName", required = false) String[] columnsName,
			@RequestJsonBody(param = "fileName", required = false) String fileName,
			@RequestJsonBody(param = "sheetTitle", required = false) String sheetTitle,
			@RequestJsonBody TableRequestDto tableRequestDto, HttpServletRequest request,
			HttpServletResponse response) {
		ExpedientesController.logger.info("[POST - generateCSVReport] : Devuelve un fichero csv");

		this.expedientesService.generateReport(filter, columns, columnsName, fileName, sheetTitle, tableRequestDto,
				request, response);
	}

	/**
	 * Detalle de un expediente
	 * 
	 * @param actionType   String
	 * @param fixedMessage String
	 * @param model        Model
	 *
	 * @return String tiles del detalle de un expediente
	 */

	@GetMapping(value = "/detail/{idExpediente00}")
	public String getDetail(@PathVariable Long idExpediente00, Model model, HttpServletRequest request) {
		ExpedientesController.logger.info("[POST - detail] : expedientes");

		if (Boolean.FALSE.equals(this.validarUsuarioAcceso(request))) {
			return "accessDenied";
		}
		// Recuperamos los datos del expediente
		Expedientes exp = atributosCabecera(idExpediente00, model, request);
		if (null == exp) {
			model.addAttribute("exception_message",
					Utilidades.getLabelFromResource(Constantes.BASENAME_RESOURCE_AD74A_I18N,
							com.ejie.ad74a.constantes.Constantes.ERROR_NOEXISTEEXP_MESSAGE,
							LocaleContextHolder.getLocale()));
			model.addAttribute("exception_name",
					Utilidades.getLabelFromResource(Constantes.BASENAME_RESOURCE_AD74A_I18N,
							com.ejie.ad74a.constantes.Constantes.ERROR_NOEXISTEEXP_NAME,
							LocaleContextHolder.getLocale()));
			return "error";
		}

		List<Combo> tipoIdentificadorList = new ArrayList<>();
		for (TipoIdentificadorEnum enumeracion : TipoIdentificadorEnum.values()) {
			tipoIdentificadorList.add(enumeracion.getCombo());
		}
		List<Combo> tipoIdentificadorPersonaFisicaList = new ArrayList<>();
		for (TipoIdentificadorEnum enumeracion : TipoIdentificadorEnum
				.valuesByTipoPersona(Constantes.TIPO_PERSONA_FISICA_BBDD)) {
			tipoIdentificadorPersonaFisicaList.add(enumeracion.getCombo());
		}
		model.addAttribute("tipoIdentificadorList", tipoIdentificadorList);
		model.addAttribute("tipoIdentificadorPersonaFisicaList", tipoIdentificadorPersonaFisicaList);

		Dependencia dependencia = new Dependencia();
		dependencia.setIdExpediente04(exp.getIdExpediente00());
		exp.setDependencia(this.dependenciaService.findByIdExp(dependencia));

		Discapacidad discapacidad = new Discapacidad();
		discapacidad.setIdExpediente71(exp.getIdExpediente00());
		exp.setDiscapacidad(this.discapacidadService.findByIdExp(discapacidad));

		model.addAttribute("expediente", exp);
		model.addAttribute("solicitante", exp.getSolicitantes());
		model.addAttribute("instancia", UtilSeguridad.getUsuarioConectado());
		model.addAttribute("menu", false);

		if (null != exp.getNumExpediente00()) {
			String[] paramTittle = { exp.getNumExpediente00() };
			model.addAttribute("title",
					UtilLiterales.getLiteralMessageWithParams(appMessageSource, "title.expediente", paramTittle));
		} else {
			model.addAttribute("title", UtilLiterales.getLiteralMessage(appMessageSource, "title.expedienteKO"));
		}

		return "expedientesDetail";
	}

	/**
	 * Metodo que recupera el jsp con la cabecera del expediente con los datos en
	 * BBDD
	 * 
	 * @param idExpediente00
	 * @param model
	 * @param request
	 * @return
	 */

	@GetMapping(value = "/obtenerCabeceraExpediente")
	public String obtenerCabeceraExpediente(
			@RequestParam(value = "idExpediente00", required = true) Long idExpediente00, Model model,
			HttpServletRequest request) {

		if (Boolean.FALSE.equals(this.validarUsuarioAcceso(request))) {
			return "accessDenied";
		}

		atributosCabecera(idExpediente00, model, request);

		return "expedienteDetailCabecera";
	}

	private Expedientes atributosCabecera(Long idExpediente00, Model model, HttpServletRequest request) {
		// Recuperamos los datos del solicitante
		Expedientes exp = this.expedientesService.find(new Expedientes(idExpediente00));
		model.addAttribute("expediente", exp);
		// Recuperamos los informes de intervencion
		Informes infomeFilter = new Informes();
		infomeFilter.setIdExpediente16(idExpediente00);
		infomeFilter.setTipoInforme16(TipoInformesEnum.INFINT.getId());
		List<Informes> informeList = this.informesService.findAllTodosEstados(infomeFilter, null);
		if (!informeList.isEmpty()) {
			exp.setInformeIntervencion(informeList.get(0));
		}
		// Recuperamos los informes sociales
		Informes infomeSocialFilter = new Informes();
		infomeSocialFilter.setIdExpediente16(idExpediente00);
		infomeSocialFilter.setTipoInforme16(TipoInformesEnum.INFSOC.getId());
		infomeSocialFilter.setEstado16(EstadoInformesEnum.DISPONIBLE.getId());
		List<Informes> informeSocialList = this.informesService.findAll(infomeSocialFilter, null);
		exp.setTieneInfSocial(!informeSocialList.isEmpty());

//		Informes infomeSocialFilter = new Informes();
//		infomeSocialFilter.setIdExpediente16(idExpediente00);
//		infomeSocialFilter.setTipoInforme16(TipoInformesEnum.INFSOC.getId());
//		infomeSocialFilter.setEstado16(EstadoInformesEnum.DISPONIBLE.getId());
//		// infomeSocialFilter.setfFinNull(false);
//		TableRequestDto tableRequestDto = new TableRequestDto();
//		tableRequestDto.setSidx("FFIN16");
//		tableRequestDto.setSord("desc");
//		Integer usuario = null;
//		if (UtilSeguridad.isDSS(request) || UtilSeguridad.isDirector(request)) {
//			usuario = ActoresEnum.DSS.getId().intValue();
//		} else if (UtilSeguridad.isPS(request)) {
//			usuario = ActoresEnum.PS.getId().intValue();
//		} else if (UtilSeguridad.isSSB(request)) {
//			usuario = ActoresEnum.SSB.getId().intValue();
//		} else if (UtilSeguridad.isAdmin(request)) {
//			usuario = ActoresEnum.ADMIN.getId().intValue();
//		}
//		List<Informes> informeSocialList = this.informesService.findAllLikePorUsuario(infomeSocialFilter,
//				tableRequestDto, false, usuario);
//		exp.setTieneInfSocial(!informeSocialList.isEmpty());

		// recuperamos el participant
		String participantID = this.plateaService.getParticipantID(exp.getFolderId00());
		model.addAttribute("participantID", participantID);

		BandejaEntradas bandejaEntradas = new BandejaEntradas();
		bandejaEntradas.setIdexpediente(idExpediente00);
		bandejaEntradas.setEstado(Constantes.EstadosBandejaPapel0.PENDIENTE);

		model.addAttribute("nEntradas", this.bandejaEntradasService.findAll(bandejaEntradas, null).size());

		model.addAttribute("existeEstudioDoc", !this.tareasTramiteDao
				.getLastNotExecutedTask(idExpediente00, TramitesEnum.ESTUDIO_DOCUMENTACION).isEmpty());
		model.addAttribute("pendienteEjecutadoPasoDesis", this.tareasTramiteDao
				.getLastNotExecutedTask(idExpediente00, TramitesEnum.PASO_DESISTIMIENTO).isEmpty());

		return exp;
	}

	@RequestMapping(value = "/tabSolicitud/{idExpediente00}", method = RequestMethod.GET)
	public String getTabSolicitud(Model model, @PathVariable Long idExpediente00, HttpServletRequest request) {

		if (Boolean.FALSE.equals(this.validarUsuarioAcceso(request))) {
			return "accessDenied";
		}

		Expedientes exp = this.expedientesService.find(new Expedientes(idExpediente00));

		Dependencia dependencia = new Dependencia();
		dependencia.setIdExpediente04(exp.getIdExpediente00());
		exp.setDependencia(this.dependenciaService.findByIdExp(dependencia));

		Discapacidad discapacidad = new Discapacidad();
		discapacidad.setIdExpediente71(exp.getIdExpediente00());
		exp.setDiscapacidad(this.discapacidadService.findByIdExp(discapacidad));
		exp.setOrigenOficioDef00(TipoCanalOrigenEnum.getDesc(exp.getOrigenOficio00()));
		model.addAttribute("expediente", exp);
		List<Combo> tipoIdentificadorList = new ArrayList<>();
		for (TipoIdentificadorEnum enumeracion : TipoIdentificadorEnum.values()) {
			tipoIdentificadorList.add(enumeracion.getCombo());
		}
		List<Combo> tipoIdentificadorPersonaFisicaList = new ArrayList<>();
		for (TipoIdentificadorEnum enumeracion : TipoIdentificadorEnum
				.valuesByTipoPersona(Constantes.TIPO_PERSONA_FISICA_BBDD)) {
			tipoIdentificadorPersonaFisicaList.add(enumeracion.getCombo());
		}
		model.addAttribute("tipoIdentificadorList", tipoIdentificadorList);
		model.addAttribute("tipoIdentificadorPersonaFisicaList", tipoIdentificadorPersonaFisicaList);
		// Niveles de urgencia
		List<Combo> listaNivelesUrgencia = new ArrayList<Combo>();
		listaNivelesUrgencia.add(new Combo("", "---", "---"));
		for (Constantes.NivelUrgenciaEnum nivel : Constantes.NivelUrgenciaEnum.values()) {
			listaNivelesUrgencia.add(nivel.getCombo());
		}
		model.addAttribute("nivelesUrgencia", listaNivelesUrgencia);
		// TODO: control estado
		model.addAttribute("isSoloLecturaSolicitud", this.isSoloLecturaSoilicitud(exp));

		// TODO: control estado
		model.addAttribute("usuarioAdmDSS", this.validarUsuarioAdmDSS());

		if (ProcedimientosEnum.ALTA.getId().equalsIgnoreCase(exp.getIdProcedimiento00())
				|| ProcedimientosEnum.X87_TEA_1.getId().equalsIgnoreCase(exp.getIdProcedimiento00())) {

			List<PisosTutelados> pisosTuteladosList = this.pisosTuteladosService.findAll(new PisosTutelados(), null);
			pisosTuteladosList.add(new PisosTutelados());
			model.addAttribute("pisosTuteladosList", pisosTuteladosList);
			Retorno retorno = exp.getDatosInterop().getDatosRetornoDGP19();

			String nombre = extraerDatosInterop(retorno);
			model.addAttribute("titularInterop", (!nombre.equals("") || nombre != null) ? nombre : null);

			return "tabSolicitudAlta";
		} else if (ProcedimientosEnum.BAJA.getId().equalsIgnoreCase(exp.getIdProcedimiento00())
				|| ProcedimientosEnum.X87_TEA_2.getId().equalsIgnoreCase(exp.getIdProcedimiento00())) {

			List<MotivosBaja> motivosBajaList;
			if (!this.isSoloLecturaSoilicitud(exp)) {
				motivosBajaList = MotivoBajaEnum.valuesMotivosBaja33(exp.getDeOficio00(), MotivoBajaEnum.BAJA_NO);
			} else {
				motivosBajaList = MotivoBajaEnum.valuesMotivosBaja33(exp.getDeOficio00(), MotivoBajaEnum.BAJA_SI);
			}

			// si el idMotivo no esta en la lista, es porque estça de baja, pero queremos
			// mostrarlo en pantalla
			if (!Utilidades.esNulo(exp.getIdMotivoBaja00())) {
				boolean encontrado = false;
				Long idMotivoBaja = exp.getIdMotivoBaja00();
				for (MotivosBaja motivo : motivosBajaList) {
					if (motivo.getIdMotivoBaja33().compareTo(idMotivoBaja) == 0) {
						encontrado = true;
						break;
					}
				}
				if (!encontrado) {
					motivosBajaList.add(this.motivosBajaService.find(new MotivosBaja(idMotivoBaja)));
				}
			}

			model.addAttribute("idMotivoBaja00List", motivosBajaList);
			return "tabSolicitudBaja";
		} else if (ProcedimientosEnum.INFORME.getId().equalsIgnoreCase(exp.getIdProcedimiento00())) {
			Informes informeInterFilter = new Informes();
			informeInterFilter.setIdExpediente16(exp.getIdExpediente00());
			List<Informes> informeInterList = this.informesService.findAll(informeInterFilter, null);
			if (!Utilidades.isEmptyList(informeInterList)) {
				exp.setInformeIntervencion(informeInterList.get(0));
			}

			return "tabSolicitudInforme";
		} else if (ProcedimientosEnum.MODIFICACION.getId().equalsIgnoreCase(exp.getIdProcedimiento00())) {
			List<PisosTutelados> pisosTuteladosList = this.pisosTuteladosService.findAll(new PisosTutelados(), null);
			pisosTuteladosList.add(new PisosTutelados());
			model.addAttribute("pisosTuteladosList", pisosTuteladosList);
			return "tabSolicitudModificacion";
		} else if (ProcedimientosEnum.REVISION_PRECIO.getId().equalsIgnoreCase(exp.getIdProcedimiento00())
				|| ProcedimientosEnum.X87_TEA_4.getId().equalsIgnoreCase(exp.getIdProcedimiento00())) {
			return "tabSolicitudRevision";
		} else if (ProcedimientosEnum.NOTIFICACION_LIQUIDACION.getId().equalsIgnoreCase(exp.getIdProcedimiento00())) {
			if (exp.getIdLiquidacion00() != null) {
				Liquidaciones liquidacion = new Liquidaciones(exp.getIdLiquidacion00());
				liquidacion = this.liquidacionesService.find(liquidacion);
				// model.addAttribute("liquidaciones", liquidacion);
				exp.setLiquidaciones(liquidacion);
				model.addAttribute("expediente", exp);
			}

			return "tabSolicitudNotificacionLiquidacion";
		}
		return "error";

	}

	private String extraerDatosInterop(Retorno retorno) {
		String nombre = "";
		if (retorno != null && retorno.getDatosTitular() != null) {
			nombre = retorno.getDatosTitular().getIdentificador();
			nombre += " | " + retorno.getDatosTitular().getNombre();
			nombre += " " + retorno.getDatosTitular().getApellido1();
			nombre += " | " + retorno.getDatosTitular().getApellido2();
			if (retorno.getDatosTitular().getDatosNacimiento() != null) {
				nombre += " | " + retorno.getDatosTitular().getDatosNacimiento().getFecha();
			}
			nombre += " | " + retorno.getDatosTitular().getSexo();
		}
		return nombre;
	}

	@RequestMapping(value = "/tabPrestacionServicio/{idExpediente00}", method = RequestMethod.GET)
	public String getTabPrestacionServicio(Model model, @PathVariable Long idExpediente00, HttpServletRequest request) {

		if (Boolean.FALSE.equals(this.validarUsuarioAcceso(request))) {
			return "accessDenied";
		}

		Expedientes exp = this.expedientesService.find(new Expedientes(idExpediente00));
		model.addAttribute("expediente", exp);
		model.addAttribute("contactos", new Contactos());
		model.addAttribute("solicitantes", exp.getSolicitantes());

		// TODO: control estado
		model.addAttribute("isSoloLecturaSoilicitud", this.isSoloLecturaSoilicitud(exp));

		return "tabPrestacionServicio";

	}

	/**
	 * Metodo filter para obtener los contactos del expediente.
	 * 
	 * @param filterContactos Contactos Bean que contiene los parametros de filtrado
	 *                        a emplear.
	 * @param tableRequestDto Dto que contiene los parametros de configuracion
	 *                        propios del RUP_TABLE a aplicar en el filtrado.
	 * @return TableResponseDto<Contactos> Dto que contiene el resultado del
	 *         filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/tabPrestacionServicio/contactos/{idExpediente00}/filter", method = RequestMethod.POST)
	public @ResponseBody TableResponseDto<Contactos> filterContactosExpediente(
			@RequestJsonBody(param = "filter") Contactos filterContactos,
			@RequestJsonBody TableRequestDto tableRequestDto, @PathVariable Long idExpediente00) {
		ExpedientesController.logger.info("[POST - filter] : Obtener Contactoss");

		filterContactos.setIdExpediente03(idExpediente00);
		return this.contactosService.filter(filterContactos, tableRequestDto, false);
	}

	/**
	 * Metodo filter para obtener los expedientes relacionados de un beneficiario.
	 * 
	 * @param filterContactos Contactos Bean que contiene los parametros de filtrado
	 *                        a emplear.
	 * @param tableRequestDto Dto que contiene los parametros de configuracion
	 *                        propios del RUP_TABLE a aplicar en el filtrado.
	 * @return TableResponseDto<Contactos> Dto que contiene el resultado del
	 *         filtrado realizado por el componente RUP_TABLE.
	 */
	@RequestMapping(value = "/tabExpedientes/expRelacionados/filter", method = RequestMethod.POST)
	public @ResponseBody TableResponseDto<Expedientes> filterExpRelacionados(
			@RequestJsonBody(param = "filter") Expedientes expedientes,
			@RequestJsonBody TableRequestDto tableRequestDto) {
		ExpedientesController.logger.info("[POST - filter] : Obtener Contactoss");

		return this.expedientesService.filterRelacionados(expedientes, tableRequestDto, false);
	}

	@RequestMapping(value = "/tabInformeSocial/{idExpediente00}", method = RequestMethod.GET)
	public String getTabInformeSocial(Model model, @PathVariable Long idExpediente00, HttpServletRequest request) {

		if (Boolean.FALSE.equals(this.validarUsuarioAcceso(request))) {
			return "accessDenied";
		}
		Expedientes exp = this.expedientesService.find(new Expedientes(idExpediente00));
		model.addAttribute("expediente", exp);
		// Vamos a capturar el expediente social
		// Recuperamos los informes sociales
//		Informes infomeSocialFilter = new Informes();
//		infomeSocialFilter.setIdExpediente16(idExpediente00);
//		infomeSocialFilter.setTipoInforme16(TipoInformesEnum.INFSOC.getId());
//		infomeSocialFilter.setEstado16(EstadoInformesEnum.DISPONIBLE.getId());
//		// infomeSocialFilter.setfFinNull(false);
//		TableRequestDto tableRequestDto = new TableRequestDto();
//		tableRequestDto.setSidx("FFIN16");
//		tableRequestDto.setSord("desc");
//		Integer usuario = null;
//		if (UtilSeguridad.isDSS(request) || UtilSeguridad.isDirector(request)) {
//			usuario = ActoresEnum.DSS.getId().intValue();
//		} else if (UtilSeguridad.isPS(request)) {
//			usuario = ActoresEnum.PS.getId().intValue();
//		} else if (UtilSeguridad.isSSB(request)) {
//			usuario = ActoresEnum.SSB.getId().intValue();
//		} else if (UtilSeguridad.isAdmin(request)) {
//			usuario = ActoresEnum.ADMIN.getId().intValue();
//		}
//		List<Informes> informeSocialList = this.informesService.findAllLikePorUsuario(infomeSocialFilter,
//				tableRequestDto, false, usuario);

		// Recuperamos los informes sociales
		Informes infomeSocialFilter = new Informes();
		infomeSocialFilter.setIdExpediente16(idExpediente00);
		infomeSocialFilter.setTipoInforme16(TipoInformesEnum.INFSOC.getId());
		infomeSocialFilter.setEstado16(EstadoInformesEnum.DISPONIBLE.getId());
		List<Informes> informeSocialList = this.informesService.findAll(infomeSocialFilter, null);

		// TODO: control estado
		if (informeSocialList.size() > 0) {
			model.addAttribute("informes", informeSocialList.get(0));
		} else {
			model.addAttribute("informes", new Informes());
		}
		model.addAttribute("isSoloLecturaSoilicitud", this.isSoloLecturaSoilicitud(exp));
		model.addAttribute("TipoEstado", EstadoInformesEnum.values());
		model.addAttribute("TipoInformes", TipoInformesEnum.values());
		return "tabInformeSocial";

	}

	@RequestMapping(value = "/tabDocumentos/{idExpediente00}", method = RequestMethod.GET)
	public String getTabDocumentos(Model model, @PathVariable Long idExpediente00, HttpServletRequest request) {

		if (Boolean.FALSE.equals(this.validarUsuarioAcceso(request))) {
			return "accessDenied";
		}

		Expedientes exp = this.expedientesService.find(new Expedientes(idExpediente00));
		model.addAttribute("expediente", exp);

		model.addAttribute("documentoApor", new DocumentosTarea());
		model.addAttribute("documentoCons", new DocumentosTarea());
		model.addAttribute("documentoGen", new DocumentosTarea());

		// TODO: control estado
		model.addAttribute("isSoloLecturaSoilicitud", this.isSoloLecturaSoilicitud(exp));

		return "tabDocumentos";

	}

	@RequestMapping(value = "/tabTramitacion/{idExpediente00}", method = RequestMethod.GET)
	public String getTabTramitacion(Model model, @PathVariable Long idExpediente00, HttpServletRequest request) {

		if (Boolean.FALSE.equals(this.validarUsuarioAcceso(request))) {
			return "accessDenied";
		}

		Expedientes exp = this.expedientesService.find(new Expedientes(idExpediente00));

		model.addAttribute("expedientes", exp);

		if (ProcedimientosEnum.X87_TEA_1.getId().equalsIgnoreCase(exp.getIdProcedimiento00())
				|| ProcedimientosEnum.X87_TEA_2.getId().equalsIgnoreCase(exp.getIdProcedimiento00())
				|| ProcedimientosEnum.X87_TEA_4.getId().equalsIgnoreCase(exp.getIdProcedimiento00())) {
			MessageFormat url = new MessageFormat(this.appConfiguration.getProperty("url.busqueda.x87"));
			// Object[] args = { LocaleContextHolder.getLocale(), exp.getFolderId00() };
			// model.addAttribute("urlClienteTramitacion", url.format(args));
			model.addAttribute("urlClienteTramitacion", url.format(null));
			return "tabTramitacionMigrado";
		}

		/****** PREPARAMOS EL DIALOGO DE TRAMITACIÓN *****/
		TramitesExpediente tramitesExpediente = new TramitesExpediente();
		// Por defecto la fecha resolucion tiene que ser la actual. Si es null seteamos
		// la actual
		if (exp.getfResolucion00() == null) {
			exp.setfResolucion00(Calendar.getInstance().getTime());
		}
		// Por defecto la resolucion de la exención va a no

		if (exp.getExencionRes00() == null) {
			exp.setExencionRes00(Constantes.VAL_NUM_NO);
		}

		tramitesExpediente.setExpediente(exp);
		model.addAttribute("tramitesExpedienteFilter", tramitesExpediente);
		TramiteTareaDto tramiteTareaDTO = new TramiteTareaDto();
		tramiteTareaDTO.setTramitesExpediente(tramitesExpediente);

		tramiteTareaDTO.setTipoPrecio(Constantes.TIPOPRECIO_PUBLICO);
		model.addAttribute("tramiteTareaDto", tramiteTareaDTO);
		/****** FIN PREPARAMOS EL DIALOGO DE TRAMITACIÓN *****/

		model.addAttribute("documentosAportados", new DocumentosTarea());

		List<Combo> resultadoEstudioList = new ArrayList<Combo>();
		resultadoEstudioList.add(new Combo("", "---", "---"));
		for (Constantes.ResultadoDocumentacion enumeracion : Constantes.ResultadoDocumentacion.values()) {
			resultadoEstudioList.add(enumeracion.getCombo());
		}
		model.addAttribute("resultadoEstudioList", resultadoEstudioList);

		MaestroMotDenegacion maestroMotDenegacionFilter = new MaestroMotDenegacion();
		maestroMotDenegacionFilter.setIdProcedimiento59(exp.getIdProcedimiento00());
		model.addAttribute("motivosDenegacionList",
				this.maestroMotDenegacionService.findAll(maestroMotDenegacionFilter, null));

		model.addAttribute("idMotivoBaja00List",
				MotivoBajaEnum.valuesMotivosBaja33(exp.getDeOficio00(), MotivoBajaEnum.BAJA_NO));

		Map<String, String> tecnicosExpediente = new LinkedHashMap<String, String>();

		List<Combo> resultadoRequerimientosList = new ArrayList<Combo>();
		for (RequerimientosEnum enumeracion : RequerimientosEnum.values()) {
			resultadoRequerimientosList.add(enumeracion.getCombo());
		}
		model.addAttribute("motivosRequerimientosList", resultadoRequerimientosList);

		try {
			tecnicosExpediente = UtilTokenXlnets.getListTecnicos();
		} catch (Exception e) {
			logger.error("Error al obtener los tecnicos");
		}

		model.addAttribute("tecnicosExpediente", tecnicosExpediente);

		DatosEconomicos datoseconomicos = new DatosEconomicos();
		datoseconomicos.setIdExpediente85(idExpediente00);
		datoseconomicos.setIdSolicitante85(exp.getIdSolicitante00());
		model.addAttribute("datoseconomicos", datoseconomicos);

		model.addAttribute("informeSoc", new Informes());

		List<Combo> tipoIdentificadorList = new ArrayList<>();
		for (TipoIdentificadorEnum enumeracion : TipoIdentificadorEnum.values()) {
			tipoIdentificadorList.add(enumeracion.getCombo());
		}
		List<Combo> tipoIdentificadorPersonaFisicaList = new ArrayList<>();
		for (TipoIdentificadorEnum enumeracion : TipoIdentificadorEnum
				.valuesByTipoPersona(Constantes.TIPO_PERSONA_FISICA_BBDD)) {
			tipoIdentificadorPersonaFisicaList.add(enumeracion.getCombo());
		}

		model.addAttribute("tipoIdentificadorList", tipoIdentificadorList);
		model.addAttribute("tipoIdentificadorPersonaFisicaList", tipoIdentificadorPersonaFisicaList);

		return "tabTramitacion";

	}

	@RequestMapping(value = "/busquedaExpedientes", method = RequestMethod.GET)
	public String getBusquedaExpedientes(Model model, HttpServletRequest request,
			@RequestParam(value = "estado", required = false) String estado,
			@RequestParam(value = "idProcedimiento", required = false) String idProcedimiento,
			@RequestParam(value = "tecnicoExpediente", required = false) String tecnicoExpediente) {
		ExpedientesController.logger.info("[GET - View] : expedientes");
		Expedientes exp = new Expedientes();
		if (null != estado) {
			exp.setEstados(new Estados(Long.valueOf(estado)));
		}
		exp.setIdProcedimiento00(idProcedimiento);
		exp.setTecnicoExpediente00(tecnicoExpediente);
		model.addAttribute("expediente", exp);

		// Cargar COMBOS
		List<Combo> idTipoNotList = new ArrayList<>();
		for (TipoExpedientes.idTipoNot00 enumeracion : TipoExpedientes.idTipoNot00.values()) {
			idTipoNotList.add(enumeracion.getCombo());
		}
		model.addAttribute("idTipoNotList", idTipoNotList);

		List<Combo> idProcedimiento00List = new ArrayList<>();
		for (ProcedimientosEnum enumeracion : ProcedimientosEnum.values()) {
			idProcedimiento00List.add(enumeracion.getCombo());
		}
		model.addAttribute("idProcedimiento00List", idProcedimiento00List);

		List<Combo> idEstado30List = new ArrayList<>();
		for (EstadosExpedienteEnum enumeracion : EstadosExpedienteEnum.values()) {
			idEstado30List.add(enumeracion.getCombo());
		}
		model.addAttribute("idEstado30List", idEstado30List);

		List<Combo> idTipoEntrada00List = new ArrayList<>();
		for (TipoExpedientes.idTipoEntrada00 enumeracion : TipoExpedientes.idTipoEntrada00.values()) {
			idTipoEntrada00List.add(enumeracion.getCombo());
		}
		model.addAttribute("idTipoEntrada00List", idTipoEntrada00List);

		model.addAttribute("title", UtilLiterales.getLiteralMessage(appMessageSource, "title.busquedaExpedientes"));

		return "busquedaExpedientes";
	}

	@RequestMapping(value = "ejecutarTarea", method = RequestMethod.POST)
	public @ResponseBody String ejecutarTarea(
			@RequestParam(value = "idExpediente00", required = false) Long idExpediente00,
			@RequestParam(value = "idTramite37", required = false) Long idTramite37, HttpServletRequest request) {
		if (Boolean.FALSE.equals(this.validarUsuarioModificacion(request))) {
			throw new Ad74aException(UtilLiterales.getLiteralMessage(appMessageSource,
					com.ejie.ad74a.util.constantes.Constantes.ERROR_ACCESO_DENEGADO));
		}
		ExpedientesController.logger.info("[POST - ejecutarTarea] : expedientes");
		Expedientes expediente = new Expedientes();
		expediente.setIdExpediente00(idExpediente00);
		expediente = this.expedientesService.find(expediente);

		// TODO:
		// this.tramitacionService.prepareNewTask(expediente, idTramite37);
		return "OK";
	}

	/**
	 * Método de presentación del RUP_TABLE para el detalle del inicio de oficio
	 * 
	 * @param model Model
	 *
	 * @return String
	 */
	@RequestMapping(value = "/inicioOficioDetail/{idProcedimiento00}", method = RequestMethod.GET)
	public String inicioOficioDetail(@PathVariable String idProcedimiento00, Model model) {
		ExpedientesController.logger.info("[GET - View] : inicioOficioDetail");
		Expedientes expediente = new Expedientes();
		expediente.setIdProcedimiento00(idProcedimiento00);
		model.addAttribute("expediente", expediente);
		model.addAttribute("Procedimientos", ProcedimientosEnum.values());
		model.addAttribute("idMotivoBaja00List",
				MotivoBajaEnum.valuesMotivosBaja33(MotivoBajaEnum.EXCLUSIVO_DE_OFICIO_SI, MotivoBajaEnum.BAJA_NO));
		List<Combo> tipoIdentificadorList = new ArrayList<>();
		for (TipoIdentificadorEnum enumeracion : TipoIdentificadorEnum.values()) {
			tipoIdentificadorList.add(enumeracion.getCombo());
		}
		List<Combo> tipoIdentificadorPersonaFisicaList = new ArrayList<>();
		for (TipoIdentificadorEnum enumeracion : TipoIdentificadorEnum
				.valuesByTipoPersona(Constantes.TIPO_PERSONA_FISICA_BBDD)) {
			tipoIdentificadorPersonaFisicaList.add(enumeracion.getCombo());
		}
		model.addAttribute("tipoIdentificadorList", tipoIdentificadorList);
		model.addAttribute("tipoIdentificadorPersonaFisicaList", tipoIdentificadorPersonaFisicaList);
		return "inicioOficioDetail";
	}

	// @RequestMapping(value = "/iniciarOficio", method = RequestMethod.POST)
	// public @ResponseBody Expedientes inicioOficio(@RequestJsonBody(param =
	// "expediente")
	// Expedientes expediente) {
	// ExpedientesController.logger.info("[POST - iniciarOficio] : Iniciar de
	// oficio");
	// this.bandejaPapel0Service.insertTabSolicitudPapel0(expediente);
	// ExpedientesController.logger.info("[PUT] : BandejaPapel0 actualizado
	// correctamente");
	// return expediente;
	// }

	@RequestMapping(value = "/adjuntarInformeSocial", method = RequestMethod.PUT)
	protected @ResponseBody Informes adjuntarInformeSocial(@RequestJsonBody(param = "idInforme16") Long idInforme16,
			@RequestJsonBody(param = "idExpediente16") Long idExpediente16) {

		// recuperamos el informe
		Informes informe = this.informesService.find(new Informes(idInforme16));
		// recuperamos el expediente
		Expedientes expediente = this.expedientesService.find(new Expedientes(idExpediente16));
		// actualizar el expediente y el solicitante en el informe social
		informe.setIdBeneficiario16(expediente.getSolicitantes().getIdSolicitante01());
		informe.setIdExpediente16(expediente.getIdExpediente00());

		this.informesService.relacionInformePorMatch(informe, expediente);

		return null;
	}

	@RequestMapping(value = "/pasarDesistimiento", method = RequestMethod.POST)
	public @ResponseBody Boolean pasarDesistimiento(@RequestJsonBody(param = "idExpediente00") Long idExpediente00) {
		ExpedientesController.logger
				.info("[POST - ExpedientesController ] : pasarDesistimiento idExpediente:" + idExpediente00);
		try {
			Expedientes expediente = this.expedientesService.find(new Expedientes(idExpediente00));
			this.tramitacionService.sugerirTarea(expediente, TareasEnum.PASO_DESISTIMIENTO);
		} catch (Throwable e) {
			ManagerErrors.manageException(e, "Error al iniciar el paso a desisitimiento");
		}
		return true;
	}

	@RequestMapping(value = "/resolucionSinAlegaciones", method = RequestMethod.POST)
	public @ResponseBody Boolean resolucionSinAlegaciones(
			@RequestJsonBody(param = "idExpediente00") Long idExpediente00) {
		ExpedientesController.logger
				.info("[POST - ExpedientesController ] : resolucionSinAlegaciones idExpediente:" + idExpediente00);
		try {
			Expedientes expediente = this.expedientesService.find(new Expedientes(idExpediente00));

			this.tramitacionService.sugerirTarea(expediente, TareasEnum.RESOL_DENEGACION_SERVICIO_AUDIENCIA);
		} catch (Throwable e) {
			ManagerErrors.manageException(e, "Error al iniciar la resolucion sin alegaciones");
		}
		return true;
	}

	@RequestMapping(value = "/nuevoEstudiDoc", method = RequestMethod.POST)
	public @ResponseBody Boolean nuevoEstudiDoc(@RequestJsonBody(param = "idExpediente00") Long idExpediente00) {
		ExpedientesController.logger
				.info("[POST - ExpedientesController ] : nuevoEstudiDoc idExpediente:" + idExpediente00);
		try {
			Expedientes expediente = this.expedientesService.find(new Expedientes(idExpediente00));

			this.tramitacionService.sugerirTarea(expediente, TareasEnum.ESTUDIO);
		} catch (Throwable e) {
			ManagerErrors.manageException(e, "Error al iniciar nuevo EstudiDoc");
		}
		return true;
	}

	/**
	 * Método para probar el envío de emails
	 * 
	 * @return
	 */
	@RequestMapping(value = "/sendTestEmail", method = RequestMethod.GET)
	public @ResponseBody Boolean sendTestEmail() {
		ExpedientesController.logger.info("[GET - ExpedientesController ] : sendTestEmail");

		Solicitantes solicitante = new Solicitantes();
		solicitante.setIdSolicitante01(321204L);
		solicitante = this.solicitantesService.find(solicitante);

		ArrayList<String> ssbTo = new ArrayList<String>();
		ssbTo.add("AD74AU02");
		try {
			UtilidadesMail.getInstance().enviarMailAviso(null, solicitante,
					com.ejie.ad74a.util.constantes.Constantes.TiposCorreo.AVISO_SSB_INF_INTERVENCION, ssbTo);
		} catch (Exception e) {
			e.printStackTrace();
			ExpedientesController.logger.error("[GET - ExpedientesController ] : sendTestEmail" + e.getMessage());
			ManagerErrors.manageException(e, "Error sendTestEmail:" + e.getMessage());
		}
		return true;
	}

	// Operación CRUD aportarDocumento. Crea una tarea de aportacion de documento

	@PostMapping(value = "/aportarDocumento")
	public @ResponseBody List<Map<String, Object>> aportarDocumento(
			@RequestParam(value = "idExpediente00", required = true) String idExpediente00,
			@RequestParam(value = "tipoDocumento", required = true) String tipodocumento,
			@RequestParam(value = "documento", required = false) MultipartFile documento, HttpServletRequest request) {
		ExpedientesController.logger.info("[POST] : APORTARDOCUMENTO ");

//		if (Boolean.FALSE.equals(this.validarUsuarioModificacion(request))) {
//			throw new Ad74aException(UtilLiterales.getLiteralMessage(appMessageSource,
//					com.ejie.ad74a.util.constantes.Constantes.ERROR_ACCESO_DENEGADO));
//		}

		Expedientes expediente = new Expedientes(Long.valueOf(idExpediente00));
		this.expedientesService.aportarDocumento(expediente, documento, tipodocumento);

		List<Map<String, Object>> filesMetaInfo = new ArrayList<Map<String, Object>>();
		// filesMetaInfo.add(this.getFileReturnMap(file));

		return filesMetaInfo;

//		return new Resource<Expedientes>(expediente);
	}

	/**
	 * Operacion CRUD Edit. Modificacion del bean indicado.
	 *
	 * @param solicitantes Solicitantes Bean que contiene la informacion a
	 *                     modificar.
	 * @return Solicitantes Bean resultante de la modificacion.
	 */
	@RequestMapping(value = "/editTabPrestacionServicio", method = RequestMethod.PUT)
	public @ResponseBody Expedientes editIdiomaServicio(@RequestBody Expedientes expediente) {
		this.solicitantesService.updateIdiomaServicio(expediente.getSolicitantes());
		this.expedientesService.updateExisteInstalacion(expediente);
		ExpedientesController.logger.info("[PUT] : TabPrestacionServicio actualizado correctamente");
		return expediente;
	}
}
