package com.ejie.ab78.service.terceros;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.ejie.ab78.comun.Constantes;
import com.ejie.ab78.comun.UtilUsuario;
import com.ejie.ab78.dao.terceros.CanalesAvisoDao;
import com.ejie.ab78.dao.terceros.DatosDireccionesDao;
import com.ejie.ab78.dao.terceros.DatosTercerosDao;
import com.ejie.ab78.dao.terceros.RelExpTerDao;
import com.ejie.ab78.dao.terceros.TiposDocumentoDao;
import com.ejie.ab78.dao.terceros.TiposTerceroDao;
import com.ejie.ab78.model.expedientes.Expedientes;
import com.ejie.ab78.model.terceros.CanalesAviso;
import com.ejie.ab78.model.terceros.DatosDirecciones;
import com.ejie.ab78.model.terceros.DatosTerceros;
import com.ejie.ab78.model.terceros.RelExpTer;
import com.ejie.ab78.model.terceros.TiposCanalAviso;
import com.ejie.ab78.model.terceros.TiposDireccion;
import com.ejie.ab78.model.terceros.VistaDatosExpediente;
import com.ejie.ab78.model.terceros.VistaTerceros;
import com.ejie.x38.dto.TableRequestDto;
import com.ejie.x38.dto.TableResponseDto;

/**
 * RelExpTerServiceImpl  
 * 
 *  
 */

@Service(value = "relExpTerService")
@SessionAttributes("usuario")
public class RelExpTerServiceImpl implements RelExpTerService {

	@Autowired
	private RelExpTerDao relExpTerDao;
	@Autowired
	private DatosDireccionesDao datosDireccionesDao;
	@Autowired
	private TiposDocumentoDao tiposDocumentoDao;
	@Autowired
	private DatosTercerosDao datosTercerosDao;
	@Autowired
	public CanalesAvisoDao canalesAvisoDao;
	@Autowired
	private TiposTerceroDao tiposTerceroDao;

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

	@Transactional(rollbackFor = Throwable.class)
	public RelExpTer add(RelExpTer relExpTer) {
		return this.relExpTerDao.add(relExpTer);
	}

	@Transactional(rollbackFor = Throwable.class)
	public RelExpTer update(RelExpTer relExpTer) {
		return this.relExpTerDao.update(relExpTer);
	}

	public RelExpTer find(RelExpTer relExpTer) {
		return this.relExpTerDao.find(relExpTer);
	}

	@Transactional(rollbackFor = Throwable.class)
	public void remove(RelExpTer relExpTer) {
		this.relExpTerDao.remove(relExpTer);
	}

	public List<RelExpTer> findAll(RelExpTer relExpTer, TableRequestDto TableRequestDto) {
		return this.relExpTerDao.findAll(relExpTer, TableRequestDto);
	}

	public List<RelExpTer> findAllLike(RelExpTer relExpTer, TableRequestDto TableRequestDto, Boolean startsWith) {
		return this.relExpTerDao.findAllLike(relExpTer, TableRequestDto, startsWith);
	}

	public List<RelExpTer> findParticipaciones(Integer idExpediente) {

		RelExpTer filter = new RelExpTer();
		filter.setIdExpediente(idExpediente);
		List<RelExpTer> listaParticipaciones = this.relExpTerDao.findParticipacionesAgrupadas(filter);
		// Se buscan todas la participaciones
		for (Iterator<RelExpTer> iterator = listaParticipaciones.iterator(); iterator.hasNext();) {
			RelExpTer participacion = iterator.next();
			List<DatosTerceros> tercerosParticipacion = this.relExpTerDao.findTerceros(idExpediente,
					participacion.getParticipantId());

			// Por cada paticipacion se recuperan los terceros y sus direcciones
			for (Iterator<DatosTerceros> itDatosTercero = tercerosParticipacion.iterator(); itDatosTercero.hasNext();) {
				DatosTerceros datosTerceros = itDatosTercero.next();
				DatosTerceros datosTercerosFound = this.datosTercerosDao.findById(datosTerceros.getIdTercero());
				datosTerceros.setNombre(datosTercerosFound.getNombre());
				datosTerceros.setApellido1(datosTercerosFound.getApellido1());
				datosTerceros.setApellido2(datosTercerosFound.getApellido2());
				datosTerceros.setDocumento(datosTercerosFound.getDocumento());
				datosTerceros.setIdioma(datosTercerosFound.getIdioma());
				datosTerceros.setEmail(datosTercerosFound.getEmail());
				datosTerceros.setTelefono(datosTercerosFound.getTelefono());
				datosTerceros.setSexo(datosTercerosFound.getSexo());
				List<DatosDirecciones> datosDirecciones = this.datosDireccionesDao
						.findUbicacionTerceroId(datosTerceros.getIdTercero());
				datosTerceros.setListDatosDirecciones(datosDirecciones);

			}
			participacion.setDatosTercerosList(tercerosParticipacion);
		}
		listaParticipaciones = reduceListaParticipaciones(listaParticipaciones);
		return listaParticipaciones;
	}

	private List<RelExpTer> reduceListaParticipaciones(List<RelExpTer> listaParticipaciones) {
		List<RelExpTer> listaParticipacionesReduced = new ArrayList<RelExpTer>();
		String participationId;
		String terceroId;
		Boolean participacionRepited = false;
		for (Iterator<RelExpTer> iterator = listaParticipaciones.iterator(); iterator.hasNext();) {
			RelExpTer participacion = iterator.next();
			participacionRepited = false;
			for (Iterator<RelExpTer> iteratorReducer = listaParticipacionesReduced.iterator(); iteratorReducer.hasNext()
					&& !participacionRepited;) {
				RelExpTer participacionReduce = iteratorReducer.next();

				boolean participacionIsNull = participacion.getParticipantId() == null;
				boolean participacionReduceIsNull = participacionReduce.getParticipantId() == null;
				boolean equalsParticipationId = (participacionIsNull && participacionReduceIsNull)
						|| (!participacionIsNull
								&& participacion.getParticipantId().equals(participacionReduce.getParticipantId()))
						|| (!participacionReduceIsNull
								&& participacionReduce.getParticipantId().equals(participacion.getParticipantId()));
				boolean tipoTerceroIsNull = participacion.getTiposTercero().getIdTipoTercero() == null;
				boolean tipoTerceroReducedIsNull = participacionReduce.getTiposTercero().getIdTipoTercero() == null;
				boolean equaslTipoTercero = (tipoTerceroIsNull && tipoTerceroReducedIsNull)
						|| participacion.getTiposTercero().getIdTipoTercero()
								.equals(participacionReduce.getTiposTercero().getIdTipoTercero());

				participacionRepited = equalsParticipationId && equaslTipoTercero;
			}
			if (!participacionRepited) {
				listaParticipacionesReduced.add(participacion);
			}

		}
		return listaParticipacionesReduced;
	}

	/**
	 * Obtener lista de participaciones y direcciones del solicitante titular
	 * 
	 * 
	 * @param idExpediente
	 *            Integer
	 * 
	 */
	public List<VistaDatosExpediente> findParticipaciones2(Integer idExpediente, Long tipoParticipantePrincipal) {
		List<RelExpTer> listaParticipaciones = this.relExpTerDao.findParticipantes(idExpediente);
		// guardaremos parcipantes de una participacion
		List<DatosTerceros> listDatosTercero = new ArrayList<DatosTerceros>();

		VistaDatosExpediente vistaDatosExpedienteAux = new VistaDatosExpediente();
		VistaDatosExpediente vistaDatosExpedienteAuxBBDD = new VistaDatosExpediente();
		VistaDatosExpediente vistaDatosExpedienteDirecciones = new VistaDatosExpediente();
		List<VistaDatosExpediente> listaPersonas = new ArrayList<VistaDatosExpediente>();

		List<VistaTerceros> listaSearchFolder = new ArrayList<VistaTerceros>();

		VistaTerceros vistaTercerosAux = new VistaTerceros();
		VistaTerceros vistaTercerosAuxDireccion = new VistaTerceros();

		List<VistaTerceros> listafinalBBDD = new ArrayList<VistaTerceros>();

		List<VistaTerceros> listaDireccionesAux = new ArrayList<VistaTerceros>();

		List<DatosDirecciones> listaDirecciones = new ArrayList<DatosDirecciones>();

		String idParcipacion = "";
		Long idTipoPersona = 12345678910L;
		for (RelExpTer participacionesN : listaParticipaciones) {

			int result = participacionesN.getTiposTercero().getIdTipoTercero().compareTo(tipoParticipantePrincipal);
			if (participacionesN.getDatosTerceros().getTipoParticipante().intValue() == Constantes.PARTICIPANTE_TITULAR
					&& result == 0) {
				listaDirecciones = datosDireccionesDao
						.findUbicacionTerceroId(participacionesN.getDatosTerceros().getIdTercero());
				vistaTercerosAuxDireccion.setListaDirecciones(listaDirecciones);
				listaDireccionesAux.add(vistaTercerosAuxDireccion);
				vistaDatosExpedienteDirecciones = new VistaDatosExpediente();
				vistaDatosExpedienteDirecciones.setVistaTercerosList(listaDireccionesAux);
			}

			if (idParcipacion != null) {
				// cambio de partcipacion
				if (!idParcipacion.equalsIgnoreCase(participacionesN.getParticipantId())) {
					// para saber que no es el primero
					if (org.apache.commons.lang.StringUtils.isNotBlank(idParcipacion)) {
						vistaTercerosAux.setDatosTercerosList(listDatosTercero);
						listaSearchFolder.add(vistaTercerosAux);
						vistaDatosExpedienteAux = new VistaDatosExpediente();
						vistaDatosExpedienteAux.setVistaTercerosList(listaSearchFolder);
						vistaTercerosAux = new VistaTerceros();
					}

					idParcipacion = participacionesN.getParticipantId();
					vistaTercerosAux.setOrden(participacionesN.getOrden());
					vistaTercerosAux.setIdTipoTercero(participacionesN.getTiposTercero().getIdTipoTercero());
					vistaTercerosAux
							.setTipoTerceroDesCas(participacionesN.getTiposTercero().getDescripcionCastellano());
					vistaTercerosAux.setTipoTerceroDesEus(participacionesN.getTiposTercero().getDescripcionEuskera());
					vistaTercerosAux.setParticipantId(idParcipacion);
					listDatosTercero = new ArrayList<DatosTerceros>();
					idTipoPersona = participacionesN.getTiposTercero().getIdTipoTercero();
				}
			} else {
				if (idTipoPersona != participacionesN.getTiposTercero().getIdTipoTercero()) {
					if (idTipoPersona != 12345678910L) {
						vistaTercerosAux.setDatosTercerosList(listDatosTercero);
						listafinalBBDD.add(vistaTercerosAux);
						vistaDatosExpedienteAuxBBDD = new VistaDatosExpediente();
						vistaDatosExpedienteAuxBBDD.setVistaTercerosList(listafinalBBDD);
						vistaTercerosAux = new VistaTerceros();
					}
					idParcipacion = participacionesN.getParticipantId();
					idTipoPersona = participacionesN.getTiposTercero().getIdTipoTercero();
					vistaTercerosAux = new VistaTerceros();
					vistaTercerosAux.setIdTipoTercero(participacionesN.getTiposTercero().getIdTipoTercero());
					vistaTercerosAux
							.setTipoTerceroDesCas(participacionesN.getTiposTercero().getDescripcionCastellano());
					vistaTercerosAux.setTipoTerceroDesEus(participacionesN.getTiposTercero().getDescripcionEuskera());
					vistaTercerosAux.setDatosTercerosList(listDatosTercero);
					vistaTercerosAux.setParticipantId(idParcipacion);
					listDatosTercero = new ArrayList<DatosTerceros>();

				}
			}

			DatosTerceros datosTerceros = new DatosTerceros();
			datosTerceros.setNombre(participacionesN.getDatosTerceros().getNombre());
			datosTerceros.setDocumento(participacionesN.getDatosTerceros().getDocumento());
			datosTerceros.setIdioma(participacionesN.getDatosTerceros().getIdioma());
			datosTerceros.setIdTercero(participacionesN.getDatosTerceros().getIdTercero());
			datosTerceros.setApellido1(participacionesN.getDatosTerceros().getApellido1());
			datosTerceros.setApellido2(participacionesN.getDatosTerceros().getApellido2());
			datosTerceros.setTipoParticipante(participacionesN.getDatosTerceros().getTipoParticipante());
			listDatosTercero.add(datosTerceros);

		}

		vistaTercerosAux.setDatosTercerosList(listDatosTercero);
		if (idParcipacion != null && idTipoPersona == 12345678910L) {
			listaSearchFolder.add(vistaTercerosAux);
			vistaDatosExpedienteAux = new VistaDatosExpediente();
			vistaDatosExpedienteAux.setVistaTercerosList(listaSearchFolder);

		} else {
			if (idParcipacion == null && (idTipoPersona == Constantes.REPRESENTANTE_LEGAL
					|| idTipoPersona == Constantes.PERSONA_CONTACTO)) {
				listafinalBBDD.add(vistaTercerosAux);
				vistaDatosExpedienteAuxBBDD = new VistaDatosExpediente();
				vistaDatosExpedienteAuxBBDD.setVistaTercerosList(listafinalBBDD);
			} else {
				listaSearchFolder.add(vistaTercerosAux);
				vistaDatosExpedienteAux = new VistaDatosExpediente();
				vistaDatosExpedienteAux.setVistaTercerosList(listaSearchFolder);
			}

		}

		listaPersonas.add(vistaDatosExpedienteAux);
		listaPersonas.add(vistaDatosExpedienteDirecciones);
		listaPersonas.add(vistaDatosExpedienteAuxBBDD);
		return listaPersonas;

	}

	private void updatearParticipante(String usuario, Date fecha, DatosTerceros datosTerceros, int idTercero,
			RelExpTer relExpTerAux, String nombre, int valorCambioRole, String participacion) {

		datosTerceros.setIdTercero(idTercero);
		datosTerceros.setUsuarioUltmodificacion(usuario);
		datosTerceros.setUsuarioRegistro(usuario);

		logger.info("Nombre de la persona Representante de la participacion: " + nombre + "idTercero: " + idTercero);
		datosTercerosDao.updateTerceroSearchfolder(datosTerceros);

		CanalesAviso canalesAviso = new CanalesAviso();
		canalesAviso.setDatosTerceros(datosTerceros);
		canalesAviso.setUsuarioRegistro(usuario);
		canalesAviso.setFechaRegistro(fecha);
		int resultado = 0;
		// Buscamos si tenemos canales de aviso para este titular
		// tema de canales de aviso del titular
		if (datosTerceros.getCanalesAvisos().size() > 0) {
			for (int i = 0; i < datosTerceros.getCanalesAvisos().size(); i++) {
				canalesAviso.setTiposCanalAviso(datosTerceros.getCanalesAvisos().get(i).getTiposCanalAviso());
				canalesAviso.setCanalAviso(datosTerceros.getCanalesAvisos().get(i).getCanalAviso());
				// busca canal de aviso por id de tercero si no esta insert sino
				// esta update
				resultado = canalesAvisoDao.findCanalByIdTercero(canalesAviso);
				if (null != datosTerceros.getCanalesAvisos().get(i).getCanalAviso()) {
					if (resultado >= 1) {

						canalesAvisoDao.updateCanalAviso(canalesAviso);
						logger.info("Updateamos canal de tipo de aviso en BBDD: "
								+ datosTerceros.getCanalesAvisos().get(i).getTiposCanalAviso() + "para el Tercero: "
								+ idTercero);
					} else {
						logger.info("Ayadimos canal de tipo de aviso en BBDD: "
								+ datosTerceros.getCanalesAvisos().get(i).getTiposCanalAviso() + "para el Tercero: "
								+ idTercero);
						if (null != datosTerceros.getCanalesAvisos().get(i).getTiposCanalAviso()
								.getIdTipoCanalAviso()) {
							canalesAvisoDao.addCanalesAviso(canalesAviso);
						}
					}
				}
			}
		} else {
			resultado = canalesAvisoDao.findTodosLosCanalByIdTercero(idTercero);
			if (resultado > 0) {
				// borramos canales del titular
				canalesAvisoDao.removeCanalesTercero(idTercero);
			}
		}

		DatosTerceros datosTercerosId = new DatosTerceros(idTercero);
		DatosDirecciones filter = new DatosDirecciones();
		filter = datosDireccionesDao.findPostalTerceroId(idTercero);
		boolean hasPostal = filter != null && filter.getIdDireccion() != null && filter.getIdDireccion() > 0;
		boolean notHasPostalPlatea = datosTerceros.getListDatosDirecciones() != null
				&& datosTerceros.getListDatosDirecciones().isEmpty();
		boolean hasPostalPlatea = datosTerceros.getListDatosDirecciones() != null
				&& !datosTerceros.getListDatosDirecciones().isEmpty();
		// Check if exists postal and not in platea, delete else register change
		if (hasPostal && notHasPostalPlatea) {
			datosDireccionesDao.remove(filter);
		} else {
			if (hasPostalPlatea) {
				List<DatosDirecciones> direccionesPostalesPlatea = datosTerceros.getListDatosDirecciones();
				DatosDirecciones direccionPlatea = direccionesPostalesPlatea.get(0);
				if (hasPostal) {
					direccionPlatea.setIdDireccion(filter.getIdDireccion());
					direccionPlatea.setDatosTerceros(datosTercerosId);
					datosDireccionesDao.update(direccionPlatea);
				} else {
					direccionPlatea.setDatosTerceros(datosTercerosId);
					datosDireccionesDao.add(direccionPlatea);
				}
			}
		}
		// ACTUALIZAMOS mi bbdd por si se ha borrado desde tramigune una
		// tipo de canal de aviso
		List<CanalesAviso> resultadoList = canalesAvisoDao.findCanalesAvisoByIdTercero(idTercero);
		if (resultadoList.size() > datosTerceros.getCanalesAvisos().size()) {
			for (int k = 0; k < resultadoList.size(); k++) {
				for (int t = 0; t < datosTerceros.getCanalesAvisos().size(); t++) {
					if (null != datosTerceros.getCanalesAvisos().get(t).getTiposCanalAviso()) {
						if (!resultadoList.get(k).getTiposCanalAviso().getIdTipoCanalAviso().equals(
								datosTerceros.getCanalesAvisos().get(t).getTiposCanalAviso().getIdTipoCanalAviso())) {
							CanalesAviso canalesAvisoAux = new CanalesAviso();
							TiposCanalAviso tiposCanalAviso = new TiposCanalAviso();
							tiposCanalAviso.setIdTipoCanalAviso(
									resultadoList.get(k).getTiposCanalAviso().getIdTipoCanalAviso());
							canalesAvisoAux.setTiposCanalAviso(tiposCanalAviso);
							canalesAvisoAux.setDatosTerceros(datosTerceros);
							canalesAvisoDao.removeCanalesByIdTercero(canalesAvisoAux);
						}
					}
				}
			}

		}
		if (valorCambioRole == 1) {
			relExpTerAux.setDatosTerceros(datosTerceros);
			relExpTerAux.setFechaUltmodificacion(fecha);
			relExpTerAux.setUsuarioUltmodificacion(usuario);
			logger.info("Updatear relacion expediente tercero: " + relExpTerAux.getParticipantId());
			this.relExpTerDao.updateByParticipantId(relExpTerAux);
		}
		if (participacion.equalsIgnoreCase("0")) {
			relExpTerAux.setDatosTerceros(datosTerceros);
			relExpTerAux.setFechaUltmodificacion(fecha);
			relExpTerAux.setUsuarioUltmodificacion(usuario);
			logger.info("Updatear relacion expediente tercero: " + relExpTerAux.getParticipantId());
			this.relExpTerDao.updateByParticipantValue(relExpTerAux);
		}
	}

	private void insertarParticipante(String usuario, Date fecha, RelExpTer relExpTerAux, DatosTerceros datosTerceros) {

		datosTerceros.setUsuarioRegistro(usuario);

		logger.info("Nombre de la persona Representante NUEVO de la participacion");
		datosTercerosDao.addTerceroSearchFolder(datosTerceros);
		DatosTerceros datosTercerosAUxId = datosTercerosDao.findUltimoId();

		CanalesAviso canalesAviso = new CanalesAviso();
		canalesAviso.setDatosTerceros(datosTercerosAUxId);
		canalesAviso.setUsuarioRegistro(usuario);
		canalesAviso.setFechaRegistro(fecha);
		canalesAviso.setDatosTerceros(datosTercerosAUxId);
		// Solo inserto del titular pq desde el search folder solo me trae ese
		if (datosTerceros.getCanalesAvisos().size() > 0) {
			for (int i = 0; i < datosTerceros.getCanalesAvisos().size(); i++) {
				if (null != datosTerceros.getCanalesAvisos().get(i).getCanalAviso()) {
					canalesAviso.setTiposCanalAviso(datosTerceros.getCanalesAvisos().get(i).getTiposCanalAviso());
					canalesAviso.setCanalAviso(datosTerceros.getCanalesAvisos().get(i).getCanalAviso());
					if (null != datosTerceros.getCanalesAvisos().get(i).getTiposCanalAviso().getIdTipoCanalAviso()) {
						canalesAvisoDao.addCanalesAviso(canalesAviso);
					}
					logger.info("Ayadimos canal de tipo de aviso en BBDD: "
							+ datosTerceros.getCanalesAvisos().get(i).getTiposCanalAviso() + "para el Tercero: "
							+ datosTercerosAUxId.getIdTercero());
				}
			}
		}
		if (datosTerceros.getListDatosDirecciones() != null && !datosTerceros.getListDatosDirecciones().isEmpty()) {
			for (Iterator<DatosDirecciones> iterator = datosTerceros.getListDatosDirecciones().iterator(); iterator
					.hasNext();) {
				DatosDirecciones datosDirecciones = iterator.next();
				datosDirecciones.setDatosTerceros(datosTercerosAUxId);
				datosDireccionesDao.add(datosDirecciones);
				logger.info("Ayadimos direcciones en BBDD: " + datosDirecciones.getTiposDireccion().getIdTipoDireccion()
						+ "para el Tercero: " + datosTercerosAUxId.getIdTercero());
			}
		}
		relExpTerAux.setDatosTerceros(datosTercerosAUxId);
		relExpTerAux.setFechaRegistro(fecha);
		relExpTerAux.setUsuarioRegistro(usuario);
		this.add(relExpTerAux);
	}

	/**
	 * Guardar ubicacion y direccion del solicitante y si es bec tambien la
	 * puntacuion
	 *
	 * @param relExpTerEmp
	 *            RelExpTerEmp Bean que contiene la informacion con la que se va
	 *            a crear el nuevo registro.
	 * @return RelExpTerEmp Bean resultante del proceso de creacion.
	 */
	public void registerDomicilioUbicacionSolicitante(HttpServletRequest request, Integer idTercero,
			Expedientes initForm) {
		RelExpTerServiceImpl.logger.info("Incio guardar Solicitante Ubicacion y/o Solicitante direccion");

		List<DatosDirecciones> datosDirecciones = this.datosDireccionesDao.findUbicacionTerceroId(idTercero);
		DatosDirecciones dirTercero = null;
		DatosDirecciones dirEstablecimiento = null;
		for (DatosDirecciones direccion : datosDirecciones) {
			if (Constantes.ID_DIRECCION_ACTIVIDAD == direccion.getTiposDireccion().getIdTipoDireccion()) {
				dirEstablecimiento = direccion;
			} else if (Constantes.ID_DIRECCION_NOTIF_POSTAL == direccion.getTiposDireccion().getIdTipoDireccion()) {
				dirTercero = direccion;
			}
		}

		if (dirTercero == null) {
			dirTercero = new DatosDirecciones();
		}
		if (dirEstablecimiento == null) {
			dirEstablecimiento = new DatosDirecciones();
		}

		Date fecha = new Date();

		Long idPaisSolicitante;

		Long idProvinciaSolicitante;
		Long idMunicipioSolicitante;
		Long idLocalidadSolicitante;

		Long idPaisActividad;
		Long idProvinciaUbicacion;
		Long idMunicipioUbicacion;
		Long idLocalidadUbicacion;

		if (null != request.getParameter("idTipoDireccionSolicitante")
				&& !"".equalsIgnoreCase(request.getParameter("idTipoDireccionSolicitante"))) {

			String direccionSolicitante = null;
			String numeroSolicitante = null;
			String pisoSolicitante = null;
			String letraSolicitante = null;
			String escaleraSolicitante = null;
			String codigoPostalSolicitante = null;
			String descProvinciaExt = null;
			String descCiudadExt = null;

			if (request.getParameter("postalType") != null && "1".equals(request.getParameter("postalType"))) {
				idPaisSolicitante = Long.parseLong(request.getParameter("idPaisOtrosSolicitante"));
				descProvinciaExt = request.getParameter("provinciaExtrSolicitante");
				descCiudadExt = request.getParameter("ciudadExtrSolicitante");
				direccionSolicitante = request.getParameter("direccionExtrSolicitante");
				codigoPostalSolicitante = request.getParameter("codigoPostalExtrSolicitante");
			} else {
				idPaisSolicitante = Constantes.ID_NORA_ESP;
				direccionSolicitante = request.getParameter("direccionSolicitante");
				numeroSolicitante = request.getParameter("numeroSolicitante");
				pisoSolicitante = request.getParameter("pisoSolicitante");
				letraSolicitante = request.getParameter("letraSolicitante");
				escaleraSolicitante = request.getParameter("escaleraSolicitante");
				codigoPostalSolicitante = request.getParameter("codigoPostalSolicitante");
			}

			if (null != request.getParameter("idProvinciaSolicitante")
					&& !"".equalsIgnoreCase(request.getParameter("idProvinciaSolicitante"))) {
				idProvinciaSolicitante = Long.parseLong(request.getParameter("idProvinciaSolicitante"));
				RelExpTerServiceImpl.logger.info("idProvinciaSolicitante = " + idProvinciaSolicitante);
				dirTercero.setIdProvincia(idProvinciaSolicitante);
			}

			if (null != request.getParameter("idMunicipioSolicitante")
					&& !"".equalsIgnoreCase(request.getParameter("idMunicipioSolicitante"))) {
				idMunicipioSolicitante = Long.parseLong(request.getParameter("idMunicipioSolicitante"));
				RelExpTerServiceImpl.logger.info("idMunicipioSolicitante = " + idMunicipioSolicitante);
				dirTercero.setIdMunicipio(idMunicipioSolicitante);
			}

			if (null != request.getParameter("idLocalidadSolicitante")
					&& !"".equalsIgnoreCase(request.getParameter("idLocalidadSolicitante"))) {
				idLocalidadSolicitante = Long.parseLong(request.getParameter("idLocalidadSolicitante"));
				RelExpTerServiceImpl.logger.info("idLocalidadSolicitante = " + idLocalidadSolicitante);
				dirTercero.setIdLocalidad(idLocalidadSolicitante);
			}
			Long idTipoDireccionSolicitante = 4L;
			if (null == request.getParameter("idTipoDireccionSolicitante")) {
				idTipoDireccionSolicitante = Constantes.ID_DIRECCION_NOTIF_POSTAL;
			} else {
				idTipoDireccionSolicitante = Long.parseLong(request.getParameter("idTipoDireccionSolicitante"));
			}

			DatosTerceros datosTercerosSolicitante = new DatosTerceros();
			datosTercerosSolicitante.setIdTercero(idTercero);
			TiposDireccion tiposDireccion = new TiposDireccion();
			tiposDireccion.setIdTipoDireccion(idTipoDireccionSolicitante);

			dirTercero.setTiposDireccion(tiposDireccion);
			dirTercero.setDatosTerceros(datosTercerosSolicitante);

			dirTercero.setIdPais(idPaisSolicitante);
			dirTercero.setCodigoPostal(codigoPostalSolicitante);
			dirTercero.setDireccion(direccionSolicitante);
			dirTercero.setEscalera(escaleraSolicitante);
			dirTercero.setLetra(letraSolicitante);
			dirTercero.setNumero(numeroSolicitante);
			dirTercero.setPiso(pisoSolicitante);
			dirTercero.setDescProvinciaExtranjera(descProvinciaExt);
			dirTercero.setDescCiudadExtranjera(descCiudadExt);
			dirTercero.setFechaRegistro(fecha);
			dirTercero.setFechaUltmodificacion(fecha);
			dirTercero.setUsuarioRegistro(UtilUsuario.getUserConnected());
			dirTercero.setUsuarioUltmodificacion(UtilUsuario.getUserConnected());
			RelExpTerServiceImpl.logger.info("Datos Solicitante = " + dirTercero);
			// DatosDirecciones dirTerceroAux = new
			// DatosDirecciones();
			if (dirTercero.getIdDireccion() == null || dirTercero.getIdDireccion() == 0) {
				this.datosDireccionesDao.add(dirTercero);
			} else {
				this.datosDireccionesDao.update(dirTercero);
			}

		}

		if (null != request.getParameter("idTipoDireccionUbicacion")
				&& !"".equalsIgnoreCase(request.getParameter("idTipoDireccionUbicacion"))) {

			Long idTipoDireccionUbicacion = Constantes.ID_DIRECCION_ACTIVIDAD;

			String direccionActividad = null;
			String numeroActividad = null;
			String pisoActividad = null;
			String letraActividad = null;
			String escaleraActividad = null;
			String codigoPostalActividad = null;
			String descProvinciaExt = null;
			String descCiudadExt = null;

			String establecimiento = request.getParameter("establecimiento");
			String identidicadorEstablecimiento = request.getParameter("identidicadorEstablecimiento");

			if (request.getParameter("postalEstType") != null && "1".equals(request.getParameter("postalEstType"))) {
				idPaisActividad = Long.parseLong(request.getParameter("idPaisOtrosActividad"));
				descProvinciaExt = request.getParameter("descProvinciaExtranjera");
				descCiudadExt = request.getParameter("descCiudadExtranjera");
				direccionActividad = request.getParameter("direccionExt");
				codigoPostalActividad = request.getParameter("codigoPostalExt");
			} else {
				idPaisActividad = Constantes.ID_NORA_ESP;
				direccionActividad = request.getParameter("direccionUbicacion");
				numeroActividad = request.getParameter("numeroUbicacion");
				pisoActividad = request.getParameter("pisoUbicacion");
				letraActividad = request.getParameter("letraUbicacion");
				escaleraActividad = request.getParameter("escaleraUbicacion");
				codigoPostalActividad = request.getParameter("codigoPostalUbicacion");
			}

			if (null != request.getParameter("idProvinciaUbicacion")
					&& !"".equalsIgnoreCase(request.getParameter("idProvinciaUbicacion"))) {
				idProvinciaUbicacion = Long.parseLong(request.getParameter("idProvinciaUbicacion"));
				RelExpTerServiceImpl.logger.info("idProvinciaUbicacion = " + idProvinciaUbicacion);
				dirEstablecimiento.setIdProvincia(idProvinciaUbicacion);
			}

			if (null != request.getParameter("idMunicipioUbicacion")
					&& !"".equalsIgnoreCase(request.getParameter("idMunicipioUbicacion"))) {
				idMunicipioUbicacion = Long.parseLong(request.getParameter("idMunicipioUbicacion"));
				RelExpTerServiceImpl.logger.info("idMunicipioUbicacion = " + idMunicipioUbicacion);
				dirEstablecimiento.setIdMunicipio(idMunicipioUbicacion);
			}

			if (null != request.getParameter("idLocalidadUbicacion")
					&& !"".equalsIgnoreCase(request.getParameter("idLocalidadUbicacion"))) {
				idLocalidadUbicacion = Long.parseLong(request.getParameter("idLocalidadUbicacion"));
				RelExpTerServiceImpl.logger.info("idLocalidadUbicacion = " + idLocalidadUbicacion);
				dirEstablecimiento.setIdLocalidad(idLocalidadUbicacion);
			}

			TiposDireccion tiposDireccionUbicacion = new TiposDireccion();
			tiposDireccionUbicacion.setIdTipoDireccion(idTipoDireccionUbicacion);

			DatosTerceros datosTercerosUbicacion = new DatosTerceros();
			datosTercerosUbicacion.setIdTercero(idTercero);
			dirEstablecimiento.setIdPais(idPaisActividad);
			dirEstablecimiento.setTiposDireccion(tiposDireccionUbicacion);
			dirEstablecimiento.setIdentificadorEstablecimiento(identidicadorEstablecimiento);
			dirEstablecimiento.setDatosTerceros(datosTercerosUbicacion);
			dirEstablecimiento.setCodigoPostal(codigoPostalActividad);
			dirEstablecimiento.setDireccion(direccionActividad);
			dirEstablecimiento.setEscalera(escaleraActividad);
			dirEstablecimiento.setEstablecimiento(establecimiento);
			dirEstablecimiento.setLetra(letraActividad);
			dirEstablecimiento.setNumero(numeroActividad);
			dirEstablecimiento.setPiso(pisoActividad);
			dirEstablecimiento.setDescProvinciaExtranjera(descProvinciaExt);
			dirEstablecimiento.setDescCiudadExtranjera(descCiudadExt);
			dirEstablecimiento.setFechaRegistro(fecha);
			dirEstablecimiento.setFechaUltmodificacion(fecha);
			dirEstablecimiento.setUsuarioRegistro(UtilUsuario.getUserConnected());
			dirEstablecimiento.setUsuarioUltmodificacion(UtilUsuario.getUserConnected());

			RelExpTerServiceImpl.logger.info("Ubicacion Solicitante = " + dirEstablecimiento);
			// DatosDirecciones datosDireccionesUbicacionAux = new
			// DatosDirecciones();
			if (dirEstablecimiento.getIdDireccion() == null || dirEstablecimiento.getIdDireccion() == 0) {
				this.datosDireccionesDao.add(dirEstablecimiento);
			} else {
				this.datosDireccionesDao.update(dirEstablecimiento);
			}
		}

	}

	public TableResponseDto<RelExpTer> filter(RelExpTer filterRelExpTer, TableRequestDto TableRequestDto,
			Boolean startsWith) {
		List<RelExpTer> listaRelExpTer = this.relExpTerDao.findAllLike(filterRelExpTer, TableRequestDto, false);
		Long recordNum = this.relExpTerDao.findAllLikeCount(filterRelExpTer != null ? filterRelExpTer : new RelExpTer(),
				false);
		return new TableResponseDto<RelExpTer>(TableRequestDto, recordNum, listaRelExpTer);
	}

	public Integer findFirstTerceroWhitoutEstablecimiento(Integer idExpediente) {
		return this.relExpTerDao.findFirstTerceroWhitoutEstablecimiento(idExpediente);
	}

	@Override
	public RelExpTer getRelExpTerByExpTercero(Integer idExpediente, Integer idTercero) {
		return this.relExpTerDao.getRelExpTerByExpTercero(idExpediente, idTercero);
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void updateSubtipo(RelExpTer expTer) {
		this.relExpTerDao.updateSubtipo(expTer);
	}

}
