package com.ejie.m62fb.service.registroVPP;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ejie.m62fb.utils.constants.IberErrorsMsgConstants;
import com.ejie.m62fb.utils.error.UFException;
import com.ejie.m62fb.dao.registroVPP.ContratoAlquilerDao;
import com.ejie.m62fb.model.ContratoAlquiler;
import com.ejie.x38.dto.JQGridRequestDto;
import com.ejie.x38.dto.JQGridResponseDto;
import com.ejie.x38.dto.TableRowDto;

/**
 * ContratoAlquilerServiceImpl generated by UDA, 20-oct-2015 12:04:31.
 * 
XXXX
 */

@Service(value = "contratoAlquilerService")
public class ContratoAlquilerServiceImpl implements ContratoAlquilerService {

	@Autowired
	private ContratoAlquilerDao contratoAlquilerDao;

	/**
	 * Inserts a single row in the ContratoAlquiler table.
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 * @return ContratoAlquiler
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
@PreAuthorize("hasPermission('CONTRATO_ALQUILER_SERVICE','SecureService','create')")
	public ContratoAlquiler add(ContratoAlquiler contratoAlquiler) {
		ContratoAlquiler contratoAlquilerBD = null;
		// Validacion fechas inicio/fin. Mensaje de error si la fecha fin es
		// menor que la fecha inicio
		if (contratoAlquiler.getFecFin().before(contratoAlquiler.getFecInicio())) {
			// Mensaje error
			throw new UFException(IberErrorsMsgConstants.FECHA_FIN_MAYOR);
		} else {
			// ADD
			contratoAlquilerBD = this.contratoAlquilerDao.add(contratoAlquiler);
			// Además de añadir el registro en BBDD, tenemos que validar si
			// debemos
			// modificar la fecha fin del contrato anterior
			Integer resultado = this
					.validarFechaFinContrato(contratoAlquilerBD);
			if (resultado != null) {
				// Actualizacion del contrato anterior
				contratoAlquilerDao.updateFecFinContratoAnterior(
						contratoAlquiler, resultado);
			}
		}
		return contratoAlquilerBD;
	}

	/**
	 * Updates a single row in the ContratoAlquiler table.
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 * @return ContratoAlquiler
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
@PreAuthorize("hasPermission('CONTRATO_ALQUILER_SERVICE','SecureService','write')")
	public ContratoAlquiler update(ContratoAlquiler contratoAlquiler) {
		ContratoAlquiler contratoAlquilerModificado = null;
		// find for update
		ContratoAlquiler contratoAlquilerBD = this.contratoAlquilerDao
				.findForUpdate(contratoAlquiler);
		// actualizar datos modificables
		contratoAlquilerBD.getExpedienteVivienda().setNumExpediente(
				contratoAlquiler.getExpedienteVivienda().getNumExpediente());
		contratoAlquilerBD.setFecEntContrato(contratoAlquiler
				.getFecEntContrato());
		contratoAlquilerBD.setFecContrato(contratoAlquiler.getFecContrato());
		contratoAlquilerBD.setFecEscritura(contratoAlquiler.getFecEscritura());
		contratoAlquilerBD.setFecEmpadron(contratoAlquiler.getFecEmpadron());
		contratoAlquilerBD.setFecInicio(contratoAlquiler.getFecInicio());
		contratoAlquilerBD.setFecFin(contratoAlquiler.getFecFin());
		contratoAlquilerBD.setDireccion(contratoAlquiler.getDireccion());
		contratoAlquilerBD.setPagadorRenta(contratoAlquiler.getPagadorRenta());
		contratoAlquilerBD.setIndVisado(contratoAlquiler.getIndVisado());
		contratoAlquilerBD.setFecVisado(contratoAlquiler.getFecVisado());
		contratoAlquilerBD.setIndRenuncia(contratoAlquiler.getIndRenuncia());
		contratoAlquilerBD.setFecRenuncia(contratoAlquiler.getFecRenuncia());
		contratoAlquilerBD
				.setIndDenegacion(contratoAlquiler.getIndDenegacion());
		contratoAlquilerBD
				.setFecDenegacion(contratoAlquiler.getFecDenegacion());
		contratoAlquilerBD.setFecIniFac(contratoAlquiler.getFecIniFac());
		contratoAlquilerBD.setImcPrecioRenta(contratoAlquiler
				.getImcPrecioRenta());
		contratoAlquilerBD.setTipoContratoAlquiler(contratoAlquiler
				.getTipoContratoAlquiler());
		contratoAlquilerBD.setCuentaBancaria(contratoAlquiler
				.getCuentaBancaria());
		contratoAlquilerBD.setTexObservaciones(contratoAlquiler
				.getTexObservaciones());

		// Validacion fechas inicio/fin. Mensaje de error si la fecha fin es
		// menor que la fecha inicio
		if (contratoAlquiler.getFecFin()
				.before(contratoAlquiler.getFecInicio())) {
			// Mensaje error
			throw new UFException(IberErrorsMsgConstants.FECHA_FIN_MAYOR);
		} else {
			// Actualiza en BBDD
			contratoAlquilerModificado = this.contratoAlquilerDao
					.update(contratoAlquilerBD);

			// Además de modificar el registro en BBDD, tenemos que validar si
			// debemos modificar la fecha fin del contrato anterior
			Integer resultado = this.validarFechaFinContrato(contratoAlquiler);
			if (resultado != null) {
				// Actualizacion del contrato anterior
				contratoAlquilerDao.updateFecFinContratoAnterior(
						contratoAlquiler, resultado);
			}
		}
		return contratoAlquilerModificado;
	}

	/**
	 * Finds a single row in the ContratoAlquiler table.
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 * @return ContratoAlquiler
	 */
	@Override
@PreAuthorize("hasPermission('CONTRATO_ALQUILER_SERVICE','SecureService','read')")
	public ContratoAlquiler find(ContratoAlquiler contratoAlquiler) {
		return this.contratoAlquilerDao.find(contratoAlquiler);
	}

	/**
	 * Deletes a single row in the ContratoAlquiler table.
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
@PreAuthorize("hasPermission('CONTRATO_ALQUILER_SERVICE','SecureService','delete')")
	public void remove(ContratoAlquiler contratoAlquiler) {
		this.contratoAlquilerDao.remove(contratoAlquiler);
	}

	/**
	 * Finds a list of rows in the ContratoAlquiler table.
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @return List<ContratoAlquiler>
	 */
	@Override
@PreAuthorize("hasPermission('CONTRATO_ALQUILER_SERVICE','SecureService','read')")
	public List<ContratoAlquiler> findAll(ContratoAlquiler contratoAlquiler,
			JQGridRequestDto jqGridRequestDto) {
		return this.contratoAlquilerDao.findAll(contratoAlquiler,
				jqGridRequestDto);
	}

	/**
	 * Finds rows in the ContratoAlquiler table using like.
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return List<ContratoAlquiler>
	 */
	@Override
@PreAuthorize("hasPermission('CONTRATO_ALQUILER_SERVICE','SecureService','read')")
	public List<ContratoAlquiler> findAllLike(
			ContratoAlquiler contratoAlquiler,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		return this.contratoAlquilerDao.findAllLike(contratoAlquiler,
				jqGridRequestDto, startsWith);
	}

	/*
	 * OPERACIONES RUP_TABLE
	 */

	/**
	 * Filter method in the ContratoAlquiler table.
	 * 
	 * @param filterContratoAlquiler
	 *            ContratoAlquiler
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return JQGridResponseDto<ContratoAlquiler>
	 */
	@Override
@PreAuthorize("hasPermission('CONTRATO_ALQUILER_SERVICE','SecureService','read')")
	public JQGridResponseDto<ContratoAlquiler> filter(
			ContratoAlquiler filterContratoAlquiler,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		List<ContratoAlquiler> listaContratoAlquiler = this.contratoAlquilerDao
				.findAllLike(filterContratoAlquiler, jqGridRequestDto, false);
		Long recordNum = this.contratoAlquilerDao.findAllLikeCount(
				filterContratoAlquiler != null ? filterContratoAlquiler
						: new ContratoAlquiler(), false);
		if (jqGridRequestDto.getMultiselection().getSelectedIds() != null) {
			List<TableRowDto<ContratoAlquiler>> reorderSelection = this.contratoAlquilerDao
					.reorderSelection(filterContratoAlquiler, jqGridRequestDto,
							startsWith);
			return new JQGridResponseDto<ContratoAlquiler>(jqGridRequestDto,
					recordNum, listaContratoAlquiler, reorderSelection);
		}
		return new JQGridResponseDto<ContratoAlquiler>(jqGridRequestDto,
				recordNum, listaContratoAlquiler);
	}

	/**
	 * Reorder the selection made in ContratoAlquiler table.
	 * 
	 * @param filterContratoAlquiler
	 *            ContratoAlquiler
	 * @param jqGridRequestDto
	 *            JQGridRequestDto
	 * @param startsWith
	 *            Boolean
	 * @return Object
	 */
	@Override
@PreAuthorize("hasPermission('CONTRATO_ALQUILER_SERVICE','SecureService','read')")
	public Object reorderSelection(ContratoAlquiler filterContratoAlquiler,
			JQGridRequestDto jqGridRequestDto, Boolean startsWith) {
		return this.contratoAlquilerDao.reorderSelection(
				filterContratoAlquiler, jqGridRequestDto, startsWith);
	}

	/**
	 * Funcion que calcula la fecha fin prorroga forzosa teniendo en cuenta la
	 * fecha inicio, fecha fin y fecha entrada.
	 * 
	 * @param numExpediente
	 *            String
	 * @param idVivienda
	 *            BigDecimal
	 * @return Date
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public Date calcFecFinProrForzosa(Date fecInicio, Date fecFin,
			Date fecEntrada) {
		return this.contratoAlquilerDao.calcFecFinProrForzosa(fecInicio,
				fecFin, fecEntrada);
	}

	/**
	 * Funcion que valida la coherencia entre las fechas inicio y fin. Consulta
	 * si estamos en el ultimo contrato. Si estamos en el ultimo contrato, la
	 * fecha inicio debe ser mayor que la fecha inicio del resto de contratos.
	 * Si no estamos en el ultimo contrato, hay que comprobar el rango de fechas
	 * inicio/fin.
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 * @return String
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public @ResponseBody
	String validarFechasIniFin(ContratoAlquiler contratoAlquiler) {
		return this.contratoAlquilerDao.validarFechasIniFin(contratoAlquiler);
	}

	/**
	 * Si estamos modificando el ultimo contrato de la vivienda, se valida si
	 * debemos modificar la fecha fin del contrato anterior, bien porque este
	 * sea nulo o sea superior a la fecha inicio de nuestro contrato, con el día
	 * anterior a la fecha de inicio de nuestro contrato.
	 * 
	 * @param contratoAlquiler
	 *            ContratoAlquiler
	 * @return String
	 */
	@Override
	@Transactional(rollbackFor = Throwable.class)
	public @ResponseBody
	Integer validarFechaFinContrato(ContratoAlquiler contratoAlquiler) {
		return this.contratoAlquilerDao
				.validarFechaFinContrato(contratoAlquiler);
	}
}
