package com.ejie.ab04b.control;

import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

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

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.xerces.dom.ElementNSImpl;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
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.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.WebDataBinder;
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.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.servlet.ModelAndView;

import com.ejie.ab04b.constantes.Constantes;
import com.ejie.ab04b.constantes.ConstantesDocumentos;
import com.ejie.ab04b.constantes.ConstantesDokusi;
import com.ejie.ab04b.constantes.ConstantesNum;
import com.ejie.ab04b.constantes.EstadosTareas;
import com.ejie.ab04b.constantes.TipoExpedienteFolderEnum;
import com.ejie.ab04b.constantes.TipoTareaFlujo;
import com.ejie.ab04b.constantes.TipoTramiteFlujo;
import com.ejie.ab04b.dao.temp.DocumentosOS2TempDao;
import com.ejie.ab04b.dao.temp.DocumentosOS3TempDao;
import com.ejie.ab04b.exception.AB04BException;
import com.ejie.ab04b.exception.ErrorField;
import com.ejie.ab04b.exception.ErrorGenericoException;
import com.ejie.ab04b.exception.Mensaje;
import com.ejie.ab04b.model.ComunicacionPrl;
import com.ejie.ab04b.model.DatosAviso;
import com.ejie.ab04b.model.DatosLocalizacion;
import com.ejie.ab04b.model.DatosNotificacion;
import com.ejie.ab04b.model.DocumentoOS2;
import com.ejie.ab04b.model.DocumentoOS3;
import com.ejie.ab04b.model.EstudioDocOS2;
import com.ejie.ab04b.model.EstudioDocOS3;
import com.ejie.ab04b.model.Folder;
import com.ejie.ab04b.model.OS2;
import com.ejie.ab04b.model.OS3;
import com.ejie.ab04b.model.RequerimientoOS2;
import com.ejie.ab04b.model.RequerimientoOS3;
import com.ejie.ab04b.model.Tablones;
import com.ejie.ab04b.model.TareaErronea;
import com.ejie.ab04b.model.TareaOS2;
import com.ejie.ab04b.model.TareaOS3;
import com.ejie.ab04b.model.TipoDocumento;
import com.ejie.ab04b.model.Tramite;
import com.ejie.ab04b.model.TramiteOS2;
import com.ejie.ab04b.model.TramiteOS3;
import com.ejie.ab04b.model.pps.PPSReturnInfo;
import com.ejie.ab04b.model.toolbar.Boton;
import com.ejie.ab04b.model.toolbar.Botonera;
import com.ejie.ab04b.service.ComunicacionPrlService;
import com.ejie.ab04b.service.DatosAvisoService;
import com.ejie.ab04b.service.DatosNotificacionService;
import com.ejie.ab04b.service.DocumentoOS2Service;
import com.ejie.ab04b.service.DocumentoOS3Service;
import com.ejie.ab04b.service.EstudioDocOS2Service;
import com.ejie.ab04b.service.EstudioDocOS3Service;
import com.ejie.ab04b.service.FolderService;
import com.ejie.ab04b.service.GeneracionPDFFichaOS2Service;
import com.ejie.ab04b.service.GeneracionPDFFichaOS3Service;
import com.ejie.ab04b.service.GeneracionPDFSubsanacionService;
import com.ejie.ab04b.service.OS2Service;
import com.ejie.ab04b.service.OS3Service;
import com.ejie.ab04b.service.RequerimientoOS2Service;
import com.ejie.ab04b.service.RequerimientoOS3Service;
import com.ejie.ab04b.service.TablonesService;
import com.ejie.ab04b.service.TareaErroneaService;
import com.ejie.ab04b.service.TareaOS2Service;
import com.ejie.ab04b.service.TareaOS3Service;
import com.ejie.ab04b.service.TramiteOS2Service;
import com.ejie.ab04b.service.TramiteOS3Service;
import com.ejie.ab04b.service.dokusi.DokusiService;
import com.ejie.ab04b.service.pif.PifService;
import com.ejie.ab04b.service.platea.PPSAportacionOS2Service;
import com.ejie.ab04b.service.platea.PPSAportacionOS3Service;
import com.ejie.ab04b.service.platea.PPSOS2Service;
import com.ejie.ab04b.service.platea.PPSOS3Service;
import com.ejie.ab04b.service.platea.PlateaTramitacionService;
import com.ejie.ab04b.service.platea.ReeService;
import com.ejie.ab04b.service.svt.SvtService;
import com.ejie.ab04b.service.tramitacion.TramitacionOS2Service;
import com.ejie.ab04b.service.tramitacion.TramitacionOS3Service;
import com.ejie.ab04b.util.DatosNavegacion;
import com.ejie.ab04b.util.ManejoSesion;
import com.ejie.ab04b.util.PPSUtils;
import com.ejie.ab04b.util.PropertiesUtil;
import com.ejie.ab04b.util.UtilidadesWar;
import com.ejie.ab04b.util.Utilities;
import com.ejie.ab04b.util.ValidadorNifCifNie;
import com.ejie.ab04b.util.seguridad.UtilSeguridad;
import com.ejie.ab04b.validation.AbstractPRLValidator.Oper;
import com.ejie.ab04b.validation.ComunicacionPrlValidator;
import com.ejie.ct.xml.DocumentStorageInfo;
import com.ejie.ct.xml.FolderDoc;
import com.ejie.ct.xml.FolderDocumentList;
import com.ejie.ctfm.xml.ContextSubmission;
import com.ejie.foldermanagement.xml.RequestReturn;
import com.ejie.t65.jaxb.beans.fsd.T65BDocumentIDType;
import com.ejie.x38.control.bind.annotation.RequestJsonBody;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRowDto;
import com.ejie.x38.rup.jqgrid.filter.model.Filter;
import com.ejie.x38.rup.jqgrid.filter.service.FilterService;

/**
 * ComunicacionPrlController generated by UDA, 23-feb-2017 13:09:29.
 * 
 * @author UDA
 */

@Controller()
@RequestMapping(value = "/comunicacionprl")
public class ComunicacionPrlController {

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

	public static final String ATTR_NAME_COMUNICACIONPRL_FILTER = "comunicPrlFiltroModel";

	private static final int NUMEXP_LPAD_SIZE = 5;
	private static final String NUMEXP_LPAD_CHAR = "0";
	// Tiempo de espera mínimo para mostrar "Reabir" cuando estado='S'
	private static final long MIN_WAIT_REOPEN = 5L * 60 * 1000;

	public static final String ATTR_NAME_COMUNICAPRL_OS2_DETALLE = "documentoOS2";
	public static final String ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_NOTIFICACION = "toolbarNotificacion";
	public static final String ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_EMPRESA = "toolbarEmpresa";
	public static final String ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_MODALIDAD = "toolbarModalidad";
	public static final String ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_AUDITORIA = "toolbarAuditoria";
	public static final String ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_ESTADO = "toolbarEstado";
	public static final String ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_DOCUMENTOS_REG = "toolbarDocumentosReg";
	public static final String ATTR_NAME_COMUNICAPRL_OS2_CERRAR_EXPEDIENTE = "cerrarExpediente";
	public static final String ATTR_NAME_COMUNICAPRL_OS2_CREAR_ESTUDIO = "crearEstudio";
	public static final String ATTR_NAME_COMUNICAPERTURA_ABRIR_EXPEDIENTE = "abrirExpediente";

	public static final String ATTR_NAME_COMUNICAPRL_OS3_DETALLE = "documentoOS3";
	public static final String ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_NOTIFICACION = "toolbarNotificacion";
	public static final String ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_EMPRESA = "toolbarEmpresa";
	public static final String ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_PREVENCION = "toolbarPrevencion";
	public static final String ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_ESTADO = "toolbarEstado";
	public static final String ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_DOCUMENTOS_REG = "toolbarDocumentosReg";
	public static final String ATTR_NAME_COMUNICAPRL_OS3_CERRAR_EXPEDIENTE = "cerrarExpediente";
	public static final String ATTR_NAME_COMUNICAPRL_OS3_CREAR_ESTUDIO = "crearEstudio";

	public static final String ATTR_NAME_COMUNICAPRL_TAB_DEFECTO = "tabActiva";
	public static final Integer TAB_DETALLE_DEFECTO = 0;

	public static final String ATTR_NAME_MODO_ACCESO = "modoAcceso";

	@Autowired()
	private ComunicacionPrlService comunicacionPrlService;

	@Autowired()
	private ComunicacionPrlValidator comunicacionPrlValidator;

	@Autowired()
	private DatosNotificacionService datosNotificacionService;

	@Autowired()
	private OS2Service os2Service;

	@Autowired()
	private OS3Service os3Service;

	@Autowired()
	private DatosAvisoService datosAvisoService;

	@Autowired()
	private FilterService filterService;

	@Autowired()
	private ReloadableResourceBundleMessageSource messageSource;

	@Autowired()
	private GeneracionPDFFichaOS2Service generacionPDFFichaOS2Service;

	@Autowired()
	private GeneracionPDFFichaOS3Service generacionPDFFichaOS3Service;

	@Autowired()
	private TareaOS2Service tareaOS2Service;
	@Autowired()
	private TareaOS3Service tareaOS3Service;

	@Autowired()
	private EstudioDocOS2Service estudioDocOS2Service;

	@Autowired()
	private RequerimientoOS2Service requerimientoOS2Service;

	@Autowired()
	private EstudioDocOS3Service estudioDocOS3Service;

	@Autowired()
	private RequerimientoOS3Service requerimientoOS3Service;

	@Autowired()
	private TablonesService tablonesService;

	@Autowired()
	private TramitacionOS2Service tramitacionOS2Service;

	@Autowired()
	private TramiteOS2Service tramiteOS2Service;

	@Autowired()
	private TramitacionOS3Service tramitacionOS3Service;

	@Autowired()
	private TramiteOS3Service tramiteOS3Service;

	@Autowired()
	private FolderService folderService;

	@Autowired()
	private PPSOS2Service ppsOS2Service;
	@Autowired()
	private PPSOS3Service ppsOS3Service;

	@Autowired()
	private PPSAportacionOS2Service ppsAportacionOS2Service;

	@Autowired()
	private PPSAportacionOS3Service ppsAportacionOS3Service;

	@Autowired()
	private PlateaTramitacionService plateaTramitacionService;

	@Autowired()
	private ReeService reeService;

	@Autowired()
	private SvtService svtService;

	@Autowired()
	private TareaErroneaService tareaErroneaService;

	@Autowired()
	private PifService pifService;

	@Autowired()
	private DokusiService dokusiService;

	@Autowired()
	private DocumentoOS2Service documentoOS2Service;
	@Autowired()
	private DocumentosOS2TempDao documentosOS2TempDao;

	@Autowired()
	private DocumentoOS3Service documentoOS3Service;
	@Autowired()
	private DocumentosOS3TempDao documentosOS3TempDao;
	@Autowired()
	private GeneracionPDFSubsanacionService generacionPDFSubsanacionService;

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

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

	/*
	 * METODOS COMPONENTE RUP_TABLE
	 */

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * model Model locale Locale request the request
	 * 
	 * @param model
	 *            the model
	 * @param locale
	 *            the locale
	 * @param request
	 *            the request String
	 * @return the form edit
	 */
	@RequestMapping(value = "/filtro", method = RequestMethod.GET)
	public String getFormEdit(Model model, Locale locale,
			HttpServletRequest request) {
		ComunicacionPrlController.logger.info("[GET - View] : comunicacionprl");

		// Combos del Filtro
		this.precargaCombosFiltroBusqueda(model);
		ComunicacionPrl comunicacionPrl = new ComunicacionPrl();
		Calendar c = Calendar.getInstance();
		comunicacionPrl.setAnoos(String.valueOf(c.get(Calendar.YEAR)));

		if (request.getParameter("tipo") != null
				&& Constantes.OS2.equals(request.getParameter("tipo"))) {
			comunicacionPrl.setTipoos(Constantes.OS2);
			comunicacionPrl.setEstadoComunicacion(Constantes.ESTADO_ABIERTO);
		} else if (request.getParameter("tipo") != null
				&& Constantes.OS3.equals(request.getParameter("tipo"))) {
			comunicacionPrl.setTipoos(Constantes.OS3);
			comunicacionPrl.setEstadoComunicacion(Constantes.ESTADO_ABIERTO);
		}

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICACIONPRL_FILTER,
				comunicacionPrl);

		// Con este parametro sabre los botones que tengo que mostrar en la
		// tabla de resultados de Aperturas de Centros de Trabajo
		if (request.getParameter("modo") != null) {
			request.getSession().setAttribute("modo",
					request.getParameter("modo"));
		}
		if (request.getParameter("tipo") != null) {
			request.getSession().setAttribute("tipo",
					request.getParameter("tipo"));
		}

		request.getSession().setAttribute(
				ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR,
				null);

		return "comunicacionprl";
	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * model Model
	 * 
	 * @param model
	 *            the model String
	 * @return the form edit
	 */
	@RequestMapping(value = "/maint", method = RequestMethod.GET)
	public String getFormEdit(Model model) {
		ComunicacionPrlController.logger.info("[GET - View] : comunicacionprl");
		return "comunicacionprl";
	}

	/**
	 * Metodo para volver al listado desde pantalla detalle.
	 * 
	 * model Model request HttpServletRequest response HttpServletResponse
	 * 
	 * @param model
	 *            the model
	 * @param request
	 *            the request
	 * @param response
	 *            the response String
	 * @return the back form edit
	 */
	@RequestMapping(value = "/backToMaint", method = RequestMethod.GET)
	public String getBackFormEdit(Model model, HttpServletRequest request,
			HttpServletResponse response) {
		ComunicacionPrlController.logger
				.info("[GET - backToMaint] : comunicacionprl");

		// Combos del Filtro
		this.precargaCombosFiltroBusqueda(model);

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICACIONPRL_FILTER,
				ManejoSesion.pasaDatosNavegacionModel(request, model,
						ComunicacionPrl.class));

		request.getSession().setAttribute(
				ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR,
				null);

		return "comunicacionprl";
	}

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

		ComunicacionPrl filter = null;

		// recupera datos filtro y sobreescribe el filtro si venimos de accion
		// volver
		Object datosFiltroSesion = ManejoSesion.recuperaDatosFiltro(request,
				jqGridRequestDto, ComunicacionPrl.class);
		if (datosFiltroSesion != null) {
			filter = (ComunicacionPrl) datosFiltroSesion;
		} else {
			// en caso de no venir de volver, guarda filtro
			filter = filterComunicacionPrl;
			ManejoSesion.guardaFiltro(request, filter, jqGridRequestDto);
		}

		// Si el usuario no tiene perfil de tramitador_osalan, no se muestran
		// los OS2/OS3 que estén en proceso de alta,
		// ya que en estos sólo se puede entrar en modo alta, y sólo pueden
		// hacerlo los tramitadores_osalan.
		List<String> perfiles = UtilSeguridad.getInstance().getUserCredentials()
				.getUserProfiles();
		if (!perfiles.contains(Constantes.ROL_TRAMITADOR_OSALAN_ALAVA)
				&& !perfiles.contains(Constantes.ROL_TRAMITADOR_OSALAN_BIZKAIA)
				&& !perfiles
						.contains(Constantes.ROL_TRAMITADOR_OSALAN_GIPUZKOA)) {
			filterComunicacionPrl.setOcultarEnProcesoAlta(true);
		} else {
			filterComunicacionPrl.setOcultarEnProcesoAlta(false);
		}

		return this.comunicacionPrlService.filter(filterComunicacionPrl,
				jqGridRequestDto, false);
	}

	/**
	 * Operacion de busqueda del componente RUP_TABLE.
	 * 
	 * filterComunicacionPrl ComunicacionPrl Bean que contiene los parametros de
	 * filtrado a emplear. searchComunicacionPrl ComunicacionPrl Bean que
	 * contiene los parametros de busqueda a emplear. jqGridRequestDto Dto que
	 * contiene los parametros de configuracion propios del RUP_TABLE a aplicar
	 * en la búsqueda.
	 * 
	 * @param filterComunicacionPrl
	 *            the filter comunicacion prl
	 * @param searchComunicacionPrl
	 *            the search comunicacion prl
	 * @param jqGridRequestDto
	 *            the jq grid request dto TableRowDto<ComunicacionPrl> Dto que
	 *            contiene el resultado de la busqueda realizada por el
	 *            componente RUP_TABLE.
	 * @return the list
	 */
	@RequestMapping(value = "/search", method = RequestMethod.POST)
	public @ResponseBody List<TableRowDto<ComunicacionPrl>> search(
			@RequestJsonBody(param = "filter") ComunicacionPrl filterComunicacionPrl,
			@RequestJsonBody(param = "search") ComunicacionPrl searchComunicacionPrl,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		ComunicacionPrlController.logger
				.info("[POST - search] : Buscar ComunicacionPrls");
		return this.comunicacionPrlService.search(filterComunicacionPrl,
				searchComunicacionPrl, jqGridRequestDto, false);
	}

	/*
	 * MULTIFILTER
	 */

	/**
	 * Filter add.
	 * 
	 * filtro Filter
	 * 
	 * @param filtro
	 *            the filtro Filter
	 * @return the filter
	 */
	@RequestMapping(value = "/multiFilter/add", method = RequestMethod.POST)
	public @ResponseBody() Filter filterAdd(
			@RequestJsonBody(param = "filtro") Filter filtro) {
		ComunicacionPrlController.logger.info("[POST - jqGrid] : add filter");

		return this.filterService.insert(filtro);
	}

	/**
	 * Filter delete.
	 * 
	 * filtro Filter
	 * 
	 * @param filtro
	 *            the filtro Filter
	 * @return the filter
	 */
	@RequestMapping(value = "/multiFilter/delete", method = RequestMethod.POST)
	public @ResponseBody() Filter filterDelete(
			@RequestJsonBody(param = "filtro") Filter filtro) {
		ComunicacionPrlController.logger
				.info("[POST - jqGrid] : delete filter");
		return this.filterService.delete(filtro);
	}

	/**
	 * Filter get default.
	 * 
	 * filterSelector String filterUser String
	 * 
	 * @param filterSelector
	 *            the filter selector
	 * @param filterUser
	 *            the filter user Filter
	 * @return the filter
	 */
	@RequestMapping(value = "/multiFilter/getDefault", method = RequestMethod.GET)
	public @ResponseBody() Filter filterGetDefault(
			@RequestParam(value = "filterSelector", required = true) String filterSelector,
			@RequestParam(value = "user", required = true) String filterUser) {
		ComunicacionPrlController.logger
				.info("[get - jqGrid] : getDefault filter");
		return this.filterService.getDefault(filterSelector, filterUser);
	}

	/**
	 * Filter get all.
	 * 
	 * filterSelector String filterUser String
	 * 
	 * @param filterSelector
	 *            the filter selector
	 * @param filterUser
	 *            the filter user List<Filter>
	 * @return the list
	 */
	@RequestMapping(value = "/multiFilter/getAll", method = RequestMethod.GET)
	public @ResponseBody() List<Filter> filterGetAll(
			@RequestParam(value = "filterSelector", required = true) String filterSelector,
			@RequestParam(value = "user", required = true) String filterUser) {
		ComunicacionPrlController.logger.info("[get - jqGrid] : GetAll filter");
		return this.filterService.getAllFilters(filterSelector, filterUser);
	}

	/**
	 * Realiza la exportaciÃ³n a Excel.
	 * 
	 * filterComunicacionPrl Expediente Bean que contiene los parÃ¡metros de
	 * filtrado a emplear. jqGridRequestDto JQGridRequestDto que contiene los
	 * parÃ¡mtros de configuraciÃ³n propios del RUP_TABLE a aplicar en el
	 * filtrado. modelMap ModelMap columns String request HttpServletRequest
	 * 
	 * @param filterComunicacionPrl
	 *            the filter comunicacion prl
	 * @param jqGridRequestDto
	 *            the jq grid request dto
	 * @param modelMap
	 *            the model map
	 * @param columns
	 *            the columns
	 * @param request
	 *            the request ModelAndView
	 * @return the report
	 */
	@RequestMapping(value = { "xlsReport",
			"xlsxReport" }, method = RequestMethod.POST)
	protected ModelAndView getReport(
			@ModelAttribute() ComunicacionPrl filterComunicacionPrl,
			@ModelAttribute() JQGridRequestDto jqGridRequestDto,
			ModelMap modelMap,
			@RequestParam(value = "columns", required = false) String columns,
			HttpServletRequest request) {

		// Limpiamos los datos de paginacion para mostrar todos los registros
		jqGridRequestDto.setPage(null);
		jqGridRequestDto.setRows(null);

		// Acceso a BD para recuperar datos
		List<ComunicacionPrl> listComunicaciones = this.comunicacionPrlService
				.findAllLike(filterComunicacionPrl, jqGridRequestDto, false);

		// GENERAMOS EL FICHERO
		UtilidadesWar.generateReport(modelMap,
				Utilities.getLiteralMessage(this.messageSource,
						"excel.titulo.comunicacionesPrl"),
				columns, listComunicaciones);

		// GeneraciÃ³n del XLS o XLSX
		if (request.getServletPath().indexOf("xlsReport") != -1) {
			return new ModelAndView("xlsReport", modelMap);
		} else {
			return new ModelAndView("xlsxReport", modelMap);
		}
	}

	/**
	 * Borrado multiple de registros.
	 * 
	 * filterComunicacionPrl ComunicacionPrl Bean que contiene los parametros de
	 * filtrado a emplear. jqGridRequestDto Dto que contiene los parametros de
	 * configuracion propios del RUP_TABLE a aplicar en la busqueda.
	 * 
	 * @param filterComunicacionPrl
	 *            the filter comunicacion prl
	 * @param jqGridRequestDto
	 *            the jq grid request dto List<String> Lista de los
	 *            identificadores de los registros eliminados.
	 * @return the list
	 */
	@RequestMapping(value = "/deleteAll", method = RequestMethod.POST)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody List<String> removeMultiple(
			@RequestJsonBody(param = "filter") ComunicacionPrl filterComunicacionPrl,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		ComunicacionPrlController.logger.info(
				"[POST - search] : [POST - removeMultiple] : Eliminar multiples ComunicacionPrls");
		this.comunicacionPrlService.removeMultiple(filterComunicacionPrl,
				jqGridRequestDto, false);
		ComunicacionPrlController.logger
				.info("All entities correctly deleted!");

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

	/*
	 * METODOS COMPONENTE RUP_TABLE - JERARQUIA
	 */

	/**
	 * Operacion de filtrado del componente RUP_TABLE para presentar los
	 * registros mediante visualizacion jerarquica.
	 * 
	 * filterComunicacionPrl ComunicacionPrl Bean que contiene los parametros de
	 * filtrado a emplear. jqGridRequestDto Dto que contiene los parametros de
	 * configuracion propios del RUP_TABLE a aplicar en el filtrado.
	 * 
	 * @param filterComunicacionPrl
	 *            the filter comunicacion prl
	 * @param jqGridRequestDto
	 *            the jq grid request dto JQGridResponseDto<JerarquiaDto
	 *            <ComunicacionPrl>> Dto que contiene el resultado del filtrado
	 *            realizado por el componente RUP_TABLE.
	 * @return the JQ grid response dto
	 */
	@RequestMapping(value = "/jerarquia/filter", method = RequestMethod.POST)
	public @ResponseBody JQGridResponseDto<JerarquiaDto<ComunicacionPrl>> jerarquia(
			@RequestJsonBody(param = "filter") ComunicacionPrl filterComunicacionPrl,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		ComunicacionPrlController.logger.info(
				"[POST - jerarquia] : Obtener ComunicacionPrls jerarquia");
		return this.comunicacionPrlService.jerarquia(filterComunicacionPrl,
				jqGridRequestDto, false);
	}

	/**
	 * Recupera los hijos de los registros desplegados en la visualizacion
	 * jerarquica.
	 * 
	 * filterComunicacionPrl ComunicacionPrl Bean que contiene los parametros de
	 * filtrado a emplear. jqGridRequestDto Dto que contiene los parametros de
	 * configuracion propios del RUP_TABLE a aplicar en el filtrado.
	 * 
	 * @param filterComunicacionPrl
	 *            the filter comunicacion prl
	 * @param jqGridRequestDto
	 *            the jq grid request dto JQGridResponseDto<JerarquiaDto
	 *            <ComunicacionPrl>> Dto que contiene el resultado del filtrado
	 *            realizado por el componente RUP_TABLE.
	 * @return the JQ grid response dto
	 */
	@RequestMapping(value = "/jerarquiaChildren", method = RequestMethod.POST)
	public @ResponseBody JQGridResponseDto<JerarquiaDto<ComunicacionPrl>> jerarquiaChildren(
			@RequestJsonBody(param = "filter") ComunicacionPrl filterComunicacionPrl,
			@RequestJsonBody JQGridRequestDto jqGridRequestDto) {
		ComunicacionPrlController.logger.info(
				"[POST - jerarquia] : Obtener ComunicacionPrls jerarquia - Hijos");
		return this.comunicacionPrlService
				.jerarquiaChildren(filterComunicacionPrl, jqGridRequestDto);
	}

	/**
	 * AÃ±ade al model los datos necesarios para la carga de los combos de la
	 * pantalla del filtro de busqueda.
	 * 
	 * model Model
	 * 
	 * @param model
	 *            the model
	 */
	private void precargaCombosFiltroBusqueda(Model model) {

		model.addAttribute("autoridades",
				UtilSeguridad.getInstance().obtenerDelegacionesUsuario());

		model.addAttribute("autoridades2",
				UtilSeguridad.getInstance().obtenerTodasDelegaciones());

		// tipo identificacion
		model.addAttribute("tipoidentificacion", Constantes.COMBO_TIPO_IDENTIF);

		// Tareas Pendientes
		model.addAttribute("tareasPendientes",
				Constantes.COMBO_TAREAS_PENDIENTE_OS);

	}

	/**
	 * Buscar empresa.
	 * 
	 * tipoIdentif String numeroDocumento String
	 * 
	 * @param tipoIdentif
	 *            the tipo identif
	 * @param numeroDocumento
	 *            the numero documento Ramas
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "buscarEmpresa", method = RequestMethod.GET)
	public @ResponseBody() ComunicacionPrl buscarEmpresa(
			@RequestParam(value = "tipoIdentif") String tipoIdentif,
			@RequestParam(value = "numeroDocumento") String numeroDocumento) {
		ComunicacionPrl empresaFind = new ComunicacionPrl();
		empresaFind.setTipdoc(tipoIdentif);
		empresaFind.setNumdoc(numeroDocumento);
		empresaFind.setTipoos(Constantes.OS3);

		List<ComunicacionPrl> listaComunicacionesPrl = this.comunicacionPrlService
				.findEmpresa(empresaFind);

		if (listaComunicacionesPrl != null
				&& listaComunicacionesPrl.size() > 0) {
			return listaComunicacionesPrl.get(0);
		} else {

			throw new ErrorGenericoException("");
		}
	}

	/**
	 * Detalle OS 2.
	 * 
	 * teros String anoos String numos Long expCreadoOK Boolean modo String tab
	 * Integer model Model request HttpServletRequest
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param expCreadoOK
	 *            the exp creado OK
	 * @param modo
	 *            the modo
	 * @param tab
	 *            the tab
	 * @param model
	 *            the model
	 * @param request
	 *            the request String
	 * @return the string
	 */
	@RequestMapping(value = "/detalleOS2/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String detalleOS2(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			@RequestParam(required = false, value = "expCreadoOK") Boolean expCreadoOK,
			@RequestParam(required = false, value = "modo") String modo,
			@RequestParam(required = false, value = "tab") Integer tab,
			Model model, HttpServletRequest request) {

		ComunicacionPrl os2 = new ComunicacionPrl();
		os2.setTeros(teros);
		os2.setAnoos(anoos);
		os2.setNumos(numos.intValue());
		os2.setTipoos(Constantes.OS2);

		/**
		 * /** Accedemos al detalle pero con la información del filtro de
		 * expedientes
		 */
		DatosNavegacion datosNavegacion = ManejoSesion
				.getDatosNavegacion(request);
		JQGridRequestDto jQGridRequestDto = new JQGridRequestDto();
		jQGridRequestDto.setSidx(datosNavegacion.getCampoOrden());
		jQGridRequestDto.setSord(datosNavegacion.getOrden());
		// Si existe un filtro de tipo Expedientes se pasa como parámetro
		ComunicacionPrl filtro = null;
		if (datosNavegacion.getFiltro() != null && ComunicacionPrl.class
				.equals(datosNavegacion.getFiltro().getClass())) {
			filtro = (ComunicacionPrl) datosNavegacion.getFiltro();
		}

		os2 = this.comunicacionPrlService.findDetalle(os2, jQGridRequestDto,
				filtro);

		OS2 os2_reg = OS2.convertComunicacionPrltoOS2(os2);

		// Pestaña seleccionada
		Integer tabAux = tab;
		if (tab == null) {
			tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		}
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_TAB_DEFECTO,
				tabAux.toString());

		if (Utilities.getInstance().isEmpty(os2.getFolderId())
				&& (expCreadoOK == null || Boolean.FALSE.equals(expCreadoOK))
				&& Constantes.VALUE_NO.equals(os2.getMigrado())) {
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_ALTA);
			request.getSession().setAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_ALTA);

			// Al entrar en un expediente en modo ALTA, guardamos cuál era el
			// modo anterior,
			// para recuperarlo si cambiamos de expediente a través de los
			// botones anterior/siguiente
			if (request.getSession().getAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR) == null) {
				this.guardarModoAnterior(modo, request);
			}
		} else if (Constantes.ESTADO_CERRADO.equals(os2.getEstado())) {
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_CONSULTA);
			request.getSession().setAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_CONSULTA);
		} else {
			if (!Utilities.getInstance().isEmpty(modo)) {
				if ("C".equals(modo)) {
					model.addAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_CONSULTA);
					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_CONSULTA);
				} else if ("M".equals(modo)) {
					model.addAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_MANTENIMIENTO);
					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_MANTENIMIENTO);
				}

				else if ("S".equals(modo)) {

					os2_reg.setDeseaRegistrar060("");
					os2_reg.setNumReg060(null);
					os2_reg.setFecReg060(null);
					this.os2Service.modificarDatosRegistro(os2_reg);
					model.addAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_SUBSANACION);
					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_SUBSANACION);
				}
				// Si viene por aquí es que viene de un expediente en modo ALTA
				// a través de los botones anterior/siguiente,
				// hay que recuperar cuál era el modo anterior a entrar en dicho
				// expediente en modo ALTA
				else if (Constantes.MODO_ACCESO_ALTA.equals(modo)) {

					model.addAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							request.getSession().getAttribute(
									ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR));
					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							request.getSession().getAttribute(
									ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR));

					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR,
							null);
				}
			}
		}

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		// Metemos la entidad Comunicación de apertura al modelo
		request.getSession().setAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		if (expCreadoOK != null && Boolean.TRUE.equals(expCreadoOK)) {
			model.addAttribute("feedback", Constantes.EXPEDIENTE_CREADO_OK);

			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_MANTENIMIENTO);
			request.getSession().setAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_MANTENIMIENTO);
		}

		return "comunicacionPrlOS2Form";
	}

	/**
	 * Al entrar en un expediente en modo ALTA, guardamos cuál era el modo
	 * anterior, para recuperarlo si cambiamos de expediente a través de los
	 * botones anterior/siguiente
	 * 
	 * @param modoAux
	 *            String
	 * @param request
	 *            the request
	 */
	private void guardarModoAnterior(String modoAux,
			HttpServletRequest request) {

		if ("C".equals(modoAux)) {
			modoAux = Constantes.MODO_ACCESO_CONSULTA;
		} else if ("M".equals(modoAux)) {
			modoAux = Constantes.MODO_ACCESO_MANTENIMIENTO;
		} else if ("S".equals(modoAux)) {
			modoAux = Constantes.MODO_ACCESO_SUBSANACION;
		}

		request.getSession().setAttribute(
				ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR,
				modoAux);
	}

	/**
	 * Detalle OS 3.
	 * 
	 * teros String anoos String numos Long expCreadoOK Boolean modo String tab
	 * Integer model Model request HttpServletRequest
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param expCreadoOK
	 *            the exp creado OK
	 * @param modo
	 *            the modo
	 * @param tab
	 *            the tab
	 * @param model
	 *            the model
	 * @param request
	 *            the request String
	 * @return the string
	 */
	@RequestMapping(value = "/detalleOS3/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String detalleOS3(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			@RequestParam(required = false, value = "expCreadoOK") Boolean expCreadoOK,
			@RequestParam(required = false, value = "modo") String modo,
			@RequestParam(required = false, value = "tab") Integer tab,
			Model model, HttpServletRequest request) {

		ComunicacionPrl os3 = new ComunicacionPrl();
		os3.setTeros(teros);
		os3.setAnoos(anoos);
		os3.setNumos(numos.intValue());
		os3.setTipoos(Constantes.OS3);

		/**
		 * /** Accedemos al detalle pero con la información del filtro de
		 * expedientes
		 */
		DatosNavegacion datosNavegacion = ManejoSesion
				.getDatosNavegacion(request);
		JQGridRequestDto jQGridRequestDto = new JQGridRequestDto();
		jQGridRequestDto.setSidx(datosNavegacion.getCampoOrden());
		jQGridRequestDto.setSord(datosNavegacion.getOrden());
		// Si existe un filtro de tipo Expedientes se pasa como parámetro
		ComunicacionPrl filtro = null;
		if (datosNavegacion.getFiltro() != null && ComunicacionPrl.class
				.equals(datosNavegacion.getFiltro().getClass())) {
			filtro = (ComunicacionPrl) datosNavegacion.getFiltro();
		}

		os3 = this.comunicacionPrlService.findDetalle(os3, jQGridRequestDto,
				filtro);

		OS3 os3_reg = OS3.convertComunicacionPrltoOS3(os3);

		// Pestaña seleccionada
		Integer tabAux = tab;
		if (tab == null) {
			tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		}
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_TAB_DEFECTO,
				tabAux.toString());

		if (Utilities.getInstance().isEmpty(os3.getFolderId())
				&& (expCreadoOK == null || Boolean.FALSE.equals(expCreadoOK))
				&& Constantes.VALUE_NO.equals(os3.getMigrado())) {
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_ALTA);
			request.getSession().setAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_ALTA);

			// Al entrar en un expediente en modo ALTA, guardamos cuál era el
			// modo anterior,
			// para recuperarlo si cambiamos de expediente a través de los
			// botones anterior/siguiente
			if (request.getSession().getAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR) == null) {
				this.guardarModoAnterior(modo, request);
			}

		} else if (Constantes.ESTADO_CERRADO.equals(os3.getEstado())) {
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_CONSULTA);
			request.getSession().setAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_CONSULTA);
		} else {

			if (!Utilities.getInstance().isEmpty(modo)) {
				if ("C".equals(modo)) {
					model.addAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_CONSULTA);
					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_CONSULTA);
				} else if ("M".equals(modo)) {
					model.addAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_MANTENIMIENTO);
					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_MANTENIMIENTO);
				}

				else if ("S".equals(modo)) {

					os3_reg.setDeseaRegistrar061("");
					os3_reg.setNumReg061(null);
					os3_reg.setFecReg061(null);
					this.os3Service.modificarDatosRegistro(os3_reg);
					model.addAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_SUBSANACION);
					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							Constantes.MODO_ACCESO_SUBSANACION);
				}
				// Si viene por aquí es que viene de un expediente en modo ALTA
				// a través de los botones anterior/siguiente,
				// hay que recuperar cuál era el modo anterior a entrar en dicho
				// expediente en modo ALTA
				else if (Constantes.MODO_ACCESO_ALTA.equals(modo)) {

					model.addAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							request.getSession().getAttribute(
									ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR));
					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
							request.getSession().getAttribute(
									ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR));

					request.getSession().setAttribute(
							ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO_ANTERIOR,
							null);
				}
			}
		}

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				os3);

		// Metemos la entidad Comunicación de apertura al modelo
		request.getSession().setAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				os3);

		if (expCreadoOK != null && Boolean.TRUE.equals(expCreadoOK))

		{
			model.addAttribute("feedback", Constantes.EXPEDIENTE_CREADO_OK);

			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_MANTENIMIENTO);
			request.getSession().setAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					Constantes.MODO_ACCESO_MANTENIMIENTO);
		}

		return "comunicacionPrlOS3Form";
	}

	/**
	 * Gets the tab datos notificacion OS 2.
	 * 
	 * model Model teros String anoos String numos Long request
	 * HttpServletRequest
	 * 
	 * @param model
	 *            the model
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param request
	 *            the request String
	 * @return the tab datos notificacion OS 2
	 */
	@RequestMapping(value = "/OS2/tabDatosNotificacionOS2/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String getTabDatosNotificacionOS2(Model model,
			@PathVariable() String teros, @PathVariable() String anoos,
			@PathVariable() Long numos, HttpServletRequest request) {

		ComunicacionPrl os2 = new ComunicacionPrl();
		os2.setTeros(teros);
		os2.setAnoos(anoos);
		os2.setNumos(numos.intValue());
		os2.setTipoos(Constantes.OS2);

		os2 = this.comunicacionPrlService
				.findComunicacionPrlConNotificacion(os2);
		OS2 os2_reg = OS2.convertComunicacionPrltoOS2(os2);

		// Preparo la configuración de las opciones de tramitación
		String modoAcceso = (String) request.getSession().getAttribute(
				ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO);

		if (Constantes.MODO_ACCESO_ALTA.equals(modoAcceso)
				|| Constantes.MODO_ACCESO_SUBSANACION.equals(modoAcceso)) {
			os2_reg = this.os2Service.findDatosRegistro(os2_reg);
			os2.setDeseaRegistrar(os2_reg.getDeseaRegistrar060());
			os2.setNumReg(os2_reg.getNumReg060());
			os2.setFecReg(os2_reg.getFecReg060());
		}

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		// tipo identificacion
		model.addAttribute("tipoidentificacion", Constantes.COMBO_TIPO_IDENTIF);

		HttpSession session = request.getSession();
		if (session != null) {
			session.setAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
					os2);
		}

		// Preparo la configuración de las opciones de tramitación
		String toolbarNotificacion = this.preparaToolbar(os2, "");
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_NOTIFICACION,
				toolbarNotificacion);

		model.addAttribute(ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
				modoAcceso);

		return "tabDatosNotificacionOS2";
	}

	/**
	 * Gets the lista datos aviso OS 2.
	 * 
	 * jqGridRequestDto JQGridRequestDto model Model request HttpServletRequest
	 * 
	 * @param jqGridRequestDto
	 *            the jq grid request dto
	 * @param model
	 *            the model
	 * @param request
	 *            the request String
	 * @return the lista datos aviso OS 2
	 */
	@RequestMapping(value = "/OS2/tabDatosNotificacionOS2/datosAviso/filter", method = RequestMethod.POST)
	public @ResponseBody() JQGridResponseDto<DatosAviso> getListaDatosAvisoOS2(
			@RequestJsonBody() JQGridRequestDto jqGridRequestDto, Model model,
			HttpServletRequest request) {

		HttpSession session = request.getSession();
		DatosAviso filterDatosAviso = new DatosAviso();

		ComunicacionPrl comunicPrlSess = new ComunicacionPrl();
		if (session != null) {
			comunicPrlSess = (ComunicacionPrl) session.getAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE);

			filterDatosAviso.setDatosNotificacion(
					comunicPrlSess.getDatosNotificacion());
		}

		return this.datosAvisoService.filter(filterDatosAviso, jqGridRequestDto,
				false);
	}

	/**
	 * Operacion CRUD Create. Creacion de un nuevo registro a partir del bean
	 * indicado.
	 * 
	 * datosAviso DatosAviso Bean que contiene la informacion con la que se va a
	 * crear el nuevo registro. request HttpServletRequest
	 * 
	 * @param datosAviso
	 *            the datos aviso
	 * @param request
	 *            the request SolPersonas Bean resultante del proceso de
	 *            creacion.
	 * @return the datos aviso
	 */
	@RequestMapping(value = "/OS2/tabDatosNotificacionOS2/datosAviso", method = RequestMethod.POST)
	public @ResponseBody() DatosAviso addDatosAvisoOS2(
			@RequestBody() DatosAviso datosAviso, HttpServletRequest request) {

		HttpSession session = request.getSession();
		ComunicacionPrl comunicPrlSess = new ComunicacionPrl();
		if (session != null) {
			comunicPrlSess = (ComunicacionPrl) session.getAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE);

			if (comunicPrlSess.getDatosNotificacion() != null) {
				datosAviso.setDatosNotificacion(
						comunicPrlSess.getDatosNotificacion());

			}
		}

		DatosAviso datosAvisoAux = this.datosAvisoService.add(datosAviso);
		ComunicacionPrlController.logger
				.info("[POST] : DatosAviso insertado correctamente");
		return datosAvisoAux;
	}

	/**
	 * Operacion CRUD Delete. Borrado del registro correspondiente al
	 * identificador especificado.
	 * 
	 * idDatoAviso068 Integer Identificador del objeto que se desea eliminar.
	 * 
	 * request HttpServletRequest
	 * 
	 * @param idDatoAviso068
	 *            the id dato aviso 068
	 * @param request
	 *            the request SolPersonas Bean eliminado.
	 * @return the datos aviso
	 */
	@RequestMapping(value = "/OS2/tabDatosNotificacionOS2/datosAviso/{idDatoAviso068}", method = RequestMethod.DELETE)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody() DatosAviso removeSolicitudOS2(
			@PathVariable() Long idDatoAviso068, HttpServletRequest request) {

		DatosAviso datosAvisoBorrar = new DatosAviso(idDatoAviso068);
		this.datosAvisoService.remove(datosAvisoBorrar);

		return datosAvisoBorrar;
	}

	/**
	 * Tab datos empresa OS 2.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/OS2/tabDatosEmpresaOS2/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabDatosEmpresaOS2(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model) {

		ComunicacionPrl os2 = new ComunicacionPrl();
		os2.setTeros(teros);
		os2.setAnoos(anoos);
		os2.setNumos(numos.intValue());
		os2.setTipoos(Constantes.OS2);
		os2 = this.comunicacionPrlService
				.findComunicacionPrlConNotificacion(os2);

		this.precargaCombosFiltroBusqueda(model);

		// Pestaña seleccionada
		// Integer tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// if (tab == null) {
		// tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// }
		// model.addAttribute(
		// ComunicacionPrlController.ATTR_NAME_COMUNICAPERTURA_TAB_DEFECTO,
		// tabAux.toString());

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		// Preparo la configuración de las opciones de tramitación
		String toolbarEmpresa = this.preparaToolbar(os2, "");
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_EMPRESA,
				toolbarEmpresa);

		return "tabDatosEmpresaOS2";
	}

	/**
	 * Tab tramtiacion OS 2.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/OS2/tabTramitacionOS2/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabTramtiacionOS2(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model) {

		ComunicacionPrl cprl = new ComunicacionPrl();
		cprl.setTeros(teros);
		cprl.setAnoos(anoos);
		cprl.setNumos(numos.intValue());
		cprl.setTipoos(Constantes.OS2);
		cprl = this.comunicacionPrlService.find(cprl);

		OS2 os2 = OS2.convertComunicacionPrltoOS2(cprl);

		// cargamos lista tareas
		TareaOS2 filterTarea = new TareaOS2();
		TramiteOS2 filterTramite = new TramiteOS2();
		filterTramite.setos2(os2);
		filterTarea.setTramiteOS2(filterTramite);
		List<TareaOS2> listaTareas = this.tareaOS2Service
				.findAllTareatramite(filterTarea, null);

		revisarErrorTareaOS2(listaTareas);

		os2.setListaTareas(listaTareas);

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		// comprobamos si no hay tareas pendientes, para mostrar el botón cerrar
		// expediente.
		boolean cerrarExp = true;
		boolean crearEstudio = true;
		boolean abrirExpediente = false;
		for (TareaOS2 tarea : listaTareas) {
			if (!EstadosTareas.EJECUTADA.getEstado()
					.equals(tarea.getEstado093())) {
				cerrarExp = true;

				if (TipoTareaFlujo.ESTUDIO
						.esEquivalente(tarea.getTipoTarea().getTaskId090())) {
					crearEstudio = false;
				}

			}
		}

		// comprobamos si el expediente está en estado='S' (no se ha abierto
		// correctamente),
		// para poner el botón 'Abrir Expediente'
		if (os2.getEstado060() != null && os2.getEstado060().equals("S")) {
			cerrarExp = false;
			crearEstudio = false;
			// comprobar si han pasado por lo menos 5 minutos desde que se ha
			// puesto en estado='S'
			Date now = new Date();
			Long diff = 0L;
			if (os2.getFecpre060() != null) {
				diff = now.getTime() - os2.getFecpre060().getTime();
			}
			if (diff > ComunicacionPrlController.MIN_WAIT_REOPEN) {
				abrirExpediente = true;
			} else {
				abrirExpediente = false;
			}
		}

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_CERRAR_EXPEDIENTE,
				cerrarExp);

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_CREAR_ESTUDIO,
				crearEstudio);

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPERTURA_ABRIR_EXPEDIENTE,
				abrirExpediente);

		// Preparo la configuración de las opciones de tramitación
		String toolbarTramitacion = "";
		try {
			// TODO obtener el modo acceso en función del usuario
			toolbarTramitacion = this.preparaToolbarTramitacion(
					Constantes.MODO_ACCESO_MANTENIMIENTO);
		} catch (Exception e) {
			ComunicacionPrlController.logger
					.error("Error al generar el toolbar de tramitacion", e);
			toolbarTramitacion = "{buttons: []}";
		}
		model.addAttribute(
				ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_TOOLBAR_TRAMITACION,
				toolbarTramitacion);

		return "tabTramitacionOS2";
	}

	private void revisarErrorTareaOS2(List<TareaOS2> listaTareas) {
		String error = "";
		String tipoTarea = "";
		TareaOS2 tarea = null;
		TareaOS2 tareaRelanzar = null;
		Collections.reverse(listaTareas);
		for (int i = 0; i < listaTareas.size(); i++) {
			tarea = listaTareas.get(i);
			if (tarea.getError() != null) {
				tipoTarea = tarea.getTipoTarea().getTaskId090();
				error = tarea.getError();
				if ((i + 1) < listaTareas.size()) {
					tareaRelanzar = listaTareas.get(i + 1);
					if (tareaRelanzar.getEstado093() == EstadosTareas.INICIADA
							.getEstado()
							&& tareaRelanzar.getTipoTarea().getTaskId090()
									.equals(tipoTarea)) {
						tareaRelanzar.setRelanzar("si");
						tareaRelanzar.setError(error);
					}
				}

			}
		}
		Collections.reverse(listaTareas);

	}

	/**
	 * Tab datos modalidad.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/OS2/tabDatosModalidad/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabDatosModalidad(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model) {

		ComunicacionPrl os2 = new ComunicacionPrl();
		os2.setTeros(teros);
		os2.setAnoos(anoos);
		os2.setNumos(numos.intValue());
		os2.setTipoos(Constantes.OS2);
		os2 = this.comunicacionPrlService.find(os2);

		// Pestaña seleccionada
		// Integer tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// if (tab == null) {
		// tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// }
		// model.addAttribute(
		// ComunicacionPrlController.ATTR_NAME_COMUNICAPERTURA_TAB_DEFECTO,
		// tabAux.toString());

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		// Preparo la configuración de las opciones de tramitación
		String toolbarModalidad = this.preparaToolbar(os2, "");
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_MODALIDAD,
				toolbarModalidad);

		return "tabDatosModalidad";
	}

	/**
	 * Tab datos auditoria.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/OS2/tabDatosAuditoria/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabDatosAuditoria(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model) {

		ComunicacionPrl os2 = new ComunicacionPrl();
		os2.setTeros(teros);
		os2.setAnoos(anoos);
		os2.setNumos(numos.intValue());
		os2.setTipoos(Constantes.OS2);
		os2 = this.comunicacionPrlService.find(os2);

		// Pestaña seleccionada
		// Integer tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// if (tab == null) {
		// tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// }
		// model.addAttribute(
		// ComunicacionPrlController.ATTR_NAME_COMUNICAPERTURA_TAB_DEFECTO,
		// tabAux.toString());

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		// Preparo la configuración de las opciones de tramitación
		String toolbarAuditoria = this.preparaToolbar(os2, "");
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_AUDITORIA,
				toolbarAuditoria);

		return "tabDatosAuditoria";
	}

	/**
	 * Tab datos estado OS 2.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/OS2/tabDatosEstadoOS2/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabDatosEstadoOS2(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model) {

		ComunicacionPrl os2 = new ComunicacionPrl();
		os2.setTeros(teros);
		os2.setAnoos(anoos);
		os2.setNumos(numos.intValue());
		os2.setTipoos(Constantes.OS2);
		os2 = this.comunicacionPrlService.find(os2);

		// Pestaña seleccionada
		// Integer tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// if (tab == null) {
		// tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// }
		// model.addAttribute(
		// ComunicacionPrlController.ATTR_NAME_COMUNICAPERTURA_TAB_DEFECTO,
		// tabAux.toString());

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		// Preparo la configuración de las opciones de tramitación
		String toolbarEstado = this.preparaToolbar(os2, "");
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_ESTADO,
				toolbarEstado);

		return "tabDatosEstadoOS2";
	}

	/**
	 * Tab documentos OS 2.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * 
	 * @param request
	 *            the request
	 * @return the string
	 */
	@RequestMapping(value = "/OS2/tabDocumentosOS2/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabDocumentosOS2(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model, HttpServletRequest request) {

		ComunicacionPrlController.logger.info("Entra en getTabDocumentos");

		String iframe = (String) request.getParameter("iframe");

		String modoAcceso = "";

		if (iframe == null) {
			modoAcceso = (String) request.getSession().getAttribute(
					ComunicacionPrlController.ATTR_NAME_MODO_ACCESO);
		} else {
			modoAcceso = Constantes.MODO_ACCESO_CONSULTA;
		}

		// cargamos comunicacionprl
		ComunicacionPrl os2 = new ComunicacionPrl();
		os2.setTeros(teros);
		os2.setAnoos(anoos);
		os2.setNumos(numos.intValue());
		os2.setTipoos(Constantes.OS2);
		os2 = this.comunicacionPrlService.find(os2);

		// String modoAcceso = Constantes.MODO_ACCESO_MANTENIMIENTO;
		// Cargamos la lista de trámites

		List<TramiteOS2> listaTramites = new ArrayList<TramiteOS2>();
		List<DocumentoOS2> listaDocs = new ArrayList<DocumentoOS2>();
		TipoDocumento tipoDoc = null;
		try {
			if (Constantes.MODO_ACCESO_ALTA.equals(modoAcceso)
					|| Constantes.MODO_ACCESO_MANTENIMIENTO.equals(modoAcceso)
					|| Constantes.MODO_ACCESO_SUBSANACION.equals(modoAcceso)) {
				DocumentoOS2 filterDoc = new DocumentoOS2();
				TramiteOS2 tramite = new TramiteOS2(null, null,
						new OS2(teros, anoos, numos.intValue()));
				filterDoc.setTramiteOS2(tramite);

				tipoDoc = new TipoDocumento();
				// Aportado o generado?
				tipoDoc.setAportGen091(Constantes.TIPO_DOCUMENTO_APORTADO);
				filterDoc.setTipoDocumento(tipoDoc);
				listaDocs = this.os2Service
						.findAllDocumentosOS2TipoTemp(filterDoc);

				// TramiteOS2 tramite = new TramiteOS2();
				tramite.setListaDocumentos(listaDocs);
				listaTramites.add(tramite);

			} else if (Constantes.MODO_ACCESO_CONSULTA.equals(modoAcceso)) {
				if (os2.getMigrado().equals("N")) {
					TramiteOS2 filterTramite = new TramiteOS2(null, null,
							new OS2(teros, anoos, numos.intValue()));

					JQGridRequestDto jqGridTramites = new JQGridRequestDto();
					jqGridTramites.setSidx("ID_TRAMITE_092");
					jqGridTramites.setSord("ASC");
					// Cargamos los documentos de cada trámite
					listaTramites = this.tramiteOS2Service
							.findAll(filterTramite, jqGridTramites);

					for (TramiteOS2 tramite : listaTramites) {
						DocumentoOS2 filterDoc = new DocumentoOS2();
						filterDoc.setTramiteOS2(tramite);
						tipoDoc = new TipoDocumento();
						filterDoc.setTipoDocumento(tipoDoc);
						// listaDocs = this.os2Service.findAll(filterDoc);
						listaDocs = this.documentoOS2Service.findAll(filterDoc,
								null);

						tramite.setListaDocumentos(listaDocs);
					}
				} else {

					FolderDocumentList fdl = os2Service
							.obtenerDocumentosMigrados(os2.getFolderId());

					Iterator<FolderDoc> iaportado = fdl
							.getContributedDocumentList().getFolderDoc()
							.iterator();

					listaDocs = new ArrayList<DocumentoOS2>();

					TramiteOS2 tramiteaOs22 = new TramiteOS2();
					Tramite tramite2 = new Tramite();
					tramite2.setDescripcionEs089("Documentos Aportados");
					tramite2.setDescripcionEu089("Aurkeztutako Dokumentuak");
					tramiteaOs22.setTipoTramite(tramite2);

					SimpleDateFormat sdf = new SimpleDateFormat(
							"dd-MM-yyyy HH:mm:ss");

					while (iaportado.hasNext()) {
						FolderDoc fdaporado = iaportado.next();

						Iterator<DocumentStorageInfo> dsiterator2 = fdaporado
								.getDocumentStorageList()
								.getDocumentStorageInfo().iterator();

						while (dsiterator2.hasNext()) {

							DocumentStorageInfo dsi2 = dsiterator2.next();
							DocumentoOS2 daporado = new DocumentoOS2();
							daporado.setNombreDoc094(dsi2.getSourceName());

							daporado.setFechaDoc094(sdf.parse(fdaporado
									.getRegistrySubmissionTimeStamp()));
							daporado.setOidDokusi094(dsi2.getDocOID());

							String formato = "E";
							if (!dsi2.getFormat().equals("")) {
								formato = dsi2.getFormat();
							}

							daporado.setFormatoAport094(formato);
							daporado.setOrigen094(0);

							TipoDocumento tipo = new TipoDocumento();

							ElementNSImpl object = (ElementNSImpl) dsi2
									.getRoleName();

							String des_eu = object.getFirstChild()
									.getFirstChild().getFirstChild()
									.getNodeValue();
							String des_es = object.getFirstChild()
									.getFirstChild().getNextSibling()
									.getFirstChild().getNodeValue();

							tipo.setDescripcionEu091(des_eu);
							tipo.setDescripcionEs091(des_es);

							daporado.setTipoDocumento(tipo);
							// daporado.setMigrado(true);

							listaDocs.add(daporado);
						}
					}

					tramiteaOs22.setListaDocumentos(listaDocs);
					listaTramites.add(tramiteaOs22);

				}
			}
			// apertura.setListaTramites(listaTramites);
			os2.setListaTramitesOs2(listaTramites);
		} catch (Exception e) {
			ComunicacionPrlController.logger
					.error("ERROR tabDocumentos " + e.getMessage());
		}
		model.addAttribute(ComunicacionPrlController.ATTR_NAME_MODO_ACCESO,
				modoAcceso);
		if (iframe == null) {
			request.getSession().setAttribute(
					ComunicacionPrlController.ATTR_NAME_MODO_ACCESO,
					modoAcceso);
		}

		model.addAttribute("iframe", iframe);

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		// Cargamos la URL de descarga del applet de digitalizacion
		model.addAttribute("urlappletdigitalizacion",
				PropertiesUtil.getProperty(PropertiesUtil.URL_DESCARGA_APPLET));

		// territorio para serie documental
		request.getSession().setAttribute("terape", os2.getTeros());
		// tipo de documento para la digitalización
		request.getSession().setAttribute("docType", Constantes.OS2);

		// Preparo la configuración de las opciones de tramitación
		String toolbarDocumentos = this.preparaToolbar(os2, modoAcceso);
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_TOOLBAR_DOCUMENTOS_REG,
				toolbarDocumentos);

		return "tabDocumentosOS2";
	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * deseaReg String numReg String fecReg Date request HttpServletRequest
	 * model Model String
	 * 
	 * @param deseaReg
	 *            the desea reg
	 * @param numReg
	 *            the num reg
	 * @param fecReg
	 *            the fec reg
	 * @param request
	 *            the request
	 * @param model
	 *            the model the string
	 * @return the string
	 */
	@RequestMapping(value = "/tabDocumentosOS3/modificar", method = RequestMethod.GET)
	public @ResponseBody() String modificarTabDocumentosOS3(
			@RequestParam(value = "deseaReg", required = false) String deseaReg,
			@RequestParam(value = "numReg", required = false) String numReg,
			@RequestParam(value = "fecReg", required = false) Date fecReg,
			HttpServletRequest request, Model model) {

		ComunicacionPrl comunicPrlSess = new ComunicacionPrl();
		String modoAcceso = "";
		HttpSession session = request.getSession();
		if (session != null) {
			comunicPrlSess = (ComunicacionPrl) session.getAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE);
			modoAcceso = (String) request.getSession().getAttribute(
					ComunicacionPrlController.ATTR_NAME_MODO_ACCESO);

		}

		ComunicacionPrl cprl = this.comunicacionPrlService
				.findDetalle(comunicPrlSess, null, null);

		// Obtenemos la lista de los documentos antiguos
		OS3 os3 = OS3.convertComunicacionPrltoOS3(cprl);

		List<ErrorField> errores = new ArrayList<ErrorField>();
		if (Constantes.MODO_ACCESO_MANTENIMIENTO.equals(modoAcceso)
				&& Constantes.VALUE_NO.equals(deseaReg)) {
			if (Utilities.getInstance().isEmpty(numReg)) {
				errores.add(new ErrorField("aperturas.detalle.numReg",
						"validacion.obligatorio"));
			}
			if (fecReg == null) {
				errores.add(new ErrorField("aperturas.detalle.fecReg",
						"validacion.obligatorio"));
			}
		}

		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		cprl.setDeseaRegistrar(deseaReg);
		cprl.setNumReg(numReg);
		cprl.setFecReg(fecReg);

		// recoger de la tabla temporal
		DocumentoOS3 docFilter = new DocumentoOS3();
		docFilter.setTramiteOS3(new TramiteOS3(null, null, os3));

		try {
			List<DocumentoOS3> listaDocumentos = this.copiarDocsR02GOS3(
					cprl.getTeros(), cprl.getAnoos(), cprl.getNumos(), false);
			ContextSubmission contextSubmission = this.ppsAportacionOS3Service
					.crearContextSubmission(false, os3, listaDocumentos);

			this.ppsAportacionOS3Service
					.enviarAportacionPresencial(contextSubmission);
			// PPSReturnInfo ppsReturnInfo = PPSUtils.getInstance()
			// .obtenerPPSReturnInfo(requestReturn);

		} catch (Exception e) {
			this.documentoOS3Service.removeTempByApertura(docFilter);
			errores.add(
					new ErrorField("comunicacion.apertura", "error.apertura"));
			throw new ErrorGenericoException(errores);
		}

		model.addAttribute(ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
				modoAcceso);

		return "ok";

	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * deseaReg String numReg String fecReg Date request HttpServletRequest
	 * model Model String
	 * 
	 * @param deseaReg
	 *            the desea reg
	 * @param numReg
	 *            the num reg
	 * @param fecReg
	 *            the fec reg
	 * @param request
	 *            the request
	 * @param model
	 *            the model the string
	 * @return the string
	 */
	@RequestMapping(value = "/tabDocumentosOS3/guardarInforme", method = RequestMethod.GET)
	public @ResponseBody() String guardarInformeOS3(HttpServletRequest request,
			Model model) {

		/*
		 * ComunicacionApertura comunicAperturaSess = new
		 * ComunicacionApertura();
		 * 
		 * HttpSession session = request.getSession(); if (session != null) {
		 * comunicAperturaSess = (ComunicacionApertura) session.getAttribute(
		 * ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_DETALLE);
		 * 
		 * }
		 * 
		 * ComunicacionApertura apertura = this.comunicAperturaService
		 * .findDetalle(comunicAperturaSess, null, null);
		 * 
		 * try {
		 * 
		 * apertura.setUsuarioTram(UtilSeguridad.getInstance()
		 * .getUserCredentials().getPosition());
		 * this.comunicAperturaService.updateUsuariosTramitacion(apertura);
		 * 
		 * this.plateaTramitacionService.crearTarea(
		 * Utilities.getInstance().obtenerProcedureIdApertura(),
		 * TipoTramiteFlujo.ADJUNTAR_INFORME_INSPECCION.name(),
		 * TipoTareaFlujo.ADJUNTAR_INFORME_INSPECCION.getTaskId(),
		 * apertura.getFolderId056(),
		 * UtilSeguridad.getInstance().getUserCredentials() .getPosition(),
		 * UtilSeguridad.getInstance().getNombre());
		 * 
		 * // Metemos la entidad Comunicación de apertura al modelo
		 * model.addAttribute(
		 * ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_DETALLE,
		 * apertura);
		 * 
		 * } catch (Exception e) { DocumentoAperturas docFilter = new
		 * DocumentoAperturas();
		 * docFilter.setIdapetemp065(apertura.getIdape056());
		 * 
		 * // borrar los temporales
		 * this.documentosAperturasTempDao.removeByIdApertura(docFilter); return
		 * "ko"; }
		 */

		return "ok";

	}

	/**
	 * Gets the tab datos notificacion OS 3.
	 * 
	 * model Model teros String anoos String numos Long request
	 * HttpServletRequest
	 * 
	 * @param model
	 *            the model
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param request
	 *            the request String
	 * @return the tab datos notificacion OS 3
	 */
	@RequestMapping(value = "/OS3/tabDatosNotificacionOS3/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String getTabDatosNotificacionOS3(Model model,
			@PathVariable() String teros, @PathVariable() String anoos,
			@PathVariable() Long numos, HttpServletRequest request) {

		ComunicacionPrl os3 = new ComunicacionPrl();
		os3.setTeros(teros);
		os3.setAnoos(anoos);
		os3.setNumos(numos.intValue());
		os3.setTipoos(Constantes.OS3);

		os3 = this.comunicacionPrlService
				.findComunicacionPrlConNotificacion(os3);

		OS3 os3_reg = OS3.convertComunicacionPrltoOS3(os3);

		// Preparo la configuración de las opciones de tramitación
		String modoAcceso = (String) request.getSession().getAttribute(
				ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO);

		if (Constantes.MODO_ACCESO_ALTA.equals(modoAcceso)
				|| Constantes.MODO_ACCESO_SUBSANACION.equals(modoAcceso)) {
			os3_reg = this.os3Service.findDatosRegistro(os3_reg);
			os3.setDeseaRegistrar(os3_reg.getDeseaRegistrar061());
			os3.setNumReg(os3_reg.getNumReg061());
			os3.setFecReg(os3_reg.getFecReg061());
		}

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				os3);

		// tipo identificacion
		model.addAttribute("tipoidentificacion", Constantes.COMBO_TIPO_IDENTIF);

		HttpSession session = request.getSession();
		if (session != null) {
			session.setAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
					os3);
		}

		// Preparo la configuración de las opciones de tramitación
		String toolbarNotificacion = this.preparaToolbar(os3, "");
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_NOTIFICACION,
				toolbarNotificacion);

		model.addAttribute(ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
				modoAcceso);

		return "tabDatosNotificacionOS3";
	}

	/**
	 * Gets the lista datos aviso OS 3.
	 * 
	 * jqGridRequestDto JQGridRequestDto model Model request HttpServletRequest
	 * 
	 * @param jqGridRequestDto
	 *            the jq grid request dto
	 * @param model
	 *            the model
	 * @param request
	 *            the request String
	 * @return the lista datos aviso OS 3
	 */
	@RequestMapping(value = "/OS3/tabDatosNotificacionOS3/datosAviso/filter", method = RequestMethod.POST)
	public @ResponseBody() JQGridResponseDto<DatosAviso> getListaDatosAvisoOS3(
			@RequestJsonBody() JQGridRequestDto jqGridRequestDto, Model model,
			HttpServletRequest request) {

		HttpSession session = request.getSession();
		DatosAviso filterDatosAviso = new DatosAviso();

		ComunicacionPrl comunicPrlSess = new ComunicacionPrl();
		if (session != null) {
			comunicPrlSess = (ComunicacionPrl) session.getAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE);

			filterDatosAviso.setDatosNotificacion(
					comunicPrlSess.getDatosNotificacion());
		}

		return this.datosAvisoService.filter(filterDatosAviso, jqGridRequestDto,
				false);
	}

	/**
	 * Operacion CRUD Create. Creacion de un nuevo registro a partir del bean
	 * indicado.
	 * 
	 * datosAviso DatosAviso Bean que contiene la informacion con la que se va a
	 * crear el nuevo registro. request HttpServletRequest
	 * 
	 * @param datosAviso
	 *            the datos aviso
	 * @param request
	 *            the request SolPersonas Bean resultante del proceso de
	 *            creacion.
	 * @return the datos aviso
	 */
	@RequestMapping(value = "/OS3/tabDatosNotificacionOS3/datosAviso", method = RequestMethod.POST)
	public @ResponseBody() DatosAviso addDatosAvisoOS3(
			@RequestBody() DatosAviso datosAviso, HttpServletRequest request) {

		HttpSession session = request.getSession();
		ComunicacionPrl comunicPrlSess = new ComunicacionPrl();
		if (session != null) {
			comunicPrlSess = (ComunicacionPrl) session.getAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE);

			if (comunicPrlSess.getDatosNotificacion() != null) {
				datosAviso.setDatosNotificacion(
						comunicPrlSess.getDatosNotificacion());

			}
		}

		DatosAviso datosAvisoAux = this.datosAvisoService.add(datosAviso);
		ComunicacionPrlController.logger
				.info("[POST] : DatosAviso insertado correctamente");
		return datosAvisoAux;
	}

	/**
	 * Operacion CRUD Delete. Borrado del registro correspondiente al
	 * identificador especificado.
	 * 
	 * idDatoAviso068 Integer Identificador del objeto que se desea eliminar.
	 * 
	 * request HttpServletRequest
	 * 
	 * @param idDatoAviso068
	 *            the id dato aviso 068
	 * @param request
	 *            the request SolPersonas Bean eliminado.
	 * @return the datos aviso
	 */
	@RequestMapping(value = "/OS3/tabDatosNotificacionOS3/datosAviso/{idDatoAviso068}", method = RequestMethod.DELETE)
	@ResponseStatus(value = HttpStatus.OK)
	public @ResponseBody() DatosAviso removeSolicitudOS3(
			@PathVariable() Long idDatoAviso068, HttpServletRequest request) {

		DatosAviso datosAvisoBorrar = new DatosAviso(idDatoAviso068);
		this.datosAvisoService.remove(datosAvisoBorrar);

		return datosAvisoBorrar;
	}

	/**
	 * Tab datos empresa OS 3.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/OS3/tabDatosEmpresaOS3/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabDatosEmpresaOS3(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model) {

		ComunicacionPrl os3 = new ComunicacionPrl();
		os3.setTeros(teros);
		os3.setAnoos(anoos);
		os3.setNumos(numos.intValue());
		os3.setTipoos(Constantes.OS3);
		os3 = this.comunicacionPrlService
				.findComunicacionPrlConNotificacion(os3);

		this.precargaCombosFiltroBusqueda(model);

		// Pestaña seleccionada
		// Integer tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// if (tab == null) {
		// tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// }
		// model.addAttribute(
		// ComunicacionPrlController.ATTR_NAME_COMUNICAPERTURA_TAB_DEFECTO,
		// tabAux.toString());

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				os3);

		// Preparo la configuración de las opciones de tramitación
		String toolbarEmpresa = this.preparaToolbar(os3, "");
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_EMPRESA,
				toolbarEmpresa);

		return "tabDatosEmpresaOS3";
	}

	/**
	 * Tab documentos OS 2.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * 
	 * @param request
	 *            the request
	 * @return the string
	 */
	@RequestMapping(value = "/OS3/tabDocumentosOS3/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabDocumentosOS3(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model, HttpServletRequest request) {

		ComunicacionPrlController.logger.info("Entra en getTabDocumentos");

		String iframe = (String) request.getParameter("iframe");

		String modoAcceso = "";

		if (iframe == null) {
			modoAcceso = (String) request.getSession().getAttribute(
					ComunicacionPrlController.ATTR_NAME_MODO_ACCESO);
		} else {
			modoAcceso = Constantes.MODO_ACCESO_CONSULTA;
		}

		// cargamos comunicacionprl
		ComunicacionPrl os3 = new ComunicacionPrl();
		os3.setTeros(teros);
		os3.setAnoos(anoos);
		os3.setNumos(numos.intValue());
		os3.setTipoos(Constantes.OS2);
		os3 = this.comunicacionPrlService.find(os3);

		// String modoAcceso = Constantes.MODO_ACCESO_MANTENIMIENTO;
		// Cargamos la lista de trámites

		List<TramiteOS3> listaTramites = new ArrayList<TramiteOS3>();
		List<DocumentoOS3> listaDocs = new ArrayList<DocumentoOS3>();
		TipoDocumento tipoDoc = null;
		try {
			if (Constantes.MODO_ACCESO_ALTA.equals(modoAcceso)
					|| Constantes.MODO_ACCESO_MANTENIMIENTO.equals(modoAcceso)
					|| Constantes.MODO_ACCESO_SUBSANACION.equals(modoAcceso)) {
				DocumentoOS3 filterDoc = new DocumentoOS3();
				TramiteOS3 tramite = new TramiteOS3(null, null,
						new OS3(teros, anoos, numos.intValue()));
				filterDoc.setTramiteOS3(tramite);

				tipoDoc = new TipoDocumento();
				// Aportado o generado?
				tipoDoc.setAportGen091(Constantes.TIPO_DOCUMENTO_APORTADO);
				filterDoc.setTipoDocumento(tipoDoc);
				listaDocs = this.os3Service
						.findAllDocumentosOS3TipoTemp(filterDoc);

				// TramiteOS2 tramite = new TramiteOS2();
				tramite.setListaDocumentos(listaDocs);
				listaTramites.add(tramite);

			} else if (Constantes.MODO_ACCESO_CONSULTA.equals(modoAcceso)) {
				if (os3.getMigrado().equals("N")) {
					TramiteOS3 filterTramite = new TramiteOS3(null, null,
							new OS3(teros, anoos, numos.intValue()));

					JQGridRequestDto jqGridTramites = new JQGridRequestDto();
					jqGridTramites.setSidx("ID_TRAMITE_095");
					jqGridTramites.setSord("ASC");
					// Cargamos los documentos de cada trámite
					listaTramites = this.tramiteOS3Service
							.findAll(filterTramite, jqGridTramites);

					for (TramiteOS3 tramite : listaTramites) {
						DocumentoOS3 filterDoc = new DocumentoOS3();
						filterDoc.setTramiteOS3(tramite);
						tipoDoc = new TipoDocumento();
						filterDoc.setTipoDocumento(tipoDoc);
						// listaDocs = this.os2Service.findAll(filterDoc);
						listaDocs = this.documentoOS3Service.findAll(filterDoc,
								null);

						tramite.setListaDocumentos(listaDocs);
					}
				} else {

					FolderDocumentList fdl = os2Service
							.obtenerDocumentosMigrados(os3.getFolderId());

					Iterator<FolderDoc> iaportado = fdl
							.getContributedDocumentList().getFolderDoc()
							.iterator();

					listaDocs = new ArrayList<DocumentoOS3>();

					TramiteOS3 tramiteaOs32 = new TramiteOS3();
					Tramite tramite2 = new Tramite();
					tramite2.setDescripcionEs089("Documentos Aportados");
					tramite2.setDescripcionEu089("Aurkeztutako Dokumentuak");
					tramiteaOs32.setTipoTramite(tramite2);

					SimpleDateFormat sdf = new SimpleDateFormat(
							"dd-MM-yyyy HH:mm:ss");

					while (iaportado.hasNext()) {
						FolderDoc fdaporado = iaportado.next();

						Iterator<DocumentStorageInfo> dsiterator2 = fdaporado
								.getDocumentStorageList()
								.getDocumentStorageInfo().iterator();

						while (dsiterator2.hasNext()) {

							DocumentStorageInfo dsi2 = dsiterator2.next();
							DocumentoOS3 daporado = new DocumentoOS3();
							daporado.setNombreDoc097(dsi2.getSourceName());

							daporado.setFechaDoc097(sdf.parse(fdaporado
									.getRegistrySubmissionTimeStamp()));
							daporado.setOidDokusi097(dsi2.getDocOID());

							String formato = "E";
							if (!dsi2.getFormat().equals("")) {
								formato = dsi2.getFormat();
							}

							daporado.setFormatoAport097(formato);
							daporado.setOrigen097(0);

							TipoDocumento tipo = new TipoDocumento();

							ElementNSImpl object = (ElementNSImpl) dsi2
									.getRoleName();

							String des_eu = object.getFirstChild()
									.getFirstChild().getFirstChild()
									.getNodeValue();
							String des_es = object.getFirstChild()
									.getFirstChild().getNextSibling()
									.getFirstChild().getNodeValue();

							tipo.setDescripcionEu091(des_eu);
							tipo.setDescripcionEs091(des_es);

							daporado.setTipoDocumento(tipo);
							// daporado.setMigrado(true);

							listaDocs.add(daporado);
						}
					}

					tramiteaOs32.setListaDocumentos(listaDocs);
					listaTramites.add(tramiteaOs32);

				}
			}
			// apertura.setListaTramites(listaTramites);
			os3.setListaTramitesOs3(listaTramites);
		} catch (Exception e) {
			ComunicacionPrlController.logger
					.error("ERROR tabDocumentos " + e.getMessage());
		}
		model.addAttribute(ComunicacionPrlController.ATTR_NAME_MODO_ACCESO,
				modoAcceso);
		if (iframe == null) {
			request.getSession().setAttribute(
					ComunicacionPrlController.ATTR_NAME_MODO_ACCESO,
					modoAcceso);
		}

		model.addAttribute("iframe", iframe);

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				os3);

		// Cargamos la URL de descarga del applet de digitalizacion
		model.addAttribute("urlappletdigitalizacion",
				PropertiesUtil.getProperty(PropertiesUtil.URL_DESCARGA_APPLET));

		// territorio para serie documental
		request.getSession().setAttribute("terape", os3.getTeros());
		// tipo de documento para la digitalización
		request.getSession().setAttribute("docType", Constantes.OS3);

		// Preparo la configuración de las opciones de tramitación
		String toolbarDocumentos = this.preparaToolbar(os3, modoAcceso);
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_DOCUMENTOS_REG,
				toolbarDocumentos);

		return "tabDocumentosOS3";
	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * deseaReg String numReg String fecReg Date request HttpServletRequest
	 * model Model String
	 * 
	 * @param deseaReg
	 *            the desea reg
	 * @param numReg
	 *            the num reg
	 * @param fecReg
	 *            the fec reg
	 * @param request
	 *            the request
	 * @param model
	 *            the model the string
	 * @return the string
	 */
	@RequestMapping(value = "/tabDocumentosOS2/modificar", method = RequestMethod.GET)
	public @ResponseBody() String modificarTabDocumentos(
			@RequestParam(value = "deseaReg", required = false) String deseaReg,
			@RequestParam(value = "numReg", required = false) String numReg,
			@RequestParam(value = "fecReg", required = false) Date fecReg,
			HttpServletRequest request, Model model) {

		ComunicacionPrl comunicPrlSess = new ComunicacionPrl();
		String modoAcceso = "";
		HttpSession session = request.getSession();
		if (session != null) {
			comunicPrlSess = (ComunicacionPrl) session.getAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE);
			modoAcceso = (String) request.getSession().getAttribute(
					ComunicacionPrlController.ATTR_NAME_MODO_ACCESO);

		}

		ComunicacionPrl cprl = this.comunicacionPrlService
				.findDetalle(comunicPrlSess, null, null);

		// Obtenemos la lista de los documentos antiguos
		// TramiteOS2 filterTramite = new TramiteOS2();
		OS2 os2 = OS2.convertComunicacionPrltoOS2(cprl);
		/*
		 * filterTramite.setos2(os2); JQGridRequestDto jqGridTramites = new
		 * JQGridRequestDto(); jqGridTramites.setSidx("ID_TRAMITE_092");
		 * jqGridTramites.setSord("ASC");
		 */
		/*
		 * List<TramiteOS2> listaTramites = this.tramiteOS2Service.findAll(
		 * filterTramite, jqGridTramites); TipoDocumento tipoDoc;
		 * List<DocumentoOS2> listaDocs = new ArrayList<DocumentoOS2>(); //
		 * Cargamos los documentos de cada trámite for (TramiteOS2 tramite :
		 * listaTramites) { DocumentoOS2 filterDoc = new DocumentoOS2();
		 * filterDoc.setTramiteOS2(tramite); tipoDoc = new TipoDocumento();
		 * filterDoc.setTipoDocumento(tipoDoc); //
		 * listaDocs.addAll(this.os2Service.findAll(filterDoc));
		 * listaDocs.addAll(documentoOS2Service.findAll(filterDoc, null)); }
		 */

		List<ErrorField> errores = new ArrayList<ErrorField>();
		if (Constantes.MODO_ACCESO_MANTENIMIENTO.equals(modoAcceso)
				&& Constantes.VALUE_NO.equals(deseaReg)) {
			if (Utilities.getInstance().isEmpty(numReg)) {
				errores.add(new ErrorField("aperturas.detalle.numReg",
						"validacion.obligatorio"));
			}
			if (fecReg == null) {
				errores.add(new ErrorField("aperturas.detalle.fecReg",
						"validacion.obligatorio"));
			}
		}

		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		cprl.setDeseaRegistrar(deseaReg);
		cprl.setNumReg(numReg);
		cprl.setFecReg(fecReg);

		// recoger de la tabla temporal
		DocumentoOS2 docFilter = new DocumentoOS2();
		docFilter.setTramiteOS2(new TramiteOS2(null, null, os2));
		// docFilter.set(apertura.getIdape056());

		try {
			List<DocumentoOS2> listaDocumentos = this.copiarDocsR02G(
					cprl.getTeros(), cprl.getAnoos(), cprl.getNumos(), false);
			ContextSubmission contextSubmission = this.ppsAportacionOS2Service
					.crearContextSubmission(false, os2, listaDocumentos);

			this.ppsAportacionOS2Service
					.enviarAportacionPresencial(contextSubmission);
			// PPSReturnInfo ppsReturnInfo = PPSUtils.getInstance()
			// .obtenerPPSReturnInfo(requestReturn);

		} catch (Exception e) {
			this.documentoOS2Service.removeTempByApertura(docFilter);
			errores.add(
					new ErrorField("comunicacion.apertura", "error.apertura"));
			throw new ErrorGenericoException(errores);
		}

		model.addAttribute(ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
				modoAcceso);

		return "ok";

	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * deseaReg String numReg String fecReg Date request HttpServletRequest
	 * model Model String
	 * 
	 * @param deseaReg
	 *            the desea reg
	 * @param numReg
	 *            the num reg
	 * @param fecReg
	 *            the fec reg
	 * @param request
	 *            the request
	 * @param model
	 *            the model the string
	 * @return the string
	 */
	@RequestMapping(value = "/tabDocumentosOS2/guardarInforme", method = RequestMethod.GET)
	public @ResponseBody() String guardarInforme(HttpServletRequest request,
			Model model) {

		/*
		 * ComunicacionApertura comunicAperturaSess = new
		 * ComunicacionApertura();
		 * 
		 * HttpSession session = request.getSession(); if (session != null) {
		 * comunicAperturaSess = (ComunicacionApertura) session.getAttribute(
		 * ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_DETALLE);
		 * 
		 * }
		 * 
		 * ComunicacionApertura apertura = this.comunicAperturaService
		 * .findDetalle(comunicAperturaSess, null, null);
		 * 
		 * try {
		 * 
		 * apertura.setUsuarioTram(UtilSeguridad.getInstance()
		 * .getUserCredentials().getPosition());
		 * this.comunicAperturaService.updateUsuariosTramitacion(apertura);
		 * 
		 * this.plateaTramitacionService.crearTarea(
		 * Utilities.getInstance().obtenerProcedureIdApertura(),
		 * TipoTramiteFlujo.ADJUNTAR_INFORME_INSPECCION.name(),
		 * TipoTareaFlujo.ADJUNTAR_INFORME_INSPECCION.getTaskId(),
		 * apertura.getFolderId056(),
		 * UtilSeguridad.getInstance().getUserCredentials() .getPosition(),
		 * UtilSeguridad.getInstance().getNombre());
		 * 
		 * // Metemos la entidad Comunicación de apertura al modelo
		 * model.addAttribute(
		 * ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_DETALLE,
		 * apertura);
		 * 
		 * } catch (Exception e) { DocumentoAperturas docFilter = new
		 * DocumentoAperturas();
		 * docFilter.setIdapetemp065(apertura.getIdape056());
		 * 
		 * // borrar los temporales
		 * this.documentosAperturasTempDao.removeByIdApertura(docFilter); return
		 * "ko"; }
		 */

		return "ok";

	}

	/**
	 * Tab tramtiacion OS 3.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/OS3/tabTramitacionOS3/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabTramtiacionOS3(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model) {

		ComunicacionPrl cprl = new ComunicacionPrl();
		cprl.setTeros(teros);
		cprl.setAnoos(anoos);
		cprl.setNumos(numos.intValue());
		cprl.setTipoos(Constantes.OS3);
		cprl = this.comunicacionPrlService.find(cprl);

		OS3 os3 = OS3.convertComunicacionPrltoOS3(cprl);

		// cargamos lista tareas
		TareaOS3 filterTarea = new TareaOS3();
		TramiteOS3 filterTramite = new TramiteOS3();
		filterTramite.setOs3(os3);
		filterTarea.setTramiteOS3(filterTramite);
		List<TareaOS3> listaTareas = this.tareaOS3Service
				.findAllTareatramite(filterTarea, null);

		revisarErrorTareaOS3(listaTareas);
		os3.setListaTareas(listaTareas);

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				os3);

		// comprobamos si no hay tareas pendientes, para mostrar el botón cerrar
		// expediente.
		boolean cerrarExp = true;
		boolean crearEstudio = true;
		boolean abrirExpediente = false;
		for (TareaOS3 tarea : listaTareas) {
			if (!EstadosTareas.EJECUTADA.getEstado()
					.equals(tarea.getEstado096())) {
				cerrarExp = true;

				if (TipoTareaFlujo.ESTUDIO
						.esEquivalente(tarea.getTipoTarea().getTaskId090())) {
					crearEstudio = false;
				}

			}
		}

		// comprobamos si el expediente está en estado='S' (no se ha abierto
		// correctamente),
		// para poner el botón 'Abrir Expediente'
		if (os3.getEstado061() != null && os3.getEstado061().equals("S")) {
			cerrarExp = false;
			crearEstudio = false;
			// comprobar si han pasado por lo menos 5 minutos desde que se ha
			// puesto en estado='S'
			Date now = new Date();
			Long diff = 0L;
			if (os3.getFecpre061() != null) {
				diff = now.getTime() - os3.getFecpre061().getTime();
			}
			if (diff > ComunicacionPrlController.MIN_WAIT_REOPEN) {
				abrirExpediente = true;
			} else {
				abrirExpediente = false;
			}
		}

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_CERRAR_EXPEDIENTE,
				cerrarExp);

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_CREAR_ESTUDIO,
				crearEstudio);

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPERTURA_ABRIR_EXPEDIENTE,
				abrirExpediente);

		// Preparo la configuración de las opciones de tramitación
		String toolbarTramitacion = "";
		try {
			// TODO obtener el modo acceso en función del usuario
			toolbarTramitacion = this.preparaToolbarTramitacion(
					Constantes.MODO_ACCESO_MANTENIMIENTO);
		} catch (Exception e) {
			ComunicacionPrlController.logger
					.error("Error al generar el toolbar de tramitacion", e);
			toolbarTramitacion = "{buttons: []}";
		}
		model.addAttribute(
				ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_TOOLBAR_TRAMITACION,
				toolbarTramitacion);

		return "tabTramitacionOS3";
	}

	private void revisarErrorTareaOS3(List<TareaOS3> listaTareas) {
		String error = "";
		String tipoTarea = "";
		TareaOS3 tarea = null;
		TareaOS3 tareaRelanzar = null;
		Collections.reverse(listaTareas);
		for (int i = 0; i < listaTareas.size(); i++) {
			tarea = listaTareas.get(i);
			if (tarea.getError() != null) {
				tipoTarea = tarea.getTipoTarea().getTaskId090();
				error = tarea.getError();
				if ((i + 1) < listaTareas.size()) {
					tareaRelanzar = listaTareas.get(i + 1);
					if (tareaRelanzar.getEstado096() == EstadosTareas.INICIADA
							.getEstado()
							&& tareaRelanzar.getTipoTarea().getTaskId090()
									.equals(tipoTarea)) {
						tareaRelanzar.setRelanzar("si");
						tareaRelanzar.setError(error);
					}
				}

			}
		}
		Collections.reverse(listaTareas);

	}

	/**
	 * Tab datos prevencion.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/OS3/tabDatosPrevencion/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabDatosPrevencion(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model) {

		ComunicacionPrl os3 = new ComunicacionPrl();
		os3.setTeros(teros);
		os3.setAnoos(anoos);
		os3.setNumos(numos.intValue());
		os3.setTipoos(Constantes.OS3);
		os3 = this.comunicacionPrlService.find(os3);

		// Pestaña seleccionada
		// Integer tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// if (tab == null) {
		// tabAux = ComunicacionPrlController.TAB_DETALLE_DEFECTO;
		// }
		// model.addAttribute(
		// ComunicacionPrlController.ATTR_NAME_COMUNICAPERTURA_TAB_DEFECTO,
		// tabAux.toString());

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				os3);

		// Preparo la configuración de las opciones de tramitación
		String toolbarPrevencion = this.preparaToolbar(os3, "");
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_PREVENCION,
				toolbarPrevencion);

		return "tabDatosPrevencion";
	}

	/**
	 * Tab datos estado OS 3.
	 * 
	 * teros String anoos String numos Long model Model
	 * 
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/OS3/tabDatosEstadoOS3/{teros}/{anoos}/{numos}", method = RequestMethod.GET)
	public String tabDatosEstadoOS3(@PathVariable() String teros,
			@PathVariable() String anoos, @PathVariable() Long numos,
			Model model) {

		ComunicacionPrl os3 = new ComunicacionPrl();
		os3.setTeros(teros);
		os3.setAnoos(anoos);
		os3.setNumos(numos.intValue());
		os3.setTipoos(Constantes.OS3);
		os3 = this.comunicacionPrlService.find(os3);

		// Metemos la entidad Comunicación de apertura al modelo
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				os3);

		// Preparo la configuración de las opciones de tramitación
		String toolbarEstado = this.preparaToolbar(os3, "");
		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_TOOLBAR_ESTADO,
				toolbarEstado);

		return "tabDatosEstadoOS3";
	}

	/**
	 * Prepara toolbar.
	 * 
	 * comunicacionPrl ComunicacionPrl modoAcceso String
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl
	 * @param modoAcceso
	 *            the modo acceso String
	 * @return the string
	 */
	private String preparaToolbar(ComunicacionPrl comunicacionPrl,
			String modoAcceso) {

		ObjectMapper mapper = new ObjectMapper();
		Botonera botonera = new Botonera();
		botonera.addBoton(new Boton("guardar", "guardar"));
		try {
			return mapper.writeValueAsString(botonera);
		} catch (Exception e) {
			return "{buttons: []}";
		}
	}

	/**
	 * Modifica los datos de la pestaña de Notificación del expediente.
	 * 
	 * comunicacionPrl ComunicacionPrl Bean que contiene la informacion con la
	 * que se va a crear el nuevo registro. request HttpServletRequest
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl
	 * @param request
	 *            the request ComunicacionPrl Bean resultante del proceso de
	 *            creacion.
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "/OS2/tabDatosNotificacionOS2/modificar", method = RequestMethod.POST)
	public @ResponseBody() ComunicacionPrl modificarTabDatosNotificacionOS2(
			@RequestBody() ComunicacionPrl comunicacionPrl,
			HttpServletRequest request) {

		HttpSession session = request.getSession();

		ComunicacionPrl comunicPrlSess = new ComunicacionPrl();
		if (session != null) {
			comunicPrlSess = (ComunicacionPrl) session.getAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE);

			this.machacarIdsDatosPrl(comunicacionPrl, comunicPrlSess);
		}
		String modoAcceso = (String) request.getSession().getAttribute(
				ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO);

		// Validate
		List<ErrorField> errores = new ArrayList<ErrorField>();

		if (Constantes.MODO_ACCESO_ALTA.equals(modoAcceso)) {
			if (Constantes.VALUE_NO
					.equals(comunicacionPrl.getDeseaRegistrar())) {
				if (Utilities.getInstance()
						.isEmpty(comunicacionPrl.getNumReg())) {
					errores.add(new ErrorField("aperturas.detalle.numReg",
							"validacion.obligatorio"));
				}
				if (comunicacionPrl.getFecReg() == null) {
					errores.add(new ErrorField("aperturas.detalle.fecReg",
							"validacion.obligatorio"));
				}
			}

			DatosNotificacion datosNotificacion = comunicacionPrl
					.getDatosNotificacion();

			// Si es notif. postal y se ha introducido localidad y CP, se valida
			if (datosNotificacion.getCanalnotif066() != null
					&& Constantes.CANAL_NOTIF_POSTAL
							.equals(datosNotificacion.getCanalnotif066())
					&& datosNotificacion.getDatosLocalizacion() != null
					&& datosNotificacion.getDatosLocalizacion()
							.getLocalidad() != null
					&& datosNotificacion.getDatosLocalizacion().getLocalidad()
							.getCodLocalidad() != null
					&& datosNotificacion.getDatosLocalizacion()
							.getCodpostal067() != null) {

				errores = this.comunicacionPrlValidator
						.validateLocalidadCP(comunicacionPrl);

			}

		} else {
			errores = this.comunicacionPrlValidator.validate(comunicacionPrl,
					Oper.EDIT_TAB_NOTIFICACION);
		}

		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		this.os2Service.modificarDatosTabNotificacionOS2(comunicacionPrl,
				false);

		if (comunicacionPrl.getFolderId() != null) {

			DatosNotificacion datosNotificacionYAviso = this.datosNotificacionService
					.findConLocalizacionYAvisos(
							comunicacionPrl.getDatosNotificacion());

			try {
				reeService.modificarDatosNotificacionExpedienteREE(

						comunicacionPrl.getFolderId(), datosNotificacionYAviso);
			} catch (Exception e) {
				errores.add(new ErrorField("Datos Notificacion",
						"No se han guardado en el Repositorio de Expedientes"));
				throw new ErrorGenericoException(errores);
			}
		}

		OS2 os2 = OS2.convertComunicacionPrltoOS2(comunicacionPrl);

		if (Constantes.MODO_ACCESO_ALTA.equals(modoAcceso)
				|| Constantes.MODO_ACCESO_SUBSANACION.equals(modoAcceso)) {
			this.os2Service.modificarDatosRegistro(os2);
		}

		ComunicacionPrlController.logger
				.info("[POST] : Expediente modificado correctamente");
		return comunicacionPrl;
	}

	/**
	 * Modifica los datos de la pestaña de EmpresaOS2 del expediente.
	 * 
	 * comunicacionPrl comunicacionPrl Bean que contiene la informacion con la
	 * que se va a crear el nuevo registro.
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl Denuncia Bean resultante del proceso de
	 *            creacion.
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "/OS2/tabDatosEmpresaOS2/modificar", method = RequestMethod.POST)
	public @ResponseBody() ComunicacionPrl modificarTabEmpresaOS2(
			@RequestBody() ComunicacionPrl comunicacionPrl) {

		// Validate
		List<ErrorField> errores = this.comunicacionPrlValidator
				.validate(comunicacionPrl, Oper.EDIT_TAB_EMPRESAOS2);
		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		OS2 os2 = OS2.convertComunicacionPrltoOS2(comunicacionPrl);

		if (Constantes.CANAL_NOTIF_POSTAL.equals(
				comunicacionPrl.getDatosNotificacion().getCanalnotif066())) {
			this.os2Service.modificarDatosTabNotificacionOS2(comunicacionPrl,
					false);
		}

		this.os2Service.modificarDatosTabEmpresaOS2(os2);

		ComunicacionPrlController.logger
				.info("[POST] : Expediente modificado correctamente");
		return comunicacionPrl;
	}

	/**
	 * Modifica los datos de la pestaña de Modalidad del expediente.
	 * 
	 * comunicacionPrl comunicacionPrl Bean que contiene la informacion con la
	 * que se va a crear el nuevo registro.
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl Denuncia Bean resultante del proceso de
	 *            creacion.
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "/OS2/tabDatosModalidad/modificar", method = RequestMethod.POST)
	public @ResponseBody() ComunicacionPrl modificarTabModalidad(
			@RequestBody() ComunicacionPrl comunicacionPrl) {

		OS2 os2 = OS2.convertComunicacionPrltoOS2(comunicacionPrl);

		// Validate
		List<ErrorField> errores = this.comunicacionPrlValidator
				.validate(comunicacionPrl, Oper.EDIT_TAB_PREVENCIONOS2);
		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		this.os2Service.modificarDatosTabModalidad(os2);

		ComunicacionPrlController.logger
				.info("[POST] : Expediente modificado correctamente");
		return comunicacionPrl;
	}

	/**
	 * Modifica los datos de la pestaña de Auditoria del expediente.
	 * 
	 * comunicacionPrl comunicacionPrl Bean que contiene la informacion con la
	 * que se va a crear el nuevo registro.
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl Denuncia Bean resultante del proceso de
	 *            creacion.
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "/OS2/tabDatosAuditoria/modificar", method = RequestMethod.POST)
	public @ResponseBody() ComunicacionPrl modificarTabAuditoria(
			@RequestBody() ComunicacionPrl comunicacionPrl) {

		// Validate
		List<ErrorField> errores = this.comunicacionPrlValidator
				.validate(comunicacionPrl, Oper.EDIT_TAB_AUDITORIA);
		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		OS2 os2 = OS2.convertComunicacionPrltoOS2(comunicacionPrl);

		this.os2Service.modificarDatosTabAuditoria(os2);

		ComunicacionPrlController.logger
				.info("[POST] : Expediente modificado correctamente");
		return comunicacionPrl;
	}

	/**
	 * Modifica los datos de la pestaña de EstadoOS2 del expediente.
	 * 
	 * comunicacionPrl comunicacionPrl Bean que contiene la informacion con la
	 * que se va a crear el nuevo registro.
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl Denuncia Bean resultante del proceso de
	 *            creacion.
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "/OS2/tabDatosEstadoOS2/modificar", method = RequestMethod.POST)
	public @ResponseBody() ComunicacionPrl modificarTabEstadoOS2(
			@RequestBody() ComunicacionPrl comunicacionPrl) {

		OS2 os2 = OS2.convertComunicacionPrltoOS2(comunicacionPrl);

		this.os2Service.modificarDatosTabEstadoOS2(os2);

		ComunicacionPrlController.logger
				.info("[POST] : Expediente modificado correctamente");
		return comunicacionPrl;
	}

	/**
	 * Modifica los datos de la pestaña de Notificación del expediente.
	 * 
	 * comunicacionPrl ComunicacionPrl Bean que contiene la informacion con la
	 * que se va a crear el nuevo registro. request HttpServletRequest
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl
	 * @param request
	 *            the request ComunicacionPrl Bean resultante del proceso de
	 *            creacion.
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "/OS3/tabDatosNotificacionOS3/modificar", method = RequestMethod.POST)
	public @ResponseBody() ComunicacionPrl modificarTabDatosNotificacionOS3(
			@RequestBody() ComunicacionPrl comunicacionPrl,
			HttpServletRequest request) {

		HttpSession session = request.getSession();

		ComunicacionPrl comunicPrlSess = new ComunicacionPrl();
		if (session != null) {
			comunicPrlSess = (ComunicacionPrl) session.getAttribute(
					ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE);

			this.machacarIdsDatosPrl(comunicacionPrl, comunicPrlSess);
		}

		String modoAcceso = (String) request.getSession().getAttribute(
				ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO);

		// Validate
		List<ErrorField> errores = new ArrayList<ErrorField>();

		if (Constantes.MODO_ACCESO_ALTA.equals(modoAcceso)) {
			if (Constantes.VALUE_NO
					.equals(comunicacionPrl.getDeseaRegistrar())) {
				if (Utilities.getInstance()
						.isEmpty(comunicacionPrl.getNumReg())) {
					errores.add(new ErrorField("aperturas.detalle.numReg",
							"validacion.obligatorio"));
				}
				if (comunicacionPrl.getFecReg() == null) {
					errores.add(new ErrorField("aperturas.detalle.fecReg",
							"validacion.obligatorio"));
				}
			}

			DatosNotificacion datosNotificacion = comunicacionPrl
					.getDatosNotificacion();

			// Si es notif. postal y se ha introducido localidad y CP, se valida
			if (datosNotificacion.getCanalnotif066() != null
					&& Constantes.CANAL_NOTIF_POSTAL
							.equals(datosNotificacion.getCanalnotif066())
					&& datosNotificacion.getDatosLocalizacion() != null
					&& datosNotificacion.getDatosLocalizacion()
							.getLocalidad() != null
					&& datosNotificacion.getDatosLocalizacion().getLocalidad()
							.getCodLocalidad() != null
					&& datosNotificacion.getDatosLocalizacion()
							.getCodpostal067() != null) {

				errores = this.comunicacionPrlValidator
						.validateLocalidadCP(comunicacionPrl);

			}

		} else {
			errores = this.comunicacionPrlValidator.validate(comunicacionPrl,
					Oper.EDIT_TAB_NOTIFICACION);
		}

		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		this.os3Service.modificarDatosTabNotificacionOS3(comunicacionPrl,
				false);

		if (comunicacionPrl.getFolderId() != null) {

			DatosNotificacion datosNotificacionYAviso = this.datosNotificacionService
					.findConLocalizacionYAvisos(
							comunicacionPrl.getDatosNotificacion());

			try {
				reeService.modificarDatosNotificacionExpedienteREE(

						comunicacionPrl.getFolderId(), datosNotificacionYAviso);
			} catch (Exception e) {
				errores.add(new ErrorField("Datos Notificacion",
						"No se han guardado en el Repositorio de Expedientes"));
				throw new ErrorGenericoException(errores);
			}
		}

		OS3 os3 = OS3.convertComunicacionPrltoOS3(comunicacionPrl);

		if (Constantes.MODO_ACCESO_ALTA.equals(modoAcceso)
				|| Constantes.MODO_ACCESO_SUBSANACION.equals(modoAcceso)) {
			this.os3Service.modificarDatosRegistro(os3);
		}

		ComunicacionPrlController.logger
				.info("[POST] : Expediente modificado correctamente");
		return comunicacionPrl;
	}

	/**
	 * Modifica los datos de la pestaña de EmpresaOS3 del expediente.
	 * 
	 * comunicacionPrl comunicacionPrl Bean que contiene la informacion con la
	 * que se va a crear el nuevo registro.
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl Denuncia Bean resultante del proceso de
	 *            creacion.
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "/OS3/tabDatosEmpresaOS3/modificar", method = RequestMethod.POST)
	public @ResponseBody() ComunicacionPrl modificarTabEmpresaOS3(
			@RequestBody() ComunicacionPrl comunicacionPrl) {

		// Validate
		List<ErrorField> errores = this.comunicacionPrlValidator
				.validate(comunicacionPrl, Oper.EDIT_TAB_EMPRESAOS3);
		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		OS3 os3 = OS3.convertComunicacionPrltoOS3(comunicacionPrl);

		if (Constantes.CANAL_NOTIF_POSTAL.equals(
				comunicacionPrl.getDatosNotificacion().getCanalnotif066())) {
			this.os3Service.modificarDatosTabNotificacionOS3(comunicacionPrl,
					false);
		}

		this.os3Service.modificarDatosTabEmpresaOS3(os3);

		ComunicacionPrlController.logger
				.info("[POST] : Expediente modificado correctamente");
		return comunicacionPrl;
	}

	/**
	 * Modifica los datos de la pestaña de Prevencion del expediente.
	 * 
	 * comunicacionPrl comunicacionPrl Bean que contiene la informacion con la
	 * que se va a crear el nuevo registro.
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl Denuncia Bean resultante del proceso de
	 *            creacion.
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "/OS3/tabDatosPrevencion/modificar", method = RequestMethod.POST)
	public @ResponseBody() ComunicacionPrl modificarTabPrevencion(
			@RequestBody() ComunicacionPrl comunicacionPrl) {

		// Validate
		List<ErrorField> errores = this.comunicacionPrlValidator
				.validate(comunicacionPrl, Oper.EDIT_TAB_PREVENCIONOS3);
		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		OS3 os3 = OS3.convertComunicacionPrltoOS3(comunicacionPrl);

		this.os3Service.modificarDatosTabPrevencion(os3);

		ComunicacionPrlController.logger
				.info("[POST] : Expediente modificado correctamente");
		return comunicacionPrl;
	}

	/**
	 * Modifica los datos de la pestaña de EstadoOS3 del expediente.
	 * 
	 * comunicacionPrl comunicacionPrl Bean que contiene la informacion con la
	 * que se va a crear el nuevo registro.
	 * 
	 * @param comunicacionPrl
	 *            the comunicacion prl Denuncia Bean resultante del proceso de
	 *            creacion.
	 * @return the comunicacion prl
	 */
	@RequestMapping(value = "/OS3/tabDatosEstadoOS3/modificar", method = RequestMethod.POST)
	public @ResponseBody() ComunicacionPrl modificarTabEstadoOS3(
			@RequestBody() ComunicacionPrl comunicacionPrl) {

		OS3 os3 = OS3.convertComunicacionPrltoOS3(comunicacionPrl);

		this.os3Service.modificarDatosTabEstadoOS3(os3);

		ComunicacionPrlController.logger
				.info("[POST] : Expediente modificado correctamente");
		return comunicacionPrl;
	}

	/**
	 * Machacha los IDs del objeto comIni (que nos viene de la request con IDs
	 * vacÃ­os) con los que estÃ¡n guardados en el objeto comIniIds, que es el
	 * que estÃ¡ en session con todos los IDs.
	 * 
	 * exp Expedientes expIds Expedientes
	 * 
	 * @param exp
	 *            the exp
	 * @param expIds
	 *            the exp ids
	 */
	private void machacarIdsDatosPrl(ComunicacionPrl exp,
			ComunicacionPrl expIds) {
		// Id expediente
		exp.setTeros(expIds.getTeros());
		exp.setAnoos(expIds.getAnoos());
		exp.setNumos(expIds.getNumos());

		// Id datos notificación solicitante
		if (exp.getDatosNotificacion() == null) {
			exp.setDatosNotificacion(new DatosNotificacion());
		}
		exp.getDatosNotificacion().setCodDatosNotif066(
				expIds.getDatosNotificacion().getCodDatosNotif066());

		// Id localización nora solicitante (direcciÃ³n)
		if (exp.getDatosNotificacion().getDatosLocalizacion() == null) {
			exp.getDatosNotificacion()
					.setDatosLocalizacion(new DatosLocalizacion());
		}

		if (expIds.getDatosNotificacion().getDatosLocalizacion() != null) {
			exp.getDatosNotificacion().getDatosLocalizacion()
					.setCodLocalizacion067(expIds.getDatosNotificacion()
							.getDatosLocalizacion().getCodLocalizacion067());

		}
	}

	/**
	 * Realiza la exportaciÃ³n a Pdf.
	 * 
	 * listado String request HttpServletRequest response HttpServletResponse
	 * 
	 * @param listado
	 *            the listado
	 * @param request
	 *            the request
	 * @param response
	 *            the response the carta apertura PDF
	 * @return the carta apertura PDF
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	@RequestMapping(value = "fichaOS/{listado}", method = RequestMethod.GET)
	public @ResponseBody void getCartaAperturaPDF(
			@PathVariable() String listado, HttpServletRequest request,
			HttpServletResponse response) throws AB04BException {
		try {
			InputStream is = null;
			String[] seleccion = listado.split(",");
			String[] selecFrom = obtenerNumerosApertura(seleccion);
			if (seleccion[0].substring(0, ConstantesNum.NUM_3)
					.equalsIgnoreCase("os2")) {
				is = this.generacionPDFFichaOS2Service.getPDF(selecFrom);
			} else {
				is = this.generacionPDFFichaOS3Service.getPDF(selecFrom);
			}

			response.setContentType("application/pdf");

			IOUtils.copy(is, response.getOutputStream());
			is.close();
			response.getOutputStream().close();
		} catch (Exception e) {
			throw new AB04BException(e, e.getMessage());
		}

	}

	/**
	 * Devuelve los numeros de apertura seleccionados.
	 * 
	 * seleccion String[]
	 * 
	 * @param seleccion
	 *            the seleccion String[]
	 * @return the string[]
	 */
	private String[] obtenerNumerosApertura(String[] seleccion) {
		String[] selecFrom = new String[seleccion.length];

		for (int i = 0; i < seleccion.length; i++) {
			String[] spl = seleccion[i].split("~");
			selecFrom[i] = spl[ConstantesNum.NUM_1] + "-"
					+ spl[ConstantesNum.NUM_2] + "-"
					+ StringUtils.leftPad(spl[ConstantesNum.NUM_3],
							ComunicacionPrlController.NUMEXP_LPAD_SIZE,
							ComunicacionPrlController.NUMEXP_LPAD_CHAR);
		}

		return selecFrom;
	}

	/**
	 * Acceder detalle tarea sugerida OS 2.
	 * 
	 * idTarea Long model Model
	 * 
	 * @param idTarea
	 *            the id tarea
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/taskOS2/{idTarea}")
	public String accederDetalleTareaSugeridaOS2(
			@PathVariable(value = "idTarea") Long idTarea, Model model) {

		TareaOS2 tarea = new TareaOS2(idTarea);
		tarea = this.tareaOS2Service.findTareaTramite(tarea);

		OS2 os2 = this.os2Service.find(tarea.getTramiteOS2().getos2());

		String tiles = "";
		String toolbarTramitacion = "";

		if (TipoTareaFlujo.ESTUDIO
				.esEquivalente(tarea.getTipoTarea().getTaskId090())) {
			tiles = "estudioOS2";

			// Obtenemos el estudio de documentación de la tarea
			EstudioDocOS2 estudio = new EstudioDocOS2();
			estudio.setTareaOS2(tarea);
			estudio = this.estudioDocOS2Service.find(estudio);

			if (estudio == null) {
				// Si no existe, lo creamos
				estudio = new EstudioDocOS2(tarea);
				this.estudioDocOS2Service.add(estudio);
			}

			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_ESTUDIO,
					estudio);

			try {
				toolbarTramitacion = this.preparaToolbarEstudio();
			} catch (Exception e) {
				ComunicacionPrlController.logger
						.error("Error al generar el toolbar de estudio", e);
				toolbarTramitacion = "{buttons: []}";
			}
		} else if (TipoTareaFlujo.ADJUNTAR_DOC_REQUERIMIENTO
				.esEquivalente(tarea.getTipoTarea().getTaskId090())) {
			tiles = "requerimientoOS2";

			// Obtenemos los motivos de subsanacion
			Tablones tablones = new Tablones();
			tablones.setCodtabla088(Constantes.TABLON_MOTIVOS_SUBSANACION_OS2);
			JQGridRequestDto jqgrid = new JQGridRequestDto();
			jqgrid.setSidx("CODIGO088");
			jqgrid.setSord("ASC");
			List<Tablones> listaMotivos = this.tablonesService.findAll(tablones,
					jqgrid);

			// Obtenemos el requerimiento de la tarea
			RequerimientoOS2 requerimiento = new RequerimientoOS2();
			requerimiento.setTareaOS2(tarea);
			List<RequerimientoOS2> listaMotivosReq = this.requerimientoOS2Service
					.findAll(requerimiento, null);

			String descOtrosEs = "";
			String descOtrosEu = "";

			if (listaMotivosReq != null && listaMotivosReq.size() > 0) {
				for (Tablones tipoMotivo : listaMotivos) {
					for (RequerimientoOS2 motivoReq : listaMotivosReq) {
						if (motivoReq.getMotivo047()
								.equals(tipoMotivo.getCodigo088())) {
							tipoMotivo.setSelected(true);
							break;
						}
					}
				}
				// Recogemos la descripcion del motivo 'Otros'
				for (RequerimientoOS2 motivoReq : listaMotivosReq) {
					if (motivoReq.getMotivo047()
							.equals(Constantes.MOTIVO_SUBSANACION_OTROS)) {
						descOtrosEs = motivoReq.getDescOtrosEs047() != null
								? motivoReq.getDescOtrosEs047() : "";
						descOtrosEu = motivoReq.getDescOtrosEu047() != null
								? motivoReq.getDescOtrosEu047() : "";
						break;
					}
				}
			}

			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_REQUERIMIENTO,
					requerimiento);
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_DESC_OTROS_ES,
					descOtrosEs);
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_DESC_OTROS_EU,
					descOtrosEu);
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_LISTA_MOTIVOS_REQ,
					listaMotivos);

			try {
				toolbarTramitacion = this.preparaToolbarRequerimiento();
			} catch (Exception e) {
				ComunicacionPrlController.logger.error(
						"Error al generar el toolbar de requerimiento", e);
				toolbarTramitacion = "{buttons: []}";
			}
		}

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				os2);

		model.addAttribute(
				ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_TOOLBAR_TRAMITACION,
				toolbarTramitacion);

		return tiles;
	}

	/**
	 * Acceder detalle tarea sugerida OS 3.
	 * 
	 * idTarea Long model Model
	 * 
	 * @param idTarea
	 *            the id tarea
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/taskOS3/{idTarea}")
	public String accederDetalleTareaSugeridaOS3(
			@PathVariable(value = "idTarea") Long idTarea, Model model) {

		TareaOS3 tarea = new TareaOS3(idTarea);
		tarea = this.tareaOS3Service.findTareaTramite(tarea);

		OS3 os3 = this.os3Service.find(tarea.getTramiteOS3().getOs3());

		String tiles = "";
		String toolbarTramitacion = "";

		if (TipoTareaFlujo.ESTUDIO
				.esEquivalente(tarea.getTipoTarea().getTaskId090())) {
			tiles = "estudioOS3";

			// Obtenemos el estudio de documentación de la tarea
			EstudioDocOS3 estudio = new EstudioDocOS3();
			estudio.setTareaOS3(tarea);
			estudio = this.estudioDocOS3Service.find(estudio);

			if (estudio == null) {
				// Si no existe, lo creamos
				estudio = new EstudioDocOS3(tarea);
				this.estudioDocOS3Service.add(estudio);
			}

			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_ESTUDIO,
					estudio);

			try {
				toolbarTramitacion = this.preparaToolbarEstudio();
			} catch (Exception e) {
				ComunicacionPrlController.logger
						.error("Error al generar el toolbar de estudio", e);
				toolbarTramitacion = "{buttons: []}";
			}
		} else if (TipoTareaFlujo.ADJUNTAR_DOC_REQUERIMIENTO
				.esEquivalente(tarea.getTipoTarea().getTaskId090())) {
			tiles = "requerimientoOS3";

			// Obtenemos los motivos de subsanacion
			Tablones tablones = new Tablones();
			tablones.setCodtabla088(Constantes.TABLON_MOTIVOS_SUBSANACION_OS3);
			JQGridRequestDto jqgrid = new JQGridRequestDto();
			jqgrid.setSidx("CODIGO088");
			jqgrid.setSord("ASC");
			List<Tablones> listaMotivos = this.tablonesService.findAll(tablones,
					jqgrid);

			// Obtenemos el requerimiento de la tarea
			RequerimientoOS3 requerimiento = new RequerimientoOS3();
			requerimiento.setTareaOS3(tarea);
			List<RequerimientoOS3> listaMotivosReq = this.requerimientoOS3Service
					.findAll(requerimiento, null);

			String descOtrosEs = "";
			String descOtrosEu = "";

			if (listaMotivosReq != null && listaMotivosReq.size() > 0) {
				for (Tablones tipoMotivo : listaMotivos) {
					for (RequerimientoOS3 motivoReq : listaMotivosReq) {
						if (motivoReq.getMotivo048()
								.equals(tipoMotivo.getCodigo088())) {
							tipoMotivo.setSelected(true);
							break;
						}
					}
				}
				// Recogemos la descripcion del motivo 'Otros'
				for (RequerimientoOS3 motivoReq : listaMotivosReq) {
					if (motivoReq.getMotivo048()
							.equals(Constantes.MOTIVO_SUBSANACION_OTROS)) {
						descOtrosEs = motivoReq.getDescOtrosEu048() != null
								? motivoReq.getDescOtrosEu048() : "";

						descOtrosEu = motivoReq.getDescOtrosEu048() != null
								? motivoReq.getDescOtrosEu048() : "";
						break;
					}
				}
			}

			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_REQUERIMIENTO,
					requerimiento);
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_DESC_OTROS_ES,
					descOtrosEs);
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_DESC_OTROS_EU,
					descOtrosEu);
			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_LISTA_MOTIVOS_REQ,
					listaMotivos);

			try {
				toolbarTramitacion = this.preparaToolbarRequerimiento();
			} catch (Exception e) {
				ComunicacionPrlController.logger.error(
						"Error al generar el toolbar de requerimiento", e);
				toolbarTramitacion = "{buttons: []}";
			}
		}

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				os3);

		model.addAttribute(
				ComunicacionAperturaController.ATTR_NAME_COMUNICAPERTURA_TOOLBAR_TRAMITACION,
				toolbarTramitacion);

		return tiles;
	}

	/**
	 * Prepara toolbar estudio.
	 * 
	 * String
	 * 
	 * @return the string
	 * @throws JsonMappingException
	 *             al parsear objeto a json
	 * @throws IOException
	 *             al parsear objeto a json
	 */
	private String preparaToolbarEstudio()
			throws JsonMappingException, IOException {

		ObjectMapper mapper = new ObjectMapper();
		Botonera botonera = new Botonera();

		Boton botonConsolidar = new Boton("consolidar", "consolidar");
		botonera.addBoton(botonConsolidar);

		return mapper.writeValueAsString(botonera);
	}

	/**
	 * Prepara toolbar requerimiento.
	 * 
	 * String
	 * 
	 * @return the string
	 * @throws JsonMappingException
	 *             al parsear objeto a json
	 * @throws IOException
	 *             al parsear objeto a json
	 */
	private String preparaToolbarRequerimiento()
			throws JsonMappingException, IOException {

		ObjectMapper mapper = new ObjectMapper();
		Botonera botonera = new Botonera();

		Boton botonPrev = new Boton("previsualizar", "previsualizar");
		botonera.addBoton(botonPrev);
		Boton botonGenerar = new Boton("generar", "generar");
		botonera.addBoton(botonGenerar);

		return mapper.writeValueAsString(botonera);
	}

	/**
	 * Consolidar estudio documentacion OS 2.
	 * 
	 * estudio EstudioDocAperturas
	 * 
	 * @param estudio
	 *            the estudio String DOCU_CORRECTA o REQ_SUBSANA
	 * @return the string
	 */
	@RequestMapping(value = "/consolidarEstudioOS2", method = RequestMethod.POST)
	public @ResponseBody() String consolidarEstudioDocumentacionOS2(
			@RequestBody() EstudioDocOS2 estudio) {

		if (Utilities.getInstance().isEmpty(estudio.getResultado046())) {
			throw new ErrorGenericoException("estudio.resultado",
					"validacion.obligatorio");
		}

		// Actualizamos el estudio en BD
		this.estudioDocOS2Service.update(estudio);

		estudio.setTareaOS2(this.tareaOS2Service.find(estudio.getTareaOS2()));

		// Tramitamos el estudio
		this.tramitacionOS2Service.tramitarEstudioDocumentacion(estudio);

		// Marcamos la tarea como iniciada (solo si está en estado SUGERIDA,
		// no sea que haya llegado antes el evento de EJECUTADA)
		TareaOS2 tarea = this.tareaOS2Service
				.findTareaTramite(estudio.getTareaOS2());
		if (EstadosTareas.SUGERIDA.getEstado().equals(tarea.getEstado093())) {
			tarea.setEstado093(EstadosTareas.INICIADA.getEstado());
			this.tareaOS2Service.updateFilled(tarea);
		}

		OS2 os2 = new OS2(tarea.getTramiteOS2().getos2().getTeros2060(),
				tarea.getTramiteOS2().getos2().getAnoos2060(),
				tarea.getTramiteOS2().getos2().getNumos2060());
		os2.setUsuarioTram060(
				UtilSeguridad.getInstance().getUserCredentials().getPosition());
		this.os2Service.updateUsuariosTramitacion(os2);

		return estudio.getResultado046();
	}

	/**
	 * Generar documento requerimiento OS 2.
	 * 
	 * listaTiposDoc List<String> idTarea Long descOtrosEs String descOtrosEu
	 * String
	 * 
	 * @param listaTiposDoc
	 *            the lista tipos doc
	 * @param idTarea
	 *            the id tarea
	 * @param descOtrosEs
	 *            the desc otros es
	 * @param descOtrosEu
	 *            the desc otros eu String
	 * @throws AB04BException
	 * @throws IOException
	 */
	@RequestMapping(value = "/prevDocumentoRequerimientoOS2", method = RequestMethod.GET)
	public void prevDocumentoRequerimientoOS2(
			@RequestParam(value = "docRequerimiento", required = false) List<String> listaTiposDoc,
			@RequestParam(value = "idTarea", required = false) Long idTarea,
			@RequestParam(value = "descOtrosEs", required = false) String descOtrosEs,
			@RequestParam(value = "descOtrosEu", required = false) String descOtrosEu,
			HttpServletResponse response) throws AB04BException, IOException {

		if (!(listaTiposDoc.size() > 0)) {
			throw new ErrorGenericoException("requerimiento.motivos",
					"error.motivos.subsanacion");
		}

		this.requerimientoOS2Service.removePorTarea(idTarea);

		// Actualizamos el requerimiento en BD
		TareaOS2 tarea = new TareaOS2(idTarea);
		for (int i = 0; i < listaTiposDoc.size(); i++) {
			RequerimientoOS2 requerimiento = new RequerimientoOS2();
			requerimiento.setTareaOS2(tarea);
			requerimiento.setMotivo047(listaTiposDoc.get(i));
			if (listaTiposDoc.get(i)
					.equals(Constantes.MOTIVO_SUBSANACION_OTROS)) {
				requerimiento.setDescOtrosEs047(descOtrosEs);
				requerimiento.setDescOtrosEu047(descOtrosEu);
			}
			this.requerimientoOS2Service.add(requerimiento);
		}

		tarea = this.tareaOS2Service.findTareaTramite(tarea);

		TramiteOS2 tramite = new TramiteOS2(
				tarea.getTramiteOS2().getIdTramite092());
		tramite = this.tramiteOS2Service.find(tramite);

		OS2 os2 = new OS2(tramite.getos2().getTeros2060(),
				tramite.getos2().getAnoos2060(),
				tramite.getos2().getNumos2060());

		os2.setUsuarioTram060(
				UtilSeguridad.getInstance().getUserCredentials().getPosition());
		this.os2Service.updateUsuariosTramitacion(os2);

		os2 = this.os2Service.find(os2);

		tramite.setos2(os2);
		tarea.setTramiteOS2(tramite);

		String foldernumber = tarea.getTramiteOS2().getos2().getNumExpediente();

		InputStream is = this.generacionPDFSubsanacionService.getPDF(
				foldernumber, ConstantesDocumentos.COMUNICACION_OS2,
				tramite.getIdTramite092());

		response.setContentType("application/pdf");
		// response.addHeader("Content-Disposition",
		// "attachment; filename=Requerimiento.pdf");

		FileCopyUtils.copy(is, response.getOutputStream());

		response.flushBuffer();
	}

	/**
	 * Generar documento requerimiento OS 2.
	 * 
	 * listaTiposDoc List<String> idTarea Long descOtrosEs String descOtrosEu
	 * String
	 * 
	 * @param listaTiposDoc
	 *            the lista tipos doc
	 * @param idTarea
	 *            the id tarea
	 * @param descOtrosEs
	 *            the desc otros es
	 * @param descOtrosEu
	 *            the desc otros eu String
	 * @return the string
	 */
	@RequestMapping(value = "/generarDocumentoRequerimientoOS2", method = RequestMethod.GET)
	public @ResponseBody() String generarDocumentoRequerimientoOS2(
			@RequestParam(value = "docRequerimiento", required = false) List<String> listaTiposDoc,
			@RequestParam(value = "idTarea", required = false) Long idTarea,
			@RequestParam(value = "descOtrosEs", required = false) String descOtrosEs,
			@RequestParam(value = "descOtrosEu", required = false) String descOtrosEu) {

		if (!(listaTiposDoc.size() > 0)) {
			throw new ErrorGenericoException("requerimiento.motivos",
					"error.motivos.subsanacion");
		}

		this.requerimientoOS2Service.removePorTarea(idTarea);

		// Actualizamos el requerimiento en BD
		TareaOS2 tarea = new TareaOS2(idTarea);
		for (int i = 0; i < listaTiposDoc.size(); i++) {
			RequerimientoOS2 requerimiento = new RequerimientoOS2();
			requerimiento.setTareaOS2(tarea);
			requerimiento.setMotivo047(listaTiposDoc.get(i));
			if (listaTiposDoc.get(i)
					.equals(Constantes.MOTIVO_SUBSANACION_OTROS)) {
				requerimiento.setDescOtrosEs047(descOtrosEs);
				requerimiento.setDescOtrosEu047(descOtrosEu);
			}
			this.requerimientoOS2Service.add(requerimiento);
		}

		tarea = this.tareaOS2Service.findTareaTramite(tarea);

		TramiteOS2 tramite = new TramiteOS2(
				tarea.getTramiteOS2().getIdTramite092());
		tramite = this.tramiteOS2Service.find(tramite);

		OS2 os2 = new OS2(tramite.getos2().getTeros2060(),
				tramite.getos2().getAnoos2060(),
				tramite.getos2().getNumos2060());

		os2.setUsuarioTram060(
				UtilSeguridad.getInstance().getUserCredentials().getPosition());
		this.os2Service.updateUsuariosTramitacion(os2);

		os2 = this.os2Service.find(os2);

		tramite.setos2(os2);
		tarea.setTramiteOS2(tramite);

		try {
			this.tramitacionOS2Service.prepararDocRequerimiento(tarea);
		} catch (Exception e) {
			ComunicacionPrlController.logger
					.error("Error al generar el documento de requerimiento", e);
		}

		// Marcamos la tarea como iniciada (solo si está en estado SUGERIDA,
		// no sea que haya llegado antes el evento de EJECUTADA)
		if (EstadosTareas.SUGERIDA.getEstado().equals(tarea.getEstado093())) {
			tarea.setEstado093(EstadosTareas.INICIADA.getEstado());
			this.tareaOS2Service.updateFilled(tarea);
		}

		return "";
	}

	/**
	 * Crear estudio documentacion OS 2.
	 * 
	 * model Model teros the teros anoos the anoos numos the numos
	 * 
	 * @param model
	 *            the model
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos String
	 * @return the string
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	@RequestMapping(value = "/crearEstudioDocumentacionOS2/{teros}/{anoos}/{numos}", method = RequestMethod.POST)
	public @ResponseBody() String crearEstudioDocumentacionOS2(Model model,
			@PathVariable() String teros, @PathVariable() String anoos,
			@PathVariable() Long numos) throws AB04BException {
		try {
			ComunicacionPrl cprl = new ComunicacionPrl();
			cprl.setTeros(teros);
			cprl.setAnoos(anoos);
			cprl.setNumos(numos.intValue());
			cprl.setTipoos(Constantes.OS2);
			cprl = this.comunicacionPrlService.find(cprl);

			this.plateaTramitacionService.crearTarea(
					Utilities.getInstance().obtenerProcedureIdOs2(),
					TipoTramiteFlujo.ESTUDIO.name(),
					TipoTareaFlujo.ESTUDIO.getTaskId(), cprl.getFolderId(),
					UtilSeguridad.getInstance().getUserCredentials()
							.getPosition(),
					UtilSeguridad.getInstance().getNombre());

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

	/**
	 * Crear estudio documentacion OS 3.
	 * 
	 * model Model teros the teros anoos the anoos numos the numos
	 * 
	 * @param model
	 *            the model
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos String
	 * @return the string
	 * @throws AB04BException
	 *             the AB 04 B exception
	 */
	@RequestMapping(value = "/crearEstudioDocumentacionOS3/{teros}/{anoos}/{numos}", method = RequestMethod.POST)
	public @ResponseBody() String crearEstudioDocumentacionOS3(Model model,
			@PathVariable() String teros, @PathVariable() String anoos,
			@PathVariable() Long numos) throws AB04BException {
		try {
			ComunicacionPrl cprl = new ComunicacionPrl();
			cprl.setTeros(teros);
			cprl.setAnoos(anoos);
			cprl.setNumos(numos.intValue());
			cprl.setTipoos(Constantes.OS3);
			cprl = this.comunicacionPrlService.find(cprl);

			this.plateaTramitacionService.crearTarea(
					Utilities.getInstance().obtenerProcedureIdOs3(),
					TipoTramiteFlujo.ESTUDIO.name(),
					TipoTareaFlujo.ESTUDIO.getTaskId(), cprl.getFolderId(),
					UtilSeguridad.getInstance().getUserCredentials()
							.getPosition(),
					UtilSeguridad.getInstance().getNombre());

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

	/**
	 * Consolidar estudio documentacion OS 3.
	 * 
	 * estudio EstudioDocAperturas
	 * 
	 * @param estudio
	 *            the estudio String DOCU_CORRECTA o REQ_SUBSANA
	 * @return the string
	 */
	@RequestMapping(value = "/consolidarEstudioOS3", method = RequestMethod.POST)
	public @ResponseBody() String consolidarEstudioDocumentacionOS3(
			@RequestBody() EstudioDocOS3 estudio) {

		if (Utilities.getInstance().isEmpty(estudio.getResultado044())) {
			throw new ErrorGenericoException("estudio.resultado",
					"validacion.obligatorio");
		}

		// Actualizamos el estudio en BD
		this.estudioDocOS3Service.update(estudio);

		estudio.setTareaOS3(this.tareaOS3Service.find(estudio.getTareaOS3()));

		// Tramitamos el estudio
		this.tramitacionOS3Service.tramitarEstudioDocumentacion(estudio);

		// Marcamos la tarea como iniciada (solo si está en estado SUGERIDA,
		// no sea que haya llegado antes el evento de EJECUTADA)
		TareaOS3 tarea = this.tareaOS3Service
				.findTareaTramite(estudio.getTareaOS3());
		if (EstadosTareas.SUGERIDA.getEstado().equals(tarea.getEstado096())) {
			tarea.setEstado096(EstadosTareas.INICIADA.getEstado());
			this.tareaOS3Service.updateFilled(tarea);
		}

		OS3 os3 = new OS3(tarea.getTramiteOS3().getOs3().getTeros3061(),
				tarea.getTramiteOS3().getOs3().getAnoos3061(),
				tarea.getTramiteOS3().getOs3().getNumos3061());
		os3.setUsuarioTram061(
				UtilSeguridad.getInstance().getUserCredentials().getPosition());
		this.os3Service.updateUsuariosTramitacion(os3);

		return estudio.getResultado044();
	}

	/**
	 * Cerrar expediente OS 2.
	 * 
	 * model Model teros the teros anoos the anoos numos the numos
	 * 
	 * @param model
	 *            the model
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos String
	 * @return the string
	 */
	@RequestMapping(value = "/cerrarExpedienteOS2/{teros}/{anoos}/{numos}", method = RequestMethod.POST)
	public @ResponseBody() String cerrarExpedienteOS2(Model model,
			@PathVariable() String teros, @PathVariable() String anoos,
			@PathVariable() Long numos) {

		OS2 os2 = new OS2(teros, anoos, numos.intValue());
		os2.setEstado060("E");
		this.os2Service.updateEstado(os2);

		return "tabTramitacion";
	}

	/**
	 * Cerrar expediente OS 3.
	 * 
	 * model Model teros the teros anoos the anoos numos the numos
	 * 
	 * @param model
	 *            the model
	 * @param teros
	 *            the teros
	 * @param anoos
	 *            the anoos
	 * @param numos
	 *            the numos String
	 * @return the string
	 */
	@RequestMapping(value = "/cerrarExpedienteOS3/{teros}/{anoos}/{numos}", method = RequestMethod.POST)
	public @ResponseBody() String cerrarExpedienteOS3(Model model,
			@PathVariable() String teros, @PathVariable() String anoos,
			@PathVariable() Long numos) {

		OS3 os3 = new OS3(teros, anoos, numos.intValue());
		os3.setEstado061("E");
		this.os3Service.updateEstado(os3);

		return "tabTramitacion";
	}

	/**
	 * Generar documento requerimiento OS 3.
	 * 
	 * listaTiposDoc List<String> idTarea Long descOtrosEs String descOtrosEu
	 * String
	 * 
	 * @param listaTiposDoc
	 *            the lista tipos doc
	 * @param idTarea
	 *            the id tarea
	 * @param descOtrosEs
	 *            the desc otros es
	 * @param descOtrosEu
	 *            the desc otros eu String
	 * @throws AB04BException
	 * @throws IOException
	 */
	@RequestMapping(value = "/prevDocumentoRequerimientoOS3", method = RequestMethod.GET)
	public void prevDocumentoRequerimientoOS3(
			@RequestParam(value = "docRequerimiento", required = false) List<String> listaTiposDoc,
			@RequestParam(value = "idTarea", required = false) Long idTarea,
			@RequestParam(value = "descOtrosEs", required = false) String descOtrosEs,
			@RequestParam(value = "descOtrosEu", required = false) String descOtrosEu,
			HttpServletResponse response) throws AB04BException, IOException {

		if (!(listaTiposDoc.size() > 0)) {
			throw new ErrorGenericoException("requerimiento.motivos",
					"error.motivos.subsanacion");
		}

		this.requerimientoOS3Service.removePorTarea(idTarea);

		// Actualizamos el requerimiento en BD
		TareaOS3 tarea = new TareaOS3(idTarea);
		for (int i = 0; i < listaTiposDoc.size(); i++) {
			RequerimientoOS3 requerimiento = new RequerimientoOS3();
			requerimiento.setTareaOS3(tarea);
			requerimiento.setMotivo048(listaTiposDoc.get(i));
			if (listaTiposDoc.get(i)
					.equals(Constantes.MOTIVO_SUBSANACION_OTROS)) {
				requerimiento.setDescOtrosEs048(descOtrosEs);
				requerimiento.setDescOtrosEu048(descOtrosEu);
			}
			this.requerimientoOS3Service.add(requerimiento);
		}

		tarea = this.tareaOS3Service.findTareaTramite(tarea);

		TramiteOS3 tramite = new TramiteOS3(
				tarea.getTramiteOS3().getIdTramite095());
		tramite = this.tramiteOS3Service.find(tramite);

		OS3 os3 = new OS3(tramite.getOs3().getTeros3061(),
				tramite.getOs3().getAnoos3061(),
				tramite.getOs3().getNumos3061());

		os3.setUsuarioTram061(
				UtilSeguridad.getInstance().getUserCredentials().getPosition());
		this.os3Service.updateUsuariosTramitacion(os3);

		os3 = this.os3Service.find(os3);

		tramite.setOs3(os3);
		tarea.setTramiteOS3(tramite);

		String foldernumber = tarea.getTramiteOS3().getOs3().getNumExpediente();

		InputStream is = this.generacionPDFSubsanacionService.getPDF(
				foldernumber, ConstantesDocumentos.COMUNICACION_OS3,
				tramite.getIdTramite095());

		response.setContentType("application/pdf");
		// response.addHeader("Content-Disposition",
		// "attachment; filename=Requerimiento.pdf");

		FileCopyUtils.copy(is, response.getOutputStream());

		response.flushBuffer();
	}

	/**
	 * Generar documento requerimiento OS 3.
	 * 
	 * listaTiposDoc List<String> idTarea Long descOtrosEs String descOtrosEu
	 * String
	 * 
	 * @param listaTiposDoc
	 *            the lista tipos doc
	 * @param idTarea
	 *            the id tarea
	 * @param descOtrosEs
	 *            the desc otros es
	 * @param descOtrosEu
	 *            the desc otros eu String
	 * @return the string
	 */
	@RequestMapping(value = "/generarDocumentoRequerimientoOS3", method = RequestMethod.GET)
	public @ResponseBody() String generarDocumentoRequerimientoOS3(
			@RequestParam(value = "docRequerimiento", required = false) List<String> listaTiposDoc,
			@RequestParam(value = "idTarea", required = false) Long idTarea,
			@RequestParam(value = "descOtrosEs", required = false) String descOtrosEs,
			@RequestParam(value = "descOtrosEu", required = false) String descOtrosEu) {

		if (!(listaTiposDoc.size() > 0)) {
			throw new ErrorGenericoException("requerimiento.motivos",
					"error.motivos.subsanacion");
		}

		this.requerimientoOS3Service.removePorTarea(idTarea);

		// Actualizamos el requerimiento en BD
		TareaOS3 tarea = new TareaOS3(idTarea);
		for (int i = 0; i < listaTiposDoc.size(); i++) {
			RequerimientoOS3 requerimiento = new RequerimientoOS3();
			requerimiento.setTareaOS3(tarea);
			requerimiento.setMotivo048(listaTiposDoc.get(i));
			if (listaTiposDoc.get(i)
					.equals(Constantes.MOTIVO_SUBSANACION_OTROS)) {
				requerimiento.setDescOtrosEs048(descOtrosEs);
				requerimiento.setDescOtrosEu048(descOtrosEu);
			}
			this.requerimientoOS3Service.add(requerimiento);
		}

		tarea = this.tareaOS3Service.findTareaTramite(tarea);

		TramiteOS3 tramite = new TramiteOS3(
				tarea.getTramiteOS3().getIdTramite095());
		tramite = this.tramiteOS3Service.find(tramite);

		OS3 os3 = new OS3(tramite.getOs3().getTeros3061(),
				tramite.getOs3().getAnoos3061(),
				tramite.getOs3().getNumos3061());

		os3.setUsuarioTram061(
				UtilSeguridad.getInstance().getUserCredentials().getPosition());
		this.os3Service.updateUsuariosTramitacion(os3);

		os3 = this.os3Service.find(os3);

		tramite.setOs3(os3);
		tarea.setTramiteOS3(tramite);

		try {
			this.tramitacionOS3Service.prepararDocRequerimiento(tarea);
		} catch (Exception e) {
			ComunicacionPrlController.logger
					.error("Error al generar el documento de requerimiento", e);
		}

		// Marcamos la tarea como iniciada (solo si está en estado SUGERIDA,
		// no sea que haya llegado antes el evento de EJECUTADA)
		if (EstadosTareas.SUGERIDA.getEstado().equals(tarea.getEstado096())) {
			tarea.setEstado096(EstadosTareas.INICIADA.getEstado());
			this.tareaOS3Service.updateFilled(tarea);
		}

		return "";
	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * model Model request HttpServletRequest locale Locale
	 * 
	 * @param model
	 *            the model
	 * @param request
	 *            the request
	 * @param locale
	 *            the locale String
	 * @return the string
	 */
	@RequestMapping(value = "/altaOS2", method = RequestMethod.GET)
	public String altaPresencialOS2(Model model, HttpServletRequest request,
			Locale locale) {

		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(new Date());
		model.addAttribute("ano", Long.valueOf(gc.get(GregorianCalendar.YEAR)));

		model.addAttribute("delegacion",
				UtilSeguridad.getInstance().obtenerDelegacionUsuario());

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS2_DETALLE,
				new OS2());
		this.precargaCombosFiltroBusqueda(model);

		return "expedientesAltaOS2";
	}

	/**
	 * Alta de Expediente
	 * 
	 * 
	 * @param os2
	 *            Denuncia Bean que contiene la informacion con la que se va a
	 *            crear el nuevo registro.
	 * @return Denuncia Bean resultante del proceso de creacion.
	 */
	@RequestMapping(value = "/addOS2", method = RequestMethod.POST)
	public @ResponseBody() OS2 add(@RequestBody() OS2 os2) {
		return this.os2Service.altaComunicacionOS2Presencial(os2);
	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * model Model request HttpServletRequest locale Locale
	 * 
	 * @param model
	 *            the model
	 * @param request
	 *            the request
	 * @param locale
	 *            the locale String
	 * @return the string
	 */
	@RequestMapping(value = "/altaOS3", method = RequestMethod.GET)
	public String altaPresencialOS3(Model model, HttpServletRequest request,
			Locale locale) {

		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(new Date());
		model.addAttribute("ano", Long.valueOf(gc.get(GregorianCalendar.YEAR)));

		model.addAttribute("delegacion",
				UtilSeguridad.getInstance().obtenerDelegacionUsuario());

		model.addAttribute(
				ComunicacionPrlController.ATTR_NAME_COMUNICAPRL_OS3_DETALLE,
				new OS3());
		this.precargaCombosFiltroBusqueda(model);

		return "expedientesAltaOS3";
	}

	/**
	 * Alta de Expediente
	 * 
	 * 
	 * @param os3
	 *            Denuncia Bean que contiene la informacion con la que se va a
	 *            crear el nuevo registro.
	 * @return Denuncia Bean resultante del proceso de creacion.
	 */
	@RequestMapping(value = "/addOS3", method = RequestMethod.POST)
	public @ResponseBody() OS3 add(@RequestBody() OS3 os3) {
		return this.os3Service.altaComunicacionOS3Presencial(os3);
	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * cprl ComunicacionPrl model Model
	 * 
	 * @param cprl
	 *            the cprl
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/abrirComunicacionOS2", method = RequestMethod.POST)
	public @ResponseBody() String abrirComunicacionOS2(
			@RequestBody() ComunicacionPrl cprl, Model model,
			HttpServletRequest request) {
		ComunicacionPrl cprlAux = cprl;

		cprlAux.setTipoos(Constantes.OS2);
		cprlAux = this.comunicacionPrlService.find(cprlAux);

		List<ErrorField> errores = new ArrayList<ErrorField>();
		this.validaComunicacionOS2Presencial(errores, cprlAux);

		OS2 os2 = OS2.convertComunicacionPrltoOS2(cprlAux);

		OS2 os2_reg = this.os2Service.findDatosRegistro(os2);
		os2.setDeseaRegistrar060(os2_reg.getDeseaRegistrar060());
		os2.setNumReg060(os2_reg.getNumReg060());
		os2.setFecReg060(os2_reg.getFecReg060());

		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		// List<DocumentoOS2> listaDocumentos = new ArrayList<DocumentoOS2>();

		try {
			String reabrir = (String) request.getParameter("reabrir");

			List<DocumentoOS2> listaDocumentos = this.copiarDocsR02G(
					cprlAux.getTeros(), cprlAux.getAnoos(), cprlAux.getNumos(),
					(reabrir != null));

			ContextSubmission contextSubmission = this.ppsOS2Service
					.crearContextSubmission(os2, listaDocumentos);

			RequestReturn requestReturn = this.ppsOS2Service
					.enviarSolicitudPresencial(contextSubmission);
			PPSReturnInfo ppsReturnInfo = PPSUtils.getInstance()
					.obtenerPPSReturnInfo(requestReturn);

			Folder folder = new Folder();
			folder.setFolderid077(ppsReturnInfo.getFolderId());
			folder.setAnoexp077(cprlAux.getAnoos());
			folder.setNumexp077(cprlAux.getNumos());
			folder.setTerexp077(cprlAux.getTeros());
			folder.setTipexp077(TipoExpedienteFolderEnum.OS2
					.getIdTipoExpediente().toString());
			try {
				this.folderService.add(folder);
			} catch (Exception e) {
				this.folderService.updateFolderId(folder);
			}

			os2.setFecpre060(new Date());
			os2.setEstado060("S");
			this.os2Service.updateFilled(os2);

		} catch (Exception e) {

			errores.add(
					new ErrorField("comunicacion.apertura", "error.apertura"));
			throw new ErrorGenericoException(errores);
		}

		model.addAttribute(ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
				Constantes.MODO_ACCESO_MANTENIMIENTO);

		return "ok";
	}

	/**
	 * Copiar docs R 02 G.
	 * 
	 * idApe Integer List<DocumentoAperturas>
	 * 
	 * @param idApe
	 *            the id ape the list
	 * 
	 * @param territorio
	 *            String
	 * @return the list
	 * @throws AB04BException
	 *             producida al copiar los documentos en PIF
	 */
	protected List<DocumentoOS2> copiarDocsR02G(String teros, String anoos,
			Integer numos, boolean reabrir) throws AB04BException {
		DocumentoOS2 filterDoc = new DocumentoOS2();
		TramiteOS2 tramite = new TramiteOS2(null, null,
				new OS2(teros, anoos, numos.intValue()));
		filterDoc.setTramiteOS2(tramite);

		TipoDocumento tipoDoc = new TipoDocumento();
		tipoDoc.setAportGen091(Constantes.TIPO_DOCUMENTO_APORTADO);
		filterDoc.setTipoDocumento(tipoDoc);

		List<DocumentoOS2> listaDocumentos = null;
		if (reabrir) {
			listaDocumentos = this.documentoOS2Service.findAll(filterDoc, null);
		} else {
			listaDocumentos = this.os2Service
					.buscarDocumentosOS2Temp(filterDoc);
		}

		for (DocumentoOS2 doc : listaDocumentos) {

			if (doc.getOidDokusi094() == null) {

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

				// doc.setTerritorio(teros);

				// copiamos documento en PIF a t65e
				String destPifPath = doc.getRutaPif094().replaceAll(
						ConstantesDokusi.PIF_AB04B_FOLDER.toUpperCase(),
						ConstantesDokusi.PIF_T65E_FOLDER);

				String ruta_dokusi = pifService
						.copyDocument(doc.getRutaPif094(), destPifPath, false);
				doc.setRutaPif094(ruta_dokusi); // no se guardará en BD

				// registramos en Dokusi
				T65BDocumentIDType t65BDocumentIDType = this.dokusiService
						.almacenarDocumento(auditUser, doc);

				// anadimos a la lista temporal los OIDs registrados
				doc.setOidDokusi094(t65BDocumentIDType.getId());
				this.documentosOS2TempDao.update(doc);
			}
		}

		return listaDocumentos;
	}

	/**
	 * Copiar docs R 02 G.
	 * 
	 * idApe Integer List<DocumentoAperturas>
	 * 
	 * @param idApe
	 *            the id ape the list
	 * 
	 * @param territorio
	 *            String
	 * @return the list
	 * @throws AB04BException
	 *             producida al copiar los documentos en PIF
	 */
	protected List<DocumentoOS3> copiarDocsR02GOS3(String teros, String anoos,
			Integer numos, boolean reabrir) throws AB04BException {
		DocumentoOS3 filterDoc = new DocumentoOS3();
		TramiteOS3 tramite = new TramiteOS3(null, null,
				new OS3(teros, anoos, numos.intValue()));
		filterDoc.setTramiteOS3(tramite);

		TipoDocumento tipoDoc = new TipoDocumento();
		tipoDoc.setAportGen091(Constantes.TIPO_DOCUMENTO_APORTADO);
		filterDoc.setTipoDocumento(tipoDoc);

		List<DocumentoOS3> listaDocumentos = null;
		if (reabrir) {
			listaDocumentos = this.documentoOS3Service.findAll(filterDoc, null);
		} else {
			listaDocumentos = this.os3Service
					.buscarDocumentosOS3Temp(filterDoc);
		}

		for (DocumentoOS3 doc : listaDocumentos) {

			if (doc.getOidDokusi097() == null) {

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

				// doc.setTerritorio(teros);

				// copiamos documento en PIF a t65e
				String destPifPath = doc.getRutaPif097().replaceAll(
						ConstantesDokusi.PIF_AB04B_FOLDER.toUpperCase(),
						ConstantesDokusi.PIF_T65E_FOLDER);

				String ruta_dokusi = pifService
						.copyDocument(doc.getRutaPif097(), destPifPath, false);
				doc.setRutaPif097(ruta_dokusi); // no se guardará en BD

				// registramos en Dokusi
				T65BDocumentIDType t65BDocumentIDType = this.dokusiService
						.almacenarDocumento(auditUser, doc);

				// anadimos a la lista temporal los OIDs registrados
				doc.setOidDokusi097(t65BDocumentIDType.getId());
				this.documentosOS3TempDao.update(doc);
			}
		}

		return listaDocumentos;
	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * cprl ComunicacionPrl request HttpServletRequest model Model
	 * 
	 * @param cprl
	 *            the cprl
	 * @param request
	 *            the request
	 * @param model
	 *            the model String
	 * @return the string
	 */

	@RequestMapping(value = "/subsanarOS2", method = RequestMethod.POST)
	public @ResponseBody() String subsanarOS2(
			@RequestBody() ComunicacionPrl cprl, HttpServletRequest request,
			Model model) {
		ComunicacionPrl cprlAux = cprl;

		cprlAux.setTipoos(Constantes.OS2);
		cprlAux = this.comunicacionPrlService.find(cprlAux);

		OS2 os2 = OS2.convertComunicacionPrltoOS2(cprlAux);

		OS2 os2_reg = this.os2Service.findDatosRegistro(os2);
		os2.setDeseaRegistrar060(os2_reg.getDeseaRegistrar060());
		os2.setNumReg060(os2_reg.getNumReg060());
		os2.setFecReg060(os2_reg.getFecReg060());

		List<DocumentoOS2> listaDocumentos = new ArrayList<DocumentoOS2>();

		String modoAcceso = (String) request.getSession().getAttribute(
				ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO);

		List<ErrorField> errores = new ArrayList<ErrorField>();
		if (Constantes.MODO_ACCESO_SUBSANACION.equals(modoAcceso)
				&& Constantes.VALUE_NO.equals(os2.getDeseaRegistrar060())) {
			if (Utilities.getInstance().isEmpty(os2.getNumReg060())) {
				errores.add(new ErrorField("aperturas.detalle.numReg",
						"validacion.obligatorio"));
			}
			if (os2.getFecReg060() == null) {
				errores.add(new ErrorField("aperturas.detalle.fecReg",
						"validacion.obligatorio"));
			}
		}

		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		try {
			ContextSubmission contextSubmission = this.ppsAportacionOS2Service
					.crearContextSubmission(true, os2, listaDocumentos);

			this.ppsAportacionOS2Service
					.enviarAportacionPresencial(contextSubmission);
		} catch (Exception e) {

			errores.add(new ErrorField("", "error.aplicacion"));
			throw new ErrorGenericoException(errores);
		}

		model.addAttribute(ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
				modoAcceso);

		return "ok";

	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * cprl ComunicacionPrl request HttpServletRequest model Model
	 * 
	 * @param cprl
	 *            the cprl
	 * @param request
	 *            the request
	 * @param model
	 *            the model String
	 * @return the string
	 */

	@RequestMapping(value = "/subsanarOS3", method = RequestMethod.POST)
	public @ResponseBody() String subsanarOS3(
			@RequestBody() ComunicacionPrl cprl, HttpServletRequest request,
			Model model) {
		ComunicacionPrl cprlAux = cprl;

		cprlAux.setTipoos(Constantes.OS3);
		cprlAux = this.comunicacionPrlService.find(cprlAux);

		OS3 os3 = OS3.convertComunicacionPrltoOS3(cprlAux);

		OS3 os3_reg = this.os3Service.findDatosRegistro(os3);
		os3.setDeseaRegistrar061(os3_reg.getDeseaRegistrar061());
		os3.setNumReg061(os3_reg.getNumReg061());
		os3.setFecReg061(os3_reg.getFecReg061());

		List<DocumentoOS3> listaDocumentos = new ArrayList<DocumentoOS3>();

		String modoAcceso = (String) request.getSession().getAttribute(
				ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO);

		List<ErrorField> errores = new ArrayList<ErrorField>();
		if (Constantes.MODO_ACCESO_SUBSANACION.equals(modoAcceso)
				&& Constantes.VALUE_NO.equals(os3.getDeseaRegistrar061())) {
			if (Utilities.getInstance().isEmpty(os3.getNumReg061())) {
				errores.add(new ErrorField("aperturas.detalle.numReg",
						"validacion.obligatorio"));
			}
			if (os3.getFecReg061() == null) {
				errores.add(new ErrorField("aperturas.detalle.fecReg",
						"validacion.obligatorio"));
			}
		}

		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		ContextSubmission contextSubmission = this.ppsAportacionOS3Service
				.crearContextSubmission(true, os3, listaDocumentos);

		try {
			this.ppsAportacionOS3Service
					.enviarAportacionPresencial(contextSubmission);

			model.addAttribute(
					ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
					modoAcceso);
		} catch (Exception e) {

			errores.add(new ErrorField("", "error.aplicacion"));
			throw new ErrorGenericoException(errores);
		}

		return "ok";

	}

	/**
	 * Valida comunicacion OS 2 presencial.
	 * 
	 * errores List<ErrorField> os2 ComunicacionPrl
	 * 
	 * @param errores
	 *            the errores
	 * @param os2
	 *            the os 2
	 */
	private void validaComunicacionOS2Presencial(List<ErrorField> errores,
			ComunicacionPrl os2) {

		os2.setDatosNotificacion(this.datosNotificacionService
				.findConLocalizacionYAvisos(os2.getDatosNotificacion()));
		if (os2.getDatosNotificacion() != null) {
			DatosAviso filterDatosAviso = new DatosAviso();
			filterDatosAviso.setDatosNotificacion(os2.getDatosNotificacion());
			os2.getDatosNotificacion().setListaDatosAviso(
					this.datosAvisoService.findAll(filterDatosAviso, null));
		}
		// DATOS NOTIFICACION
		List<ErrorField> errorTabDatosNotificacion = this.comunicacionPrlValidator
				.validate(os2, Oper.EDIT_TAB_NOTIFICACION);

		if (Constantes.VALUE_NO.equals(os2.getDeseaRegistrar())) {
			if (Utilities.getInstance().isEmpty(os2.getNumReg())) {
				errorTabDatosNotificacion.add(new ErrorField(
						"aperturas.detalle.numReg", "validacion.obligatorio"));
			}
			if (os2.getFecReg() == null) {
				errorTabDatosNotificacion.add(new ErrorField(
						"aperturas.detalle.fecReg", "validacion.obligatorio"));
			}
		}

		if (os2.getNumdocrepresentante() != null) {
			if (!ValidadorNifCifNie.isCifValido(os2.getNumdocrepresentante())
					&& !ValidadorNifCifNie
							.isNifValido(os2.getNumdocrepresentante())) {
				errorTabDatosNotificacion.add(
						new ErrorField("aperturas.detalle.datosRepresentante",
								"error.nifcif.incorrecto"));
			}
		}
		if ((os2.getNumdocrepresentante() != null
				&& os2.getNomrepresentante() == null)
				|| (os2.getNumdocrepresentante() == null
						&& os2.getNomrepresentante() != null)) {
			errorTabDatosNotificacion
					.add(new ErrorField("perturas.detalle.datosRepresentante2",
							"validacion.obligatorio"));
		}

		if (!errorTabDatosNotificacion.isEmpty()) {
			List<Mensaje> listaMensajes = new ArrayList<Mensaje>();
			for (ErrorField error : errorTabDatosNotificacion) {
				listaMensajes.add(new Mensaje(error.getCampo()));
			}
			errores.add(
					new ErrorField("aperturas.tabs.datosNotif", listaMensajes));
		}

		// DATOS EMPRESA
		List<ErrorField> errorTabEmpresa = this.comunicacionPrlValidator
				.validate(os2, Oper.EDIT_TAB_EMPRESAOS2);
		if (!errorTabEmpresa.isEmpty()) {
			List<Mensaje> listaMensajes = new ArrayList<Mensaje>();
			for (ErrorField error : errorTabEmpresa) {
				listaMensajes.add(new Mensaje(error.getCampo()));
			}
			errores.add(new ErrorField("aperturas.tabs.datosEmpresa",
					listaMensajes));
		}

		List<ErrorField> errorTabPrevencion = this.comunicacionPrlValidator
				.validate(os2, Oper.EDIT_TAB_PREVENCIONOS2);
		if (!errorTabPrevencion.isEmpty()) {
			List<Mensaje> listaMensajes = new ArrayList<Mensaje>();
			for (ErrorField error : errorTabPrevencion) {
				listaMensajes.add(new Mensaje(error.getCampo()));
			}
			errores.add(new ErrorField("aperturas.tabs.datosmodPreventiva",
					listaMensajes));
		}

		// DATOS CENTRO
		List<ErrorField> errorTabAuditoria = this.comunicacionPrlValidator
				.validate(os2, Oper.EDIT_TAB_AUDITORIA);
		if (!errorTabAuditoria.isEmpty()) {
			List<Mensaje> listaMensajes = new ArrayList<Mensaje>();
			for (ErrorField error : errorTabAuditoria) {
				listaMensajes.add(new Mensaje(error.getCampo()));
			}
			errores.add(new ErrorField("aperturas.tabs.datosAuditoria",
					listaMensajes));
		}

	}

	/**
	 * Metodo de presentacion del RUP_TABLE.
	 * 
	 * cprl ComunicacionPrl model Model
	 * 
	 * @param cprl
	 *            the cprl
	 * @param model
	 *            the model String
	 * @return the string
	 */
	@RequestMapping(value = "/abrirComunicacionOS3", method = RequestMethod.POST)
	public @ResponseBody() String abrirComunicacionOS3(
			@RequestBody() ComunicacionPrl cprl, Model model,
			HttpServletRequest request) {
		ComunicacionPrl cprlAux = cprl;

		cprlAux.setTipoos(Constantes.OS3);
		cprlAux = this.comunicacionPrlService.find(cprlAux);

		List<ErrorField> errores = new ArrayList<ErrorField>();
		this.validaComunicacionOS3Presencial(errores, cprlAux);

		OS3 os3 = OS3.convertComunicacionPrltoOS3(cprlAux);

		OS3 os3_reg = this.os3Service.findDatosRegistro(os3);
		os3.setDeseaRegistrar061(os3_reg.getDeseaRegistrar061());
		os3.setNumReg061(os3_reg.getNumReg061());
		os3.setFecReg061(os3_reg.getFecReg061());

		if (!errores.isEmpty()) {
			throw new ErrorGenericoException(errores);
		}

		// List<DocumentoOS3> listaDocumentos = new ArrayList<DocumentoOS3>();
		try {
			String reabrir = (String) request.getParameter("reabrir");

			List<DocumentoOS3> listaDocumentos = this.copiarDocsR02GOS3(
					cprlAux.getTeros(), cprlAux.getAnoos(), cprlAux.getNumos(),
					(reabrir != null));

			ContextSubmission contextSubmission = this.ppsOS3Service
					.crearContextSubmission(os3, listaDocumentos);

			RequestReturn requestReturn = this.ppsOS3Service
					.enviarSolicitudPresencial(contextSubmission);
			PPSReturnInfo ppsReturnInfo = PPSUtils.getInstance()
					.obtenerPPSReturnInfo(requestReturn);

			Folder folder = new Folder();
			folder.setFolderid077(ppsReturnInfo.getFolderId());
			folder.setAnoexp077(cprlAux.getAnoos());
			folder.setNumexp077(cprlAux.getNumos());
			folder.setTerexp077(cprlAux.getTeros());
			folder.setTipexp077(TipoExpedienteFolderEnum.OS3
					.getIdTipoExpediente().toString());
			try {
				this.folderService.add(folder);
			} catch (Exception e) {
				this.folderService.updateFolderId(folder);
			}

			os3.setFecpre061(new Date());
			os3.setEstado061("S");
			this.os3Service.updateFilled(os3);

		} catch (Exception e) {

			errores.add(
					new ErrorField("comunicacion.apertura", "error.apertura"));
			throw new ErrorGenericoException(errores);
		}

		model.addAttribute(ComunicacionAperturaController.ATTR_NAME_MODO_ACCESO,
				Constantes.MODO_ACCESO_MANTENIMIENTO);

		return "ok";
	}

	/**
	 * Valida comunicacion OS 3 presencial.
	 * 
	 * errores List<ErrorField> os3 ComunicacionPrl
	 * 
	 * @param errores
	 *            the errores
	 * @param os3
	 *            the os 3
	 */
	private void validaComunicacionOS3Presencial(List<ErrorField> errores,
			ComunicacionPrl os3) {

		os3.setDatosNotificacion(this.datosNotificacionService
				.findConLocalizacionYAvisos(os3.getDatosNotificacion()));
		if (os3.getDatosNotificacion() != null) {
			DatosAviso filterDatosAviso = new DatosAviso();
			filterDatosAviso.setDatosNotificacion(os3.getDatosNotificacion());
			os3.getDatosNotificacion().setListaDatosAviso(
					this.datosAvisoService.findAll(filterDatosAviso, null));
		}
		// DATOS NOTIFICACION
		List<ErrorField> errorTabDatosNotificacion = this.comunicacionPrlValidator
				.validate(os3, Oper.EDIT_TAB_NOTIFICACION);

		if (Constantes.VALUE_NO.equals(os3.getDeseaRegistrar())) {
			if (Utilities.getInstance().isEmpty(os3.getNumReg())) {
				errorTabDatosNotificacion.add(new ErrorField(
						"aperturas.detalle.numReg", "validacion.obligatorio"));
			}
			if (os3.getFecReg() == null) {
				errorTabDatosNotificacion.add(new ErrorField(
						"aperturas.detalle.fecReg", "validacion.obligatorio"));
			}
		}

		if (os3.getNumdocrepresentante() != null) {
			if (!ValidadorNifCifNie.isCifValido(os3.getNumdocrepresentante())
					&& !ValidadorNifCifNie
							.isNifValido(os3.getNumdocrepresentante())) {
				errorTabDatosNotificacion.add(
						new ErrorField("aperturas.detalle.datosRepresentante",
								"error.nifcif.incorrecto"));
			}
		}
		if ((os3.getNumdocrepresentante() != null
				&& os3.getNomrepresentante() == null)
				|| (os3.getNumdocrepresentante() == null
						&& os3.getNomrepresentante() != null)) {
			errorTabDatosNotificacion
					.add(new ErrorField("perturas.detalle.datosRepresentante2",
							"validacion.obligatorio"));
		}

		if (!errorTabDatosNotificacion.isEmpty()) {
			List<Mensaje> listaMensajes = new ArrayList<Mensaje>();
			for (ErrorField error : errorTabDatosNotificacion) {
				listaMensajes.add(new Mensaje(error.getCampo()));
			}
			errores.add(
					new ErrorField("aperturas.tabs.datosNotif", listaMensajes));
		}

		// DATOS EMPRESA
		List<ErrorField> errorTabEmpresa = this.comunicacionPrlValidator
				.validate(os3, Oper.EDIT_TAB_EMPRESAOS3);
		if (!errorTabEmpresa.isEmpty()) {
			List<Mensaje> listaMensajes = new ArrayList<Mensaje>();
			for (ErrorField error : errorTabEmpresa) {
				listaMensajes.add(new Mensaje(error.getCampo()));
			}
			errores.add(new ErrorField("aperturas.tabs.datosEmpresa",
					listaMensajes));
		}

		// DATOS CENTRO
		List<ErrorField> errorTabAuditoria = this.comunicacionPrlValidator
				.validate(os3, Oper.EDIT_TAB_PREVENCIONOS3);
		if (!errorTabAuditoria.isEmpty()) {
			List<Mensaje> listaMensajes = new ArrayList<Mensaje>();
			for (ErrorField error : errorTabAuditoria) {
				listaMensajes.add(new Mensaje(error.getCampo()));
			}
			errores.add(new ErrorField("aperturas.tabs.datosPrevencion",
					listaMensajes));
		}

	}

	/**
	 * ComunicacionPrlController.
	 * 
	 * modoAcceso String
	 * 
	 * @param modoAcceso
	 *            the modo acceso String
	 * @return the string
	 * @throws JsonMappingException
	 *             al parsear objeto a json
	 * @throws IOException
	 *             al parsear objeto a json
	 */
	private String preparaToolbarTramitacion(String modoAcceso)
			throws JsonMappingException, IOException {

		ObjectMapper mapper = new ObjectMapper();
		Botonera botonera = new Botonera();

		Boton botonAccionesDisponibles = new Boton("accionesdisponibles",
				"accionesdisponibles");
		List<Boton> listaBotonesAccionesDisponibles = new ArrayList<Boton>();
		if (Constantes.MODO_ACCESO_MANTENIMIENTO.equals(modoAcceso)) {

			// Abrir expediente
			listaBotonesAccionesDisponibles
					.add(new Boton("reabrirExpediente", "abrirExpediente"));

			// Estudio de documentación
			listaBotonesAccionesDisponibles.add(
					new Boton("estudiodocumentacion", "estudiodocumentacion"));

			// Cerrar expediente
			listaBotonesAccionesDisponibles
					.add(new Boton("borrarExpediente", "borrarExpediente"));
		}

		if (!listaBotonesAccionesDisponibles.isEmpty()) {
			botonAccionesDisponibles
					.setButtons(listaBotonesAccionesDisponibles);
		}
		botonera.addBoton(botonAccionesDisponibles);

		return mapper.writeValueAsString(botonera);
	}

	@RequestMapping(value = "/relanzarError", method = RequestMethod.POST)
	public @ResponseBody() String relanzarError(
			@RequestParam(value = "mailbox", required = false) String mailboxTaskId,
			@RequestParam(value = "type", required = false) String taskType,
			Model model) throws Exception {

		tareaErroneaService.remove(new TareaErronea(mailboxTaskId, taskType));
		svtService.process(mailboxTaskId, taskType);

		return "ok";
	}

}
