/*
 * 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.spa;

import com.arrebol.taxiservicios.beans.TaxiGenericBean;
import com.arrebol.taxiservicios.controller.admin.GenericValidationController;
import com.arrebol.taxiservicios.controller.spa.CabinasController;
import com.arrebol.taxiservicios.controller.spa.CatalogoProductosController;
import com.arrebol.taxiservicios.controller.spa.DevolucionesController;
import com.arrebol.taxiservicios.controller.spa.VentasBeanController;
import com.arrebol.taxiservicios.model.core.Person;
import com.arrebol.taxiservicios.model.enums.EstatusPagoMultiple;
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.MetodoPago;
import com.arrebol.taxiservicios.model.enums.PeriodoPago;
import com.arrebol.taxiservicios.model.enums.PersonType;
import com.arrebol.taxiservicios.model.enums.TipoAbono;
import com.arrebol.taxiservicios.model.spa.Cabinas;
import com.arrebol.taxiservicios.model.spa.CatalogoProductos;
import com.arrebol.taxiservicios.model.spa.Cesiones;
import com.arrebol.taxiservicios.model.spa.HistorialAbonoMultipleSpa;
import com.arrebol.taxiservicios.model.spa.Pagos;
import com.arrebol.taxiservicios.model.spa.PagosDetalle;
import com.arrebol.taxiservicios.model.spa.PagosSpaView;
import com.arrebol.taxiservicios.model.spa.SolicitudDevolucionPagoVenta;
import com.arrebol.taxiservicios.model.spa.SolicitudesCancelacionVenta;
import com.arrebol.taxiservicios.model.spa.VentaDetalles;
import com.arrebol.taxiservicios.model.spa.Ventas;
import com.arrebol.taxiservicios.model.view.PersonListView;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
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("ventasBean")
@ViewScoped
public class VentasBean extends TaxiGenericBean implements Serializable {

   private static final long serialVersionUID = -7284027390656669184L;
   final Logger logger = LogManager.getLogger(getClass());

   private VentasBeanController ventasBeanController;
   private CatalogoProductosController catalogoProductosController;
   private CabinasController cabinasController;
   private GenericValidationController genericController;
   private DevolucionesController devolucionesController;

   private List<Ventas> listVentas;
   private Ventas selectVenta;
   private List<Pagos> listPagos;
   private Pagos selectPago;
   private List<PersonListView> personas;
   private List<Cabinas> listCabinas;
   private List<CatalogoProductos> listCatalogoProductos;
   private List<Cesiones> listCesiones;
   private Cesiones selectCesion;
   private Boolean tipoPago;
   private String imagen;
   private String pagoSiguiente;
   private String pagoSiguienteR;
   private Double pagoMultiple;
   private HistorialAbonoMultipleSpa selectAbonoMultiple;

   // vetas
   private String selectPersona;
   private String selectProducto;
   // Paquete
   private String selectCabina;

   private Integer numeroPagos;
   private String periodoPago;
   private Date fechaAPagar;

   private Integer numeroCesiones;
   private String periodoCesiones;
   private Date fechaProgramado;

   private Double anticipo;
   private Boolean pagoExitoso;

   private Double descuentoFijo;
   private Double descuentoPorcentage;
   private Double totalPorcentage;
   private Double totalAPagar;
   private String metodoPago;
   private List<CatalogoProductos> selectListCatalogoProductos;
   private CatalogoProductos selectProductoVenta;
   private CatalogoProductos selectProductoVentaNew;
   private Boolean tipoVenta;
   private Double totalInicial;

   private Double cantidadPagada;
   private List<PagosDetalle> listPagosDetalle;
   private PagosDetalle selectDetallePago;
   private Date fechaCesion;
   private String selectPaqueteSesion;
   private List<CatalogoProductos> listPaquetesSesion;
   private Integer horaSesion;
   private Integer minutosSesion;

   private Boolean PagoMultipleExitoso;

   private String comentarioDevolucion;

   @PostConstruct
   public void init() {
      logger.info("Start  init()");
      try {

         setCatalogoProductosController(new CatalogoProductosController());
         setVentasBeanController(new VentasBeanController());
         setCabinasController(new CabinasController());
         setGenericController(new GenericValidationController());
         setDevolucionesController(new DevolucionesController());

         setImagen("images/logot.png");
         setTipoPago(false);
         setPagoExitoso(false);
         setDescuentoFijo(0.0);
         setDescuentoPorcentage(0.0);
         setTotalPorcentage(0.0);
         setMetodoPago("");
         setTotalAPagar(0.0);
         setAnticipo(0.0);

         setSelectListCatalogoProductos(new ArrayList<>());

         setTipoVenta(true);

         setListCatalogoProductos(getCatalogoProductosController().fillCatalogoProductosByLocation(getLoggedUser().getLocation()));

         setPersonas(getVentasBeanController().findListOfPersonsByType(PersonType.CUSTOMER, getLoggedUser().getLocation()));
         setListCabinas(getCabinasController().fillCabinasByLocation(getLoggedUser().getLocation()));
         setListVentas(getVentasBeanController().fillVentasByLocation(getLoggedUser().getLocation()));

      } catch (Exception e) {
         logger.error("init(): ", e);
      }
   }

   public void addVenta() {
      logger.info("addVenta");
      try {
         setCatalogoProductosController(new CatalogoProductosController());
         setVentasBeanController(new VentasBeanController());

         if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
            showMessage(FacesMessage.SEVERITY_WARN, "Error", "No se puede hacer ninguna acción si existe un corte del día");
            return;
         }
         if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
            showMessage(FacesMessage.SEVERITY_WARN, "Dia cerrado", "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
            return;
         }

         if (getAnticipo() > getTotalAPagar()) {
            showMessage(FacesMessage.SEVERITY_WARN, "Advetencia", "El anticipo no puede ser mayor al monto total a pagar");
            return;
         }

         // se valida el tipo de producto seleccionado
         // CatalogoProductos pro = getCatalogoProductosController().fillCatalogoProductosById(getSelectProducto());
         // se le suma un día a la fecha por la diferencia de orario con respecto a la del servidor
         Calendar fechaInicialP = Calendar.getInstance();
         Calendar fechaInicialC = Calendar.getInstance();

         fechaInicialP.setTime(getFechaAPagar());
         fechaInicialC.setTime(getFechaProgramado());

         Ventas newVenta = new Ventas();
         //newVenta.setProducto(pro);
         newVenta.setCliente(new Person(getSelectPersona()));
         newVenta.setLocation(getLoggedUser().getLocation());
         newVenta.setEstatusActivo(GenericEnumType.ENABLED);
         newVenta.setPago(getTotalInicial());
         newVenta.setAnticipo(getAnticipo());
         newVenta.setDescuentoFijo(getDescuentoFijo());
         newVenta.setPorcentajeDescuento(getTotalPorcentage());
         newVenta.setDescuentoPorcentaje(getDescuentoPorcentage());
         newVenta.setTotalPago(getTotalAPagar() - getAnticipo());
         newVenta.setCabina(new Cabinas(getSelectCabina()));
         newVenta.setEstatusVenta(EstatusVenta.PROCESO);

         // CESIONES
         newVenta.setNumeroCesiones(getNumeroCesiones());
         newVenta.setFechaProgramado(fechaInicialC.getTime());
         switch (getPeriodoCesiones()) {
            case "MENSUAL":
               newVenta.setPeriodoCesiones(PeriodoPago.MENSUAL);
               break;
            case "QUINCENAL":
               newVenta.setPeriodoCesiones(PeriodoPago.QUINCENAL);
               break;
            default:
               showMessage(FacesMessage.SEVERITY_WARN, "Error", "No se seleccionó un periodo para las cesiones válido ");
               logger.error("No se seleccionó un periodo para las cesiones  válido ");
               return;
         }

         //PAGOS
         newVenta.setNumeroPagos(getNumeroPagos());
         newVenta.setFechaAPagar(fechaInicialP.getTime());
         // se valida el periodo de pago seleccionado
         switch (getPeriodoPago()) {
            case "MENSUAL":
               newVenta.setPeriodoPago(PeriodoPago.MENSUAL);
               break;
            case "QUINCENAL":
               newVenta.setPeriodoPago(PeriodoPago.QUINCENAL);
               break;
            default:
               showMessage(FacesMessage.SEVERITY_WARN, "Error", "No se seleccionó un periodo de pago válido ");
               logger.error("No se seleccionó un periodo de pago válido ");
               return;
         }

         newVenta.setFechaVenta(correcciónDeHr(new Date(), -7));
         newVenta.setCantidadPagada(0.0);

         //PAGOS
         Boolean mensualP;
         mensualP = newVenta.getPeriodoPago() == PeriodoPago.MENSUAL;
         List<Calendar> fechasDePago = new ArrayList<>();
         fechasDePago = generarFechasDePago(fechaInicialP, getNumeroPagos(), mensualP);

         // CESIONES
         Boolean mensualC;
         mensualC = newVenta.getPeriodoCesiones() == PeriodoPago.MENSUAL;
         List<Calendar> fechasDeCesiones = new ArrayList<>();
         fechasDeCesiones = generarFechasDePago(fechaInicialC, getNumeroCesiones(), mensualC);

         // cantidad a pagar por pago
         Double montoPago = newVenta.getTotalPago() / newVenta.getNumeroPagos();

         // se guarda la venta
         getVentasBeanController().addVenta(newVenta, getLoggedUser(), true);

         // Se asocian los productos a la venta
         StringBuilder descripcionProductos = new StringBuilder();
         for (CatalogoProductos newPro : getSelectListCatalogoProductos()) {
            VentaDetalles detalle = new VentaDetalles();
            detalle.setVenta(newVenta);
            detalle.setProducto(newPro);
            detalle.setCostoProductos(newPro.getCosto());
            detalle.setEstatusActivo(GenericEnumType.ENABLED);
            getVentasBeanController().addVentaDetalles(detalle, getLoggedUser(), true);

            descripcionProductos.insert(0, newPro.getDescripcion() + ", ");
         }

         // Elimina la coma adicional al final
         if (descripcionProductos.length() > 0) {
            descripcionProductos.setLength(descripcionProductos.length() - 2);
         }

         newVenta.setProductosVendidos(descripcionProductos.toString());
         getVentasBeanController().addVenta(newVenta, getLoggedUser(), false);

         // se valida el anticipo
         if (getAnticipo() > 0) {
            // se obtiene el folio
            String folio = obtenerFolio("P");
            if (folio == null) {
               setPagoExitoso(false);
               logger.info("Ocurrió un error al generar el folio");
               showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error al generar el folio");
               return;
            }

            // se genera el anticipo si lo ahi
            Pagos newAnticipo = new Pagos();
            newAnticipo.setVenta(newVenta);
            newAnticipo.setFolio(folio);
            newAnticipo.setEstatusActivo(GenericEnumType.ENABLED);
            newAnticipo.setFechaAPagar(correcciónDeHr(new Date(), -7));
            newAnticipo.setFechaPago(correcciónDeHr(new Date(), -7));
            newAnticipo.setCobro(getLoggedUser());
            newAnticipo.setTipoPago(TipoAbono.ANTICIPO);
            newAnticipo.setPagoEstatus(GenericEnumType.ENABLED);
            newAnticipo.setPago(getAnticipo());
            newAnticipo.setCantidadPagada(getAnticipo());
            newAnticipo.setDiferenciaPago(0.0);
            newAnticipo.setMetodoPago(MetodoPago.OTRO);
            newAnticipo.setLastUpdatedBy(getLoggedUser());
            newAnticipo.setLastUpdatedOn(correcciónDeHr(new Date(), -7));
            getVentasBeanController().addPagos(newAnticipo, getLoggedUser(), true);
         }

         // se registran los pagos
         recorrerFechas(fechasDePago, newVenta, montoPago);

         // se regitran las cesiones
         recorrerFechasCesiones(fechasDeCesiones, newVenta);

         setListVentas(getVentasBeanController().fillVentasByLocation(getLoggedUser().getLocation()));
         setPagoExitoso(true);
         clearVenta();
         showMessage(FacesMessage.SEVERITY_INFO, "Venta realizada", "La venta sea realizada correctamente");
      } catch (Exception e) {
         setPagoExitoso(false);
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al realizar la venta");
         logger.error("addVenta(): " + e);
      }
   }

   public void recorrerFechas(List<Calendar> fechas, Ventas venta, Double pagoPorMes) {
      logger.info("Insertando pagos por fecha");

      // Usamos Collections.sort() para ordenar la lista de fechas
      Collections.sort(fechas, new Comparator<Calendar>() {
         @Override
         public int compare(Calendar fecha1, Calendar fecha2) {
            // Comparamos las fechas usando el método compareTo()
            return fecha1.compareTo(fecha2);
         }
      });

      // recorre las fechas ordenadas
      setVentasBeanController(new VentasBeanController());
      for (Calendar fecha : fechas) {
         try {
            Pagos pago = new Pagos();
            pago.setVenta(venta);
            pago.setEstatusActivo(GenericEnumType.ENABLED);
            pago.setFechaAPagar(fecha.getTime());
            pago.setTipoPago(TipoAbono.ABONO);
            pago.setPagoEstatus(GenericEnumType.DISABLED);
            pago.setMetodoPago(MetodoPago.EFECTIVO);
            pago.setPago(pagoPorMes);
            getVentasBeanController().addPagos(pago, getLoggedUser(), true);
         } catch (Exception e) {
            logger.error("Error al generar el pago correspondiente a la fecha: (" + fecha + ") " + e);
            showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Error al generar el pago correspondiente a la fecha   (" + fecha + ")");
         }
      }
   }

   public void agregarProductoVenta() {
      try {
         logger.info("Producto agregado " + getSelectProductoVentaNew().getDescripcion());
         getSelectListCatalogoProductos().add(getSelectProductoVentaNew());
         calcularTotalPago();
         showMessage(FacesMessage.SEVERITY_INFO, "Producto agregado", "Producto agregado a la venta");
      } catch (Exception e) {
         showMessage(FacesMessage.SEVERITY_ERROR, "Error al agregar el producto", "Ocurrió un error al agregar el producto");
         logger.error("Error al agregar el producto a la venta" + e);
      }
   }

   public void quitarProductoVenta() {
      try {
         logger.info("Producto retirado " + getSelectProductoVenta().getDescripcion());
         getSelectListCatalogoProductos().remove(getSelectProductoVenta());
         calcularTotalPago();
         showMessage(FacesMessage.SEVERITY_INFO, "Producto retirado", "Producto retirado de la venta");
      } catch (Exception e) {
         showMessage(FacesMessage.SEVERITY_ERROR, "Error al retirar el producto", "Ocurrió un error al retirar el producto");
         logger.error("Error al retirado el producto a la venta");
      }
   }

   public void recorrerFechasCesiones(List<Calendar> fechas, Ventas venta) {
      logger.info("Creando cesiones por fecha");

      // Usamos Collections.sort() para ordenar la lista de fechas
      Collections.sort(fechas, new Comparator<Calendar>() {
         @Override
         public int compare(Calendar fecha1, Calendar fecha2) {
            // Comparamos las fechas usando el método compareTo()
            return fecha1.compareTo(fecha2);
         }
      });

      // recorre las fechas ordenadas
      setVentasBeanController(new VentasBeanController());
      for (Calendar fecha : fechas) {
         try {
            Cesiones cesion = new Cesiones();
            cesion.setVenta(venta);
            cesion.setEstatusActivo(GenericEnumType.ENABLED);
            cesion.setEstatusCesion(GenericEnumType.DISABLED);
            cesion.setFechaCesion(fecha.getTime());
            cesion.setHora(0);
            cesion.setMinutos(0);
            cesion.setDuracion(0.0);
            getVentasBeanController().addCesiones(cesion, getLoggedUser(), true);
         } catch (Exception e) {
            logger.error("Error al generar la cesion correspondiente a la fecha: (" + fecha + ") " + e);
            showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Error al generar la cesion correspondiente a la fecha   (" + fecha + ")");
         }
      }

   }

   public List<Calendar> generarFechasDePago(Calendar fechaInicial, int numeroPagos, Boolean mensual) {
      logger.info("Generación fechas");
      //lista de fechas
      List<Calendar> fechasDePago = new ArrayList<>();
      if (mensual) {
         fechasDePago.add(fechaInicial);
      }
      Calendar fechaActual = (Calendar) fechaInicial.clone();
      //captura el dia de una fecha en caso de que no se encuntre en le mes siguinte
      boolean detenerFecha = false;
      Calendar fechaDetenida = Calendar.getInstance();

      if (mensual) {
         for (int i = 1; i < numeroPagos; i++) {
            Calendar fechaSiguiente = (Calendar) fechaActual.clone();
            fechaSiguiente.add(Calendar.MONTH, 1);
            if (detenerFecha == false) {
               if (fechaActual.get(Calendar.DAY_OF_MONTH) > fechaSiguiente.getActualMaximum(Calendar.DAY_OF_MONTH)) {
                  detenerFecha = true;
                  fechaDetenida = (Calendar) fechaActual.clone();
                  fechaSiguiente.set(Calendar.DAY_OF_MONTH, fechaSiguiente.getActualMaximum(Calendar.DAY_OF_MONTH));
               }
            } else {
               if (fechaSiguiente.get(Calendar.DAY_OF_MONTH) <= fechaDetenida.get(Calendar.DAY_OF_MONTH)) {
                  detenerFecha = false;
                  fechaSiguiente.set(Calendar.DAY_OF_MONTH, fechaDetenida.get(Calendar.DAY_OF_MONTH));
               } else {
                  fechaSiguiente.set(Calendar.DAY_OF_MONTH, fechaSiguiente.getActualMaximum(Calendar.DAY_OF_MONTH));
               }
            }
            fechasDePago.add(fechaSiguiente);
            fechaActual = fechaSiguiente;
         }
      } else {
         for (int i = 0; i < numeroPagos;) {
            Calendar fechaSiguiente = (Calendar) fechaActual.clone();
            fechaSiguiente.set(Calendar.DAY_OF_MONTH, 15);
            fechasDePago.add(fechaSiguiente);
            i++;

            if (i < numeroPagos) {
               fechaSiguiente = (Calendar) fechaActual.clone();
               fechaSiguiente.set(Calendar.DAY_OF_MONTH, fechaSiguiente.getActualMaximum(Calendar.DAY_OF_MONTH));
               fechasDePago.add(fechaSiguiente);
               i++;
            }
            fechaActual.add(Calendar.MONTH, 1);
         }
      }

      return fechasDePago;
   }

   public void actualizarVenta() {
      logger.info("actualizarVenta()");
      try {
         getVentasBeanController().addVenta(getSelectVenta(), getLoggedUser(), false);
         clearSelected();
         setListVentas(getVentasBeanController().fillVentasByLocation(getLoggedUser().getLocation()));
         showMessage(FacesMessage.SEVERITY_INFO, "Actualizado", "Venta actualizada correctamente");
      } catch (Exception e) {
         clearSelected();
         logger.error("actualizarVenta(): " + e);
         showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Ocurrió un error al actualizar la venta");
      }
   }

   public void updatedForm() {
      logger.info("updatedForm");
   }

   public void cargarPago() {
      if (getSelectPago().getPagoEstatus().equals(GenericEnumType.INCOMPLETE)) {
         setCantidadPagada(getSelectPago().getDiferenciaPago());
      } else {
         setCantidadPagada(getSelectPago().getPago());
      }
   }

   public void pagar() {
      logger.info("pagar()");
      try {
         setVentasBeanController(new VentasBeanController());
         setPagoExitoso(false);
         if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Error", "No se puede hacer ninguna acción si existe un corte del día");
            return;
         }
         if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Dia cerrado", "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
            return;
         }

         if ((int) getDevolucionesController().countSolicitudesPagoDevolusion(getSelectPago().getVenta().getId()) > 0) {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Solicitudes pendientes", "No puede realizar más pagos hasta que no apruebe o rechace las solicitudes de devolución que tiene pendiente");
            return;
         }

         // Redondeo el pago esperado a 2 decimales para verificar que el pago dado no sea mayor al esperado
         BigDecimal bd1 = new BigDecimal(getSelectPago().getPago());
         bd1 = bd1.setScale(2, RoundingMode.HALF_UP);
         double pagoRedondeado1 = bd1.doubleValue();
         if (getCantidadPagada() > pagoRedondeado1) {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Advertencia", "No puedes pagar más de la cantidad a pagar");
            return;
         }

         // se valida el pago realizado sea el siguiente según el consecutivo
         if (getSelectPago().getId().equals(getPagoSiguiente())) {
            setImagen("images/logot.png");

            // se optiene el folio consecutivo
            String folio = obtenerFolio("P");
            if (folio != null) {
               // Redondeo el pago esperado a 2 decimales para verificar que el pago dado no sea mayor al esperado
               BigDecimal bd = new BigDecimal(getSelectPago().getPago());
               bd = bd.setScale(2, RoundingMode.HALF_UP);
               double pagoRedondeado = bd.doubleValue();

               // se valida la cantidad pagada con respecto a lo que se debe de pagar
               if (getCantidadPagada() < pagoRedondeado) {
                  // se actualiza el pago incompleto
                  getSelectPago().setPagoEstatus(GenericEnumType.INCOMPLETE);
                  getSelectPago().setCantidadPagada(getCantidadPagada());
                  getSelectPago().setDiferenciaPago(getSelectPago().getPago() - getCantidadPagada());
                  getVentasBeanController().addPagos(getSelectPago(), getLoggedUser(), false);

                  // se crea el sub abono
                  PagosDetalle pagoDetalle = new PagosDetalle();

                  // Se valida el metodo de pago 
                  switch (getMetodoPago()) {
                     case "TARJETA_DEBITO":
                        pagoDetalle.setMetodoPago(MetodoPago.TARJETA_DEBITO);
                        break;
                     case "TARJETA_CREDITO":
                        pagoDetalle.setMetodoPago(MetodoPago.TARJETA_CREDITO);
                        break;
                     case "DEPOSITO_TRANSFERENCIA":
                        pagoDetalle.setMetodoPago(MetodoPago.DEPOSITO_TRANSFERENCIA);
                        break;
                     case "EFECTIVO":
                        pagoDetalle.setMetodoPago(MetodoPago.EFECTIVO);
                        break;
                     case "TRES_MESES_SIN_INTERESES":
                        pagoDetalle.setMetodoPago(MetodoPago.TRES_MESES_SIN_INTERESES);
                        break;
                     case "SEIS_MESES_SIN_INTERESES":
                        pagoDetalle.setMetodoPago(MetodoPago.SEIS_MESES_SIN_INTERESES);
                        break;
                     case "NUEVE_MESES_SIN_INTERESES":
                        pagoDetalle.setMetodoPago(MetodoPago.NUEVE_MESES_SIN_INTERESES);
                        break;
                     case "DOCE_MESES_SIN_INTERESES":
                        pagoDetalle.setMetodoPago(MetodoPago.DOCE_MESES_SIN_INTERESES);
                        break;
                     case "CLIP":
                        pagoDetalle.setMetodoPago(MetodoPago.CLIP);
                        break;
                     case "OTRO":
                        pagoDetalle.setMetodoPago(MetodoPago.OTRO);
                        break;
                     default:
                        pagoDetalle.setMetodoPago(MetodoPago.OTRO);
                  }

                  pagoDetalle.setPago(getSelectPago());
                  pagoDetalle.setCantidadPagada(getCantidadPagada());
                  pagoDetalle.setEstatusActivo(GenericEnumType.ENABLED);
                  pagoDetalle.setPagoEstatus(GenericEnumType.ENABLED);
                  pagoDetalle.setFolio(folio);
                  getVentasBeanController().addPagosDetalle(pagoDetalle, getLoggedUser(), true);

                  // se actuliza la venta
                  getSelectVenta().setCantidadPagada(getSelectVenta().getCantidadPagada() + getCantidadPagada());
                  //se valida si la venta ya fue liquidada
                  double cantidadPa = getSelectVenta().getCantidadPagada();
                  double costoTotal = getSelectVenta().getTotalPago();
                  double tolerancia = 0.001;
                  if (Math.abs(cantidadPa - costoTotal) < tolerancia) {
                     getSelectVenta().setEstatusVenta(EstatusVenta.PAGADA);
                  }
                  getVentasBeanController().addVenta(getSelectVenta(), getLoggedUser(), false);

                  // se actualizan los datos del pago principal solo para la impresión del ticket
                  getSelectPago().setFolio(folio);
                  getSelectPago().setFechaPago(correcciónDeHr(new Date(), -7));
                  getSelectPago().setCobro(getLoggedUser());

               } else if (getCantidadPagada() == pagoRedondeado) {

                  // Se valida el metodo de pago
                  switch (getMetodoPago()) {
                     case "TARJETA_DEBITO":
                        getSelectPago().setMetodoPago(MetodoPago.TARJETA_DEBITO);
                        break;
                     case "TARJETA_CREDITO":
                        getSelectPago().setMetodoPago(MetodoPago.TARJETA_CREDITO);
                        break;
                     case "DEPOSITO_TRANSFERENCIA":
                        getSelectPago().setMetodoPago(MetodoPago.DEPOSITO_TRANSFERENCIA);
                        break;
                     case "EFECTIVO":
                        getSelectPago().setMetodoPago(MetodoPago.EFECTIVO);
                        break;
                     case "TRES_MESES_SIN_INTERESES":
                        getSelectPago().setMetodoPago(MetodoPago.TRES_MESES_SIN_INTERESES);
                        break;
                     case "SEIS_MESES_SIN_INTERESES":
                        getSelectPago().setMetodoPago(MetodoPago.SEIS_MESES_SIN_INTERESES);
                        break;
                     case "NUEVE_MESES_SIN_INTERESES":
                        getSelectPago().setMetodoPago(MetodoPago.NUEVE_MESES_SIN_INTERESES);
                        break;
                     case "DOCE_MESES_SIN_INTERESES":
                        getSelectPago().setMetodoPago(MetodoPago.DOCE_MESES_SIN_INTERESES);
                        break;
                     case "CLIP":
                        getSelectPago().setMetodoPago(MetodoPago.CLIP);
                        break;
                     case "OTRO":
                        getSelectPago().setMetodoPago(MetodoPago.OTRO);
                        break;
                     default:
                        getSelectPago().setMetodoPago(MetodoPago.OTRO);
                  }

                  // se actualiza el pago
                  getSelectPago().setPagoEstatus(GenericEnumType.ENABLED);
                  getSelectPago().setFolio(folio);
                  getSelectPago().setFechaPago(correcciónDeHr(new Date(), -7));
                  getSelectPago().setCobro(getLoggedUser());
                  getSelectPago().setCantidadPagada(getCantidadPagada());
                  getSelectPago().setDiferenciaPago(0.0);
                  getVentasBeanController().addPagos(getSelectPago(), getLoggedUser(), false);

                  // se actuliza la venta
                  getSelectVenta().setCantidadPagada(getSelectVenta().getCantidadPagada() + getCantidadPagada());
                  //se valida si la venta ya fue liquidada
                  double cantidadPa = getSelectVenta().getCantidadPagada();
                  double costoTotal = getSelectVenta().getTotalPago();
                  double tolerancia = 0.001;
                  if (Math.abs(cantidadPa - costoTotal) < tolerancia) {
                     getSelectVenta().setEstatusVenta(EstatusVenta.PAGADA);
                  }
                  getVentasBeanController().addVenta(getSelectVenta(), getLoggedUser(), false);
               }

               // se actualiza la lista de pagos y ventas
               fillPagos();
               setListVentas(getVentasBeanController().fillVentasByLocation(getLoggedUser().getLocation()));
               setPagoExitoso(true);
               logger.info("El pago se realizó correctamente");
               showMessage(FacesMessage.SEVERITY_INFO, "Pago realizado", "El pago se realizó correctamente");
            } else {
               logger.error("Ocurrió un error al generar el folio");
               showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error al generar el folio");
            }

         } else {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Error", "Solo puede pagar el pago consecutivo");
         }

      } catch (Exception e) {
         setPagoExitoso(false);
         showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error al realizar el pago");
         logger.error("pagar(): " + e);
      }
   }

   public void pagarIncompleto() {
      logger.info("pagarIncompleto()");
      try {

         setVentasBeanController(new VentasBeanController());
         setPagoExitoso(false);
         if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Error", "No se puede hacer ninguna acción si existe un corte del día");
            return;
         }
         if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Dia cerrado", "No se puede hacer ninguna acción porque ya existe un cuadre de caja chica del día");
            return;
         }

         if ((int) getDevolucionesController().countSolicitudesPagoDevolusion(getSelectPago().getVenta().getId()) > 0) {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Solicitudes pendientes", "No puede realizar más pagos hasta que no apruebe o rechace las solicitudes de devolución que tiene pendiente");
            return;
         }

         // Redondeo el pago esperado a 2 decimales para verificar que el pago dado no sea mayor al esperado
         BigDecimal bd1 = new BigDecimal(getSelectPago().getDiferenciaPago());
         bd1 = bd1.setScale(2, RoundingMode.HALF_UP);
         double pagoRedondeado1 = bd1.doubleValue();
         if (getCantidadPagada() > pagoRedondeado1) {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Advertencia", "No puedes pagar más de la cantidad restante del pago");
            return;
         }

         // se valida el pago realizado sea el siguiente según el consecutivo
         if (getSelectPago().getId().equals(getPagoSiguiente())) {
            setImagen("images/logot.png");
            // Redondeo el pago esperado a 2 decimales para verificar que el pago dado no sea mayor al esperado
            BigDecimal bd = new BigDecimal(getSelectPago().getDiferenciaPago());
            bd = bd.setScale(2, RoundingMode.HALF_UP);
            double pagoRedondeado = bd.doubleValue();
            getSelectPago().setDiferenciaPago(pagoRedondeado - getCantidadPagada());
            getSelectPago().setCantidadPagada(getSelectPago().getCantidadPagada() + getCantidadPagada());
            // se valida si el abono se pago completamente
            PagosDetalle pagoDetalle = new PagosDetalle();

            // Se valida el metodo de pago 
            switch (getMetodoPago()) {
               case "TARJETA_DEBITO":
                  pagoDetalle.setMetodoPago(MetodoPago.TARJETA_DEBITO);
                  break;
               case "TARJETA_CREDITO":
                  pagoDetalle.setMetodoPago(MetodoPago.TARJETA_CREDITO);
                  break;
               case "DEPOSITO_TRANSFERENCIA":
                  pagoDetalle.setMetodoPago(MetodoPago.DEPOSITO_TRANSFERENCIA);
                  break;
               case "EFECTIVO":
                  pagoDetalle.setMetodoPago(MetodoPago.EFECTIVO);
                  break;
               case "TRES_MESES_SIN_INTERESES":
                  pagoDetalle.setMetodoPago(MetodoPago.TRES_MESES_SIN_INTERESES);
                  break;
               case "SEIS_MESES_SIN_INTERESES":
                  pagoDetalle.setMetodoPago(MetodoPago.SEIS_MESES_SIN_INTERESES);
                  break;
               case "NUEVE_MESES_SIN_INTERESES":
                  pagoDetalle.setMetodoPago(MetodoPago.NUEVE_MESES_SIN_INTERESES);
                  break;
               case "DOCE_MESES_SIN_INTERESES":
                  pagoDetalle.setMetodoPago(MetodoPago.DOCE_MESES_SIN_INTERESES);
                  break;
               case "CLIP":
                  pagoDetalle.setMetodoPago(MetodoPago.CLIP);
                  break;
               case "OTRO":
                  pagoDetalle.setMetodoPago(MetodoPago.OTRO);
                  break;
               default:
                  pagoDetalle.setMetodoPago(MetodoPago.OTRO);
            }

            if (getSelectPago().getDiferenciaPago() > 0) {
               // se optiene el folio consecutivo
               String folio = obtenerFolio("P");
               if (folio != null) {
                  // se crea el sub abono
                  pagoDetalle.setPago(getSelectPago());
                  pagoDetalle.setCantidadPagada(getCantidadPagada());
                  pagoDetalle.setEstatusActivo(GenericEnumType.ENABLED);
                  pagoDetalle.setPagoEstatus(GenericEnumType.ENABLED);
                  pagoDetalle.setFolio(folio);
                  getVentasBeanController().addPagosDetalle(pagoDetalle, getLoggedUser(), true);
                  getVentasBeanController().addPagos(getSelectPago(), getLoggedUser(), false);
                  logger.info("Sub abono creado correctamente");
               } else {
                  logger.error("Ocurrió un error al generar el folio");
                  showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error al generar el folio para el abono principal");
               }
            } else {
               // se optiene el folio consecutivo
               String folio = obtenerFolio("P");
               if (folio != null) {
                  // se crea el sub abono
                  pagoDetalle.setPago(getSelectPago());
                  pagoDetalle.setCantidadPagada(getCantidadPagada());
                  pagoDetalle.setEstatusActivo(GenericEnumType.ENABLED);
                  pagoDetalle.setPagoEstatus(GenericEnumType.ENABLED);
                  pagoDetalle.setFolio(folio);
                  getVentasBeanController().addPagosDetalle(pagoDetalle, getLoggedUser(), true);
                  logger.info("Sub abono creado correctamente");
                  // se crea el sub abono
                  String folio2 = obtenerFolio("P");
                  if (folio2 != null) {
                     getSelectPago().setFolio(folio2);
                     getSelectPago().setCobro(getLoggedUser());
                     getSelectPago().setPagoEstatus(GenericEnumType.ENABLED);
                     getVentasBeanController().addPagos(getSelectPago(), getLoggedUser(), false);
                     logger.info("Abono principal actualizado correctamente");
                  } else {
                     logger.error("Ocurrió un error al generar el folio");
                     showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error al generar el folio para el abono principal");
                  }
               } else {
                  logger.error("Ocurrió un error al generar el folio");
                  showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error al generar el folio para el abono principal");
               }
            }

            // se actuliza la venta
            getSelectVenta().setCantidadPagada(getSelectVenta().getCantidadPagada() + getCantidadPagada());
            //se valida si la venta ya fue liquidada
            double cantidadPa = getSelectVenta().getCantidadPagada();
            double costoTotal = getSelectVenta().getTotalPago();
            double tolerancia = 0.001;
            if (Math.abs(cantidadPa - costoTotal) < tolerancia) {
               getSelectVenta().setEstatusVenta(EstatusVenta.PAGADA);
            }
            getVentasBeanController().addVenta(getSelectVenta(), getLoggedUser(), false);

            logger.error("Cantidad pagada del espacio actualizada");

            // se actualizan los datos del pago principal solo para la impresión del ticket
            getSelectPago().setCantidadPagada(getCantidadPagada());
            getSelectPago().setFolio(pagoDetalle.getFolio());
            getSelectPago().setFechaPago(correcciónDeHr(new Date(), -7));
            getSelectPago().setCobro(getLoggedUser());

            // se actualiza la lista de pagos y ventas
            fillPagos();
            setListVentas(getVentasBeanController().fillVentasByLocation(getLoggedUser().getLocation()));
            setPagoExitoso(true);
            logger.info("El pago se realizó correctamente");
            showMessage(FacesMessage.SEVERITY_INFO, "Pago realizado", "El pago se realizó correctamente");
         } else {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Error", "Solo puede pagar el pago consecutivo");
         }

      } catch (Exception e) {
         logger.error("pagarIncompleto(): " + e);
      }
   }

   public void marcarCesion() {
      logger.info("marcarCesion()");
      try {
         setVentasBeanController(new VentasBeanController());
         getSelectCesion().setEstatusCesion(GenericEnumType.ENABLED);
         getVentasBeanController().addCesiones(getSelectCesion(), getLoggedUser(), false);
         fillCesiones();
         logger.info("La sesión se marcó como tomada");
         showMessage(FacesMessage.SEVERITY_INFO, "Cesión actualizada", "La sesión se marcó como tomada");
      } catch (Exception e) {
         logger.error("marcarCesion(): " + e);
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al marcar la sesión como tomada");
      }
   }

   public void confirmarCesion() {
      logger.info("confirmarCesion()");
      try {
         setVentasBeanController(new VentasBeanController());
         getSelectCesion().setConfirmada(true);
         getVentasBeanController().addCesiones(getSelectCesion(), getLoggedUser(), false);
         fillCesiones();
         logger.info("La sesión se marcó como confirmada");
         showMessage(FacesMessage.SEVERITY_INFO, "Cesión actualizada", "La sesión se marcó como confirmada");
      } catch (Exception e) {
         logger.error("confirmarCesion(): " + e);
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al marcar la sesión como confirmada");
      }
   }

   public void cargarSesion() {
      logger.info("cargando sesion");
      try {
         setVentasBeanController(new VentasBeanController());

         // se cargan los paquetes de la sesion
         if (getSelectCesion().getVenta().getProducto() == null) {
            List<VentaDetalles> listVentaDetalles = getVentasBeanController().fillVentaDetallesByVenta(getSelectCesion().getVenta());
            List<CatalogoProductos> pro = new ArrayList<CatalogoProductos>();
            for (VentaDetalles listVentaDetalle : listVentaDetalles) {
               pro.add(listVentaDetalle.getProducto());
            }
            setListPaquetesSesion(pro);
         } else {
            List<CatalogoProductos> pro = new ArrayList<CatalogoProductos>();
            pro.add(getSelectCesion().getVenta().getProducto());
            setListPaquetesSesion(pro);
         }

         // se carga el paquete de la sesion si la ahi
         if (getSelectCesion().getProducto() != null) {
            setSelectPaqueteSesion(getSelectCesion().getProducto().getId());
         }

         // se cargan la fecha y hora de la sesión
         //FECHA
         if (getSelectCesion().getFechaCesion() != null) {
            setFechaCesion(correcciónDeHr(getSelectCesion().getFechaCesion(), 7));
         } else {
            setFechaCesion(new Date());
         }
         //HORA
         if (getSelectCesion().getHora() != null) {
            setHoraSesion(getSelectCesion().getHora());
         } else {
            setHoraSesion(1);
         }
         //MINUTOS
         if (getSelectCesion().getMinutos() != null) {
            setHoraSesion(getSelectCesion().getMinutos());
         } else {
            setHoraSesion(0);
         }
      } catch (Exception e) {
         logger.error("Error al cargar la sesion" + e);
      }
   }

   public void eliminarCesion() {
      logger.info("eliminarCesion()");
      try {
         setVentasBeanController(new VentasBeanController());
         getSelectCesion().setEstatusActivo(GenericEnumType.DISABLED);
         getVentasBeanController().addCesiones(getSelectCesion(), getLoggedUser(), false);
         fillCesiones();
         logger.info("La sesión se eliminó correctamente");
         showMessage(FacesMessage.SEVERITY_INFO, "Cesión actualizada", "La sesión se eliminó correctamente");
      } catch (Exception e) {
         logger.error("eliminarCesion(): " + e);
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al eliminar la sesión");
      }
   }

   public void agregarCesion() {
      logger.info("agregarCesion()");
      try {
         setVentasBeanController(new VentasBeanController());
         Cesiones cesion = new Cesiones();
         cesion.setVenta(getSelectVenta());
         cesion.setEstatusActivo(GenericEnumType.ENABLED);
         cesion.setEstatusCesion(GenericEnumType.DISABLED);
         cesion.setFechaCesion(getFechaCesion());
         cesion.setHora(getHoraSesion());
         cesion.setMinutos(getMinutosSesion());
         getVentasBeanController().addCesiones(cesion, getLoggedUser(), true);
         fillCesiones();
         logger.info("Sesión agregada correctamente");
         showMessage(FacesMessage.SEVERITY_INFO, "Sesión agregada", "Sesión agregada correctamente ");
      } catch (Exception e) {
         logger.error("agregarCesion(): " + e);
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al agregada la sesión");
      }
   }

   public void editarCesion() {
      logger.info("editarCesion()");
      try {
         // Actualizando datos de la sesión actualizada 
         setVentasBeanController(new VentasBeanController());
         if (!getSelectPaqueteSesion().isEmpty() && getSelectPaqueteSesion() != null) {
            getSelectCesion().setProducto(new CatalogoProductos(getSelectPaqueteSesion()));
         } else {
            getSelectCesion().setProducto(null);
         }
         getSelectCesion().setFechaCesion(getFechaCesion());
         getVentasBeanController().addCesiones(getSelectCesion(), getLoggedUser(), false);
         // Reagendando cesiones no tomadas
         //reagendarCesiones(getSelectCesion(), getFechaCesion());
         // Actualizando datos 
         clearSelectedCesion();
         fillCesiones();
         logger.info("Sesión editada correctamente");
         showMessage(FacesMessage.SEVERITY_INFO, "Sesión editada", "Sesión editada correctamente ");
      } catch (Exception e) {
         logger.error("editarCesion(): " + e);
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al editar la sesión");
      }
   }

   public void editarComentarioCesion() {
      logger.info("editarCesion()");
      try {
         // Actualizando datos de la sesión actualizada 
         setVentasBeanController(new VentasBeanController());
         getVentasBeanController().addCesiones(getSelectCesion(), getLoggedUser(), false);
         // Actualizando datos 
         clearSelectedCesion();
         fillCesiones();
         logger.info("Sesión editada correctamente");
         showMessage(FacesMessage.SEVERITY_INFO, "Sesión editada", "Sesión editada correctamente ");
      } catch (Exception e) {
         logger.error("editarCesion(): " + e);
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al editar la sesión");
      }
   }

   private void reagendarCesiones(Cesiones sesion, Date fechaSesion) {
      logger.info("Reagendando sesiones");
      try {
         List<Cesiones> sesionesPendientes = getVentasBeanController().fillCesionesByVentaAndEstatus(sesion.getVenta(), GenericEnumType.DISABLED);
         // numero de dia de la nueva fecha
         Calendar calendario = Calendar.getInstance();
         calendario.setTime(fechaSesion);
         int numeroDia = calendario.get(Calendar.DAY_OF_MONTH);
         int numeroMes = calendario.get(Calendar.MONTH);
         // Actualizando fecha de las sesiones restantes
         for (Cesiones sesionesP : sesionesPendientes) {
            sesionesP.setFechaCesion(actualizarDiaMes(numeroMes, numeroDia));
            getVentasBeanController().addCesiones(sesionesP, getLoggedUser(), false);
            numeroMes++;
         }
      } catch (Exception e) {
         logger.error("Error al reagendar las cesiones");
      }
   }

   public Date actualizarDiaMes(int numeroMeses, int numeroDia) {
      // Obtener la fecha actual
      Calendar calendario = Calendar.getInstance();
      calendario.setTime(new Date());
      // Establecer el número de meses
      calendario.set(Calendar.MONTH, numeroMeses);
      // Establecer el número del día
      calendario.set(Calendar.DAY_OF_MONTH, numeroDia);
      // Valida si el nuevo número del día es mayor que el máximo del mes
      int maximoDia = calendario.getActualMaximum(Calendar.DAY_OF_MONTH);
      if (numeroDia > maximoDia) {
         calendario.set(Calendar.DAY_OF_MONTH, maximoDia);
      }
      calendario.set(Calendar.HOUR_OF_DAY, 0);
      calendario.set(Calendar.MINUTE, 0);
      calendario.set(Calendar.SECOND, 0);
      calendario.set(Calendar.MILLISECOND, 0);
      // Obtener la fecha resultante
      Date fecha = calendario.getTime();
      return fecha;
   }

   public void clearSelectedCesion() {
      logger.info("clearSelectedCesion()");
      try {
         getListPaquetesSesion().clear();
         setSelectPaqueteSesion(null);
      } catch (Exception e) {
         logger.error("clearSelectedCesion(): " + e);
      }
   }

   private String obtenerFolio(String ab) {
      logger.info("Obteniendo último folio ");
      try {
         setVentasBeanController(new VentasBeanController());
         // Se cargan los abonos para validar el folio
         String abreviacion = ab;
         PagosSpaView ultimoFolio = getVentasBeanController().fillFoliosByPagos(abreviacion);
         // Se valida si ya existen folios registrados para el proyecto y se le asigna el último encontrado
         int consecutivo = 0;
         if (ultimoFolio != null) {
            String folior = ultimoFolio.getFolio();
            // Dividir el folio en partes utilizando el guion como separador
            String[] partes = folior.split("-");
            // Obtener la parte del consecutivo
            String consecutivoParte = partes[1];
            // Convertir el consecutivo a un entero
            consecutivo = Integer.parseInt(consecutivoParte);
         }
         // se formatea el consecutivo
         String numeroFormateado = String.format("%06d", consecutivo + 1);
         String folio;
         if (consecutivo == 0) {
            folio = abreviacion + "-" + "000001";
         } else {
            folio = abreviacion + "-" + numeroFormateado;
         }
         return folio;
      } catch (NumberFormatException e) {
         logger.error("Ocurrió un erro al obtener el último folio ");
         showMessage(FacesMessage.SEVERITY_INFO, "Error", "Ocurrió un error al generar el folio");
         return null;
      }
   }

   private void deleteVenta() {
      logger.info("deleteVenta");
      try {
         setVentasBeanController(new VentasBeanController());
         List<Pagos> Lpagos = getVentasBeanController().fillPagosByVenta(getSelectVenta());
         // se deshabilitan los pagos de la venta
         for (Pagos Lpago : Lpagos) {
            Lpago.setEstatusActivo(GenericEnumType.DISABLED);
            getVentasBeanController().addPagos(Lpago, getLoggedUser(), false);
         }
         // Se deshabilitan la venta principal
         getSelectVenta().setEstatusActivo(GenericEnumType.DISABLED);
         getVentasBeanController().addVenta(getSelectVenta(), getLoggedUser(), false);
         // se actualiza la lisa de ventas
         clearSelected();
         setListVentas(getVentasBeanController().fillVentasByLocation(getLoggedUser().getLocation()));
         showMessage(FacesMessage.SEVERITY_INFO, "Venta eliminada", "la venta se eliminó correctamente");
      } catch (Exception e) {
         showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Ocurrió un error al eliminar la venta");
         logger.error("deleteVenta(): " + e);
      }
   }

   public void solicitarDevolucionAbono(String tipo) {
      logger.info("solicitarDevolucionAbono()");
      try {

         SolicitudDevolucionPagoVenta solicitud = new SolicitudDevolucionPagoVenta();
         solicitud.setVenta(getSelectVenta());
         solicitud.setLocation(getLoggedUser().getLocation());
         solicitud.setEstatusActivo(GenericEnumType.ENABLED);
         switch (tipo) {
            case "ABONO":
               solicitud.setIdPagoODetalle(getSelectPago().getId());
               solicitud.setTipoPago(TipoAbono.ABONO);
               solicitud.setMontoDevolucion(getSelectPago().getCantidadPagada());
               solicitud.setFolio(getSelectPago().getFolio());
               // se cambia el estatus del pago
               getSelectPago().setPagoEstatus(GenericEnumType.CANCELED);
               getVentasBeanController().addPagos(getSelectPago(), getLoggedUser(), false);
               setSelectPago(null);
               break;
            case "DETALLE":
               solicitud.setIdPagoODetalle(getSelectDetallePago().getId());
               solicitud.setTipoPago(TipoAbono.SUBABONO);
               solicitud.setMontoDevolucion(getSelectDetallePago().getCantidadPagada());
               solicitud.setFolio(getSelectDetallePago().getFolio());
               // se cambia el estatus del pago talle
               getSelectDetallePago().setPagoEstatus(GenericEnumType.CANCELED);
               getVentasBeanController().addPagosDetalle(getSelectDetallePago(), getLoggedUser(), false);
               setSelectDetallePago(null);
               break;
            default:
               showMessage(FacesMessage.SEVERITY_WARN, "Error", "El tipo de abono a regresar no es válido");
               logger.info("Tipo de pago no válido");
               return;
         }
         solicitud.setEstatusSolicitud(EstatusSolicitud.PENDIENTE);
         solicitud.setComentario(getComentarioDevolucion());
         getDevolucionesController().addSolicitudDevolucionPagoVenta(solicitud, getLoggedUser(), true);
         setComentarioDevolucion(null);
         showMessage(FacesMessage.SEVERITY_INFO, "Solicitud realizada", "Solicitud realizada correctamente");
         logger.info("Solicitud realizada correctamente");
      } catch (Exception e) {
         showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Ocurrió un error la solicitud de cancelación");
         logger.error("solicitarDevolucionAbono(): " + e);
      }
   }

   public void solicitarDevolucionVenta() {
      logger.info("solicitarDevolucionVenta()");
      try {
         // Se genera la solicitud
         SolicitudesCancelacionVenta solicitud = new SolicitudesCancelacionVenta();
         solicitud.setVenta(getSelectVenta());
         solicitud.setEstatusActivo(GenericEnumType.ENABLED);
         solicitud.setEstatusSolicitud(EstatusSolicitud.PENDIENTE);
         solicitud.setComentario(getComentarioDevolucion());
         getDevolucionesController().addSolicitudDevolucionVenta(solicitud, getLoggedUser(), true);
         // se actualiza el estatus de la venta
         getSelectVenta().setEstatusVenta(EstatusVenta.CANCELADA);
         getVentasBeanController().addVenta(getSelectVenta(), getLoggedUser(), false);
         showMessage(FacesMessage.SEVERITY_INFO, "Solicitud realizada", "Solicitud realizada correctamente");
         logger.info("Solicitud realizada correctamente");
      } catch (Exception e) {
         showMessage(FacesMessage.SEVERITY_FATAL, "Error", "Ocurrió un error la solicitud de cancelación");
         logger.error("solicitarDevolucionVenta(): " + e);
      }
   }

   public void clearSelected() {
      setSelectVenta(null);
   }

   public void clearVenta() {
      getSelectListCatalogoProductos().clear();
      setSelectProducto(null);
      setSelectPersona(null);
      setPeriodoPago(null);
      setFechaAPagar(null);
      setNumeroPagos(null);
      setAnticipo(0.0);
      setDescuentoFijo(0.0);
      setDescuentoPorcentage(0.0);
      setTotalPorcentage(0.0);
      setMetodoPago("");
      setTotalAPagar(0.0);
      setPeriodoCesiones(null);
      setFechaProgramado(null);
      setNumeroCesiones(null);
      setSelectCabina(null);
      valTipoVenta();
      clearSelected();
   }

   public void valTipoVenta() {
      logger.info("valTipoVenta()");
      try {

         setDescuentoFijo(0.0);
         setDescuentoPorcentage(0.0);
         setTotalPorcentage(0.0);
         setMetodoPago("");
         setTotalAPagar(0.0);

         calcularTotalPago();
      } catch (Exception e) {
         setTipoPago(false);
         logger.info("valTipoVenta(): " + e);
      }
   }

   public void fillPagos() {
      logger.info("fillPagos()");
      try {

         // Se carga la lista de pagos
         setVentasBeanController(new VentasBeanController());
         setListPagos(getVentasBeanController().fillPagosByVenta(getSelectVenta()));

         // Encuentra el índice del primer ANTICIPO (si existe)
         int indiceAnticipo = -1;
         for (int i = 0; i < getListPagos().size(); i++) {
            if (TipoAbono.ANTICIPO.equals(getListPagos().get(i).getTipoPago())) {
               indiceAnticipo = i;
               break;
            }
         }

         // Mueve el ANTICIPO al principio de la lista (si existe)
         if (indiceAnticipo != -1) {
            Pagos ant = getListPagos().remove(indiceAnticipo);
            getListPagos().add(0, ant);
         }

         // Se encuentra el siguiente pago a realizar
         String idSiguientePago = "";
         String idUltimoPagoReembolsable = "";

         // Verificamos que la lista de pagos no esté vacía
         if (!getListPagos().isEmpty()) {
            // Variable para almacenar el último pago por si no se encuentra ninguno INCOMPLETE o DISABLED
            Pagos ultimoPago = getListPagos().get(getListPagos().size() - 1);

            // Recorremos la lista de pagos
            for (int i = 0; i < getListPagos().size(); i++) {
               Pagos pagoActual = getListPagos().get(i);

               // Si el pago está en estado INCOMPLETE o DISABLED
               if (pagoActual.getPagoEstatus().equals(GenericEnumType.INCOMPLETE)
                       || pagoActual.getPagoEstatus().equals(GenericEnumType.DISABLED)) {

                  idSiguientePago = pagoActual.getId(); // Siguiente pago disponible

                  // Si el estado es DISABLED y existe un pago anterior
                  if (i > 0 && pagoActual.getPagoEstatus().equals(GenericEnumType.DISABLED)) {
                     idUltimoPagoReembolsable = getListPagos().get(i - 1).getId(); // Pago anterior elegible para reembolso
                  }

                  // Detenemos el bucle ya que hemos encontrado el siguiente pago
                  break;
               }
            }

            // Si no se ha encontrado ningún pago INCOMPLETE o DISABLED, se toma el último pago
            if (idSiguientePago.isEmpty()) {
               idUltimoPagoReembolsable = ultimoPago.getId();
            }
         }

         // Actualizamos los valores correspondientes
         setPagoSiguiente(idSiguientePago);
         setPagoSiguienteR(idUltimoPagoReembolsable);

      } catch (Exception e) {
         logger.error("Error a la cargar los pagos " + e);
      }
   }

   public void cargarDetallesPago() {
      setVentasBeanController(new VentasBeanController());
      setListPagosDetalle(getVentasBeanController().fillPagosDetalleByPagos(getSelectPago()));
   }

   public void fillCesiones() {
      logger.info("fillCesiones()");
      try {
         setVentasBeanController(new VentasBeanController());
         setListCesiones(getVentasBeanController().fillCesionesByVenta(getSelectVenta()));
         int n = 0;
         for (Cesiones ce : getListCesiones()) {
            n++;
            ce.setNumeroSesion(n);
         }
      } catch (Exception e) {
         logger.error("fillCesiones(): " + e);
      }
   }

   public void reimprimirTicket() {
      setPagoExitoso(true);
      try {
         setImagen("images/logot.png");
      } catch (Exception e) {
         logger.error("Error al definir el logo para el tiked  " + e);
      }
   }

   public void calcularTotalPago() {
      try {
         Double totalPago = 0.0;
         for (CatalogoProductos catalogoProductos : getSelectListCatalogoProductos()) {
            totalPago = totalPago + catalogoProductos.getCosto();
         }
         setTotalInicial(totalPago);
         setDescuentoPorcentage((totalPago - getDescuentoFijo()) * (getTotalPorcentage() / 100));
         setTotalAPagar((totalPago - getDescuentoFijo()) - getDescuentoPorcentage());
      } catch (Exception e) {
         logger.error("Error al calcular los totales");
      }
   }

   private Date correcciónDeHr(Date fecha, int horas) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(fecha);
      calendar.add(Calendar.HOUR_OF_DAY, horas);
      Date nuevaFecha = calendar.getTime();
      return nuevaFecha;
   }

   public String validarColores(String estatusVenta, String idVenta) {
      // numero de cesiones pendientes
      long cesNoTomadas = getVentasBeanController().fillCesionesNoTomadasByVenta(idVenta);
      // Validadar color 
      if (estatusVenta.equals("Cancelando")) {
         return "bgRed";
      } else if (estatusVenta.equals("Pagada") && cesNoTomadas > 0) {
         return "bgAzul";
      } else if (estatusVenta.equals("Pagada") && cesNoTomadas == 0) {
         return "bgVerde";
      } else {
         return "";
      }
   }

   public void addPagoMultiple() {
      logger.info("Generando abono múltiple");
      try {
         setPagoMultipleExitoso(false);
         // se valida el metodo de pago para cargarlo en los abonos
         MetodoPago metodoP;
         switch (getMetodoPago()) {
            case "TARJETA_DEBITO":
               metodoP = MetodoPago.TARJETA_DEBITO;
               break;
            case "TARJETA_CREDITO":
               metodoP = MetodoPago.TARJETA_CREDITO;
               break;
            case "DEPOSITO_TRANSFERENCIA":
               metodoP = MetodoPago.DEPOSITO_TRANSFERENCIA;
               break;
            case "EFECTIVO":
               metodoP = MetodoPago.EFECTIVO;
               break;
            case "TRES_MESES_SIN_INTERESES":
               metodoP = MetodoPago.TRES_MESES_SIN_INTERESES;
               break;
            case "SEIS_MESES_SIN_INTERESES":
               metodoP = MetodoPago.SEIS_MESES_SIN_INTERESES;
               break;
            case "NUEVE_MESES_SIN_INTERESES":
               metodoP = MetodoPago.NUEVE_MESES_SIN_INTERESES;
               break;
            case "DOCE_MESES_SIN_INTERESES":
               metodoP = MetodoPago.DOCE_MESES_SIN_INTERESES;
               break;
            case "CLIP":
               metodoP = MetodoPago.CLIP;
               break;
            case "OTRO":
               metodoP = MetodoPago.OTRO;
               break;
            default:
               metodoP = MetodoPago.OTRO;
         }
         // Guardará la lista de folios creados por el abono múltiple
         List<String> folios = new ArrayList<>();
         // Se carga el total del abono multiple
         Double totalAbonoMultiple = getPagoMultiple();
         // Guardara los detalles del abono multiple
         String detallesAbonoMultiple = "";
         // Formatos de fecha y numerico
         SimpleDateFormat formatoF = new SimpleDateFormat("dd-MM-yyyy");
         DecimalFormat formatoDecimal = new DecimalFormat("#.##");
         // (1) validación de cortes del día
         if (getGenericController().existClosingDayByCreatedOn(new Date(), getLoggedUser())) {
            showMessage(FacesMessage.SEVERITY_WARN, "Error", "No se puede hacer ninguna acción si existe un corte del día");
            return;
         }
         if (getGenericController().existStableGeneralBoxByCurdate(getLoggedUser())) {
            showMessage(FacesMessage.SEVERITY_WARN, "Día cerrado", "No se pueden eliminar más registros porque ya existe un cuadre de caja chica del día");
            return;
         }
         if ((int) getDevolucionesController().countSolicitudesPagoDevolusion(getSelectVenta().getId()) > 0) {
            setPagoExitoso(false);
            showMessage(FacesMessage.SEVERITY_WARN, "Solicitudes pendientes", "No puede realizar más pagos hasta que no apruebe o rechace las solicitudes de devolución que tiene pendiente");
            return;
         }
         // (2) cargado de lista de abonos no pagados e incompletos de la venta
         Ventas venta = getSelectVenta();
         List<Pagos> abonos = getVentasBeanController().fillPagosNoPagafosByVentaAnd(venta);
         if (abonos.isEmpty()) {
            showMessage(FacesMessage.SEVERITY_WARN, "Error ", "No se encontraron abonos disponibles");
            return;
         }
         // (3) Validación de que el abono múltiple no sea mayor al adeudo restante
         Double totalRestante = redondearA2(venta.getTotalPago() - venta.getCantidadPagada());
         if (totalAbonoMultiple > totalRestante) {
            showMessage(FacesMessage.SEVERITY_WARN, "Advertencia", "El abono múltiple no puede ser mayor que el adeudo restante de $" + totalRestante);
            return;
         }
         // (4) Se crea un registro del abono múltiple
         HistorialAbonoMultipleSpa abonoMultiple = new HistorialAbonoMultipleSpa();
         abonoMultiple.setVenta(venta);
         abonoMultiple.setMetodoPago(metodoP);
         abonoMultiple.setLocation(getLoggedUser().getLocation());
         abonoMultiple.setTotalPago(totalAbonoMultiple);
         abonoMultiple.setEstatus(EstatusPagoMultiple.PAGADO);
         abonoMultiple.setFechaPago(new Date());
         abonoMultiple.setCliente(venta.getCliente());
         getVentasBeanController().addHitorialAbonoMultipleSpa(abonoMultiple, getLoggedUser(), true);
         // (5) Se recorre la lista de bonos no pagados
         for (Pagos pa : abonos) {
            // (5.1) Se actualiza el abono principal
            pa.setAbonoMultiple(abonoMultiple);
            // (5.2) Se verifica si el abono es incompleto
            if (pa.getPagoEstatus().equals(GenericEnumType.INCOMPLETE)) {
               // (5.2.1) Se valida si la diferencia del abono es mayor que el restante del abono multiple
               if (pa.getDiferenciaPago() > totalAbonoMultiple) {
                  // (5.2.1.1) Se actualiza el abono con el restante del abono multiple
                  pa.setCantidadPagada(pa.getCantidadPagada() + totalAbonoMultiple);
                  pa.setDiferenciaPago(pa.getPago() - pa.getCantidadPagada());
                  getVentasBeanController().addPagos(pa, getLoggedUser(), false);
                  // (5.2.1.2) Se crea el detalle del abono 
                  String f = obtenerFolio("P"); // Se genera el folio
                  folios.add(f); // Se carga el folio en la lista de folios para la impresión del tiked
                  PagosDetalle detalle = new PagosDetalle();
                  detalle.setMetodoPago(metodoP);
                  detalle.setPago(pa);
                  detalle.setCantidadPagada(totalAbonoMultiple);
                  detalle.setEstatusActivo(GenericEnumType.ENABLED);
                  detalle.setPagoEstatus(GenericEnumType.ENABLED);
                  detalle.setFolio(f);
                  detalle.setAbonoMultiple(abonoMultiple);
                  getVentasBeanController().addPagosDetalle(detalle, getLoggedUser(), true);
                  // (5.2.1.3) Se actualiza el detalle del abono múltiple
                  String fechaApagarFormateada = formatoF.format(pa.getFechaAPagar());
                  String catidadPagadaFormateada = formatoDecimal.format(pa.getPago());
                  detallesAbonoMultiple = detallesAbonoMultiple + " | " + f + ", " + fechaApagarFormateada + ", " + catidadPagadaFormateada;
                  // (5.2.1.4) Se actualiza el pago múltiple a 0 y se detiene el ciclo
                  totalAbonoMultiple = 0D;
                  break;
               } else { // (5.2.2) En caso de que el abono multipleser sea mayor que el la diferencia del abono
                  // (5.2.2.1) Se guarda la diferencia del abono para crear el del abono principal
                  Double diferencia = pa.getDiferenciaPago();
                  // (5.2.2.2) Se crea el detalle del abono 
                  String f1 = obtenerFolio("P"); // Se genera el folio 1
                  folios.add(f1); // Se carga el folio en la lista de folios para la impresión del tiked
                  PagosDetalle detalle = new PagosDetalle();
                  detalle.setFolio(f1);
                  detalle.setMetodoPago(metodoP);
                  detalle.setPago(pa);
                  detalle.setCantidadPagada(diferencia);
                  detalle.setEstatusActivo(GenericEnumType.ENABLED);
                  detalle.setPagoEstatus(GenericEnumType.ENABLED);
                  detalle.setAbonoMultiple(abonoMultiple);
                  getVentasBeanController().addPagosDetalle(detalle, getLoggedUser(), true);
                  // (5.2.2.3)  Se actualiza el detalle del abono múltiple
                  String fechaApagarFormateada = formatoF.format(pa.getFechaAPagar());
                  String catidadPagadaFormateada = formatoDecimal.format(pa.getPago());
                  detallesAbonoMultiple = detallesAbonoMultiple + " | " + f1 + ", " + fechaApagarFormateada + ", " + catidadPagadaFormateada;
                  // (5.2.2.4) Se actualiza el abono principal ha pagado 
                  String f2 = obtenerFolio("P"); // Se genera el folio 2
                  folios.add(f2); // Se carga el folio en la lista de folios para la impresión del tiked
                  pa.setFolio(f2);
                  pa.setDiferenciaPago(0D);
                  pa.setCantidadPagada(pa.getPago());
                  pa.setCobro(getLoggedUser());
                  pa.setPagoEstatus(GenericEnumType.ENABLED);
                  getVentasBeanController().addPagos(pa, getLoggedUser(), false);
                  // (5.2.2.5) Se actualiza el detalle del abono múltiple
                  String catidadPagadaFormateada2 = formatoDecimal.format(pa.getPago());
                  detallesAbonoMultiple = detallesAbonoMultiple + " | " + f2 + ", " + fechaApagarFormateada + ", " + catidadPagadaFormateada2;
                  // (5.2.2.6) Se actualiza el pago múltiple
                  totalAbonoMultiple = totalAbonoMultiple - diferencia;
               }
            } else if (pa.getPago() < totalAbonoMultiple) { // (5.3) Se verifica si el abono múltiple cubre el abono principal
               // (5.3.1) Se actualiza el abono principal ha pagado 
               String f = obtenerFolio("P"); // Se genera el folio 2
               folios.add(f); // Se carga el folio en la lista de folios para la impresión del tiked
               pa.setFolio(f);
               pa.setDiferenciaPago(0D);
               pa.setCantidadPagada(pa.getPago());
               pa.setMetodoPago(metodoP);
               pa.setCobro(getLoggedUser());
               pa.setFechaPago(correcciónDeHr(new Date(), -7));
               pa.setPagoEstatus(GenericEnumType.ENABLED);
               getVentasBeanController().addPagos(pa, getLoggedUser(), false);
               // (5.3.2) Se actualiza el pago múltiple
               totalAbonoMultiple = totalAbonoMultiple - pa.getPago();
               // (5.3.3) Se actualiza el detalle del abono múltiple
               String fechaApagarFormateada = formatoF.format(pa.getFechaAPagar());
               String catidadPagadaFormateada = formatoDecimal.format(pa.getPago());
               detallesAbonoMultiple = detallesAbonoMultiple + " | " + f + ", " + fechaApagarFormateada + ", " + catidadPagadaFormateada;
            } else if (totalAbonoMultiple > 0) { // (5.4) Entra si el abono no era incompleto y el abono múltiple no cubrió el abono principal
               // (5.4.1) Se actualiza el abono principal y define el folio
               String f = obtenerFolio("P"); // Se genera el folio
               folios.add(f); // Se carga el folio en la lista de folios para la impresión del tiked
               pa.setCantidadPagada(redondearA2(totalAbonoMultiple));
               pa.setDiferenciaPago(pa.getPago() - pa.getCantidadPagada());
               // (5.4.2) Se valida si el abono múltiple cubrió exactamente el abono principal
               if (pa.getDiferenciaPago() == 0) {
                  pa.setFolio(f);
                  pa.setMetodoPago(metodoP);
                  pa.setPagoEstatus(GenericEnumType.ENABLED);
                  pa.setFechaPago(correcciónDeHr(new Date(), -7));
                  pa.setCobro(getLoggedUser());
               } else { // (5.4.3) Entre si el abono múltiple no cubrió el abono principal
                  // (5.4.3.1) Se define le abono principal como incompleto 
                  pa.setPagoEstatus(GenericEnumType.INCOMPLETE);
                  // (5.4.3.2) Se crea el detalle del abono con el restante del abono múltiple 
                  PagosDetalle detalle = new PagosDetalle();
                  detalle.setFolio(f);
                  detalle.setPago(pa);
                  detalle.setMetodoPago(metodoP);
                  detalle.setCantidadPagada(totalAbonoMultiple);
                  detalle.setEstatusActivo(GenericEnumType.ENABLED);
                  detalle.setPagoEstatus(GenericEnumType.ENABLED);
                  detalle.setAbonoMultiple(abonoMultiple);
                  getVentasBeanController().addPagosDetalle(detalle, getLoggedUser(), true);
               }
               // (5.4.3) Se actualiza el abono principal 
               getVentasBeanController().addPagos(pa, getLoggedUser(), false);
               // Se actualiza el detalle del abono múltiple
               String fechaApagarFormateada = formatoF.format(pa.getFechaAPagar());
               String catidadPagadaFormateada = formatoDecimal.format(pa.getPago());
               detallesAbonoMultiple = detallesAbonoMultiple + " | " + f + ", " + fechaApagarFormateada + ", " + catidadPagadaFormateada;
               // Se actualiza el pago múltiple a 0 y se detiene el ciclo
               totalAbonoMultiple = 0D;
               break;
            }
         }
         // (6) Se convierte la lista de folios a un string
         StringBuilder folioS = new StringBuilder();
         for (String folio : folios) {
            folioS.append(folio).append(", ");
         }
         if (folioS.length() > 0) {
            folioS.setLength(folioS.length() - 2);
         }
         // (7) actulizar abono multiple
         abonoMultiple.setFolios(folioS.toString());
         abonoMultiple.setDetalle(detallesAbonoMultiple);
         getVentasBeanController().addHitorialAbonoMultipleSpa(abonoMultiple, getLoggedUser(), false);
         // (8) Se actuliza la venta
         venta.setCantidadPagada(venta.getCantidadPagada() + getPagoMultiple());
         // (9) Se valida si la venta ya fue liquidada
         double cantidadPa = venta.getCantidadPagada();
         double costoTotal = venta.getTotalPago();
         double tolerancia = 0.001;
         if (Math.abs(cantidadPa - costoTotal) < tolerancia) {
            venta.setEstatusVenta(EstatusVenta.PAGADA);
         }
         getVentasBeanController().addVenta(venta, getLoggedUser(), false);
         // (10) Se carga el abono múltiple generado en para el tiket
         setSelectAbonoMultiple(abonoMultiple);
         // (11) Se actualiza la lista de pagos y ventas
         fillPagos();
         setListVentas(getVentasBeanController().fillVentasByLocation(getLoggedUser().getLocation()));
         setPagoMultipleExitoso(true);
         logger.info("El pago multiple se realizó correctamente");
         showMessage(FacesMessage.SEVERITY_INFO, "Pago multiple realizado", "El pago multiple se realizó correctamente");
      } catch (Exception e) {
         setPagoMultipleExitoso(false);
         showMessage(FacesMessage.SEVERITY_ERROR, "Error", "Ocurrió un error al realizar el abono múltiple");
         logger.error("Ocurrió un error al realizar el abono múltiple");
      }
   }

   private double redondearA2(double cantidad) {
      logger.info("Redondeando cantidad a 2 decimales");
      try {
         BigDecimal bd = new BigDecimal(cantidad);
         bd = bd.setScale(2, RoundingMode.HALF_UP);
         double pagoRedondeado = bd.doubleValue();
         return pagoRedondeado;
      } catch (Exception e) {
         logger.error("Ocurrió un error al redondear la cantidad" + e);
         return cantidad;
      }
   }

   public void clearSelectedAbonoMultiple() {
      setSelectAbonoMultiple(null);
   }

   public VentasBeanController getVentasBeanController() {
      return ventasBeanController;
   }

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

   public List<Ventas> getListVentas() {
      return listVentas;
   }

   public void setListVentas(List<Ventas> listVentas) {
      this.listVentas = listVentas;
   }

   public Ventas getSelectVenta() {
      return selectVenta;
   }

   public void setSelectVenta(Ventas selectVenta) {
      this.selectVenta = selectVenta;
   }

   public List<PersonListView> getPersonas() {
      return personas;
   }

   public void setPersonas(List<PersonListView> personas) {
      this.personas = personas;
   }

   public CatalogoProductosController getCatalogoProductosController() {
      return catalogoProductosController;
   }

   public void setCatalogoProductosController(CatalogoProductosController catalogoProductosController) {
      this.catalogoProductosController = catalogoProductosController;
   }

   public CabinasController getCabinasController() {
      return cabinasController;
   }

   public void setCabinasController(CabinasController cabinasController) {
      this.cabinasController = cabinasController;
   }

   public List<Cabinas> getListCabinas() {
      return listCabinas;
   }

   public void setListCabinas(List<Cabinas> listCabinas) {
      this.listCabinas = listCabinas;
   }

   public String getSelectCabina() {
      return selectCabina;
   }

   public void setSelectCabina(String selectCabina) {
      this.selectCabina = selectCabina;
   }

   public List<CatalogoProductos> getListCatalogoProductos() {
      return listCatalogoProductos;
   }

   public void setListCatalogoProductos(List<CatalogoProductos> listCatalogoProductos) {
      this.listCatalogoProductos = listCatalogoProductos;
   }

   public String getSelectProducto() {
      return selectProducto;
   }

   public void setSelectProducto(String selectProducto) {
      this.selectProducto = selectProducto;
   }

   public String getSelectPersona() {
      return selectPersona;
   }

   public void setSelectPersona(String selectPersona) {
      this.selectPersona = selectPersona;
   }

   public List<Pagos> getListPagos() {
      return listPagos;
   }

   public void setListPagos(List<Pagos> listPagos) {
      this.listPagos = listPagos;
   }

   public Pagos getSelectPago() {
      return selectPago;
   }

   public void setSelectPago(Pagos selectPago) {
      this.selectPago = selectPago;
   }

   public Boolean getTipoPago() {
      return tipoPago;
   }

   public void setTipoPago(Boolean tipoPago) {
      this.tipoPago = tipoPago;
   }

   public String getPeriodoPago() {
      return periodoPago;
   }

   public void setPeriodoPago(String periodoPago) {
      this.periodoPago = periodoPago;
   }

   public Double getAnticipo() {
      return anticipo;
   }

   public void setAnticipo(Double anticipo) {
      this.anticipo = anticipo;
   }

   public Boolean getPagoExitoso() {
      return pagoExitoso;
   }

   public void setPagoExitoso(Boolean pagoExitoso) {
      this.pagoExitoso = pagoExitoso;
   }

   public String getImagen() {
      return imagen;
   }

   public void setImagen(String imagen) {
      this.imagen = imagen;
   }

   public String getPagoSiguiente() {
      return pagoSiguiente;
   }

   public void setPagoSiguiente(String pagoSiguiente) {
      this.pagoSiguiente = pagoSiguiente;
   }

   public Integer getNumeroPagos() {
      return numeroPagos;
   }

   public void setNumeroPagos(Integer numeroPagos) {
      this.numeroPagos = numeroPagos;
   }

   public Date getFechaAPagar() {
      return fechaAPagar;
   }

   public void setFechaAPagar(Date fechaAPagar) {
      this.fechaAPagar = fechaAPagar;
   }

   public Integer getNumeroCesiones() {
      return numeroCesiones;
   }

   public void setNumeroCesiones(Integer numeroCesiones) {
      this.numeroCesiones = numeroCesiones;
   }

   public String getPeriodoCesiones() {
      return periodoCesiones;
   }

   public void setPeriodoCesiones(String periodoCesiones) {
      this.periodoCesiones = periodoCesiones;
   }

   public Date getFechaProgramado() {
      return fechaProgramado;
   }

   public void setFechaProgramado(Date fechaProgramado) {
      this.fechaProgramado = fechaProgramado;
   }

   public List<Cesiones> getListCesiones() {
      return listCesiones;
   }

   public void setListCesiones(List<Cesiones> listCesiones) {
      this.listCesiones = listCesiones;
   }

   public Cesiones getSelectCesion() {
      return selectCesion;
   }

   public void setSelectCesion(Cesiones selectCesion) {
      this.selectCesion = selectCesion;
   }

   public GenericValidationController getGenericController() {
      return genericController;
   }

   public void setGenericController(GenericValidationController genericController) {
      this.genericController = genericController;
   }

   public Double getDescuentoFijo() {
      return descuentoFijo;
   }

   public void setDescuentoFijo(Double descuentoFijo) {
      this.descuentoFijo = descuentoFijo;
   }

   public Double getDescuentoPorcentage() {
      return descuentoPorcentage;
   }

   public void setDescuentoPorcentage(Double descuentoPorcentage) {
      this.descuentoPorcentage = descuentoPorcentage;
   }

   public Double getTotalPorcentage() {
      return totalPorcentage;
   }

   public void setTotalPorcentage(Double totalPorcentage) {
      this.totalPorcentage = totalPorcentage;
   }

   public String getMetodoPago() {
      return metodoPago;
   }

   public void setMetodoPago(String metodoPago) {
      this.metodoPago = metodoPago;
   }

   public Double getTotalAPagar() {
      return totalAPagar;
   }

   public void setTotalAPagar(Double totalAPagar) {
      this.totalAPagar = totalAPagar;
   }

   public Boolean getTipoVenta() {
      return tipoVenta;
   }

   public void setTipoVenta(Boolean tipoVenta) {
      this.tipoVenta = tipoVenta;
   }

   public List<CatalogoProductos> getSelectListCatalogoProductos() {
      return selectListCatalogoProductos;
   }

   public void setSelectListCatalogoProductos(List<CatalogoProductos> selectListCatalogoProductos) {
      this.selectListCatalogoProductos = selectListCatalogoProductos;
   }

   public CatalogoProductos getSelectProductoVenta() {
      return selectProductoVenta;
   }

   public void setSelectProductoVenta(CatalogoProductos selectProductoVenta) {
      this.selectProductoVenta = selectProductoVenta;
   }

   public CatalogoProductos getSelectProductoVentaNew() {
      return selectProductoVentaNew;
   }

   public void setSelectProductoVentaNew(CatalogoProductos selectProductoVentaNew) {
      this.selectProductoVentaNew = selectProductoVentaNew;
   }

   public Double getTotalInicial() {
      return totalInicial;
   }

   public void setTotalInicial(Double totalInicial) {
      this.totalInicial = totalInicial;
   }

   public Double getCantidadPagada() {
      return cantidadPagada;
   }

   public void setCantidadPagada(Double cantidadPagada) {
      this.cantidadPagada = cantidadPagada;
   }

   public List<PagosDetalle> getListPagosDetalle() {
      return listPagosDetalle;
   }

   public void setListPagosDetalle(List<PagosDetalle> listPagosDetalle) {
      this.listPagosDetalle = listPagosDetalle;
   }

   public PagosDetalle getSelectDetallePago() {
      return selectDetallePago;
   }

   public void setSelectDetallePago(PagosDetalle selectDetallePago) {
      this.selectDetallePago = selectDetallePago;
   }

   public Date getFechaCesion() {
      return fechaCesion;
   }

   public void setFechaCesion(Date fechaCesion) {
      this.fechaCesion = fechaCesion;
   }

   public String getSelectPaqueteSesion() {
      return selectPaqueteSesion;
   }

   public void setSelectPaqueteSesion(String selectPaqueteSesion) {
      this.selectPaqueteSesion = selectPaqueteSesion;
   }

   public List<CatalogoProductos> getListPaquetesSesion() {
      return listPaquetesSesion;
   }

   public void setListPaquetesSesion(List<CatalogoProductos> listPaquetesSesion) {
      this.listPaquetesSesion = listPaquetesSesion;
   }

   public Integer getHoraSesion() {
      return horaSesion;
   }

   public void setHoraSesion(Integer horaSesion) {
      this.horaSesion = horaSesion;
   }

   public Integer getMinutosSesion() {
      return minutosSesion;
   }

   public void setMinutosSesion(Integer minutosSesion) {
      this.minutosSesion = minutosSesion;
   }

   public Boolean getPagoMultipleExitoso() {
      return PagoMultipleExitoso;
   }

   public void setPagoMultipleExitoso(Boolean PagoMultipleExitoso) {
      this.PagoMultipleExitoso = PagoMultipleExitoso;
   }

   public Double getPagoMultiple() {
      return pagoMultiple;
   }

   public void setPagoMultiple(Double pagoMultiple) {
      this.pagoMultiple = pagoMultiple;
   }

   public HistorialAbonoMultipleSpa getSelectAbonoMultiple() {
      return selectAbonoMultiple;
   }

   public void setSelectAbonoMultiple(HistorialAbonoMultipleSpa selectAbonoMultiple) {
      this.selectAbonoMultiple = selectAbonoMultiple;
   }

   public String getComentarioDevolucion() {
      return comentarioDevolucion;
   }

   public void setComentarioDevolucion(String comentarioDevolucion) {
      this.comentarioDevolucion = comentarioDevolucion;
   }

   public DevolucionesController getDevolucionesController() {
      return devolucionesController;
   }

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

   public String getPagoSiguienteR() {
      return pagoSiguienteR;
   }

   public void setPagoSiguienteR(String pagoSiguienteR) {
      this.pagoSiguienteR = pagoSiguienteR;
   }

}
