/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package com.arrebol.taxiservicios.beans.admin;

import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.beans.cobranza.CobranzaBean;
import com.arrebol.taxiservicios.controller.admin.ClosingDayController;
import com.arrebol.taxiservicios.controller.cobranza.CobranzaController;
import com.arrebol.taxiservicios.controller.predio.AbonoLoteController;
import com.arrebol.taxiservicios.controller.predio.DevolucionAbonoController;
import com.arrebol.taxiservicios.controller.predio.LoteController;
import com.arrebol.taxiservicios.model.admin.ClosingDay;
import com.arrebol.taxiservicios.model.enums.EstatusSolicitud;
import com.arrebol.taxiservicios.model.enums.GenericEnumType;
import com.arrebol.taxiservicios.model.enums.TipoCaseacionFolio;
import com.arrebol.taxiservicios.model.predio.AbonoLote;
import com.arrebol.taxiservicios.model.predio.AbonoLoteDetalle;
import com.arrebol.taxiservicios.model.predio.DevolucionAbono;
import com.arrebol.taxiservicios.model.predio.DevolucionAbonoEntrada;
import com.arrebol.taxiservicios.model.predio.FoliosCancelados;
import com.arrebol.taxiservicios.model.predio.HitorialAbonoMultiple;
import com.arrebol.taxiservicios.model.predio.Lote;
import com.arrebol.taxiservicios.model.predio.SolicitudDevolucionAbono;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 *
 * @author pc one
 */
@Named("aprobarDevolucionBean")
@ViewScoped
public class AprobarDevolucionAbonoBean extends TaxiGenericBean implements Serializable {

    private static final long serialVersionUID = -2400590341745672164L;
    final Logger logger = LogManager.getLogger(CobranzaBean.class);

    private DevolucionAbonoController devolucionAbonoController;
    private AbonoLoteController abonoLoteController;
    private ClosingDayController closingDayController;
    private LoteController loteController;
    private List<SolicitudDevolucionAbono> solicitudes;
    private SolicitudDevolucionAbono selectSolicitud;
    private CobranzaController cobranzaController;
    
    @PostConstruct
    public void init() {
        logger.info("init");
        try {
            setDevolucionAbonoController(new DevolucionAbonoController());
            setSolicitudes(getDevolucionAbonoController().fillAllSolicitudDevolucionAbonoByLocation(getLoggedUser().getLocation()));
        } catch (Exception e) {
            logger.error("CobranzaBean init", e);
        }
    }

    public void aprobarCancelacion() {
        try {
            // Se actualiza la solicitud de devolución 
            setDevolucionAbonoController(new DevolucionAbonoController());
            getSelectSolicitud().setEstatusSolicitud(EstatusSolicitud.APROBADO);
            getDevolucionAbonoController().addSolicitudDevolucionAbono(getSelectSolicitud(), getLoggedUser(), false);
            // se actulisa el abono lote 
            setAbonoLoteController(new AbonoLoteController());
            AbonoLote abonoL = getSelectSolicitud().getAbonoLote();
            
            // Se guarda la fecha de actualización  del abono lote para verificarlos si le abono ya fue completado en el cort
            Date LastUpdatedOn = abonoL.getLastUpdatedOn();
            
            abonoL.setPagoEstatus(GenericEnumType.DISABLED);
            abonoL.setCantidadPagada(0.0);
            abonoL.setDiferenciaPago(0.0);
            abonoL.setCobranzaPagada(0D);
            abonoL.setCobranzaPagar(0D);
            abonoL.setMandadoPagado(0D);
            abonoL.setMandadoPagar(0D);
            abonoL.setLastUpdatedOn(null);
            getAbonoLoteController().updateAbonoLote2(abonoL, getLoggedUser());
            // Se desactivan los abonos lote detalle si los hay
            setCobranzaController(new CobranzaController());
            List<AbonoLoteDetalle> abonoLoteDetalle = getCobranzaController().fillAbonoLoteDetalleLoteByAbonoLote(abonoL);
            if(!abonoLoteDetalle.isEmpty()){
                for (AbonoLoteDetalle abD : abonoLoteDetalle) {
                    abD.setEstatusActivo(GenericEnumType.DISABLED);
                    getCobranzaController().updateAbonoLoteDetalle(abD, getLoggedUser());
                }
            }
            // se actuliza el monto pagado
            setLoteController(new LoteController());
            Lote lote = getSelectSolicitud().getAbonoLote().getLote();
            lote.setMontoPagado(lote.getMontoPagado()-getSelectSolicitud().getMontoDevolucion());
            getLoteController().updateMontoPagado(lote, getLoggedUser());
            // Se crea un nuevo registro en devolución abono salida
            DevolucionAbono newDevolucion = new DevolucionAbono();
            newDevolucion.setSolicitudDevolucionAbono(getSelectSolicitud());
            newDevolucion.setLocation(getLoggedUser().getLocation());
            newDevolucion.setPagoEstatus(GenericEnumType.ENABLED);
            newDevolucion.setEstatusActivo(GenericEnumType.ENABLED);
            newDevolucion.setCantidadDevuelta(getSelectSolicitud().getMontoDevolucion());
            newDevolucion.setSolicitante(getSelectSolicitud().getCreatedBy());  
            getDevolucionAbonoController().addDevolucionAbono(newDevolucion, getLoggedUser(), true);  
             
            //Se obtinen el ultimo corte de caja 
            setClosingDayController(new ClosingDayController());
            ClosingDay corte = getClosingDayController().findLastClosingDay(getLoggedUser().getLocation().getId());
            
             // Validar si la fecha del abono es posterior o higual a la fecha del último corte
             if (LastUpdatedOn.before(corte.getCreatedOn()) || LastUpdatedOn.equals(corte.getCreatedOn())) {
               logger.info("no nueva salida");
            }else{
                 logger.info("nueva salida");
                //Se crea un nuevo registro en devolución abono entrada
                DevolucionAbonoEntrada newDevolucionEntrada = new DevolucionAbonoEntrada();
                newDevolucionEntrada.setSolicitudDevolucionAbono(getSelectSolicitud());
                newDevolucionEntrada.setLocation(getLoggedUser().getLocation());
                newDevolucionEntrada.setPagoEstatus(GenericEnumType.ENABLED);
                newDevolucionEntrada.setEstatusActivo(GenericEnumType.ENABLED);
                newDevolucionEntrada.setCantidadDevuelta(getSelectSolicitud().getMontoDevolucion());
                newDevolucionEntrada.setSolicitante(getSelectSolicitud().getCreatedBy());  
                getDevolucionAbonoController().addDevolucionAbonoEntrada(newDevolucionEntrada, getLoggedUser(), true);  
             }       
             
             // Se guarda registro del folio cancelado si lo tiene 
             if(getSelectSolicitud().getAbonoLote().getFolio()!=null && !getSelectSolicitud().getAbonoLote().getFolio().isEmpty()){
                 FoliosCancelados foliosCancelados = new FoliosCancelados();
                 foliosCancelados.setFolio(getSelectSolicitud().getAbonoLote().getFolio());
                 foliosCancelados.setPredio(getSelectSolicitud().getAbonoLote().getLote().getManzana().getPredio());
                 foliosCancelados.setAbonoLote(getSelectSolicitud().getAbonoLote());
                 foliosCancelados.setUserElimino(getLoggedUser());
                 foliosCancelados.setFechaEliminacion(new Date());
                 foliosCancelados.setTipoCaseacion(TipoCaseacionFolio.ABONO);
                 foliosCancelados.setMotivoCaseacion(getSelectSolicitud().getComentario());
                 getDevolucionAbonoController().addFoliosCancelados(foliosCancelados, getLoggedUser(), true);
             }     
             
             // se validaba si el abono lote tiene una relación con una abono múltiple
             if(getSelectSolicitud().getAbonoLote().getAbonoMultiple()!=null){
                HitorialAbonoMultiple abonoMultiple = getCobranzaController().fillHitorialAbonoMultipleById(getSelectSolicitud().getAbonoLote().getAbonoMultiple().getId());
                if(abonoMultiple!=null){
                    // Se le resta al total del pago múltiple el abono lote regresado de forma individual 
                    abonoMultiple.setTotalPago(abonoMultiple.getTotalPago()-getSelectSolicitud().getMontoDevolucion());
                    abonoMultiple.setCometario(abonoMultiple.getCometario()+". Se eliminó  el abono lote "+abonoL.getFechaAPagar()+" de forma individual");
                    getCobranzaController().addHitorialAbonoMultiple(abonoMultiple, getLoggedUser(), false);                    
                    // Se elimina la relación del abono múltiple con sub abono devuelto de forma individual
                    abonoL.setAbonoMultiple(null);
                    getAbonoLoteController().updateAbonoLote2(abonoL, getLoggedUser());
                }
             }
             
            
            // Se actualiza la lista de registros 
            setSolicitudes(getDevolucionAbonoController().fillAllSolicitudDevolucionAbonoByLocation(getLoggedUser().getLocation()));
            logger.info("Solicitud aprobada correctamente");
            showMessage(FacesMessage.SEVERITY_INFO, "Solicitud aprobada correctamente", "La solicitud se aprobó correctamente ");
        } catch (Exception e) {
            logger.info("Ocurrió un error al realizar la aprobasion de devolución" + e);
            showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un erro al aprobar la solicitud de devolución");
        }
    }

    public void rechazarCancelacion() {
        try {
            // Se actualiza el abono a cancelar 
            setAbonoLoteController(new AbonoLoteController());
            AbonoLote updateAb = getSelectSolicitud().getAbonoLote();
            updateAb.setPagoEstatus(GenericEnumType.ENABLED);
            getAbonoLoteController().updateAbonoLote2(updateAb, getLoggedUser());
            // Se actualiza la solicitud de devolución 
            setDevolucionAbonoController(new DevolucionAbonoController());
            getSelectSolicitud().setEstatusSolicitud(EstatusSolicitud.CANCELADO);
            getDevolucionAbonoController().addSolicitudDevolucionAbono(getSelectSolicitud(), getLoggedUser(), false);
            // Se actualiza la lista de registros 
            setSolicitudes(getDevolucionAbonoController().fillAllSolicitudDevolucionAbonoByLocation(getLoggedUser().getLocation()));
            logger.info("Solicitud rechazada correctamente");
            showMessage(FacesMessage.SEVERITY_INFO, "Solicitud rechazada correctamente", "La solicitud se rechazo correctamente ");
        } catch (Exception e) {
            logger.info("Ocurrió un error al rechazo la devolución" + e);
            showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al realizar el rechazo de devolución");
        }
    }

    public DevolucionAbonoController getDevolucionAbonoController() {
        return devolucionAbonoController;
    }

    public void setDevolucionAbonoController(DevolucionAbonoController devolucionAbonoController) {
        this.devolucionAbonoController = devolucionAbonoController;
    }

    public List<SolicitudDevolucionAbono> getSolicitudes() {
        return solicitudes;
    }

    public void setSolicitudes(List<SolicitudDevolucionAbono> solicitudes) {
        this.solicitudes = solicitudes;
    }

    public SolicitudDevolucionAbono getSelectSolicitud() {
        return selectSolicitud;
    }

    public void setSelectSolicitud(SolicitudDevolucionAbono selectSolicitud) {
        this.selectSolicitud = selectSolicitud;
    }

    public LoteController getLoteController() {
        return loteController;
    }

    public void setLoteController(LoteController loteController) {
        this.loteController = loteController;
    }

    public AbonoLoteController getAbonoLoteController() {
        return abonoLoteController;
    }

    public void setAbonoLoteController(AbonoLoteController abonoLoteController) {
        this.abonoLoteController = abonoLoteController;
    }

    public ClosingDayController getClosingDayController() {
        return closingDayController;
    }

    public void setClosingDayController(ClosingDayController closingDayController) {
        this.closingDayController = closingDayController;
    }

    public CobranzaController getCobranzaController() {
        return cobranzaController;
    }

    public void setCobranzaController(CobranzaController cobranzaController) {
        this.cobranzaController = cobranzaController;
    }

}
