package com.ejie.ad74a.service;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
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 java.util.Locale;

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

import org.apache.commons.beanutils.BeanUtils;
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.i18n.LocaleContextHolder;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ejie.ad74a.dao.DependenciaDao;
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.exceptions.Ad74aException;
import com.ejie.ad74a.exceptions.ManagerErrors;
import com.ejie.ad74a.model.Dependencia;
import com.ejie.ad74a.model.Direcciones;
import com.ejie.ad74a.model.Discapacidad;
import com.ejie.ad74a.model.DocTemporales;
import com.ejie.ad74a.model.Expedientes;
import com.ejie.ad74a.model.Perfiles;
import com.ejie.ad74a.model.PisosTutelados;
import com.ejie.ad74a.service.documentos.DocumentosService;
import com.ejie.ad74a.util.comun.UtilLiterales;
import com.ejie.ad74a.util.comun.UtilSeguridad;
import com.ejie.ad74a.util.constantes.ProcedimientosEnum;
import com.ejie.ad74a.util.constantes.TiposDocumentoRoleEnum;
import com.ejie.ad74a.util.pif.Ad74aPIFws;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;
import com.ejie.x38.dto.TableRowDto;
import com.ejie.x38.json.JSONObject;
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;

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

@Service(value = "expedientesService")
public class ExpedientesServiceImpl implements ExpedientesService {

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

	@Autowired
	private ExpedientesDao expedientesDao;

	@Autowired
	private DocumentosService documentosService;

	@Autowired
	private DireccionesService direccionesService;

	@Autowired
	private PerfilesService perfilesService;

	@Autowired
	private CuentasService cuentasService;

	@Autowired
	private DiscapacidadDao discapacidadDao;

	@Autowired
	private DependenciaDao dependenciaDao;

	@Autowired
	private PisosTuteladosDao pisosTuteladosDao;

	@Autowired
	private PerfilesDao perfilesDao;

	@Autowired
	private SolicitantesService solicitantesService;

	@Resource
	private ReloadableResourceBundleMessageSource appMessageSource;

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

	/**
	 * Updates a single row in the Expedientes table.
	 *
	 * @param expedientes Expedientes
	 * @return Expedientes
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Expedientes update(Expedientes expedientes) {

		if (expedientes != null
				&& ProcedimientosEnum.ALTA.getId().equalsIgnoreCase(expedientes.getIdProcedimiento00())) {

			// Dirección
			if (expedientes.getDirecciones() != null && expedientes.getDirecciones().getIdDireccion06() == null) {
				expedientes.getDirecciones().setUsuAlta06(UtilSeguridad.getUsuarioConectado().getUserName());
				expedientes.getDirecciones().setIdSolicitante06(expedientes.getSolicitantes().getIdSolicitante01());
				Direcciones newDireccion = this.direccionesService.add(expedientes.getDirecciones());
				expedientes.setDirecciones(newDireccion);
			} else {
				if (expedientes.getDirecciones() == null) {
					expedientes.setDirecciones(new Direcciones());
				}
				expedientes.getDirecciones().setIdSolicitante06(expedientes.getSolicitantes().getIdSolicitante01());
				this.direccionesService.updateDireccion(expedientes.getDirecciones());
			}

			// La direccion de interesado en el expediente de alta, al no estar resuelto y
			// no ser un beneficiario, no se guarda en el historico. Por lo que se actualiza
			// directamente el registro. (Solo se pasaria a historico si se modifica desde
			// la pantalla de beneficiario)
			if (expedientes.getDirecciones() != null) {
				// mirar si es piso tutelado
				if (expedientes.getPerfiles().getPisoTutelado07() == 1) {

					this.perfilesDao.updatePisoTutelado(expedientes.getPerfiles());
				}

			}
//			if (expedientes.getDirecciones() != null) {
//				this.direccionesService.update(expedientes.getDirecciones());
//				// mirar si es piso tutelado
//				if (null != expedientes.getDirecciones()) {
//					PisosTutelados pisoTu = isPisoTutelado(expedientes.getDirecciones());
//					if (null != pisoTu) {
//						expedientes.getPerfiles().setPisoTutelado07(Constantes.PisoTutelado.ESTA);
//						expedientes.getPerfiles().setPisosTutelados(pisoTu);
//					} else {
//						expedientes.getPerfiles().setPisoTutelado07(Constantes.PisoTutelado.NO_ESTA);
//						expedientes.getPerfiles().setPisosTutelados(null);
//					}
//					this.perfilesDao.updatePisoTutelado(expedientes.getPerfiles());
//				}
//
//			}

			if (expedientes.getDireccionNotif() != null) {
				if (expedientes.getDireccionNotif().getIdDireccion06() == null) {
					expedientes.getDireccionNotif().setUsuAlta06(UtilSeguridad.getUsuarioConectado().getNif());
					expedientes.setDireccionNotif(this.direccionesService.add(expedientes.getDireccionNotif()));
				} else {

					this.direccionesService.update(expedientes.getDireccionNotif());
				}
			}
			// El numero de cuenta en el expediente de alta, al no estar resuelto y no ser
			// un beneficiario, no se guarda en el historico. Por lo que se actualiza
			// directamente el registro. (Solo se pasaria a historico si se modifica desde
			// la pantalla de beneficiario)
			this.cuentasService.update(expedientes.getCuentas());

			// Actualizamos el perfil
			this.perfilesService.updateBloquePerfilesPisosTut(expedientes.getPerfiles());

			// Actualizamos dependencia
			if (expedientes.getDependencia() != null) {
				if (expedientes.getDependencia().getIdDependencia04() != null) {
					this.dependenciaDao.update(expedientes.getDependencia());
				} else {
					expedientes.getDependencia().setIdExpediente04(expedientes.getIdExpediente00());
					expedientes.getDependencia().setIdSolicitante04(expedientes.getIdSolicitante00());
					expedientes.setDependencia(this.dependenciaDao.add(expedientes.getDependencia()));
				}
			}

			// Actualizamos discapacidad
			if (expedientes.getDiscapacidad() != null) {
				if (expedientes.getDiscapacidad().getIdDiscapacidad71() != null) {

					this.discapacidadDao.update(expedientes.getDiscapacidad());
				} else {
					expedientes.getDiscapacidad().setIdExpediente71(expedientes.getIdExpediente00());
					expedientes.getDiscapacidad().setIdSolicitante71(expedientes.getIdSolicitante00());
					expedientes.setDiscapacidad(this.discapacidadDao.add(expedientes.getDiscapacidad()));
				}
			}

			// Actualizar los datos del usuario fecha nacimiento nss tis
			this.solicitantesService.updateDatosExpediente(expedientes.getSolicitantes());

			return this.expedientesDao.updateAlta(expedientes);

		} else if (expedientes != null
				&& ProcedimientosEnum.BAJA.getId().equalsIgnoreCase(expedientes.getIdProcedimiento00())) {

			// Actualizar los datos del usuario fecha nacimiento
			this.solicitantesService.updateFNac(expedientes.getSolicitantes());

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

					expedientes.setDireccionNotif(this.direccionesService.add(expedientes.getDireccionNotif()));
				} else {

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

			return this.expedientesDao.updateBaja(expedientes);

		} else if (expedientes != null
				&& ProcedimientosEnum.MODIFICACION.getId().equalsIgnoreCase(expedientes.getIdProcedimiento00())) {

			// La direccion de interesado en el expediente de modificación, al no estar
			// resuelto y
			// no ser un beneficiario, no se guarda en el historico. Por lo que se actualiza
			// directamente el registro. (Solo se pasaria a historico si se modifica desde
			// la pantalla de beneficiario)
			// Dirección
			if (expedientes.getDirecciones() != null && expedientes.getDirecciones().getIdDireccion06() == null) {
				expedientes.getDirecciones().setUsuAlta06(UtilSeguridad.getUsuarioConectado().getUserName());
				expedientes.getDirecciones().setIdSolicitante06(expedientes.getSolicitantes().getIdSolicitante01());
				Direcciones newDireccion = this.direccionesService.add(expedientes.getDirecciones());
				expedientes.setDirecciones(newDireccion);
			} else {
				if (expedientes.getDirecciones() == null) {
					expedientes.setDirecciones(new Direcciones());
				}
				expedientes.getDirecciones().setIdSolicitante06(expedientes.getSolicitantes().getIdSolicitante01());
				this.direccionesService.updateDireccion(expedientes.getDirecciones());
			}

			// Actualizar los datos del usuario fecha nacimiento
			this.solicitantesService.updateFNac(expedientes.getSolicitantes());

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

					expedientes.setDireccionNotif(this.direccionesService.add(expedientes.getDireccionNotif()));
				} else {

					this.direccionesService.update(expedientes.getDireccionNotif());
				}
			}
			if (expedientes.getDirecciones() != null) {
				// mirar si es piso tutelado
				if (expedientes.getPerfiles().getPisoTutelado07() != null
						&& expedientes.getPerfiles().getIdPerfil07() != null) {
					this.perfilesDao.updatePisoTutelado(expedientes.getPerfiles());
				} else if (expedientes.getPerfiles().getPisoTutelado07() != null
						&& expedientes.getPerfiles().getIdPerfil07() == null) {
					Perfiles perfil = this.perfilesDao.add(expedientes.getPerfiles());
					expedientes.setPerfiles(perfil);
				}

			}

			return this.expedientesDao.updateModificacion(expedientes);

		} else if (expedientes != null
				&& ProcedimientosEnum.INFORME.getId().equalsIgnoreCase(expedientes.getIdProcedimiento00())) {

			// Actualizar los datos del usuario fecha nacimiento
			this.solicitantesService.updateFNac(expedientes.getSolicitantes());

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

					expedientes.setDireccionNotif(this.direccionesService.add(expedientes.getDireccionNotif()));
				} else {

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

			return this.expedientesDao.updateInforme(expedientes);

		} else if (expedientes != null
				&& ProcedimientosEnum.REVISION_PRECIO.getId().equalsIgnoreCase(expedientes.getIdProcedimiento00())) {

			// Actualizar los datos del usuario fecha nacimiento
			this.solicitantesService.updateFNac(expedientes.getSolicitantes());

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

					expedientes.setDireccionNotif(this.direccionesService.add(expedientes.getDireccionNotif()));
				} else {

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

			// Actualizamos dependencia
			if (expedientes.getDependencia() != null) {
				if (expedientes.getDependencia().getIdDependencia04() != null) {
					this.dependenciaDao.update(expedientes.getDependencia());
				} else {
					expedientes.getDependencia().setIdExpediente04(expedientes.getIdExpediente00());
					// expedientes.getDependencia().setIdSolicitante04(expedientes.getIdSolicitante00());
					expedientes.setDependencia(this.dependenciaDao.add(expedientes.getDependencia()));
				}
			}

			// Actualizamos discapacidad
			if (expedientes.getDiscapacidad() != null) {
				if (expedientes.getDiscapacidad().getIdDiscapacidad71() != null) {

					this.discapacidadDao.update(expedientes.getDiscapacidad());
				} else {
					expedientes.getDiscapacidad().setIdExpediente71(expedientes.getIdExpediente00());
					// expedientes.getDiscapacidad().setIdSolicitante71(expedientes.getIdSolicitante00());
					expedientes.setDiscapacidad(this.discapacidadDao.add(expedientes.getDiscapacidad()));
				}
			}

			return this.expedientesDao.updateRevision(expedientes);

		} else if (expedientes != null && ProcedimientosEnum.NOTIFICACION_LIQUIDACION.getId()
				.equalsIgnoreCase(expedientes.getIdProcedimiento00())) {

			// Actualizar los datos del usuario fecha nacimiento
			// this.solicitantesService.updateFNac(expedientes.getSolicitantes());

			if (expedientes.getDirecciones() != null && expedientes.getDirecciones().getIdDireccion06() == null) {
				expedientes.getDirecciones().setUsuAlta06(UtilSeguridad.getUsuarioConectado().getUserName());
				expedientes.getDirecciones().setIdSolicitante06(expedientes.getSolicitantes().getIdSolicitante01());
				Direcciones newDireccion = this.direccionesService.add(expedientes.getDirecciones());
				expedientes.setDirecciones(newDireccion);
			} else {
				if (expedientes.getDirecciones() == null) {
					expedientes.setDirecciones(new Direcciones());
				}
				expedientes.getDirecciones().setIdSolicitante06(expedientes.getSolicitantes().getIdSolicitante01());
				this.direccionesService.updateDireccion(expedientes.getDirecciones());
			}

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

					expedientes.setDireccionNotif(this.direccionesService.add(expedientes.getDireccionNotif()));
				} else {

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

			return this.expedientesDao.updateRevision(expedientes);

		}

		ManagerErrors.manageError("No se ha podido realizar la operación");

		return expedientes;
	}

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

	/**
	 * Finds a single row in the Expedientes table.
	 *
	 * @param expedientes Expedientes
	 * @return Expedientes
	 */
	public Expedientes find(Expedientes expedientes) {
		Expedientes expediente = this.expedientesDao.find(expedientes);
		Dependencia dependencia = new Dependencia();
		dependencia.setIdExpediente04(expediente.getIdExpediente00());
		expediente.setDependencia(this.dependenciaDao.findByIdExp(dependencia));

		Discapacidad discapacidad = new Discapacidad();
		discapacidad.setIdExpediente71(expediente.getIdExpediente00());
		expediente.setDiscapacidad(this.discapacidadDao.findByIdExp(discapacidad));

		return expediente;
	}

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

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

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

	public List<Expedientes> findAllLikeBandejaPapel0(Expedientes expedientes, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return (List<Expedientes>) this.expedientesDao.findAllLikeBandejaPapel0(expedientes, tableRequestDto,
				startsWith);
	}

	public List<Expedientes> findByNumRegBandejaPapel0(Expedientes expedientes, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return (List<Expedientes>) this.expedientesDao.findByNumRegBandejaPapel0(expedientes, tableRequestDto,
				startsWith);
	}
	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the Expedientes table.
	 *
	 * @param tableRequestDto TableRequestDto
	 */
	public void removeMultiple(TableRequestDto tableRequestDto) {
		this.expedientesDao.removeMultiple(tableRequestDto);
	}

	/**
	 * Filter method in the Expedientes table.
	 *
	 * @param filterExpedientes Expedientes
	 * @param tableRequestDto   TableRequestDto
	 * @param startsWith        Boolean
	 * @return TableResponseDto<Expedientes>
	 */
	public TableResponseDto<Expedientes> filter(Expedientes filterExpedientes, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		List<Expedientes> listaExpedientes = this.expedientesDao.findAllLike(filterExpedientes, tableRequestDto, false);
		Long recordNum = this.expedientesDao
				.findAllLikeCount(filterExpedientes != null ? filterExpedientes : new Expedientes(), false);

		TableResponseDto<Expedientes> tableResponseDto = new TableResponseDto<Expedientes>(tableRequestDto, recordNum,
				listaExpedientes);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<Expedientes>> reorderSelection = this.expedientesDao.reorderSelection(filterExpedientes,
					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<Expedientes>> reorderSeeker = this.expedientesDao.reorderSelection(filterExpedientes,
					tableRequestDto, startsWith);
			tableResponseDto.setReorderedSeeker(reorderSeeker);
			tableResponseDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return tableResponseDto;
	}

	/**
	 * Filter method in the Expedientes table.
	 *
	 * @param filterExpedientes Expedientes
	 * @param tableRequestDto   TableRequestDto
	 * @param startsWith        Boolean
	 * @return TableResponseDto<Expedientes>
	 */
	@Override
	public TableResponseDto<Expedientes> filterRelacionados(Expedientes filterExpedientes,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<Expedientes> listaExpedientes = this.expedientesDao.findAllLikeRelacionados(filterExpedientes,
				tableRequestDto, false);
		Long recordNum = this.expedientesDao
				.findAllLikeCountRelacionados(filterExpedientes != null ? filterExpedientes : new Expedientes(), false);

		TableResponseDto<Expedientes> tableResponseDto = new TableResponseDto<Expedientes>(tableRequestDto, recordNum,
				listaExpedientes);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<Expedientes>> reorderSelection = this.expedientesDao.reorderSelection(filterExpedientes,
					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<Expedientes>> reorderSeeker = this.expedientesDao.reorderSelection(filterExpedientes,
					tableRequestDto, startsWith);
			tableResponseDto.setReorderedSeeker(reorderSeeker);
			tableResponseDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return tableResponseDto;
	}

	/**
	 * Filter method in the Expedientes table.
	 *
	 * @param filterExpedientes Expedientes
	 * @param tableRequestDto   TableRequestDto
	 * @param startsWith        Boolean
	 * @return TableResponseDto<Expedientes>
	 */
	@Override
	public List<Expedientes> findAllLikeRelacionados(Expedientes filterExpedientes) {
		return this.expedientesDao.findAllLikeRelacionados(filterExpedientes, null, false);

	}

	/**
	 * Searches rows in the Expedientes table.
	 *
	 * @param filterExpedientes Expedientes
	 * @param searchExpedientes Expedientes
	 * @param tableRequestDto   TableRequestDto
	 * @param startsWith        Boolean
	 * @return List<TableRowDto<Expedientes>>
	 */
	public List<TableRowDto<Expedientes>> search(Expedientes filterExpedientes, Expedientes searchExpedientes,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		return this.expedientesDao.search(filterExpedientes, searchExpedientes, tableRequestDto, startsWith);
	}

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

	/*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */

	/**
	 * Finder method in the hierarchical the Expedientes table.
	 *
	 * @param filterExpedientes Expedientes
	 * @param tableRequestDto   TableRequestDto
	 * @param startsWith        Boolean
	 * @return TableResponseDto<JerarquiaDto<Expedientes>>
	 */
	public TableResponseDto<JerarquiaDto<Expedientes>> jerarquia(Expedientes filterExpedientes,
			TableRequestDto tableRequestDto, Boolean startsWith) {
		List<JerarquiaDto<Expedientes>> listaExpedientes = this.expedientesDao.findAllLikeJerarquia(filterExpedientes,
				tableRequestDto);
		Long recordNum = this.expedientesDao.findAllLikeCountJerarquia(filterExpedientes, tableRequestDto);
		return new TableResponseDto<JerarquiaDto<Expedientes>>(tableRequestDto, recordNum, listaExpedientes);
	}

	/**
	 * Finder method for siblings rows in the hierarchical the Expedientes table.
	 *
	 * @param filterExpedientes Expedientes
	 * @param tableRequestDto   TableRequestDto
	 * @return TableResponseDto<JerarquiaDto<Expedientes>>
	 */
	public TableResponseDto<JerarquiaDto<Expedientes>> jerarquiaChildren(Expedientes filterExpedientes,
			TableRequestDto tableRequestDto) {
		TableResponseDto<JerarquiaDto<Expedientes>> tableResponseDto = new TableResponseDto<JerarquiaDto<Expedientes>>();
		tableResponseDto.addAdditionalParam(TableResponseDto.CHILDREN,
				this.expedientesDao.findAllChild(filterExpedientes, tableRequestDto));
		return tableResponseDto;
	}

	/**
	 * Exporta Datos al clipBoard
	 *
	 */
	public List<Expedientes> getMultiple(Expedientes filterExpedientes, TableRequestDto tableRequestDto,
			Boolean startsWith) {
		return this.expedientesDao.getMultiple(filterExpedientes, tableRequestDto, startsWith);
	}

	/**
	 * Devuelve un fichero en el formato deseado que contiene los datos exportados
	 * de la tabla.
	 *
	 * @param filterExpedientes Expedientes
	 * @param columns           String[]
	 * @param fileName          String
	 * @param sheetTitle        String
	 * @param reportsParams     ArrayList<?>
	 * @param tableRequestDto   TableRequestDto
	 * @param request           HttpServletRequest
	 * @param response          HttpServletResponse
	 */
	@Override
	public void generateReport(Expedientes filterExpedientes, String[] columns, String[] columnsName, String fileName,
			String sheetTitle, TableRequestDto tableRequestDto, HttpServletRequest request,
			HttpServletResponse response) {
		// Accede a la DB para recuperar datos
		List<Expedientes> filteredData = getDataForReports(filterExpedientes, 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 : Expedientes.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 = Expedientes.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);
					Expedientes.class.getMethod("get" + methodName);
					tempColumns.add(fields[i].getName());
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				}

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

		// si no se definen el nombre de las columnas , se dejan las de 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<Expedientes>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param sheetTitle   String
	 * @param extension    String
	 * @param formatter    SimpleDateFormat
	 * @param response     HttpServletResponse
	 */
	private void generateExcelReport(List<Expedientes> 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(
						UtilLiterales.getLiteralMessage(appMessageSource, "excelReportLiteral." + 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 (Expedientes rowExpedientes : 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 cellExpedientes = row.createCell(cellNumber++);
					cellExpedientes.setCellValue(getCellValue(column, rowExpedientes));
				}
			}

			// 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<Expedientes>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param response     HttpServletResponse
	 */
	private void generatePDFReport(List<Expedientes> 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 (Expedientes rowExpedientes : 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, rowExpedientes));
				}
			}

			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<Expedientes>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param sheetTitle   String
	 * @param response     HttpServletResponse
	 */
	private void generateODSReport(List<Expedientes> 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 (Expedientes rowExpedientes : 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, rowExpedientes));
				}
			}

			// 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<Expedientes>
	 * @param columns      String[]
	 * @param fileName     String
	 * @param sheetTitle   String
	 * @param language     String
	 * @param response     HttpServletResponse
	 */
	private void generateCSVReport(List<Expedientes> 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 (Expedientes rowExpedientes : 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, rowExpedientes);

					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 filterExpedientes Expedientes
	 * @param tableRequestDto   TableRequestDto
	 */
	private List<Expedientes> getDataForReports(Expedientes filterExpedientes, TableRequestDto tableRequestDto) {
		if (tableRequestDto.getMultiselection().getSelectedAll()
				&& tableRequestDto.getMultiselection().getSelectedIds().isEmpty()) {
			if (filterExpedientes != null) {
				return this.expedientesDao.findAllLike(filterExpedientes, tableRequestDto, false);
			} else {
				return this.expedientesDao.findAll(new Expedientes(), null);
			}
		} else {
			return this.expedientesDao.getMultiple(filterExpedientes, tableRequestDto, false);
		}
	}

	/**
	 * Obtiene los valores de las celdas.
	 *
	 * @param column         String
	 * @param rowExpedientes Expedientes
	 */
	private String getCellValue(String column, Expedientes rowExpedientes) {
		String cellValue = "";
		try {

			if ("solicitantes.nombre01".equalsIgnoreCase(column)) {
				cellValue = rowExpedientes.getSolicitantes().getNombreCompleto();
			} else {
				cellValue = BeanUtils.getProperty(rowExpedientes, column) != null
						? BeanUtils.getProperty(rowExpedientes, column)
						: "";
			}
			if ("urgencia00".equalsIgnoreCase(column)) {
				Locale locale = LocaleContextHolder.getLocale();
				if (rowExpedientes.getUrgencia00() != null) {

					if (rowExpedientes.getUrgencia00() == 0)
						cellValue = UtilLiterales.getLiteralMessage(appMessageSource, locale,
								"expediente.urgencia.noUrgente");

					if (rowExpedientes.getUrgencia00() == 1)
						cellValue = UtilLiterales.getLiteralMessage(appMessageSource, locale,
								"expediente.urgencia.urgenteSolicitud");

					if (rowExpedientes.getUrgencia00() == 2)
						cellValue = UtilLiterales.getLiteralMessage(appMessageSource, locale,
								"expediente.urgencia.urgenteDireccion");

					if (rowExpedientes.getUrgencia00() == 3)
						cellValue = UtilLiterales.getLiteralMessage(appMessageSource, locale,
								"expediente.urgencia.urgenteTecnico");
				}
			}
			if ("idTipoEntrada00".equalsIgnoreCase(column)) {
				Locale locale = LocaleContextHolder.getLocale();
				if (rowExpedientes.getIdTipoEntrada00() != null) {

					if (rowExpedientes.getIdTipoEntrada00().equals("1"))
						cellValue = UtilLiterales.getLiteralMessage(appMessageSource, locale,
								"expediente.urgencia.tipoEntradaTelematica");

					if (rowExpedientes.getIdTipoEntrada00().equals("2"))
						cellValue = UtilLiterales.getLiteralMessage(appMessageSource, locale,
								"expediente.urgencia.tipoEntradaPapel0");

					if (rowExpedientes.getIdTipoEntrada00().equals("3"))
						cellValue = UtilLiterales.getLiteralMessage(appMessageSource, locale,
								"expediente.urgencia.tipoEntradaPresencial");

					if (rowExpedientes.getIdTipoEntrada00().equals("4"))
						cellValue = UtilLiterales.getLiteralMessage(appMessageSource, locale,
								"expediente.urgencia.tipoEntradaInicioOficio");
				}
			}
			if ("idProcedimiento00".equalsIgnoreCase(column)) {
				if (rowExpedientes.getIdProcedimiento00() != null) {
					cellValue = ProcedimientosEnum.getDesc(cellValue);
				} else {
					cellValue = BeanUtils.getProperty(rowExpedientes, column) != null
							? BeanUtils.getProperty(rowExpedientes, column)
							: "";
				}
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		return cellValue;
	}

	public Expedientes findExpBySolProc(Expedientes expedientes, ProcedimientosEnum... procedimientosEnum) {
		return this.expedientesDao.findExpBySolProc(expedientes, procedimientosEnum);
	}

	/***
	 * Finds the data for the Cuadro Mando
	 * 
	 * @param expediente
	 * @return List<JSONObject>
	 */
	@Override
	public List<JSONObject> findCuadroMando(Expedientes expediente) {
		return this.expedientesDao.findCuadroMando(expediente);
	}

	/**
	 * Finds rows in the Expedientes table to use in search in BandejaPapel0.
	 *
	 * @param expedientes     Expedientes
	 * @param tableRequestDto TableRequestDto
	 * @param startsWith      Boolean
	 * @return List<Expedientes>
	 */
	@Override
	public TableResponseDto<Expedientes> findPapel0(Expedientes filterExpedientes, TableRequestDto tableRequestDto,
			Boolean startsWith) {

		List<Expedientes> listaExpedientes = this.expedientesDao.findPapel0(filterExpedientes, tableRequestDto, false);
		Long recordNum = this.expedientesDao
				.findPapel0Count(filterExpedientes != null ? filterExpedientes : new Expedientes(), false);

		TableResponseDto<Expedientes> tableResponseDto = new TableResponseDto<Expedientes>(tableRequestDto, recordNum,
				listaExpedientes);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<Expedientes>> reorderSelection = this.expedientesDao.reorderSelection(filterExpedientes,
					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<Expedientes>> reorderSeeker = this.expedientesDao.reorderSelection(filterExpedientes,
					tableRequestDto, startsWith);
			tableResponseDto.setReorderedSeeker(reorderSeeker);
			tableResponseDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return tableResponseDto;
	}

	/**
	 * Updates a single row in the Expedientes table from solicitudPapel0.
	 *
	 * @param expedientes Expedientes
	 * @return Expedientes
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Expedientes updateTabSolicitudPapel0(Expedientes expedientes) {
		return this.expedientesDao.updateTabSolicitudPapel0(expedientes);
	}

	/**
	 * Updates a single row in the Expedientes folderID table from solicitudPapel0.
	 *
	 * @param expedientes Expedientes
	 * @return Expedientes
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Expedientes updateFolderID(Expedientes expedientes) {
		return this.expedientesDao.updateFolderID(expedientes);
	}

	/**
	 * Updates a single row in the Expedientes observaciones
	 *
	 * @param expedientes Expedientes
	 * @return Expedientes
	 */
	@Transactional(rollbackFor = Throwable.class)
	public Expedientes updateObservaciones(Expedientes expedientes) {
		return this.expedientesDao.updateObservaciones(expedientes);
	}

	@Transactional(rollbackFor = Throwable.class)
	public Expedientes updateTecnico(Expedientes expedientes) {
		return this.expedientesDao.updateTecnico(expedientes);
	}

	public void interoperabilidadJob() throws Exception {
		ExpedientesServiceImpl.logger.info("Proceso de reinvocación de Servicios de Interoperabilidad - inicio ");

		// 1. Recuperar aquellos expedientes que cumplan lo siguiente: La fecha actual
		// sea igual o superior a alguno de los campos FINVOKE_CONS_SS_36 o
		// FINVOKE_CONS_ATRIBUT_36
		List<Expedientes> expedientesList = this.expedientesDao.findInterop();

		// 2.Invocar a Platea para recuperar los documentos de cada expediente anterior
		// 3. Por cada documento recuperar el resultado de la invocación de Platea y
		// actualizar la BBDD

		if (!expedientesList.isEmpty()) {
			ExpedientesServiceImpl.logger
					.info("Proceso de reinvocación de Servicios de Interoperabilidad - Exptes. encontrados : "
							+ expedientesList.size());

			// documentos aportados por la entidad
			for (Expedientes exp : expedientesList) {
				documentosService.authorizationResultJob(expedientesList);
			}

		} else {
			ExpedientesServiceImpl.logger
					.info("Proceso de reinvocación de Servicios de Interoperabilidad - Exptes. encontrados : 0.");

		}
		ExpedientesServiceImpl.logger.info("Proceso de reinvocación de Servicios de Interoperabilidad - fin ");
	}

	public void updateEstado(Expedientes expediente) {
		this.expedientesDao.updateEstado(expediente);
	}

	/**
	 * Busca el último expediente de un beneficiario
	 * 
	 * @param filterExpedientes
	 * @return Expedientes
	 */
	public Expedientes findBeneficiarioUltimoExp(Expedientes filterExpedientes) {
		return this.expedientesDao.findBeneficiarioUltimoExp(filterExpedientes);
	}

	public void aportarDocumento(Expedientes expediente, MultipartFile documento, String roleID) {

		Ad74aPIFws pifService = Ad74aPIFws.getInstance();
		String rutaPif = "";
		try {

			// Buscar datos del expediente
			expediente = this.expedientesDao.find(expediente);

			// Subir documento a pif
			InputStream inputStream = new BufferedInputStream(documento.getInputStream());
			rutaPif = pifService.uploadDocument(inputStream, "/r02g/ad74a/" + documento.getOriginalFilename(), false);

			// Guardar el documento en la BD en la tabla temporal y sugerir la tarea
			DocTemporales docTemporal = new DocTemporales();
			docTemporal.setFolderId72(expediente.getFolderId00());
			docTemporal.setNombreDoc72(documento.getOriginalFilename());
			docTemporal.setRutapif72(rutaPif);
			docTemporal.setExterno72(0);

			docTemporal.setIdTipoDoc72(TiposDocumentoRoleEnum.getIdByRole(roleID));
			docTemporal.setUsuAportacion72(UtilSeguridad.getUsuarioConectado().getUserName());

			this.documentosService.aportarDocumento(docTemporal);

		} catch (Exception e) {
			throw new Ad74aException(e, com.ejie.ad74a.util.constantes.Constantes.ERROR_GENERICO);
//			throw new Ad74aException(UtilLiterales.getLiteralMessage(appMessageSource,
//					com.ejie.ad74a.util.constantes.Constantes.ERROR_GENERICO));
		}

	}

	@Override
	public TableResponseDto<Expedientes> filterBanedeja(Expedientes filterExpedientes, TableRequestDto tableRequestDto,
			boolean startsWith) {
		List<Expedientes> listaExpedientes = this.expedientesDao.findBanedejaAllLike(filterExpedientes, tableRequestDto,
				false);
		Long recordNum = this.expedientesDao
				.findBanedejaAllLikeCount(filterExpedientes != null ? filterExpedientes : new Expedientes(), false);

		TableResponseDto<Expedientes> tableResponseDto = new TableResponseDto<Expedientes>(tableRequestDto, recordNum,
				listaExpedientes);

		if (tableRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<Expedientes>> reorderSelection = this.expedientesDao.reorderSelection(filterExpedientes,
					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<Expedientes>> reorderSeeker = this.expedientesDao.reorderSelection(filterExpedientes,
					tableRequestDto, startsWith);
			tableResponseDto.setReorderedSeeker(reorderSeeker);
			tableResponseDto.addAdditionalParam("reorderedSeeker", reorderSeeker);
		}
		return tableResponseDto;
	}

	@Override
	public Expedientes updateExisteInstalacion(Expedientes expediente) {

		return this.expedientesDao.updateExisteInstalacion(expediente);
	}

	@Override
	public Expedientes updateIdLiquidacion(Expedientes expediente) {

		return this.expedientesDao.updateIdLiquidacion(expediente);
	}
}
