package com.ejie.ab63.service;

import java.util.Iterator;
import java.util.List;

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 com.ejie.ab63.comun.Constantes;
import com.ejie.ab63.dao.TercerosEstablecimientoDao;
import com.ejie.ab63.model.Establecimiento;
import com.ejie.ab63.model.TercerosEstablecimiento;
import com.ejie.ab63.model.terceros.DatosDirecciones;
import com.ejie.ab63.model.terceros.DatosTerceros;
import com.ejie.ab63.model.terceros.TiposDireccion;
import com.ejie.ab63.model.terceros.TiposTercero;
import com.ejie.ab63.service.terceros.DatosDireccionesService;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.dto.JerarquiaDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * Ab6339s00ServiceImpl  
 * 
 *  
 */

@Service(value = "tercerosEstablecimientoService")
public class TercerosEstablecimientoServiceImpl implements TercerosEstablecimientoService {

	@Autowired
	private TercerosEstablecimientoDao tercerosEstablecimientoDao;

	@Autowired
	private DatosDireccionesService datosDireccionesService;

	@Autowired
	private ReloadableResourceBundleMessageSource appMessageSource;

	@Autowired
	private EstablecimientoService establecimientoService;

	/**
	 * Inserts a single row in the Ab6339s00 table.
	 *
	 * @param tercerosEstablecimiento
	 *            Ab6339s00
	 * @return Ab6339s00
	 */
	@Transactional(rollbackFor = Throwable.class)
	public TercerosEstablecimiento add(TercerosEstablecimiento tercerosEstablecimiento) {

		TiposDireccion tiposDireccion = new TiposDireccion((long) Constantes.ID_DIRECCION_NOTIF_POSTAL, null, null,
				null, null);

		if (tercerosEstablecimiento.getEstablecimiento().getDatosDirecciones() == null) {
			DatosDirecciones datosDirecciones = new DatosDirecciones();
			tercerosEstablecimiento.getEstablecimiento().setDatosDirecciones(datosDirecciones);
		}
		if (tercerosEstablecimiento.getEstablecimiento().getDatosDirecciones().getTiposDireccion() == null) {
			tercerosEstablecimiento.getEstablecimiento().getDatosDirecciones().setTiposDireccion(tiposDireccion);
		}

		tercerosEstablecimiento = this.tercerosEstablecimientoDao.addDatosTercero(tercerosEstablecimiento);
		if (tercerosEstablecimiento.getEstablecimiento().getDatosDirecciones() != null) {
			tercerosEstablecimiento = this.tercerosEstablecimientoDao.addDatosDireccionTercero(tercerosEstablecimiento);
		}
		tercerosEstablecimiento = this.tercerosEstablecimientoDao.add(tercerosEstablecimiento);

		return tercerosEstablecimiento;
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public TercerosEstablecimiento insertNewTerceroFromTemp(DatosTerceros datosTerceros,
			Establecimiento establecimientoCensado, TiposTercero tiposTercero) {
		// Relacion tercero - establecimiento
		TercerosEstablecimiento tercerosEstablecimiento = new TercerosEstablecimiento();
		tercerosEstablecimiento.setTiposTercero(tiposTercero);
		tercerosEstablecimiento.setEstablecimiento(establecimientoCensado);

		if (Constantes.TITULAR_ACTIVIDAD.equals(tiposTercero.getIdTipoTercero())) {
			// set old titular to tilular anterior
			checkPreAddRelationTerceroEstablecimientoRequiered(establecimientoCensado);
		}

		// Recuperar la direccion postal actual del tercero
		DatosDirecciones filter = new DatosDirecciones();
		filter.setDatosTerceros(datosTerceros);
		filter.setTiposDireccion(new TiposDireccion(Constantes.ID_DIRECCION_NOTIF_POSTAL));
		List<DatosDirecciones> datosDireccionesTercero = this.datosDireccionesService.findAll(filter, null);

		// Registrar el tercero nuevo.
		datosTerceros = this.tercerosEstablecimientoDao.addDatosTercero(datosTerceros);

		// Registrar direcciones postales para el nuevo tercero
		for (Iterator<DatosDirecciones> iterator = datosDireccionesTercero.iterator(); iterator.hasNext();) {
			DatosDirecciones datosDirecciones = iterator.next();
			datosDirecciones.setDatosTerceros(datosTerceros);
			datosDirecciones.setIdDireccion(null);
			datosDireccionesService.add(datosDirecciones);
		}

		// // Actualizar titulares activos
		if (Constantes.TITULAR_ACTIVIDAD.equals(tiposTercero.getIdTipoTercero())) {
			TercerosEstablecimiento tercerosEstablecimientoTemp = new TercerosEstablecimiento();
			tercerosEstablecimientoTemp.setTiposTercero(tiposTercero);
			tercerosEstablecimientoTemp.setEstablecimiento(establecimientoCensado);
			this.tercerosEstablecimientoDao.removeByEst(tercerosEstablecimientoTemp);
		}

		// Registrar relacion nueva
		tercerosEstablecimiento.setIdTercerosEstab(datosTerceros.getIdTercero());
		tercerosEstablecimiento.setDatosTerceros(datosTerceros);
		tercerosEstablecimiento = this.tercerosEstablecimientoDao.add(tercerosEstablecimiento);

		Boolean populateChangeTitular = Constantes.AGENCIA_VIAJE
				.equalsIgnoreCase(establecimientoCensado.getTipoEstablecimiento().getIdTipoEstablecimiento())
				&& establecimientoCensado.getModalidad() != null && Constantes.ModalidadFijos.AAVV_PRINCIPAL
						.equalsIgnoreCase(establecimientoCensado.getModalidad().getIdModalidad());

		if (populateChangeTitular) {
			List<Establecimiento> sucursalesPuntoVentaAsociados = this.establecimientoService
					.findEstablecimientoByOfiPpalInteresados(tercerosEstablecimiento.getEstablecimiento());

			for (Establecimiento sucursalPuntoVenta : sucursalesPuntoVentaAsociados) {
				datosTerceros = this.tercerosEstablecimientoDao.addDatosTercero(datosTerceros);

				for (Iterator<DatosDirecciones> iterator = datosDireccionesTercero.iterator(); iterator.hasNext();) {
					DatosDirecciones datosDirecciones = iterator.next();
					datosDirecciones.setDatosTerceros(datosTerceros);
					datosDirecciones.setIdDireccion(null);
					datosDireccionesService.add(datosDirecciones);
				}

				tercerosEstablecimiento.setTiposTercero(tiposTercero);
				tercerosEstablecimiento.setEstablecimiento(sucursalPuntoVenta);
				tercerosEstablecimiento.setIdTercerosEstab(datosTerceros.getIdTercero());
				tercerosEstablecimiento.setDatosTerceros(datosTerceros);
				tercerosEstablecimiento = this.tercerosEstablecimientoDao.add(tercerosEstablecimiento);
			}
		}
		return tercerosEstablecimiento;
	}

	protected void checkPreAddRelationTerceroEstablecimientoRequiered(Establecimiento establecimientoCensado) {
		Boolean populateChangeTitular = Constantes.AGENCIA_VIAJE
				.equalsIgnoreCase(establecimientoCensado.getTipoEstablecimiento().getIdTipoEstablecimiento())
				&& establecimientoCensado.getModalidad() != null && Constantes.ModalidadFijos.AAVV_PRINCIPAL
						.equalsIgnoreCase(establecimientoCensado.getModalidad().getIdModalidad());
		Establecimiento filter = new Establecimiento(establecimientoCensado.getIdEstablecimiento());
		filter.setOnlyTitularIfExists(false);

		List<TercerosEstablecimiento> terceros = this.tercerosEstablecimientoDao.findAllByEstablecimiento(filter);
		for (Iterator<TercerosEstablecimiento> iterator = terceros.iterator(); iterator.hasNext();) {
			TercerosEstablecimiento tercero = iterator.next();
			if (Constantes.TITULAR_ACTIVIDAD.equals(tercero.getTiposTercero().getIdTipoTercero())) {
				tercero.setTiposTercero(new TiposTercero(Constantes.TITULAR_ACTIVIDAD_ANTERIOR));
				tercero.setBaja(1);
				tercero.setIdTipoTerceroAnt(Constantes.TITULAR_ACTIVIDAD);
				this.tercerosEstablecimientoDao.update(tercero);

				if (populateChangeTitular) {
					tercero.setEstablecimiento(establecimientoCensado);
					tratarInteresadosAgenciasProcedimientoModificacion(tercero,
							new TiposTercero(Constantes.TITULAR_ACTIVIDAD_ANTERIOR));
				}
			}

		}
	}

	public void tratarInteresadosAgenciasProcedimientoModificacion(TercerosEstablecimiento inTercero,
			TiposTercero newTipoTercero) {

		// Busco sucursales o puntos de venta
		List<Establecimiento> sucursalesPuntoVentaAsociados = this.establecimientoService
				.findEstablecimientoByOfiPpalInteresados(inTercero.getEstablecimiento());

		// Info original para filtro de búsqueda de terceros afectados
		Long tipoTerceroAnterior = inTercero.getIdTipoTerceroAnt();
		String documentoAnterior = inTercero.getDatosTerceros().getDocumento();

		// Recorro las sucursales y puntos de venta
		for (Establecimiento sucursalPuntoVenta : sucursalesPuntoVentaAsociados) {

			// Monto objeto para la búsqueda
			Integer idSucursalPuntoVenta = sucursalPuntoVenta.getIdEstablecimiento();

			TercerosEstablecimiento tercerosEstablecimientoAux = new TercerosEstablecimiento();
			DatosTerceros datosTerceros = new DatosTerceros();
			TiposTercero tipoTercero = new TiposTercero(tipoTerceroAnterior);

			tercerosEstablecimientoAux.setEstablecimiento(new Establecimiento(idSucursalPuntoVenta));

			datosTerceros.setDocumento(documentoAnterior);
			tercerosEstablecimientoAux.getEstablecimiento().setDatosTerceros(datosTerceros);

			tercerosEstablecimientoAux.setTiposTercero(tipoTercero);

			// Lanzo búsqueda por cada sucursal punto de venta
			TercerosEstablecimiento terceroEncontrado = this.tercerosEstablecimientoDao
					.busquedaInteresadosAfectadosSucursalesPuntosVenta(tercerosEstablecimientoAux);

			// Trato resultado de la búsqueda
			if (null != terceroEncontrado) {
				terceroEncontrado.setTiposTercero(newTipoTercero);
				terceroEncontrado.setBaja(1);
				terceroEncontrado.setIdTipoTerceroAnt(Constantes.TITULAR_ACTIVIDAD);
				this.tercerosEstablecimientoDao.update(terceroEncontrado);
			}
		}
	}

	@Override
	public TercerosEstablecimiento addDatosTercero(TercerosEstablecimiento ab6339s00) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public TercerosEstablecimiento addDatosDireccionTercero(TercerosEstablecimiento ab6339s00) {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * Si el tipo de establecimiento es Agencia de Viajes con Modalidad distinta
	 * de Oficina Principal no se debe permitir modificar los interesados
	 * Titular y Representante Legal. 9 y 6. Si sobre un establecimiento de tipo
	 * Agencia de Viajes con Modalidad igual a Oficina Principal se modificaran
	 * los interesados Titular ó Representante Legal, se debe propagar el cambio
	 * a todas sucursales/puntos de venta
	 * 
	 * @param inTercero
	 * @param addDireccion
	 */
	public void tratarInteresadosAgencias(TercerosEstablecimiento inTercero, boolean addDireccion) {

		// Busco sucursales o puntos de venta
		List<Establecimiento> sucursalesPuntoVentaAsociados = this.establecimientoService
				.findEstablecimientoByOfiPpalInteresados(inTercero.getEstablecimiento());

		// Info original para filtro de búsqueda de terceros afectados
		Long tipoTerceroAnterior = inTercero.getIdTipoTerceroAnt();
		String documentoAnterior = inTercero.getDocumentoAnt();

		// Recorro las sucursales y puntos de venta
		for (Establecimiento sucursalPuntoVenta : sucursalesPuntoVentaAsociados) {

			// Monto objeto para la búsqueda
			Integer idSucursalPuntoVenta = sucursalPuntoVenta.getIdEstablecimiento();

			TercerosEstablecimiento tercerosEstablecimientoAux = new TercerosEstablecimiento();
			DatosTerceros datosTerceros = new DatosTerceros();
			TiposTercero tipoTercero = new TiposTercero(tipoTerceroAnterior);

			tercerosEstablecimientoAux.setEstablecimiento(new Establecimiento(idSucursalPuntoVenta));

			datosTerceros.setDocumento(documentoAnterior);
			tercerosEstablecimientoAux.getEstablecimiento().setDatosTerceros(datosTerceros);

			tercerosEstablecimientoAux.setTiposTercero(tipoTercero);

			// Lanzo búsqueda por cada sucursal punto de venta
			TercerosEstablecimiento terceroEncontrado = this.tercerosEstablecimientoDao
					.busquedaInteresadosAfectadosSucursalesPuntosVenta(tercerosEstablecimientoAux);

			// Trato resultado de la búsqueda
			if (null != terceroEncontrado) {

				// Igualamos el tercero guardado por el usuario a un nuevo
				// tercero al que establecemos los ids del tercero encontrado
				TercerosEstablecimiento terceroActualizar = inTercero;
				terceroActualizar.setIdTercerosEstab(terceroEncontrado.getIdTercerosEstab());
				terceroActualizar.getEstablecimiento().getDatosTerceros()
						.setIdTercero(terceroEncontrado.getIdTercerosEstab());
				terceroActualizar.getEstablecimiento().getDatosDirecciones()
						.setIdDireccion(terceroEncontrado.getEstablecimiento().getDatosDirecciones().getIdDireccion());

				// Actualizamos en BD
				this.tercerosEstablecimientoDao.update(terceroActualizar); // AB6339T00
				this.tercerosEstablecimientoDao.updateDatosTercero(terceroActualizar);// AB6135T00

				// AB6136T00
				if (addDireccion) {

					this.tercerosEstablecimientoDao.addDatosDireccionTercero(terceroActualizar);

				} else {

					this.tercerosEstablecimientoDao.updateDatosDireccionTercero(terceroActualizar);
				}
			}
		}
	}

	private void tratarInteresadosAgenciasBajaPorBoton(TercerosEstablecimiento inTercero) {

		// Busco sucursales o puntos de venta
		List<Establecimiento> sucursalesPuntoVentaAsociados = this.establecimientoService
				.findEstablecimientoByOfiPpalInteresados(inTercero.getEstablecimiento());

		// Info original para filtro de búsqueda de terceros afectados
		Long idTipoTercero = inTercero.getTiposTercero().getIdTipoTercero();
		String documento = inTercero.getEstablecimiento().getDatosTerceros().getDocumento();

		// Recorro las sucursales y puntos de venta
		for (Establecimiento sucursalPuntoVenta : sucursalesPuntoVentaAsociados) {

			// Monto objeto para la búsqueda
			Integer idSucursalPuntoVenta = sucursalPuntoVenta.getIdEstablecimiento();

			TercerosEstablecimiento tercerosEstablecimientoAux = new TercerosEstablecimiento();
			DatosTerceros datosTerceros = new DatosTerceros();
			TiposTercero tipoTercero = new TiposTercero(idTipoTercero);

			tercerosEstablecimientoAux.setEstablecimiento(new Establecimiento(idSucursalPuntoVenta));

			datosTerceros.setDocumento(documento);
			tercerosEstablecimientoAux.getEstablecimiento().setDatosTerceros(datosTerceros);

			tercerosEstablecimientoAux.setTiposTercero(tipoTercero);

			// Lanzo búsqueda por cada sucursal punto de venta
			TercerosEstablecimiento terceroEncontrado = this.tercerosEstablecimientoDao
					.busquedaInteresadosAfectadosSucursalesPuntosVenta(tercerosEstablecimientoAux);

			// Trato resultado de la búsqueda
			if (null != terceroEncontrado) {

				// Instanciamos un nuevo tercero con el id del tercero
				// encontrado
				TercerosEstablecimiento terceroAfectadoAborrar = new TercerosEstablecimiento(
						terceroEncontrado.getIdTercerosEstab());

				// Borramos (lógico) en BD
				this.tercerosEstablecimientoDao.remove(terceroAfectadoAborrar); // AB6339T00
			}
		}

	}

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

		ab6339s00 = this.tercerosEstablecimientoDao.update(ab6339s00);
		ab6339s00 = this.tercerosEstablecimientoDao.updateDatosTercero(ab6339s00);
		ab6339s00 = this.tercerosEstablecimientoDao.updateDatosDireccionTercero(ab6339s00);

		if (Constantes.AGENCIA_VIAJE
				.equals(ab6339s00.getEstablecimiento().getTipoEstablecimiento().getIdTipoEstablecimiento())
				&& Constantes.ModalidadFijos.AAVV_PRINCIPAL
						.equals(ab6339s00.getEstablecimiento().getModalidad().getIdModalidad())
				&& (ab6339s00.getIdTipoTerceroAnt() == Constantes.REPRESENTANTE_LEGAL
						|| ab6339s00.getIdTipoTerceroAnt() == Constantes.TITULAR_ACTIVIDAD)) {
			tratarInteresadosAgencias(ab6339s00, false);
		}

		return ab6339s00;
	}

	/**
	 * Updates a single row in the Ab6339s00 table.
	 *
	 * @param ab6339s00
	 *            Ab6339s00
	 * @return Ab6339s00
	 */
	@Transactional(rollbackFor = Throwable.class)
	public TercerosEstablecimiento updateTerceroWithOutDireccion(TercerosEstablecimiento ab6339s00) {

		TiposDireccion tiposDireccion = new TiposDireccion((long) Constantes.ID_DIRECCION_NOTIF_POSTAL, null, null,
				null, null);

		if (ab6339s00.getEstablecimiento().getDatosDirecciones() == null
				|| ab6339s00.getEstablecimiento().getDatosDirecciones().getIdDireccion() == null) {
			DatosDirecciones datosDirecciones = new DatosDirecciones();
			ab6339s00.getEstablecimiento().setDatosDirecciones(datosDirecciones);
		}

		ab6339s00.getEstablecimiento().getDatosDirecciones().setTiposDireccion(tiposDireccion);

		ab6339s00 = this.tercerosEstablecimientoDao.update(ab6339s00);
		ab6339s00 = this.tercerosEstablecimientoDao.updateDatosTercero(ab6339s00);
		// En este caso creamos una dirección
		ab6339s00 = this.tercerosEstablecimientoDao.addDatosDireccionTercero(ab6339s00);

		if (Constantes.AGENCIA_VIAJE
				.equals(ab6339s00.getEstablecimiento().getTipoEstablecimiento().getIdTipoEstablecimiento())
				&& Constantes.ModalidadFijos.AAVV_PRINCIPAL
						.equals(ab6339s00.getEstablecimiento().getModalidad().getIdModalidad())
				&& (ab6339s00.getIdTipoTerceroAnt() == Constantes.REPRESENTANTE_LEGAL
						|| ab6339s00.getIdTipoTerceroAnt() == Constantes.TITULAR_ACTIVIDAD)) {

			tratarInteresadosAgencias(ab6339s00, true);

		}

		return ab6339s00;
	}

	@Override
	public TercerosEstablecimiento updateDatosTercero(TercerosEstablecimiento ab6339s00) {
		return this.tercerosEstablecimientoDao.updateDatosTercero(ab6339s00);
	}

	@Override
	public TercerosEstablecimiento updateDatosDireccionTercero(TercerosEstablecimiento ab6339s00) {
		return this.tercerosEstablecimientoDao.updateDatosDireccionTercero(ab6339s00);
	}

	/**
	 * Finds a single row in the Ab6339s00 table.
	 *
	 * @param ab6339s00
	 *            Ab6339s00
	 * @return Ab6339s00
	 */
	public TercerosEstablecimiento find(TercerosEstablecimiento ab6339s00) {
		return (TercerosEstablecimiento) this.tercerosEstablecimientoDao.find(ab6339s00);
	}

	/**
	 * Deletes a single row in the Ab6339s00 table.
	 *
	 * @param ab6339s00
	 *            Ab6339s00
	 */
	@Transactional(rollbackFor = Throwable.class)
	public void remove(TercerosEstablecimiento ab6339s00) {

		// En realidad es una update
		this.tercerosEstablecimientoDao.remove(ab6339s00);

		if (Constantes.AGENCIA_VIAJE
				.equals(ab6339s00.getEstablecimiento().getTipoEstablecimiento().getIdTipoEstablecimiento())
				&& Constantes.ModalidadFijos.AAVV_PRINCIPAL
						.equals(ab6339s00.getEstablecimiento().getModalidad().getIdModalidad())
				&& (ab6339s00.getTiposTercero().getIdTipoTercero() == Constantes.REPRESENTANTE_LEGAL
						|| ab6339s00.getTiposTercero().getIdTipoTercero() == Constantes.TITULAR_ACTIVIDAD)) {
			tratarInteresadosAgenciasBajaPorBoton(ab6339s00);
		}
	}

	/**
	 * Finds a list of rows in the Ab6339s00 table.
	 *
	 * @param ab6339s00
	 *            Ab6339s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<Ab6339s00>
	 */
	public List<TercerosEstablecimiento> findAll(TercerosEstablecimiento ab6339s00, JQGridRequestDto jqGridRequestDto) {
		return (List<TercerosEstablecimiento>) this.tercerosEstablecimientoDao.findAll(ab6339s00, jqGridRequestDto);
	}

	/**
	 * Finds rows in the Ab6339s00 table using like.
	 *
	 * @param ab6339s00
	 *            Ab6339s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<Ab6339s00>
	 */
	public List<TercerosEstablecimiento> findAllLike(TercerosEstablecimiento ab6339s00,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		return (List<TercerosEstablecimiento>) this.tercerosEstablecimientoDao.findAllLike(ab6339s00, jqGridRequestDto,
				startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Removes rows from the Ab6339s00 table.
	 *
	 * @param filterAb6339s00
	 *            Ab6339s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 */
	public void removeMultiple(TercerosEstablecimiento filterAb6339s00, JQGridRequestDto jqGridRequestDto,
			Boolean startsWith) {
		this.tercerosEstablecimientoDao.removeMultiple(filterAb6339s00, jqGridRequestDto, startsWith);
	}

	/**
	 * Filter method in the Ab6339s00 table.
	 *
	 * @param filterAb6339s00
	 *            Ab6339s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return JQGridResponseDto<Ab6339s00>
	 */
	public JQGridResponseDto<TercerosEstablecimiento> filter(TercerosEstablecimiento filterAb6339s00,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		List<TercerosEstablecimiento> listaAb6339s00 = this.tercerosEstablecimientoDao.findAllLike(filterAb6339s00,
				jqGridRequestDto, false);
		Long recordNum = this.tercerosEstablecimientoDao
				.findAllLikeCount(filterAb6339s00 != null ? filterAb6339s00 : new TercerosEstablecimiento(), false);
		if (jqGridRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<TercerosEstablecimiento>> reorderSelection = this.tercerosEstablecimientoDao
					.reorderSelection(filterAb6339s00, jqGridRequestDto, startsWith);
			return new JQGridResponseDto<TercerosEstablecimiento>(jqGridRequestDto, recordNum, listaAb6339s00,
					reorderSelection);
		}

		for (TercerosEstablecimiento tercero : listaAb6339s00) {

			if (tercero.getBaja() != null && tercero.getBaja() == 0) {

				tercero.setDescripcionBaja(
						appMessageSource.getMessage("afirmativo", null, LocaleContextHolder.getLocale()));
			}

		}
		return new JQGridResponseDto<TercerosEstablecimiento>(jqGridRequestDto, recordNum, listaAb6339s00);
	}

	/**
	 * Searches rows in the Ab6339s00 table.
	 *
	 * @param filterAb6339s00
	 *            Ab6339s00
	 * @param searchAb6339s00
	 *            Ab6339s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<TableRowDto<Ab6339s00>>
	 */
	public List<TableRowDto<TercerosEstablecimiento>> search(TercerosEstablecimiento filterAb6339s00,
			TercerosEstablecimiento searchAb6339s00, JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		return this.tercerosEstablecimientoDao.search(filterAb6339s00, searchAb6339s00, jqGridRequestDto, startsWith);
	}

	/**
	 * Reorder the selection made in Ab6339s00 table.
	 *
	 * @param filterAb6339s00
	 *            Ab6339s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return Object
	 */
	public Object reorderSelection(TercerosEstablecimiento filterAb6339s00, JQGridRequestDto jqGridRequestDto,
			Boolean startsWith) {
		return this.tercerosEstablecimientoDao.reorderSelection(filterAb6339s00, jqGridRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE JERARQUIA
	 */

	/**
	 * Finder method in the hierarchical the Ab6339s00 table.
	 *
	 * @param filterAb6339s00
	 *            Ab6339s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return JQGridResponseDto<JerarquiaDto<Ab6339s00>>
	 */
	public JQGridResponseDto<JerarquiaDto<TercerosEstablecimiento>> jerarquia(TercerosEstablecimiento filterAb6339s00,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		List<JerarquiaDto<TercerosEstablecimiento>> listaAb6339s00 = this.tercerosEstablecimientoDao
				.findAllLikeJerarquia(filterAb6339s00, jqGridRequestDto);
		Long recordNum = this.tercerosEstablecimientoDao.findAllLikeCountJerarquia(filterAb6339s00, jqGridRequestDto);
		return new JQGridResponseDto<JerarquiaDto<TercerosEstablecimiento>>(jqGridRequestDto, recordNum,
				listaAb6339s00);
	}

	/**
	 * Finder method for siblings rows in the hierarchical the Ab6339s00 table.
	 *
	 * @param filterAb6339s00
	 *            Ab6339s00
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return JQGridResponseDto<JerarquiaDto<Ab6339s00>>
	 */
	public JQGridResponseDto<JerarquiaDto<TercerosEstablecimiento>> jerarquiaChildren(
			TercerosEstablecimiento filterAb6339s00, JQGridRequestDto jqGridRequestDto) {
		JQGridResponseDto<JerarquiaDto<TercerosEstablecimiento>> jqGridResponseDto = new JQGridResponseDto<JerarquiaDto<TercerosEstablecimiento>>();
		jqGridResponseDto.addAdditionalParam(JQGridResponseDto.CHILDREN,
				this.tercerosEstablecimientoDao.findAllChild(filterAb6339s00, jqGridRequestDto));
		return jqGridResponseDto;
	}

	@Override
	public List<TercerosEstablecimiento> findAllByEstablecimiento(Establecimiento establecimiento) {
		return this.tercerosEstablecimientoDao.findAllByEstablecimiento(establecimiento);
	}

	@Override
	public List<TercerosEstablecimiento> findAllByEstablecimientoConDireccion(Establecimiento establecimiento) {
		return this.tercerosEstablecimientoDao.findAllByEstablecimientoConDireccion(establecimiento);
	}

	@Override
	public JQGridResponseDto<TercerosEstablecimiento> filterByTipoDireccion(TercerosEstablecimiento filterAb6339s00,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		List<TercerosEstablecimiento> listaAb6339s00 = this.tercerosEstablecimientoDao
				.findAllLikeByTipoDireccion(filterAb6339s00, jqGridRequestDto, false);
		Long recordNum = this.tercerosEstablecimientoDao.findAllLikeCountByTipoDireccion(
				filterAb6339s00 != null ? filterAb6339s00 : new TercerosEstablecimiento(), false);
		if (jqGridRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<TercerosEstablecimiento>> reorderSelection = this.tercerosEstablecimientoDao
					.reorderSelectionByTipoDireccion(filterAb6339s00, jqGridRequestDto, startsWith);
			return new JQGridResponseDto<TercerosEstablecimiento>(jqGridRequestDto, recordNum, listaAb6339s00,
					reorderSelection);
		}

		for (TercerosEstablecimiento tercero : listaAb6339s00) {

			if (tercero.getBaja() != null && tercero.getBaja() == 0) {

				tercero.setDescripcionBaja(
						appMessageSource.getMessage("afirmativo", null, LocaleContextHolder.getLocale()));
			} else {
				tercero.setDescripcionBaja(
						appMessageSource.getMessage("negativo", null, LocaleContextHolder.getLocale()));
			}

		}
		return new JQGridResponseDto<TercerosEstablecimiento>(jqGridRequestDto, recordNum, listaAb6339s00);
	}

	@Override
	public TercerosEstablecimiento findByTipoDireccionFilter(TercerosEstablecimiento ab6339s00) {
		return (TercerosEstablecimiento) this.tercerosEstablecimientoDao.findByTipoDireccionFilter(ab6339s00);
	}

	@Override
	public TercerosEstablecimiento getTerceroByIdTerceroAAVV(TercerosEstablecimiento tercero) {
		return this.tercerosEstablecimientoDao.getTerceroByIdTerceroAAVV(tercero);
	}

	@Override
	public TercerosEstablecimiento getTerceroByIdTercero(TercerosEstablecimiento tercero) {
		return this.tercerosEstablecimientoDao.getTerceroByIdTercero(tercero);
	}

	@Override
	public TercerosEstablecimiento findTerceroCensado(TercerosEstablecimiento tercero) {
		return this.tercerosEstablecimientoDao.findTerceroCensado(tercero);
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public TercerosEstablecimiento altaTerceros(TercerosEstablecimiento tercerosEstablecimiento) {

		this.add(tercerosEstablecimiento);

		if (Constantes.AGENCIA_VIAJE.equals(
				tercerosEstablecimiento.getEstablecimiento().getTipoEstablecimiento().getIdTipoEstablecimiento())
				&& Constantes.ModalidadFijos.AAVV_PRINCIPAL
						.equals(tercerosEstablecimiento.getEstablecimiento().getModalidad().getIdModalidad())
				&& (tercerosEstablecimiento.getTiposTercero().getIdTipoTercero() == Constantes.REPRESENTANTE_LEGAL
						|| tercerosEstablecimiento.getTiposTercero()
								.getIdTipoTercero() == Constantes.TITULAR_ACTIVIDAD)) {

			List<Establecimiento> sucursalesPuntoVentaAsociados = this.establecimientoService
					.findEstablecimientoByOfiPpalInteresados(tercerosEstablecimiento.getEstablecimiento());

			for (Establecimiento sucursalPuntoVenta : sucursalesPuntoVentaAsociados) {
				tercerosEstablecimiento.getEstablecimiento()
						.setIdEstablecimiento(sucursalPuntoVenta.getIdEstablecimiento());

				this.add(tercerosEstablecimiento);

			}

		}
		//

		return tercerosEstablecimiento;
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void updateTipoTercero(Integer idTercero, Long tipoTerceroNuevo) {
		this.tercerosEstablecimientoDao.updateTipoTercero(idTercero, tipoTerceroNuevo);
	}
}
