/*
* Copyright 2021 E.J.I.E., S.A.
*
* Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);
* Solo podrá usarse esta obra si se respeta la Licencia.
* Puede obtenerse una copia de la Licencia en
*
* http://ec.europa.eu/idabc/eupl.html
*
* Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,
* el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,
* SIN GARANT�?AS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.
* Véase la Licencia en el idioma concreto que rige los permisos y limitaciones
* que establece la Licencia.
*/
package com.ejie.ad74a.service;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

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

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.odftoolkit.odfdom.doc.OdfSpreadsheetDocument;
import org.odftoolkit.odfdom.doc.table.OdfTable;
import org.odftoolkit.odfdom.doc.table.OdfTableRow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ejie.ad74a.dao.BandejaPapel0Dao;
import com.ejie.ad74a.dao.CuentasDao;
import com.ejie.ad74a.dao.DependenciaDao;
import com.ejie.ad74a.dao.DireccionesDao;
import com.ejie.ad74a.dao.DiscapacidadDao;
import com.ejie.ad74a.dao.ExpedientesDao;
import com.ejie.ad74a.dao.PerfilesDao;
import com.ejie.ad74a.dao.PisosTuteladosDao;
import com.ejie.ad74a.dao.SolicitantesDao;
import com.ejie.ad74a.dao.TareasTramiteDao;
import com.ejie.ad74a.dao.TramitesExpedienteDao;
import com.ejie.ad74a.exceptions.Ad74aException;
import com.ejie.ad74a.exceptions.ErrorField;
import com.ejie.ad74a.exceptions.ManagerErrors;
import com.ejie.ad74a.exceptions.ValidatorException;
import com.ejie.ad74a.model.BandejaPapel0;
import com.ejie.ad74a.model.Cuentas;
import com.ejie.ad74a.model.DatosTareaEstudio;
import com.ejie.ad74a.model.Dependencia;
import com.ejie.ad74a.model.Direcciones;
import com.ejie.ad74a.model.Discapacidad;
import com.ejie.ad74a.model.DocumentoPapel0;
import com.ejie.ad74a.model.DocumentosTarea;
import com.ejie.ad74a.model.Estados;
import com.ejie.ad74a.model.Expedientes;
import com.ejie.ad74a.model.Perfiles;
import com.ejie.ad74a.model.PisosTutelados;
import com.ejie.ad74a.model.Solicitantes;
import com.ejie.ad74a.model.TareasTramite;
import com.ejie.ad74a.model.TramitesExpediente;
import com.ejie.ad74a.service.tramitacion.TramitacionService;
import com.ejie.ad74a.util.comun.UtilLiterales;
import com.ejie.ad74a.util.comun.UtilSeguridad;
import com.ejie.ad74a.util.comun.UtilTokenXlnets;
import com.ejie.ad74a.util.comun.Utilidades;
import com.ejie.ad74a.util.comun.UtilidadesFecha;
import com.ejie.ad74a.util.constantes.Constantes;
import com.ejie.ad74a.util.constantes.Constantes.EstadosBandejaPapel0;
import com.ejie.ad74a.util.constantes.EstadosExpedienteEnum;
import com.ejie.ad74a.util.constantes.FinalizacionEstudioEnum;
import com.ejie.ad74a.util.constantes.ProcedimientosEnum;
import com.ejie.ad74a.util.constantes.TareasEnum;
import com.ejie.ad74a.util.constantes.TipoAportacionEnum;
import com.ejie.ad74a.util.constantes.TipoProcesoEnum;
import com.ejie.ad74a.util.constantes.TipoTramiteExpediente;
import com.ejie.ad74a.util.constantes.TiposDocumentoRoleEnum;
import com.ejie.ad74a.util.constantes.TramitesEnum;
import com.ejie.ad74a.util.constantes.modelos.TipoExpedientes;
import com.ejie.ad74a.validacion.EntradasValidator;
import com.ejie.ad74a.validacion.SolicitudesPapel0Validator;
import com.ejie.ad74a.ws.client.documentum.X97DistributionWebServiceImpl;
import com.ejie.ad74a.ws.client.platea.service.PlateaService;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;
import com.ejie.x38.util.DateTimeManager;
import com.lowagie.text.Document;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

/**
 * BandejaPapel0ServiceImpl generated by UDA, 19-abr-2023 10:08:13.
 * 
 * @author UDA
 */

@Service(value = "bandejaPapel0Service")
public class BandejaPapel0ServiceImpl implements BandejaPapel0Service {

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

	@Autowired
	private BandejaPapel0Dao bandejaPapel0Dao;

	@Autowired
	private DocumentoPapel0Service documentoPapel0Service;

	@Autowired
	private ExpedientesDao expedientesDao;

	@Autowired
	private SolicitantesDao solicitantesDao;

	@Autowired
	private ReloadableResourceBundleMessageSource appMessageSource;

	@Autowired
	private ExpedientesService expedientesService;

	@Autowired
	private PlateaService plateaService;

	@Autowired
	private X97DistributionWebServiceImpl x97DistributionWebServiceImpl;

	@Autowired
	private DireccionesDao direccionesDao;

	@Autowired
	private InformesService informesService;

	@Autowired
	private EntradasValidator entradasValidator;

	@Autowired
	private SolicitudesPapel0Validator solicitudesPapel0Validator;

	@Autowired
	private PerfilesDao perfilesDao;

	@Autowired
	private CuentasDao cuentasDao;

	@Autowired
	private TramitacionService tramitacionService;

	@Autowired
	private PisosTuteladosDao pisosTuteladosDao;

	@Autowired
	private DependenciaDao dependenciaDao;

	@Autowired
	private DiscapacidadDao discapacidadDao;

	@Autowired
	private DireccionesService direccionesService;

	@Autowired
	private TareasTramiteDao tareasTramiteDao;

	@Autowired
	private TramitesExpedienteDao tramitesExpedienteDao;

	/**
	 * Inserts a single row in the BandejaPapel0 table.
	 *
	 * @param bandejaPapel0 BandejaPapel0
	 *
	 * @return BandejaPapel0
	 */
	@Transactional(rollbackFor = Throwable.class)
	public BandejaPapel0 add(BandejaPapel0 bandejaPapel0) {
		return this.bandejaPapel0Dao.add(bandejaPapel0);
	}

	/**
	 * Updates a single row in the BandejaPapel0 table.
	 *
	 * @param bandejaPapel0 BandejaPapel0
	 *
	 * @return BandejaPapel0
	 */
	@Transactional(rollbackFor = Throwable.class)
	public BandejaPapel0 update(BandejaPapel0 bandejaPapel0) {
		return this.bandejaPapel0Dao.update(bandejaPapel0);
	}

	/**
	 * Finds a single row in the BandejaPapel0 table.
	 *
	 * @param bandejaPapel0 BandejaPapel0
	 *
	 * @return BandejaPapel0
	 */
	public BandejaPapel0 find(BandejaPapel0 bandejaPapel0) {
		return (BandejaPapel0) this.bandejaPapel0Dao.find(bandejaPapel0);
	}

	/**
	 * Deletes a single row in the BandejaPapel0 table.
	 *
	 * @param bandejaPapel0 BandejaPapel0
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void remove(BandejaPapel0 bandejaPapel0) {
		this.bandejaPapel0Dao.remove(bandejaPapel0);
	}

	/**
	 * Finds a list of rows in the BandejaPapel0 table.
	 *
	 * @param bandejaPapel0   BandejaPapel0
	 * @param tableRequestDto TableRequestDto
	 *
	 * @return List<BandejaPapel0>
	 */
	public List<BandejaPapel0> findAll(BandejaPapel0 bandejaPapel0, TableRequestDto tableRequestDto) {
		return (List<BandejaPapel0>) this.bandejaPapel0Dao.findAll(bandejaPapel0, tableRequestDto);
	}

	/**
	 * Finds rows in the BandejaPapel0 table using like.
	 *
	 * @param bandejaPapel0   BandejaPapel0
	 * @param tableRequestDto TableRequestDto
	 * @param startsWith      Boolean
	 * 
	 * @return List<BandejaPapel0>
	 */
	public List<BandejaPapel0> findAllLike(BandejaPapel0 bandejaPapel0, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return (List<BandejaPapel0>) this.bandejaPapel0Dao.findAllLike(bandejaPapel0, tableRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the BandejaPapel0 table.
	 *
	 * @param tableRequestDto TableRequestDto
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void removeMultiple(TableRequestDto tableRequestDto) {
		this.bandejaPapel0Dao.removeMultiple(tableRequestDto);
	}

	/**
	 * Filter method in the BandejaPapel0 table.
	 *
	 * @param filterBandejaPapel0 BandejaPapel0
	 * @param tableRequestDto     TableRequestDto
	 * @param startsWith          Boolean
	 *
	 * @return TableResourceResponseDto<BandejaPapel0>
	 */
	public TableResponseDto<BandejaPapel0> filter(BandejaPapel0 filterBandejaPapel0, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		List<BandejaPapel0> listaBandejaPapel0 = this.bandejaPapel0Dao.findAllLike(filterBandejaPapel0, tableRequestDto,
				false);
		Long recordNum = this.bandejaPapel0Dao
				.findAllLikeCount(filterBandejaPapel0 != null ? filterBandejaPapel0 : new BandejaPapel0(), false);
		TableResponseDto<BandejaPapel0> tableResponseDto = new TableResponseDto<BandejaPapel0>(tableRequestDto,
				recordNum, listaBandejaPapel0);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null
				&& !tableRequestDto.getMultiselection().getSelectedIds().isEmpty()) {
			List<TableRowDto<BandejaPapel0>> reorderSelection = this.bandejaPapel0Dao
					.reorderSelection(filterBandejaPapel0, tableRequestDto, startsWith);
			tableResponseDto.setReorderedSelection(reorderSelection);
			tableResponseDto.addAdditionalParam("reorderedSelection", reorderSelection);
			tableResponseDto.addAdditionalParam("selectedAll", tableRequestDto.getMultiselection().getSelectedAll());
		}
		if (tableRequestDto.getSeeker().getSelectedIds() != null) {
			tableRequestDto.setMultiselection(tableRequestDto.getSeeker());
			List<TableRowDto<BandejaPapel0>> reorderSeeker = this.bandejaPapel0Dao.reorderSelection(filterBandejaPapel0,
					tableRequestDto, startsWith);
			tableResponseDto.setReorderedSeeker(reorderSeeker);
			tableResponseDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return tableResponseDto;
	}

	/**
	 * Búsqueda en bandeja papel 0 join con expedientes
	 * 
	 * @param filterBandejaPapel0
	 * @return
	 */
	public List<BandejaPapel0> getBandejaPapel0Complete(BandejaPapel0 filterBandejaPapel0) {
		List<BandejaPapel0> listaBandejaPapel0 = this.bandejaPapel0Dao.getBandejaPapel0Complete(filterBandejaPapel0);

		// Buscamos informe social (si tiene la urgencia definida no hacemos el match ya
		// que se habrá hecho al registrarla)
		// Además sólo se hará para las solicitudes
		for (BandejaPapel0 bandejaPapel0 : listaBandejaPapel0) {
			if (bandejaPapel0.getTipo12().equalsIgnoreCase(TipoAportacionEnum.SOLICITUD.getTipo())
					&& !Utilidades.esBlancoNulo(bandejaPapel0.getRemitente12())) {
				String[] remitente = bandejaPapel0.getRemitente12().split("-");

				if (remitente != null && remitente.length > 1) {
					bandejaPapel0
							.setInformes(this.informesService.getInformeSocialSinMatchByNIF(remitente[1].trim(), true));
				}
			}

		}
		return listaBandejaPapel0;
	}

	/**
	 * Searches rows in the BandejaPapel0 table.
	 *
	 * @param filterBandejaPapel0 BandejaPapel0
	 * @param searchBandejaPapel0 BandejaPapel0
	 * @param tableRequestDto     TableRequestDto
	 * @param startsWith          Boolean
	 *
	 * @return List<TableRowDto<BandejaPapel0>>
	 */
	public List<TableRowDto<BandejaPapel0>> search(BandejaPapel0 filterBandejaPapel0, BandejaPapel0 searchBandejaPapel0,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.bandejaPapel0Dao.search(filterBandejaPapel0, searchBandejaPapel0, tableRequestDto, startsWith);
	}

	/**
	 * Reorder the selection made in BandejaPapel0 table.
	 *
	 * @param filterBandejaPapel0 BandejaPapel0
	 * @param tableRequestDto     TableRequestDto
	 * @param startsWith          Boolean
	 *
	 * @return Object
	 */
	public Object reorderSelection(BandejaPapel0 filterBandejaPapel0, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.bandejaPapel0Dao.reorderSelection(filterBandejaPapel0, tableRequestDto, startsWith);
	}

	/**
	 * Get multiple
	 * 
	 * @param filterBandejaPapel0 BandejaPapel0
	 * @param tableRequestDto     TableRequestDto
	 * @param startsWith          Boolean
	 * @return List<BandejaPapel0>
	 */
	@Transactional(rollbackFor = Throwable.class)
	public List<BandejaPapel0> getMultiple(BandejaPapel0 filterBandejaPapel0, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.bandejaPapel0Dao.getMultiple(filterBandejaPapel0, tableRequestDto, startsWith);
	}

	/**
	 * Devuelve un fichero en el formato deseado que contiene los datos exportados
	 * de la tabla.
	 *
	 * @param filterBandejaPapel0 BandejaPapel0
	 * @param columns             String[]
	 * @param columnsName         String[]
	 * @param fileName            String
	 * @param sheetTitle          String
	 * @param reportsParams       ArrayList<?>
	 * @param tableRequestDto     TableRequestDto
	 * @param request             HttpServletRequest
	 * @param response            HttpServletResponse
	 */
	@Override
	public void generateReport(BandejaPapel0 filterBandejaPapel0, String[] columns, String[] columnsName,
			String fileName, String sheetTitle, ArrayList<?> reportsParams, TableRequestDto tableRequestDto,
			HttpServletRequest request, HttpServletResponse response) {
		// Accede a la DB para recuperar datos
		List<BandejaPapel0> filteredData = getDataForReports(filterBandejaPapel0, tableRequestDto);
		String extension = null;

		// Comprobar si las siguientes variables estan vacias, en caso de estarlo se las
		// asigna un valor generico
		fileName = (fileName != null && !fileName.isEmpty()) ? fileName : "report";
		sheetTitle = (sheetTitle != null && !sheetTitle.isEmpty()) ? sheetTitle : BandejaPapel0.class.getSimpleName();

		// Obtener el formato de fecha especifico del locale
		SimpleDateFormat formatter = DateTimeManager.getDateTimeFormat(request.getLocale());

		// Cuando no se definen columnas porque se quieren obtener todas
		if (columns == null) {
			Field[] fields = BandejaPapel0.class.getDeclaredFields();
			ArrayList<String> tempColumns = new ArrayList<String>();

			for (int i = 0; i < fields.length; i++) {
				try {
					String methodName = fields[i].getName();
					methodName = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
					BandejaPapel0.class.getMethod("get" + methodName);
					tempColumns.add(fields[i].getName());
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				}

			}
			columns = tempColumns.toArray(new String[0]);
		}

		// Si no se definen los nombres de las columnas se dejan las definidas por
		// defecto
		if (columnsName == null) {
			columnsName = columns;
		}

		String servletPath = request.getServletPath();
		String reportType = null;
		if (servletPath.contains("/") && (servletPath.lastIndexOf("/") + 1 != servletPath.length())) {
			reportType = servletPath.substring(servletPath.lastIndexOf("/") + 1, servletPath.length());
		} else {
			reportType = servletPath.substring(0, servletPath.length());
		}

		if (reportType.equals("xlsReport")) {
			extension = ".xls";
			generateExcelReport(filteredData, columns, columnsName, fileName, sheetTitle, extension, formatter,
					response);
		} else if (reportType.equals("xlsxReport")) {
			extension = ".xlsx";
			generateExcelReport(filteredData, columns, columnsName, fileName, sheetTitle, extension, formatter,
					response);
		} else if (reportType.equals("pdfReport")) {
			extension = ".pdf";
			generatePDFReport(filteredData, columns, columnsName, fileName, response);
		} else if (reportType.equals("odsReport")) {
			extension = ".ods";
			generateODSReport(filteredData, columns, columnsName, fileName, sheetTitle, response);
		} else if (reportType.equals("csvReport")) {
			extension = ".csv";
			// Obtener idioma
			String language = request.getLocale().getLanguage();
			generateCSVReport(filteredData, columns, columnsName, fileName, sheetTitle, language, response);
		}

	}

	/**
	 * Devuelve un fichero excel que contiene los datos exportados de la tabla.
	 *
	 * @param filteredData List<BandejaPapel0>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param sheetTitle   String
	 * @param extension    String
	 * @param formatter    SimpleDateFormat
	 * @param response     HttpServletResponse
	 */
	private void generateExcelReport(List<BandejaPapel0> filteredData, String[] columns, String[] columnsName,
			String fileName, String sheetTitle, String extension, SimpleDateFormat formatter,
			HttpServletResponse response) {
		try {
			// Creacion del Excel
			Workbook workbook = null;
			if (extension == ".xlsx") {
				workbook = new XSSFWorkbook();
				response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
			} else {
				workbook = new HSSFWorkbook();
				response.setContentType("application/vnd.ms-excel");
			}

			response.setHeader("Content-Disposition", "attachment; filename=" + fileName + extension + "");

			// Creacion de una hoja y asignacion de su nombre
			Sheet sheet = workbook.createSheet(sheetTitle);

			// Se crea una fuente para estilizar las cabeceras
			Font headerFont = workbook.createFont();
			headerFont.setBold(true);
			headerFont.setFontHeightInPoints((short) 12);

			// Se crea un CellStyle con la fuente
			CellStyle headerCellStyle = workbook.createCellStyle();
			headerCellStyle.setAlignment(HorizontalAlignment.CENTER);
			headerCellStyle.setFont(headerFont);

			// Inicializar contador de filas
			int rowNumber = 0;

			// Se crea la fila para insertar los titulos de las columnas
			Row row = sheet.createRow(rowNumber++);

			// Añadir titulos
			for (int i = 0; i < columnsName.length; i++) {
				Cell cell = row.createCell(i);
				cell.setCellValue(columnsName[i]);
				cell.setCellStyle(headerCellStyle);
			}

			// CreationHelper ayudara a mantener la compatibilidad del DataFormat tanto si
			// se crea un .xls como un .xlsx
			CreationHelper createHelper = workbook.getCreationHelper();

			// Se crea un CellStyle para añadir el formateador de fechas
			CellStyle dateCellStyle = workbook.createCellStyle();
			dateCellStyle.setDataFormat(createHelper.createDataFormat().getFormat(formatter.toPattern()));

			// Añadir datos
			for (BandejaPapel0 rowBandejaPapel0 : filteredData) {
				int cellNumber = 0;
				row = sheet.createRow(rowNumber++);

				// Se iteran las columnas y se insertan los datos respetando el orden que tenian
				// las columnas en la tabla
				for (String column : columns) {
					Cell cellBandejaPapel0 = row.createCell(cellNumber++);
					cellBandejaPapel0.setCellValue(getCellValue(column, rowBandejaPapel0));
				}
			}

			// Se adapta el ancho de las columnas al contenido
			for (int i = 0; i < columns.length; i++) {
				sheet.autoSizeColumn(i);
			}

			// Se añade el fichero excel al response
			workbook.write(response.getOutputStream());
			workbook.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Devuelve un fichero pdf que contiene los datos exportados de la tabla.
	 *
	 * @param filteredData List<BandejaPapel0>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param response     HttpServletResponse
	 */
	private void generatePDFReport(List<BandejaPapel0> filteredData, String[] columns, String[] columnsName,
			String fileName, HttpServletResponse response) {
		try {
			// Se añade el fichero excel al response y se añade el contenido
			response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".pdf");
			response.setContentType("application/pdf");

			Document document = new Document();
			// Se añade el fichero pdf al response
			PdfWriter.getInstance(document, response.getOutputStream());

			document.open();

			PdfPTable table = new PdfPTable(columns.length);

			for (String column : columnsName) {
				PdfPCell header = new PdfPCell();
				header.setBorderWidth(2);
				header.setPhrase(new Phrase(column));
				table.addCell(header);
			}

			// Añadir datos
			for (BandejaPapel0 rowBandejaPapel0 : filteredData) {
				// Se iteran las columnas y se insertan los datos respetando el orden que tenian
				// las columnas en la tabla
				for (String column : columns) {
					table.addCell(getCellValue(column, rowBandejaPapel0));
				}
			}

			document.add(table);
			document.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Devuelve un fichero ods que contiene los datos exportados de la tabla.
	 *
	 * @param filteredData List<BandejaPapel0>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param sheetTitle   String
	 * @param response     HttpServletResponse
	 */
	private void generateODSReport(List<BandejaPapel0> filteredData, String[] columns, String[] columnsName,
			String fileName, String sheetTitle, HttpServletResponse response) {
		try {
			// Se añade el fichero ods al response y se añade el contenido
			response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".ods");
			response.setContentType("application/vnd.oasis.opendocument.spreadsheet");

			OdfSpreadsheetDocument ods = OdfSpreadsheetDocument.newSpreadsheetDocument();
			ods.getOrCreateDocumentStyles();

			// Hay que eliminar la hoja que se genera por defecto
			ods.getTableByName("Sheet1").remove();

			// Hoja nueva
			OdfTable table = OdfTable.newTable(ods, filteredData.size() + 1, columns.length);
			table.setTableName(sheetTitle);

			// Inicializar contador de filas
			int rowNumber = 0;

			// Cabeceras
			OdfTableRow row = table.getRowByIndex(rowNumber++);
			for (int i = 0; i < columnsName.length; i++) {
				row.getCellByIndex(i).setStringValue(columnsName[i]);
			}

			// Añadir datos
			for (BandejaPapel0 rowBandejaPapel0 : filteredData) {
				row = table.getRowByIndex(rowNumber++);
				int cellNumber = 0;

				// Se iteran las columnas y se insertan los datos respetando el orden que tenian
				// las columnas en la tabla
				for (String column : columns) {
					row.getCellByIndex(cellNumber++).setStringValue(getCellValue(column, rowBandejaPapel0));
				}
			}

			// Se añade el fichero ods al response
			ods.save(response.getOutputStream());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Devuelve un fichero csv que contiene los datos exportados de la tabla.
	 *
	 * @param filteredData List<BandejaPapel0>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param sheetTitle   String
	 * @param language     String
	 * @param response     HttpServletResponse
	 */
	private void generateCSVReport(List<BandejaPapel0> filteredData, String[] columns, String[] columnsName,
			String fileName, String sheetTitle, String language, HttpServletResponse response) {
		try {
			// Se añade el fichero excel al response y se añade el contenido
			response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".csv");
			response.setContentType("text/csv");

			// Separador de campos dependiendo del idioma
			String separator = ";";
			if (language.equals("en")) {
				separator = ",";
			}

			// Se añade el fichero csv al response
			OutputStream out = response.getOutputStream();
			// Añadir titulos
			boolean addTitles = true;

			// Añadir datos
			for (BandejaPapel0 rowBandejaPapel0 : filteredData) {
				int cellNumber = 1;
				StringBuilder columnsTitles = new StringBuilder();
				StringBuilder row = new StringBuilder();

				// Se iteran las columnas y se insertan los datos respetando el orden que tenian
				// las columnas en la tabla
				for (String column : columns) {
					String cellValue = getCellValue(column, rowBandejaPapel0);

					if (cellNumber < columns.length) {
						if (addTitles) {
							columnsTitles.append("\"");
							columnsTitles.append(column);
							columnsTitles.append("\"");
							columnsTitles.append(separator);
						}
						row.append("\"");
						row.append(cellValue);
						row.append("\"");
						row.append(separator);
						cellNumber++;
					} else {
						if (addTitles) {
							columnsTitles.append("\"");
							columnsTitles.append(column);
							columnsTitles.append("\"\n");
						}
						row.append("\"");
						row.append(cellValue);
						row.append("\"\n");
					}
				}

				if (addTitles) {
					out.write(columnsTitles.toString().getBytes());
					addTitles = false;
				}
				out.write(row.toString().getBytes());
			}
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Devuelve los datos recuperados de la DB.
	 *
	 * @param filterBandejaPapel0 BandejaPapel0
	 * @param tableRequestDto     TableRequestDto
	 *
	 * @return List<BandejaPapel0>
	 */
	public List<BandejaPapel0> getDataForReports(BandejaPapel0 filterBandejaPapel0, TableRequestDto tableRequestDto) {
		if (tableRequestDto.getMultiselection().getSelectedAll()
				&& tableRequestDto.getMultiselection().getSelectedIds().isEmpty()) {
			if (filterBandejaPapel0 != null) {
				return this.bandejaPapel0Dao.findAllLike(filterBandejaPapel0, tableRequestDto, false);
			} else {
				return this.bandejaPapel0Dao.findAll(new BandejaPapel0(), null);
			}
		} else {
			return this.bandejaPapel0Dao.getMultiple(filterBandejaPapel0, tableRequestDto, false);
		}
	}

	/**
	 * Obtiene los valores de las celdas.
	 *
	 * @param column           String
	 * @param rowBandejaPapel0 BandejaPapel0
	 *
	 * @return String
	 */
	private String getCellValue(String column, BandejaPapel0 rowBandejaPapel0) {
		String cellValue = "";
		try {
			cellValue = BeanUtils.getProperty(rowBandejaPapel0, column) != null
					? BeanUtils.getProperty(rowBandejaPapel0, column)
					: "";
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		return cellValue;
	}

	/**
	 * Actualiza el ocultar de la entrada
	 * 
	 * @param BandejaPapel0
	 */
	public void updateOculto(BandejaPapel0 bandejaPapel0) {
		this.bandejaPapel0Dao.updateOculto(bandejaPapel0);
	}

	/**
	 * Actualiza el estado de la entrada
	 * 
	 * @param BandejaPapel0
	 */
	public void updateEstado(BandejaPapel0 bandejaPapel0) {

		this.bandejaPapel0Dao.updateEstado(bandejaPapel0);

	}

	/**
	 * Actualiza el bloqueo de la entrada
	 * 
	 * @param BandejaPapel0
	 */
	public void updateBloqueo(BandejaPapel0 bandejaPapel0) {

		this.bandejaPapel0Dao.updateBloqueo(bandejaPapel0);

	}

	/**
	 * Actualiza el expediente de la entrada
	 * 
	 * @param BandejaPapel0
	 */
	public void updateExpediente(BandejaPapel0 bandejaPapel0) {

		this.bandejaPapel0Dao.updateExpediente(bandejaPapel0);

	}

	/**
	 * Actualiza las observaciones de la entrada
	 * 
	 * @param BandejaPapel0
	 */
	public void updateObservaciones(BandejaPapel0 bandejaPapel0) {

		this.bandejaPapel0Dao.updateObservaciones(bandejaPapel0);

	}

	/**
	 * validar que las acciones telematicas seleccionadas para el procedimiento son
	 * compatibles
	 * 
	 * - Alta -> Sol Desis Apor Subs Recur
	 * 
	 * - Baja -> Sol Desis Apor Recur
	 * 
	 * - Modif -> Sol Apor Subs
	 * 
	 * - Revis -> Sol Desis Apor Subs Recur
	 * 
	 * - InfInter -> Sol Apor Subs
	 * 
	 * @param bandejaPapel0
	 */
	private void validarProcessProcActionTel(BandejaPapel0 bandejaPapel0) {
		String procedure = bandejaPapel0.getProcedureid12();
		String tipoProceso = bandejaPapel0.getTipo12();

		switch (procedure) {

		case Constantes.Procedimientos.ALTA:
			break;

		case Constantes.Procedimientos.BAJA:
			if (TipoProcesoEnum.getNuevoTipoByTipo(TipoProcesoEnum.SUBSANACION_DOCUMENTOS.getTipo())
					.equalsIgnoreCase(tipoProceso)) {
				throw new Ad74aException(
						UtilLiterales.getLiteralMessage(appMessageSource, "error.procesar.incompatible"));
			}
			break;

		case Constantes.Procedimientos.MODIFICACION:
			if (TipoProcesoEnum.getNuevoTipoByTipo(TipoProcesoEnum.DESISTIMIENTO.getTipo())
					.equalsIgnoreCase(tipoProceso)
					|| TipoProcesoEnum.getNuevoTipoByTipo(TipoProcesoEnum.RECURSO_DESISTIMIENTO.getTipo())
							.equalsIgnoreCase(tipoProceso)) {
				throw new Ad74aException(
						UtilLiterales.getLiteralMessage(appMessageSource, "error.procesar.incompatible"));
			}
			break;

		case Constantes.Procedimientos.REVISION_PRECIO:
			break;

		case Constantes.Procedimientos.INFORME_INTERVENCION:
			if (TipoProcesoEnum.getNuevoTipoByTipo(TipoProcesoEnum.DESISTIMIENTO.getTipo())
					.equalsIgnoreCase(tipoProceso)
					|| TipoProcesoEnum.getNuevoTipoByTipo(TipoProcesoEnum.RECURSO_DESISTIMIENTO.getTipo())
							.equalsIgnoreCase(tipoProceso)) {
				throw new Ad74aException(
						UtilLiterales.getLiteralMessage(appMessageSource, "error.procesar.incompatible"));
			}
			break;
		default:
			ManagerErrors.manageError("Procedimiento no existente - procedure: " + procedure);
		}

	}

	/***
	 * Procesa la entrada
	 * 
	 * @param bandejaPapel0
	 * @return BandejaPapel0
	 * @throws Throwable
	 */
	@Transactional(rollbackFor = Throwable.class)
	public BandejaPapel0 procesarEntrada(BandejaPapel0 bandejaPapel0) {

		List<ErrorField> errores = new ArrayList<ErrorField>();
		entradasValidator.validateEntradaPapel0(errores, bandejaPapel0);
		String numRegistro = bandejaPapel0.getNumRegistro12();
		String estadoEntrada = bandejaPapel0.getEstado12();
		if (errores.size() != com.ejie.ad74a.constantes.Constantes.CERO) {
			throw new ValidatorException(errores);
		}

		try {

			Solicitantes solicitante = new Solicitantes();
			Expedientes expediente = Utilidades.esNulo(bandejaPapel0.getExpediente()) ? new Expedientes()
					: bandejaPapel0.getExpediente();

			// recuperar entrada y comprobar que no esta aceptada
			BandejaPapel0 banTemp = new BandejaPapel0();
			banTemp.setIdEntrada12(bandejaPapel0.getIdEntrada12());
			banTemp = this.bandejaPapel0Dao.find(banTemp);
			if (banTemp.getEstado12().equalsIgnoreCase(Constantes.EstadosBandejaPapel0.ACEPTADO)) {
				ManagerErrors.manageError(UtilLiterales.getLiteralMessage(appMessageSource, "error.entradaProcesada"));
			}

			bandejaPapel0.setProcedureid12(banTemp.getProcedureid12());
			bandejaPapel0.setfRegistro12(banTemp.getfRegistro12());
			bandejaPapel0.setfRegOriginal12(banTemp.getfRegOriginal12());
			bandejaPapel0.setNumRegistro12(banTemp.getNumRegistro12());
			bandejaPapel0.setNumRegOriginal12(banTemp.getNumRegOriginal12());
			bandejaPapel0.setfAlta12(banTemp.getfAlta12());

			// validar que las acciones telematicas seleccionadas para el procedimiento son
			// compatibles
			this.validarProcessProcActionTel(bandejaPapel0);

			// comprobar que todos los documentos están tipificados
			DocumentoPapel0 documentoPapel0 = new DocumentoPapel0();
			BandejaPapel0 bandejaAux = new BandejaPapel0();
			bandejaAux.setIdEntrada12(bandejaPapel0.getIdEntrada12());
			documentoPapel0.setBandejaPapel0(bandejaAux);
			bandejaPapel0.setDocumentosPapel0(this.documentoPapel0Service.getAllByEntrada(documentoPapel0));
			boolean existsSolicitud = false;
			// marcamos por defecto la urgencia a 0
			if (null == expediente.getUrgencia00()
					&& (bandejaPapel0.getUrgencia12() == null || bandejaPapel0.getUrgencia12() == 0)) {
				expediente.setUrgencia00(TipoExpedientes.urgencia00.NO.getId());
			} else {
				expediente.setUrgencia00(bandejaPapel0.getUrgencia12());
			}
			for (DocumentoPapel0 documento : bandejaPapel0.getDocumentosPapel0()) {
				if (documento.getIdTipoDoc13() == null || documento.getIdTipoDoc13() == 0) {
					ManagerErrors.manageError(
							UtilLiterales.getLiteralMessage(appMessageSource, "error.documentosNoTipificados"));
				}

				if (documento.getTipoDocumento().getRoleid36()
						.equalsIgnoreCase(Constantes.RolesIDDocumentos.DOC_URGENCIA)) {
					expediente.setUrgencia00(TipoExpedientes.urgencia00.SI.getId());
				}

				if (documento.getTipoDocumento().getRoleid36()
						.equalsIgnoreCase(TiposDocumentoRoleEnum.SOLICITUD.getRoleID())) {
					existsSolicitud = true;
				}
			}

			// Si es una solicitud, uno de los doucmento ha de estar tipificado como
			// SOLICITUD
			if (!existsSolicitud && (TipoProcesoEnum.SOLICITUD_ALTA.getTipo().equals(bandejaPapel0.getTipoProceso12())
					|| TipoProcesoEnum.SOLICITUD_BAJA.getTipo().equals(bandejaPapel0.getTipoProceso12())
					|| TipoProcesoEnum.SOLICITUD_INF_INTERVENCION.getTipo().equals(bandejaPapel0.getTipoProceso12())
					|| TipoProcesoEnum.SOLICITUD_MODIFICACION.getTipo().equals(bandejaPapel0.getTipoProceso12())
					|| TipoProcesoEnum.SOLICITUD_REVISION.getTipo().equals(bandejaPapel0.getTipoProceso12()))) {
				ManagerErrors.manageError(
						UtilLiterales.getLiteralMessage(appMessageSource, "error.documentoSolicitudObligatorio"));
			}

			bandejaPapel0.setExpediente(expediente);
			// String observaciones = expediente.getObservaciones00();

			bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.ACEPTADO);

			BandejaPapel0ServiceImpl.logger.info("BandejaPapel0ServiceImpl.procesarEntrada - Inicio");

			// TODO: Procesamos la entrada según el tipo de proceso elegido
			if (TipoProcesoEnum.SOLICITUD_ALTA.getTipo().equals(bandejaPapel0.getTipoProceso12())) {
				if (!estadoEntrada.equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
					this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					solicitante = this.crearSolicitante();
					expediente = this.crearExpediente(TipoProcesoEnum.SOLICITUD_ALTA, bandejaPapel0, solicitante);
				} else {
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					expediente.setNumRegistro00(numRegistro);
					expediente = DataAccessUtils
							.uniqueResult(this.expedientesService.findByNumRegBandejaPapel0(expediente, null, false));
				}
			} else if (TipoProcesoEnum.SOLICITUD_BAJA.getTipo().equals(bandejaPapel0.getTipoProceso12())) {
				if (!estadoEntrada.equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
					this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					solicitante = this.crearSolicitante();
					expediente = this.crearExpediente(TipoProcesoEnum.SOLICITUD_BAJA, bandejaPapel0, solicitante);
				} else {
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					expediente.setNumRegistro00(numRegistro);
					expediente = DataAccessUtils
							.uniqueResult(this.expedientesService.findByNumRegBandejaPapel0(expediente, null, false));
				}
			} else if (TipoProcesoEnum.SOLICITUD_MODIFICACION.getTipo().equals(bandejaPapel0.getTipoProceso12())) {
				if (!estadoEntrada.equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
					this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					solicitante = this.crearSolicitante();
					expediente = this.crearExpediente(TipoProcesoEnum.SOLICITUD_MODIFICACION, bandejaPapel0,
							solicitante);
				} else {
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					expediente.setNumRegistro00(numRegistro);
					expediente = DataAccessUtils
							.uniqueResult(this.expedientesService.findByNumRegBandejaPapel0(expediente, null, false));
				}
			} else if (TipoProcesoEnum.SOLICITUD_REVISION.getTipo().equals(bandejaPapel0.getTipoProceso12())) {
				if (!estadoEntrada.equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
					this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					solicitante = this.crearSolicitante();
					expediente = this.crearExpediente(TipoProcesoEnum.SOLICITUD_REVISION, bandejaPapel0, solicitante);
				} else {
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					expediente.setNumRegistro00(numRegistro);
					expediente = DataAccessUtils
							.uniqueResult(this.expedientesService.findByNumRegBandejaPapel0(expediente, null, false));
				}
			} else if (TipoProcesoEnum.SOLICITUD_INF_INTERVENCION.getTipo().equals(bandejaPapel0.getTipoProceso12())) {
				if (!estadoEntrada.equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
					this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					solicitante = this.crearSolicitante();
					expediente = this.crearExpediente(TipoProcesoEnum.SOLICITUD_INF_INTERVENCION, bandejaPapel0,
							solicitante);
				} else {
					bandejaPapel0.setEstado12(Constantes.EstadosBandejaPapel0.EN_CURSO);
					expediente.setNumRegistro00(numRegistro);
					expediente = DataAccessUtils
							.uniqueResult(this.expedientesService.findByNumRegBandejaPapel0(expediente, null, false));
				}
			} else if (TipoProcesoEnum.APORTACION.getTipo().equals(bandejaPapel0.getTipoProceso12())) {
				if (!estadoEntrada.equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
					this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
				}
				expediente = this.findExpediente(bandejaPapel0.getExpediente());
				this.aportarDocPapel0(bandejaPapel0);
				// Insertar trámite de aportación en expediente y aportar los documentos
			} else if (TipoProcesoEnum.SUBSANACION_DOCUMENTOS.getTipo().equals(bandejaPapel0.getTipoProceso12())) {
				if (!estadoEntrada.equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
					this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
				}
				expediente = this.findExpediente(bandejaPapel0.getExpediente());
				this.aportarDocPapel0(bandejaPapel0);
				// expediente = this.updateObservaciones(expediente, observaciones);
				// Insertar trámite de subsanación en expediente y aportar los documentos
			} else if (TipoProcesoEnum.DESISTIMIENTO.getTipo().equals(bandejaPapel0.getTipoProceso12())) {
				if (!estadoEntrada.equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
					this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
				}
				expediente = this.findExpediente(bandejaPapel0.getExpediente());
				this.desistir(bandejaPapel0);
				this.aportarDocPapel0(bandejaPapel0);
				// expediente = this.updateObservaciones(expediente, observaciones);
				// Insertar trámite de desistimiento en expedient y aportar los documentos
			} else if (TipoProcesoEnum.RECURSO_DESISTIMIENTO.getTipo().equals(bandejaPapel0.getTipoProceso12())) {
				if (!estadoEntrada.equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
					this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
				}
				expediente = this.findExpediente(bandejaPapel0.getExpediente());
				this.aportarDocPapel0(bandejaPapel0);
				// expediente = this.updateObservaciones(expediente, observaciones);
				// Insertar trámite de recurso de desistimiento en expediente y aportar los
				// documentos
			}

			// actualizamos la entrada
			bandejaPapel0.setExpediente(expediente);
			bandejaPapel0.setNumExpediente12(expediente.getNumExpediente00());
			bandejaPapel0.setUsuModif12(UtilSeguridad.getUsuarioConectado().getUserName());
			bandejaPapel0.setfModif12(UtilidadesFecha.getFechaSistema());
			this.bandejaPapel0Dao.updateProcesarEntradaBandeja(bandejaPapel0);
			this.expedientesDao.updateUrgenciaExpedientebyNumRegistro(bandejaPapel0);

		} catch (Throwable e) {
			ManagerErrors.manageException(e,
					UtilLiterales.getLiteralMessage(appMessageSource, "error.procesarEntrada"));
		}

		BandejaPapel0ServiceImpl.logger.info("BandejaPapel0ServiceImpl.procesarEntrada - Fin");

		return bandejaPapel0;
	}

	// private Expedientes updateObservaciones(Expedientes expediente, String
	// observaciones) {
//      String obsExp = Utilidades.isEmpty(expediente.getObservaciones00()) ? "" : expediente.getObservaciones00();
//      expediente.setObservaciones00(obsExp + (Utilidades.isEmpty(observaciones) ? "" : observaciones));
	// this.expedientesDao.updateObservaciones(expediente);
	// return expediente;
	// }

	private void aportarDocPapel0(BandejaPapel0 bandejaPapel0) throws Throwable {
		Expedientes expediente = new Expedientes();
		expediente.setNumExpediente00(bandejaPapel0.getExpediente().getNumExpediente00());
		expediente = this.findExpediente(expediente);
		bandejaPapel0.setExpediente(expediente);
		bandejaPapel0.setNumExpediente12(expediente.getNumExpediente00());
		DocumentoPapel0 docPapel = new DocumentoPapel0();
		docPapel.setBandejaPapel0(new BandejaPapel0(bandejaPapel0.getIdEntrada12()));
		List<DocumentoPapel0> listDocPapel0 = this.documentoPapel0Service.findAll(docPapel, null);

		// actualizamos el numExpediente en el documento
		for (DocumentoPapel0 documento : listDocPapel0) {
			documento.setUsuModif13(UtilSeguridad.getUsuarioConectado().getUserName());
			documento.setIdExpediente13(bandejaPapel0.getExpediente().getIdExpediente00());
			this.documentoPapel0Service.updateExpediente(documento);
		}
		// actualizamos el numExpediente en la bandeja
		this.bandejaPapel0Dao.updateExpediente(bandejaPapel0);

		// Creamos tramite hueco
		this.tramitacionService.tratamientoTramiteBandejaPapel0(bandejaPapel0,
				Constantes.PLATEA_TASK_ID_RECEPCION_DOC_FICTICIO, TareasEnum.RECEP_DOCUMENTACION,
				Constantes.EstadoTramitacion.ESTADO_TRAMITE_FINALIZADO);

		// hacemos la aportacion del expediente
		this.plateaService.aportacionDocuPapel0(expediente, listDocPapel0, bandejaPapel0);

	}

	private void desistir(BandejaPapel0 bandejaPapel0) throws Throwable {
		BandejaPapel0ServiceImpl.logger.info("BandejaPapel0ServiceImpl.desistir - Inicio");
		Expedientes expediente = new Expedientes();
		expediente.setNumExpediente00(bandejaPapel0.getExpediente().getNumExpediente00());
		expediente = this.findExpediente(expediente);
		bandejaPapel0.setExpediente(expediente);
		bandejaPapel0.setNumExpediente12(expediente.getNumExpediente00());

		// TODO No se si hay que hacerlo ** crear el tramite de Recepcion Desistimiento
		// expreso ** //
		TramitesExpediente tramiteExp = this.tramitacionService.tratamientoTramiteBandejaPapel0(bandejaPapel0,
				Constantes.PLATEA_TASK_ID_RECEP_DESIS_EXPRESO_FICTICIO, TareasEnum.RECEPCION_DESIS_EXPRESO,
				Constantes.EstadoTramitacion.ESTADO_TRAMITE_FINALIZADO);

		DocumentoPapel0 docPapel = new DocumentoPapel0();
		docPapel.setBandejaPapel0(new BandejaPapel0(bandejaPapel0.getIdEntrada12()));
		List<DocumentoPapel0> listDocPapel0 = this.documentoPapel0Service.findAll(docPapel, null);
		// actualizamos el numExpediente en el documento
		for (DocumentoPapel0 documento : listDocPapel0) {

			documento.setUsuModif13(UtilSeguridad.getUsuarioConectado().getUserName());
			documento.setIdExpediente13(bandejaPapel0.getExpediente().getIdExpediente00());
			this.documentoPapel0Service.updateExpediente(documento);
		}
		// actualizamos el numExpediente en la bandeja
		this.bandejaPapel0Dao.updateExpediente(bandejaPapel0);

		// actualizamos el estado y el tipo de desistimiento
		expediente.setEstados(new Estados(EstadosExpedienteEnum.PEND_RESOL_DES.getId()));
		this.expedientesDao.updateEstado(expediente);
		expediente.setTipoDesis00(Constantes.TiposDesistimiento.TIPO_DESISTIMIENTO_EXPRESO);
		expediente.setfDesistimiento00(bandejaPapel0.getfRegistro12());
		// actualizamos el estado a lo que corresponda
		expediente = this.expedientesDao.updateDesistimiento(expediente);

		// Actualizamos los datos de estudio con el fin de desistimiento para que se
		// puedan consultar (Tramite y tarea).

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

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

			tramiteEstudio.setTipoEstudioDoc10(
					TipoTramiteExpediente.tipoEstudioDoc10.ESTUDIO_DOCUMENTACION_DESISTIMIENTO.getId());
			this.tramitesExpedienteDao.update(tramiteEstudio);

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

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

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

		BandejaPapel0ServiceImpl.logger.info("BandejaPapel0ServiceImpl.desistir - Fin");
	}

	private Solicitantes crearSolicitante() {

		Solicitantes solicitante = new Solicitantes();
		solicitante.setTipoIdentificador01(Constantes.ValoresDefectoBandejaPapel0.TIPO_IDENTIFICADOR);
		solicitante.setIdentificador01(Constantes.ValoresDefectoBandejaPapel0.IDENTIFICADOR);
		solicitante.setUsuAlta01(UtilSeguridad.getUsuarioConectado().getUserName());
		solicitante.setUsuModif01(UtilSeguridad.getUsuarioConectado().getUserName());
		solicitante.setfAlta01(UtilidadesFecha.getFechaSistema());
		solicitante.setfModif01(UtilidadesFecha.getFechaSistema());

		return this.solicitantesDao.add(solicitante);

	}

	private Expedientes crearExpediente(TipoProcesoEnum tipo, BandejaPapel0 bandejaPapel0, Solicitantes solicitante)
			throws Exception {

		Expedientes expediente = bandejaPapel0.getExpediente();
		expediente.setIdProcedimiento00(tipo.getProcedimiento().getId());
		expediente.setIdTipoEntrada00(TipoExpedientes.idTipoEntrada00.PAPEL0.getIdStr());
		expediente.setDeOficio00(Constantes.TipoSolicitud.SOLICITUD_NO_OFICIO);
		expediente.setEstados(EstadosExpedienteEnum.PEND_COMPLETAR.getEstado());
		expediente.setfRegistro00(bandejaPapel0.getfRegistro12());
		expediente.setfRegistroOtro00(bandejaPapel0.getfRegOriginal12());
		expediente.setNumRegistro00(bandejaPapel0.getNumRegistro12());
		expediente.setNumRegistroOtro00(bandejaPapel0.getNumRegOriginal12());
		expediente.setfRecepcion00(bandejaPapel0.getfAlta12());
		expediente.setIdTipoNot00(Constantes.TipoNotificacion.TELEMATICA);
		expediente.setCanalNot00(Constantes.CanalNotificacion.CANAL_NOTIF_ALL);
		expediente.setFolderId00(Constantes.ValoresDefectoBandejaPapel0.FOLDERID);
		expediente.setSolicitantes(solicitante);
		expediente.setObservaciones00(bandejaPapel0.getRemitente12());
		// [jbhg] por defecto no se opone a la interoperabilidad
		expediente.setSeOpone00(Constantes.OponerDssRecabarinfo.NO_SE_OPONE);
		// Si la ureguncia no esta vacia se ñle marca el check
		if (bandejaPapel0.getUrgencia12() != null) {
			expediente.setUrgencia00(bandejaPapel0.getUrgencia12());
		}
		expediente.setUsuAlta00(UtilSeguridad.getUsuarioConectado().getUserName());
		expediente.setUsuModif00(UtilSeguridad.getUsuarioConectado().getUserName());
		expediente.setfAlta00(UtilidadesFecha.getFechaSistema());
		expediente.setfModif00(UtilidadesFecha.getFechaSistema());
		expediente.setTecnicoExpediente00(UtilSeguridad.getUsuarioConectado().getUserName());

		if (null != tipo && tipo.getProcedimiento().getId().equals(ProcedimientosEnum.BAJA.getId())
				&& null == expediente.getfBaja00()) {
			expediente.setfBaja00(bandejaPapel0.getfAlta12());
		}

		expediente = this.expedientesDao.add(expediente);

		bandejaPapel0.setExpediente(expediente);
		// Actualizar los documentos con el idexpediente creado
		updateExpedienteDocumentos(bandejaPapel0);

		return expediente;

	}

	// private String getFolderNumber(String procedure) throws Exception {
	// BandejaPapel0ServiceImpl.logger.info("BandejaPapel0ServiceImpl.getFolderNumber
	// - Inicio");
	// int codSeqInt = this.expedientesDao.getNumberFolderSequence(procedure);
	//
	// String folderNumber = TareasUtils.generateFolderNumber(codSeqInt, procedure);
	// BandejaPapel0ServiceImpl.logger
	// .info("BandejaPapel0ServiceImpl.getFolderNumber - Fin folderNumber: " +
	// folderNumber);
	// return folderNumber;
	//
	// }

	private void updateExpedienteDocumentos(BandejaPapel0 bandejaPapel0) {

		DocumentoPapel0 documentoPapel0 = new DocumentoPapel0();
		BandejaPapel0 bandejaAux = new BandejaPapel0();
		bandejaAux.setIdEntrada12(bandejaPapel0.getIdEntrada12());
		documentoPapel0.setBandejaPapel0(bandejaAux);
		bandejaPapel0.setDocumentosPapel0(this.documentoPapel0Service.getAllByEntrada(documentoPapel0));
		for (DocumentoPapel0 documento : bandejaPapel0.getDocumentosPapel0()) {
			documento.setUsuModif13(UtilSeguridad.getUsuarioConectado().getUserName());
			documento.setIdExpediente13(bandejaPapel0.getExpediente().getIdExpediente00());
			this.documentoPapel0Service.updateExpediente(documento);
		}
	}

	private Expedientes findExpediente(Expedientes expedienteFilter) {

		expedienteFilter.setObservaciones00(null);
		List<Expedientes> expedientes = this.expedientesDao.findAllLike(expedienteFilter, null, false);

		if (!expedientes.isEmpty()) {
			Expedientes exp = expedientes.get(0);
			exp.setDireccionNotif(this.direccionesDao.find(exp.getDireccionNotif()));
			return expedientes.get(0);
		}

		return new Expedientes();
	}

	/**
	 * Actualiza el expediente de la entrada
	 * 
	 * @param BandejaPapel0
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void updateTabSolicitudPapel0(Expedientes expediente, boolean finalizar) {
		// [jbhg] control del check de "se opone" a la interoperabilidad
		if (expediente.getSeOpone00() == null) {
			// Si no han chequeado el campo, vendra a null
			expediente.setSeOpone00(Constantes.VAL_NUM_NO);
		}

		// TODO: validaciones de datos y de permisos
		List<ErrorField> errores = new ArrayList<ErrorField>();
		BandejaPapel0 bandejaPapel0 = new BandejaPapel0();
		bandejaPapel0.setExpediente(expediente);
		bandejaPapel0.setUrgencia12(expediente.getUrgencia00());

//		if (finalizar) {
//			solicitudesPapel0Validator.validateEntradaPapel0(errores, bandejaPapel0);
//			if (errores.size() != com.ejie.ad74a.constantes.Constantes.CERO) {
//				throw new ValidatorException(errores);
//			}
//		}

		this.bandejaPapel0Dao.updateUrgenciabyNumRegis(bandejaPapel0);

		// TODO: crear o actualizar las direcciones, las cuentas, el
		// contacto(representante),
		// el perfil y el informe social
		if ((ProcedimientosEnum.ALTA.getId().equalsIgnoreCase(bandejaPapel0.getExpediente().getIdProcedimiento00()))
				|| (ProcedimientosEnum.MODIFICACION.getId()
						.equalsIgnoreCase(bandejaPapel0.getExpediente().getIdProcedimiento00()))) {
			// Dirección
			if (expediente.getDirecciones() != null && expediente.getDirecciones().getIdDireccion06() == null) {
				expediente.getDirecciones().setUsuAlta06(UtilSeguridad.getUsuarioConectado().getUserName());
				expediente.getDirecciones().setIdSolicitante06(expediente.getSolicitantes().getIdSolicitante01());
				Direcciones newDireccion = this.direccionesDao.add(expediente.getDirecciones());
				expediente.setDirecciones(newDireccion);
			} else {
				if (expediente.getDirecciones() == null) {
					expediente.setDirecciones(new Direcciones());
				}
				expediente.getDirecciones().setIdSolicitante06(expediente.getSolicitantes().getIdSolicitante01());
				this.direccionesDao.updateDireccion(expediente.getDirecciones());
			}

			// Perfil
			if (expediente.getPerfiles() != null && expediente.getPerfiles().getIdPerfil07() == null) {
				expediente.getPerfiles().setUsuAlta07(UtilSeguridad.getUsuarioConectado().getUserName());
				if (ProcedimientosEnum.MODIFICACION.getId()
						.equalsIgnoreCase(bandejaPapel0.getExpediente().getIdProcedimiento00())) {
					// Si es un procedimiento de modificación recuperamos los datos del perfil del
					// beneficiario
					Perfiles perfiBeneficiario = this.solicitantesDao.findPorDni(expediente.getSolicitantes())
							.getPerfiles();
					perfiBeneficiario.setPisoTutelado07(expediente.getPerfiles().getPisoTutelado07());
					perfiBeneficiario.setPisosTutelados(expediente.getPerfiles().getPisosTutelados());
					expediente.setPerfiles(perfiBeneficiario);

				}
				Perfiles newPerfil = this.perfilesDao.add(expediente.getPerfiles());
				expediente.setPerfiles(newPerfil);
			} else if (expediente.getPerfiles() != null) {
				this.perfilesDao.updatePerfil(expediente.getPerfiles());
			}

		}
		if (ProcedimientosEnum.ALTA.getId().equalsIgnoreCase(bandejaPapel0.getExpediente().getIdProcedimiento00())) {
			// Perfil
			// mirar si es piso tutelado
			/*
			 * if (null != expediente.getDirecciones()) { // mirar si es piso tutelado
			 * expediente.getPerfiles().setPisoTutelado07(Constantes.PisoTutelado.NO_ESTA);
			 * PisosTutelados pisoTu = isPisoTutelado(expediente.getDirecciones()); if (null
			 * != pisoTu) {
			 * expediente.getPerfiles().setPisoTutelado07(Constantes.PisoTutelado.ESTA);
			 * expediente.getPerfiles().setPisosTutelados(pisoTu); } }
			 */

			// Cuenta
			if (expediente.getCuentas() != null && expediente.getCuentas().getIdCuenta05() == null) {
				expediente.getCuentas().setUsuAlta05(UtilSeguridad.getUsuarioConectado().getUserName());
				expediente.getCuentas().setIdSolicitante05(expediente.getSolicitantes().getIdSolicitante01());
				Cuentas newCuenta = this.cuentasDao.add(expediente.getCuentas());
				expediente.setCuentas(newCuenta);
			} else if (expediente.getCuentas() != null) {
				expediente.getCuentas().setIdSolicitante05(expediente.getSolicitantes().getIdSolicitante01());
				this.cuentasDao.updateCuenta(expediente.getCuentas());
			}
			// Dependencia
			Dependencia dependenciaFilter = new Dependencia();
			dependenciaFilter.setIdExpediente04(expediente.getIdExpediente00());
			dependenciaFilter.setIsHistorico(Boolean.FALSE);
			List<Dependencia> dependenciaList = this.dependenciaDao.findAll(dependenciaFilter, null);

			if (null == expediente.getDependencia()) {
				expediente.setDependencia(new Dependencia());
			}

			if (CollectionUtils.isEmpty(dependenciaList)) {
				expediente.getDependencia().setUsuAlta04(UtilSeguridad.getUsuarioConectado().getUserName());
				expediente.getDependencia().setIdSolicitante04(expediente.getSolicitantes().getIdSolicitante01());
				Dependencia depen = expediente.getDependencia();
				depen.setIdExpediente04(expediente.getIdExpediente00());
				this.dependenciaDao.add(depen);
			} else {
				expediente.getDependencia().setIdDependencia04(dependenciaList.get(0).getIdDependencia04());
				expediente.getDependencia().setIdExpediente04(expediente.getIdExpediente00());
				if (expediente.getSolicitantes() != null) {
					expediente.getDependencia().setIdSolicitante04(expediente.getSolicitantes().getIdSolicitante01());
				}
				this.dependenciaDao.update(expediente.getDependencia());
			}

			// Discapacidad
			Discapacidad discapacidadFilter = new Discapacidad();
			discapacidadFilter.setIdExpediente71(expediente.getIdExpediente00());
			discapacidadFilter.setIsHistorico(Boolean.FALSE);
			List<Discapacidad> discapacidadList = this.discapacidadDao.findAll(discapacidadFilter, null);
			if (null == expediente.getDiscapacidad()) {
				expediente.setDiscapacidad(new Discapacidad());
			}
			if (CollectionUtils.isEmpty(discapacidadList)) {
				expediente.getDiscapacidad().setUsuAlta71(UtilSeguridad.getUsuarioConectado().getUserName());
				expediente.getDiscapacidad().setIdSolicitante71(expediente.getSolicitantes().getIdSolicitante01());
				Discapacidad disca = expediente.getDiscapacidad();
				disca.setIdExpediente71(expediente.getIdExpediente00());
				this.discapacidadDao.add(disca);
			} else {
				expediente.getDiscapacidad().setIdDiscapacidad71(discapacidadList.get(0).getIdDiscapacidad71());
				expediente.getDiscapacidad().setIdExpediente71(expediente.getIdExpediente00());
				this.discapacidadDao.update(expediente.getDiscapacidad());
			}
		}
		// TODO: comprobar si está entre los ténicos autorizados
		expediente.setTecnicoExpediente00(UtilSeguridad.getUsuarioConectado().getUserName());
		expediente.setUsuModif00(UtilSeguridad.getUsuarioConectado().getUserName());
		expediente.setfModif00(UtilidadesFecha.getFechaSistema());

		if (expediente.getDireccionNotif() != null) {
			if (expediente.getDireccionNotif().getIdDireccion06() == null) {

				expediente.getDireccionNotif().setUsuAlta06(UtilSeguridad.getUsuarioConectado().getNif());
				expediente.setDireccionNotif(this.direccionesService.add(expediente.getDireccionNotif()));
			} else {

				this.direccionesService.update(expediente.getDireccionNotif());
			}
		}

		this.expedientesDao.updateTabSolicitudPapel0(expediente);

		if (expediente.getSolicitantes().getIdentificador01() != null) {
			expediente.getSolicitantes().setCuentas(expediente.getCuentas());
			expediente.getSolicitantes().setDirecciones(expediente.getDirecciones());
			expediente.getSolicitantes().setUsuModif01(UtilSeguridad.getUsuarioConectado().getUserName());
			expediente.getSolicitantes().setfModif01(UtilidadesFecha.getFechaSistema());
			if (null != expediente.getPerfiles() && null != expediente.getPerfiles().getIdPerfil07()) {
				expediente.getSolicitantes().setPerfiles(new Perfiles(expediente.getPerfiles().getIdPerfil07()));
			}

			this.solicitantesDao.updateTabSolicitudPapel0(expediente.getSolicitantes());
		}
	}

	// /**
	// * Crea un expediente de oficio
	// *
	// * @param BandejaPapel0
	// */
	// @Transactional(rollbackFor = Throwable.class)
	// public Expedientes insertTabSolicitudInici(Expedientes expediente) {
	//
	// // TODO: validaciones de datos y de permisos
	// List<ErrorField> errores = new ArrayList<ErrorField>();
	// BandejaPapel0 bandejaPapel0 = new BandejaPapel0();
	// bandejaPapel0.setExpediente(expediente);
	//
	// // solicitudesPapel0Validator.validateEntradaPapel0(errores, bandejaPapel0);
	//
	// if (errores.size() != com.ejie.ad74a.constantes.Constantes.CERO) {
	// throw new ValidatorException(errores);
	// }
	//
	// // TODO: crear o actualizar las direcciones, las cuentas, el
	// // contacto(representante),
	// // el perfil y el informe social
	//
	// // Dirección
//		if (expediente.getDirecciones() != null && expediente.getDirecciones().getIdDireccion06() == null) {
	// expediente.getDirecciones().setUsuAlta06(UtilSeguridad.getUsuarioConectado().getUserName());
	// expediente.getDirecciones().setIdSolicitante06(expediente.getSolicitantes().getIdSolicitante01());
	// Direcciones newDireccion =
	// this.direccionesDao.add(expediente.getDirecciones());
	// expediente.setDirecciones(newDireccion);
	// } else if (expediente.getDirecciones() != null) {
	// expediente.getDirecciones().setIdSolicitante06(expediente.getSolicitantes().getIdSolicitante01());
	// this.direccionesDao.updateDireccion(expediente.getDirecciones());
	// }
	//
	// // Cuenta
	// if (expediente.getCuentas() != null &&
	// expediente.getCuentas().getIdCuenta05() == null) {
	// expediente.getCuentas().setUsuAlta05(UtilSeguridad.getUsuarioConectado().getUserName());
	// expediente.getCuentas().setIdSolicitante05(expediente.getSolicitantes().getIdSolicitante01());
	// Cuentas newCuenta = this.cuentasDao.add(expediente.getCuentas());
	// expediente.setCuentas(newCuenta);
	// } else if (expediente.getCuentas() != null) {
	// expediente.getCuentas().setIdSolicitante05(expediente.getSolicitantes().getIdSolicitante01());
	// this.cuentasDao.updateCuenta(expediente.getCuentas());
	// }
	//
	// expediente.getSolicitantes().setCuentas(expediente.getCuentas());
	// expediente.getSolicitantes().setDirecciones(expediente.getDirecciones());
	// expediente.getSolicitantes().setUsuModif01(UtilSeguridad.getUsuarioConectado().getUserName());
	// expediente.getSolicitantes().setfModif01(UtilidadesFecha.getFechaSistema());
	// expediente.setFolderId00(Constantes.ValoresDefectoBandejaPapel0.FOLDERID);
	// // expediente.setIdTipoNot00(Constantes.TipoNotificacion.TELEMATICA);
	// if (!Utilidades.esBlancoNulo(expediente.getIdTipoNot00())) {
	// expediente.setIdTipoNot00(expediente.getIdTipoNot00());
	// } else {
	// ManagerErrors.manageError("No hay tipo de notificacion");
	// }
	//
	// // expediente.setCanalNot00(Constantes.CanalNotificacion.CANAL_NOTIF_ALL);
	// if (!Utilidades.esBlancoNulo(expediente.getCanalNot00())) {
	// expediente.setCanalNot00(expediente.getCanalNot00());
	// } else {
	// ManagerErrors.manageError("No hay canal de notificacion");
	// }
	//
	// expediente.setUsuAlta00(UtilSeguridad.getUsuarioConectado().getUserName());
	// expediente.setUsuModif00(UtilSeguridad.getUsuarioConectado().getUserName());
	// expediente.setfAlta00(UtilidadesFecha.getFechaSistema());
	// expediente.setfModif00(UtilidadesFecha.getFechaSistema());
	// expediente.setIdTipoEntrada00(TipoEntradaEnum.PAPEL0.getId());
	// expediente.setEstados(EstadosExpedienteEnum.PEND_COMPLETAR.getEstado());
	// expediente.setNumRegistro00(Constantes.ValoresDefectoRegistro.NUM_REGISTRO);
	// expediente.setfRegistro00(Constantes.ValoresDefectoRegistro.FREGISTRO);
	//
	// Expedientes nuevoExp =
	// this.solicitantesDao.insertTabSolicitudPapel0(expediente);
	// return nuevoExp;
	// }

	/**
	 * Finaliza la solicitud iniciando la apertura del expediente en PLATEA
	 * 
	 * @param Expedientes
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Expedientes finalizarSolicitud(Expedientes expediente) {

		validarFinalizarPapel0(expediente);

//		List<Expedientes> expedientes = this.expedientesService.findAllLike(expediente, null, false);
		// if (expedientes.isEmpty()) {
		// throw new Ad74aException(UtilLiterales.getLiteralMessage(appMessageSource,
		// com.ejie.ad74a.util.constantes.Constantes.ERROR_GENERICO));
		//
		// }
		Long idEntrada12 = expediente.getIdEntrada();
		expediente = this.expedientesService.find(expediente);
		if (null == expediente) {
			throw new Ad74aException(UtilLiterales.getLiteralMessage(appMessageSource,
					com.ejie.ad74a.util.constantes.Constantes.ERROR_GENERICO));

		}
		// Recuperamos las direcciones para la consulta de interoperabildiad
		expediente.getSolicitantes()
				.setDirecciones(this.direccionesDao.find(expediente.getSolicitantes().getDirecciones()));

		// Actualizamos el expediente al estado pendiente de apertura, ya que se ha
		// finalizado el el mismo y es necesario para procesar correctamente la
		// sugerencia del estudio de documentación
		expediente.getEstados().setIdEstado30(EstadosExpedienteEnum.PEND_APERTURA.getId());
		this.expedientesService.updateEstado(expediente);

		expediente.setIdEntrada(idEntrada12);

		// expediente = expedientes.get(0);
		// TODO: validar el expediente

		// Preparar los documentos
		List<DocumentosTarea> listaDocumentosTarea = new ArrayList<DocumentosTarea>();
		DocumentoPapel0 filterDocumentoPapel0 = new DocumentoPapel0();
		filterDocumentoPapel0.setIdExpediente13(expediente.getIdExpediente00());
		List<DocumentoPapel0> listaDocumentoPapel0 = this.documentoPapel0Service.findAllLike(filterDocumentoPapel0,
				null, false);

		for (DocumentoPapel0 documento : listaDocumentoPapel0) {
			DocumentosTarea documentoTarea = new DocumentosTarea();

			documentoTarea.setMaestroTiposDoc(documento.getTipoDocumento());
			documentoTarea.setOiddokusi18(documento.getOidDocumento13());

			// TODO: Mirar en PH a ver que nombre les dan
			// if (!Utilidades.esBlancoNulo(docTarea.getNombreDoc18())) {
			// String[] datos = docTarea.getNombreDoc18().split("\\.");
			// doc.setExtension(datos[1]);
			// doc.setSourceName(docTarea.getNombreDoc18());
			// }

			listaDocumentosTarea.add(documentoTarea);
		}

		// Añadir cambio de estado papel 0
		BandejaPapel0 bandejapapel0 = new BandejaPapel0();
		// bandejapapel0.setExpediente(expediente);
		bandejapapel0.setIdEntrada12(expediente.getIdEntrada());
		bandejapapel0 = DataAccessUtils.uniqueResult(this.bandejaPapel0Dao.findAllLike(bandejapapel0, null, false));
		bandejapapel0.setEstado12(Constantes.EstadosBandejaPapel0.ACEPTADO);
		this.bandejaPapel0Dao.updateEstado(bandejapapel0);

		String folderID = this.plateaService.aperturaSolicitud(expediente, listaDocumentosTarea);
		expediente.setFolderId00(folderID);

		this.expedientesService.updateFolderID(expediente);

		return expediente;

	}

	private void validarFinalizarPapel0(Expedientes expediente) {
		Boolean expedientesIniciados = this.solicitantesDao.tieneExpedienteInciado(expediente.getIdProcedimiento00(),
				expediente.getSolicitantes().getIdentificador01());
		if (Boolean.TRUE.equals(expedientesIniciados)) {
			ManagerErrors
					.manageError(UtilLiterales.getLiteralMessage(appMessageSource, "error.expedienteYaPresentado"));
		}

	}

	@Override
	public void rechazarEntrada(BandejaPapel0 bandejaPapel0, Boolean isUpdate) {

		bandejaPapel0.setEstado12(EstadosBandejaPapel0.RECHAZADO);

		if (isUpdate) {
			this.bandejaPapel0Dao.updateEstado(bandejaPapel0);
		} else {
			bandejaPapel0 = this.bandejaPapel0Dao.add(bandejaPapel0);
		}

		String tokenSesion = UtilTokenXlnets.getTokenStringXLNets(com.ejie.ad74a.constantes.Constantes.COD_APLICACION);
		StringBuilder info = new StringBuilder();
		info.append("<distribution><registryNumber>");
		info.append(bandejaPapel0.getNumRegistro12());
		info.append("</registryNumber><cause>");
		info.append("No pertenece");
		info.append("</cause>");
		info.append("</distribution>");

		try {
			this.x97DistributionWebServiceImpl.rejectDistribution(tokenSesion, info.toString());
		} catch (Exception e) {
			BandejaPapel0ServiceImpl.logger.error("rechazarEntrada error", e);
		}
	}

	@Override
	public void guardarEntrada(BandejaPapel0 bandejaPapel0) {

		try {
			Expedientes expediente = Utilidades.esNulo(bandejaPapel0.getExpediente()) ? new Expedientes()
					: this.findExpediente(bandejaPapel0.getExpediente());

			bandejaPapel0.setExpediente(expediente);
			bandejaPapel0.setNumExpediente12(expediente.getNumExpediente00());
			bandejaPapel0.setUsuModif12(UtilSeguridad.getUsuarioConectado().getUserName());
			bandejaPapel0.setfModif12(UtilidadesFecha.getFechaSistema());

			this.bandejaPapel0Dao.updateProcesarEntradaBandeja(bandejaPapel0);
			this.expedientesDao.updateUrgenciaExpedientebyNumRegistro(bandejaPapel0);
			if (!bandejaPapel0.getEstado12().equals(Constantes.EstadosBandejaPapel0.EN_CURSO)) {
				this.bandejaPapel0Dao.updateTipoProceso(bandejaPapel0);
			}

		} catch (Throwable e) {
			ManagerErrors.manageException(e, UtilLiterales.getLiteralMessage(appMessageSource, "error.guardarEntrada"));
		}

	}

	private PisosTutelados isPisoTutelado(Direcciones direccion) {
		List<PisosTutelados> listPisos = this.pisosTuteladosDao.isPisoTutelado(direccion);
		if (null != listPisos && listPisos.size() > 0) {
			return listPisos.get(0);
		}
		return null;
	}

	@Override
	public Expedientes obtenerAvisoSolicitanteUltimoExp(String idSolicitante) {
		return this.bandejaPapel0Dao.obtenerAvisoSolicitanteUltimoExp(idSolicitante);
	}

}
