/*
 * 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.controller.admin.ClosingDayController;
import com.arrebol.taxiservicios.controller.spa.DevolucionesController;
import com.arrebol.taxiservicios.controller.spa.VentasBeanController;
import com.arrebol.taxiservicios.model.admin.ClosingDay;
import com.arrebol.taxiservicios.model.enums.EstatusSolicitud;
import com.arrebol.taxiservicios.model.enums.EstatusVenta;
import com.arrebol.taxiservicios.model.enums.GenericEnumType;
import com.arrebol.taxiservicios.model.enums.TipoAbono;
import com.arrebol.taxiservicios.model.spa.DevolucionPagoVenta;
import com.arrebol.taxiservicios.model.spa.Pagos;
import com.arrebol.taxiservicios.model.spa.PagosDetalle;
import com.arrebol.taxiservicios.model.spa.SolicitudDevolucionPagoVenta;
import com.arrebol.taxiservicios.model.spa.SolicitudesCancelacionVenta;
import com.arrebol.taxiservicios.model.spa.Ventas;
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 Crov
 */
@Named("devolucionVentaBean")
@ViewScoped
public class AprobarDevolucionVentaBean extends TaxiGenericBean implements Serializable {

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

   private DevolucionesController devolucionesController;
   private VentasBeanController ventasBeanController;
   private ClosingDayController closingDayController;

   private List<SolicitudesCancelacionVenta> solicitudes;
   private SolicitudesCancelacionVenta selectSolicitud;

   @PostConstruct
   public void init() {
      logger.info("init");
      try {
         setDevolucionesController(new DevolucionesController());
         setVentasBeanController(new VentasBeanController());
         setSolicitudes(getDevolucionesController().fillSolicitudesCancelacionVentaByLocation(getLoggedUser().getLocation()));
      } catch (Exception e) {
         logger.error("init", e);
      }
   }

   public void aprobarCancelacion() {
      logger.info("aprobarCancelacion()");
      try {
         // Se valida y desactivan los pagos
         List<Pagos> listPagos = getVentasBeanController().fillPagosByVenta(getSelectSolicitud().getVenta());
         for (Pagos pa : listPagos) {
            if (pa.getEstatusActivo().equals(GenericEnumType.ENABLED) && (pa.getPagoEstatus().equals(GenericEnumType.ENABLED) || pa.getPagoEstatus().equals(GenericEnumType.INCOMPLETE))) {
               recorrerPagos(pa);
            } else {
               pa.setEstatusActivo(GenericEnumType.DISABLED);
               getVentasBeanController().addPagos(pa, getLoggedUser(), false);
            }
         }
         // Se cancela la venta principal 
         Ventas venta = getSelectSolicitud().getVenta();
         venta.setEstatusActivo(GenericEnumType.DISABLED);
         getVentasBeanController().addVenta(venta, getLoggedUser(), false);
         // Se cambia el estatus de la solicitud 
         getSelectSolicitud().setEstatusSolicitud(EstatusSolicitud.APROBADO);
         getDevolucionesController().addSolicitudDevolucionVenta(selectSolicitud, getLoggedUser(), false);
         // se actualiza la lista de solitudes
         setSolicitudes(getDevolucionesController().fillSolicitudesCancelacionVentaByLocation(getLoggedUser().getLocation()));
      } catch (Exception e) {
         showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error al tratar de aprobar la solicitud");
         logger.error("aprobarCancelacion(): " + e);
      }
   }

   public void recorrerPagos(Pagos pago) {
      logger.info("recorrerPagos()");
      try {
         // Se crea una solisitud
         SolicitudDevolucionPagoVenta solicitud = new SolicitudDevolucionPagoVenta();
         solicitud.setVenta(pago.getVenta());
         solicitud.setLocation(getLoggedUser().getLocation());
         solicitud.setEstatusActivo(GenericEnumType.DISABLED);
         solicitud.setIdPagoODetalle(pago.getId());
         solicitud.setTipoPago(TipoAbono.ABONO);
         solicitud.setMontoDevolucion(pago.getCantidadPagada());
         if (pago.getPagoEstatus().equals(GenericEnumType.INCOMPLETE)) {
            solicitud.setFolio("Pago incompleto");
         } else {
            solicitud.setFolio(pago.getFolio());
         }
         solicitud.setEstatusSolicitud(EstatusSolicitud.APROBADO);
         solicitud.setComentario("Solitud de devolución de pago por cancelación de venta");
         getDevolucionesController().addSolicitudDevolucionPagoVenta(solicitud, getLoggedUser(), true);

         // Se desactivan los abonos lote detalle si los hay
         List<PagosDetalle> subAbonos = getVentasBeanController().fillPagosDetalleByPagos(pago);
         if (!subAbonos.isEmpty()) {
            for (PagosDetalle abD : subAbonos) {
               abD.setEstatusActivo(GenericEnumType.DISABLED);
               getVentasBeanController().addPagosDetalle(abD, getLoggedUser(), false);
            }
         }
         // Se guarda la fecha de actualización  del abono lote para verificarlos si le abono ya fue completado en el corte
         Date LastUpdatedOn = pago.getLastUpdatedOn();
         // se deshabilita el pago
         pago.setEstatusActivo(GenericEnumType.DISABLED);
         getVentasBeanController().addPagos(pago, getLoggedUser(), false);
         // Se crea un nuevo registro en devolución abono salida
         DevolucionPagoVenta devolucion = new DevolucionPagoVenta();
         devolucion.setSolicitud(solicitud);
         devolucion.setLocation(pago.getVenta().getLocation());
         devolucion.setPagoEstatus(GenericEnumType.ENABLED);
         devolucion.setEstatusActivo(GenericEnumType.ENABLED);
         devolucion.setCantidadDevuelta(pago.getCantidadPagada() == null ? 0.0 : pago.getCantidadPagada());
         devolucion.setTipoMovimiento(1);
         devolucion.setSolicitante(pago.getCreatedBy());
         devolucion.setDetalles("Devoción de cancelación de venta");
         getDevolucionesController().addDevolucionPagoVenta(devolucion, getLoggedUser(), true);
         //Se obtinen el ultimo corte de caja
         setClosingDayController(new ClosingDayController());
         ClosingDay corte = getClosingDayController().findLastClosingDay(pago.getVenta().getLocation().getId(), pago.getLastUpdatedBy().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
            DevolucionPagoVenta devolucionS = new DevolucionPagoVenta();
            devolucionS.setSolicitud(solicitud);
            devolucionS.setLocation(pago.getVenta().getLocation());
            devolucionS.setPagoEstatus(GenericEnumType.ENABLED);
            devolucionS.setEstatusActivo(GenericEnumType.ENABLED);
            devolucionS.setCantidadDevuelta(pago.getCantidadPagada());
            devolucionS.setTipoMovimiento(0);
            devolucionS.setSolicitante(pago.getCreatedBy());
            devolucion.setDetalles("Devoción de cancelación de venta");
            getDevolucionesController().addDevolucionPagoVenta(devolucionS, getLoggedUser(), true);
         }
         logger.info("Pago venta devuelto, folio: " + pago.getFolio());
      } catch (Exception e) {
         logger.info("Ocurrió un error al regresar abono, Folio:" + pago.getFolio() + ".\n Error: " + e);
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al regresar abono, folio: " + pago.getFolio());
      }
   }

   public void rechazarCancelacion() {
      logger.info("rechazarCancelacion()");
      try {
         // Se restaura el estatus de la venta
         Ventas ven = getSelectSolicitud().getVenta();
         ven.setEstatusVenta(EstatusVenta.PROCESO);
         getVentasBeanController().addVenta(ven, getLoggedUser(), false);
         // Se cancela la solicitud
         getSelectSolicitud().setEstatusSolicitud(EstatusSolicitud.CANCELADO);
         getDevolucionesController().addSolicitudDevolucionVenta(selectSolicitud, getLoggedUser(), false);
      } catch (Exception e) {
         showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error al tratar de rechazar la solicitud");
         logger.error("rechazarCancelacion(): " + e);
      }
   }

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

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

   public DevolucionesController getDevolucionesController() {
      return devolucionesController;
   }

   public void setDevolucionesController(DevolucionesController devolucionesController) {
      this.devolucionesController = devolucionesController;
   }

   public SolicitudesCancelacionVenta getSelectSolicitud() {
      return selectSolicitud;
   }

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

   public VentasBeanController getVentasBeanController() {
      return ventasBeanController;
   }

   public void setVentasBeanController(VentasBeanController ventasBeanController) {
      this.ventasBeanController = ventasBeanController;
   }

   public ClosingDayController getClosingDayController() {
      return closingDayController;
   }

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

}
