public void eliminarProducto(ActionEvent e) {
    FacesContext context = FacesContext.getCurrentInstance();
    Integer productoId =
        Integer.parseInt(context.getExternalContext().getRequestParameterMap().get("productoId"));

    logger.debug("################################ >> eliminarProducto: productoId=" + productoId);
    int indexToDelete = -1, i = 0;
    for (PedidoVentaDetalleWrapper dvp : pedidoVentaDetalleList) {
      if (dvp.getProducto().getId().intValue() == productoId.intValue()) {
        indexToDelete = i;
        logger.debug("\t################################ >> indexToDelete=" + indexToDelete);
        break;
      }
      i++;
    }
    if (indexToDelete != -1) {
      PedidoVentaDetalleWrapper dvpDeleted = pedidoVentaDetalleList.remove(indexToDelete);
      logger.debug(
          "\t\t################################ >> dvpDeleted["
              + indexToDelete
              + "] = "
              + dvpDeleted);
    } else {
      logger.debug("\t\t################################ >> can delete[" + indexToDelete + "]");
      throw new IllegalStateException("can't delete row:" + indexToDelete);
    }
    logger.debug("################################ >> end: eliminarProducto");
  }
  public void activarDescuento(ActionEvent e) {
    FacesContext context = FacesContext.getCurrentInstance();
    Integer productoId =
        Integer.parseInt(context.getExternalContext().getRequestParameterMap().get("productoId"));

    logger.debug("## >> activarDescuento: productoId=" + productoId);
    boolean selectedFromDetalle = false;
    for (PedidoVentaDetalleWrapper dvp : pedidoVentaDetalleList) {
      logger.debug(
          "## >> activarDescuento: ["
              + dvp.getProducto().getId()
              + "] == "
              + productoId
              + " ? "
              + (dvp.getProducto().getId() == productoId)
              + " , or use .equals ?"
              + (dvp.getProducto().getId().equals(productoId)));
      if (dvp.getProducto().getId().equals(productoId)) {
        // dvp.setDescuentoAplicado(dvp.getProducto().getFactorMaxDesc());
        selectedFromDetalle = true;
        break;
      }
    }
    if (!selectedFromDetalle) {
      logger.warn(
          "\t## >> productoId=" + productoId + " => selectedFromDetalle=" + selectedFromDetalle);
    }
    logger.debug("## >> end: activarDescuento");
  }
  public String confirmarPedido() {
    logger.debug("========================================================>>");
    logger.debug("-->>confirmarPedido():");
    logger.debug("========================================================>>");
    try {

      dataValidation();
      try {
        pedidoVenta.setCliente(new Cliente(clienteId));
        pedidoVenta.setFormaDePago(new FormaDePago(formaDePagoId));
        pedidoVenta.setUsuario(sessionUserMB.getUsuarioAuthenticated());
        pedidoVenta.setComentarios("PedidoNuevoMB.confirmarPedido @" + new Date());
        pedidoVenta.setFactoriva(LogicaFinaciera.getImpuestoIVA());

        Collection<PedidoVentaDetalle> pedidoVentaDetalleCollection =
            new ArrayList<PedidoVentaDetalle>();

        for (PedidoVentaDetalleWrapper pvdw : pedidoVentaDetalleList) {
          pedidoVentaDetalleCollection.add(pvdw.getPedidoVentaDetalle());
        }
        for (PedidoVentaDetalle pvd : pedidoVentaDetalleCollection) {
          logger.debug(
              "\t==>>pedidoVentaDetalleCollection:"
                  + pvd.getCantidad()
                  + " x "
                  + pvd.getProducto());
        }
        pedidoVenta.setPedidoVentaDetalleCollection(pedidoVentaDetalleCollection);

        pedidoVenta =
            pedidoVentaBusinessLogic.crearPedidoCapturado(
                pedidoVenta, sessionUserMB.getUsuarioAuthenticated());
        logger.debug("<<===================== OK crearPedidoCapturado =======================");
        // pedidoVenta =
        // pedidoVentaBusinessLogic.crearPedidoVentaDetalleCapturado(pedidoVenta,pedidoVentaDetalleCollection);
        // logger.debug("<<===================== OK crearPedidoVentaDetalleCapturado
        // =======================");
        pedidoVentaBusinessLogic.sincronizarPedido(
            pedidoVenta, sessionUserMB.getUsuarioAuthenticated());
        logger.debug("<<===================== OK sincronizarPedido =======================");
        return "pedidoCreado";
      } catch (Exception ex) {
        logger.debug("<<++++++++++++++++++++++++++++++++++++++++++++++++++");
        ex.printStackTrace(System.err);
        logger.debug("Error in MB to create pedido:", ex);

        throw new ValidatorException(
            new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.toString(), ex.toString()));
      } finally {
        reiniciarPedido();
      }
    } catch (ValidatorException ve) {
      logger.debug("<<!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
      FacesContext.getCurrentInstance().addMessage(null, ve.getFacesMessage());
      return null;
    }
  }
  public PedidoVentaDetalleFooter getPedidoFooter() {

    PedidoVentaDetalleFooter dvpf = new PedidoVentaDetalleFooter();

    int totalPiezas = 0;
    dvpf.setCantTotal(totalPiezas);
    dvpf.setDescuento(0.0);
    double subtotal = 0.0;
    double descuento = 0.0;
    double importeDescuento = 0.0;
    double subTotalRegistro = 0.0;
    for (PedidoVentaDetalleWrapper dvp : pedidoVentaDetalleList) {
      totalPiezas += dvp.getCantidad();
      subTotalRegistro = dvp.getCantidad() * dvp.getPrecioVenta();
      subtotal += subTotalRegistro;
    }

    dvpf.setNumItems(totalPiezas);

    descuentoCalculado = 0;
    if (modoVenta == Constants.ALMACEN_LINEA) {
      if (subtotal >= 5000 && subtotal < 10000) {
        descuento = 0.05;
        descuentoCalculado = 5;
      } else if (subtotal >= 10000) {
        descuento = 0.1;
        descuentoCalculado = 10;
      }
    }

    descuento = descuento + (descuentoEspecial / 100.0);

    importeDescuento = subtotal * descuento;

    double subtotalDeplegar = subtotal / (1 + LogicaFinaciera.getImpuestoIVA());
    double impuestoDesplegar = subtotal - subtotalDeplegar;

    dvpf.setSubtotal(subtotalDeplegar);
    dvpf.setImpuesto(impuestoDesplegar);
    dvpf.setDescuento(importeDescuento);

    dvpf.setTotal(subtotalDeplegar + impuestoDesplegar - importeDescuento);

    return dvpf;
  }
  public void cantidadDetalleBtnChanged(ActionEvent e) {
    FacesContext context = FacesContext.getCurrentInstance();
    Integer productoId =
        Integer.parseInt(context.getExternalContext().getRequestParameterMap().get("productoId"));

    logger.debug("## >> cantidadDetalleBtnChanged: productoId=" + productoId);
    try {
      for (PedidoVentaDetalleWrapper dvp : pedidoVentaDetalleList) {
        logger.debug(
            "## >> cantidadDetalleBtnChanged:\t"
                + dvp.getProducto().getCodigoBarras()
                + ", "
                + dvp.getCantidad()
                + " ["
                + dvp.getCantMax()
                + "]");
        if (dvp.getProducto().getId().intValue() == productoId.intValue()) {
          if (dvp.getCantidad() > dvp.getCantMax()) {
            logger.debug("## \t\t>> cantidadDetalleBtnChanged: Excede Max!");
            dvp.setCantidad(dvp.getCantMax());
            throw new Exception(
                "Cantidad del producto ["
                    + dvp.getProducto().getCodigoBarras()
                    + "] exede máximo en almacén actual. se asignará el máximo.");
          }
        }
      }
    } catch (Exception ex) {
      FacesContext.getCurrentInstance()
          .addMessage(
              null,
              new FacesMessage(
                  FacesMessage.SEVERITY_ERROR,
                  "Error al actualizar la cantidad : ",
                  ex.getMessage()));
    }
  }
  public void guardarCantidadPedidoVentaDetalleSeleccionado(ActionEvent e) {
    FacesContext context = FacesContext.getCurrentInstance();

    logger.debug(
        "## >> guardarCantidadPedidoVentaDetalleSeleccionado: productoId="
            + detalleVentaPedidoSeleccionado.getProducto().getId()
            + ", cantidad="
            + detalleVentaPedidoSeleccionado.getCantidad());
    for (PedidoVentaDetalleWrapper dvp : pedidoVentaDetalleList) {
      if (dvp.getProducto().getId() == detalleVentaPedidoSeleccionado.getProducto().getId()) {
        dvp.setCantidad(detalleVentaPedidoSeleccionado.getCantidad());
        logger.debug("\t## >> ok, edited ");
        break;
      }
    }
    detalleVentaPedidoSeleccionado = new PedidoVentaDetalleWrapper(new PedidoVentaDetalle());
    logger.debug("## >> end: guardarCantidadPedidoVentaDetalleSeleccionado");
  }
  public void seleccionarProducto(ActionEvent e) {
    FacesContext context = FacesContext.getCurrentInstance();
    Integer productoId =
        Integer.parseInt(context.getExternalContext().getRequestParameterMap().get("productoId"));

    logger.debug("## >> seleccionarProducto: productoId=" + productoId);
    boolean selectedFromDetalle = false;
    for (PedidoVentaDetalleWrapper dvp : pedidoVentaDetalleList) {
      if (dvp.getProducto().getId() == productoId) {
        detalleVentaPedidoSeleccionado.setProducto(dvp.getProducto());
        detalleVentaPedidoSeleccionado.setCantidad(dvp.getCantidad());
        selectedFromDetalle = true;
        break;
      }
    }
    if (!selectedFromDetalle) {
      logger.warn(
          "\t## >> productoId=" + productoId + " => detalleVentaPedidoSeleccionado is null");
    }
    logger.debug("## >> end: seleccionarProducto");
  }
  public PedidoVentaDetalleFooter getPedidoFooter() {

    PedidoVentaDetalleFooter dvpf = new PedidoVentaDetalleFooter();

    int totalPiezas = 0;
    dvpf.setCantTotal(totalPiezas);
    dvpf.setDescuento(0.0);
    double subtotal = 0.0;
    double descuento = 0.0;
    double descuentoRegistro = 0.0;
    double impuesto = 0.0;
    double impuestoRegistro = 0.0;
    double subTotalRegistro = 0.0;
    for (PedidoVentaDetalleWrapper dvp : pedidoVentaDetalleList) {
      totalPiezas += dvp.getCantidad();
      subTotalRegistro = dvp.getCantidad() * dvp.getPrecioVenta();

      impuestoRegistro = subTotalRegistro * LogicaFinaciera.getImpuestoIVA();

      if (dvp.getDescuentoAplicado() != 0.0) {
        descuentoRegistro = dvp.getDescuentoAplicado() * (subTotalRegistro + impuestoRegistro);
      } else {
        descuentoRegistro = 0;
      }

      impuesto += impuestoRegistro;
      descuento += descuentoRegistro;
      subtotal += subTotalRegistro;
    }

    dvpf.setNumItems(totalPiezas);

    dvpf.setSubtotal(subtotal);
    dvpf.setImpuesto(impuesto);
    dvpf.setDescuento(descuento);

    dvpf.setTotal(subtotal + impuesto - descuento);

    return dvpf;
  }
  private synchronized int agregarProductoADetallePrevia(Integer productoIdAgregar, int cantidad) {
    int cantidadPrevia = 0;
    PedidoVentaDetalleWrapper detalleVentaPedidoAgregar = null;
    logger.debug(
        "-->> agregarProductoADetallePrevia: productoIdAgregar="
            + productoIdAgregar
            + ", cantidad="
            + cantidad);
    for (PedidoVentaDetalleWrapper dvp : pedidoVentaDetalleList) {
      if (dvp.getProducto().getId().intValue() == productoIdAgregar.intValue()) {
        detalleVentaPedidoAgregar = dvp;
        break;
      }
    }
    if (detalleVentaPedidoAgregar != null) {
      if (detalleVentaPedidoAgregar.getCantidad() + cantidad
          > detalleVentaPedidoAgregar.getCantMax()) {
        throw new ValidatorException(
            new FacesMessage(
                FacesMessage.SEVERITY_ERROR,
                "Agregar Producto : ",
                "Producto ["
                    + detalleVentaPedidoAgregar.getProducto().getCodigoBarras()
                    + "] ya agregado, pero con esta cantidad (+"
                    + cantidad
                    + ") excede la existencia en Almacén de "
                    + detalleVentaPedidoAgregar.getCantMax()
                    + " unidades."));
      } else {
        cantidadPrevia = detalleVentaPedidoAgregar.getCantidad();
        detalleVentaPedidoAgregar.setCantidad(cantidadPrevia + cantidad);
        logger.debug("-->> agregarProductoADetallePrevia: Ok, actualizada");
      }
    } else {
      detalleVentaPedidoAgregar = new PedidoVentaDetalleWrapper(new PedidoVentaDetalle());
      detalleVentaPedidoAgregar.setCantidad(cantidad);

      Producto producto = productoJPAController.findById(productoIdAgregar);
      Collection<AlmacenProducto> almacenProductoCollection =
          producto.getAlmacenProductoCollection();
      int cantMaxAlmacen = 0;
      double precioObjetivo = 0.0;
      for (AlmacenProducto almacenProducto : almacenProductoCollection) {
        if (almacenProducto.getAlmacen().getId().intValue()
            == getAlmacenObjetivo().getId().intValue()) {
          precioObjetivo = almacenProducto.getPrecioVenta();
          cantMaxAlmacen = almacenProducto.getCantidadActual();
        }
      }

      if (cantidad > cantMaxAlmacen) {
        throw new ValidatorException(
            new FacesMessage(
                FacesMessage.SEVERITY_ERROR,
                "Agregar Producto : ",
                "Producto ["
                    + producto.getCodigoBarras()
                    + "] se hiba a agregar, pero con esta cantidad (+"
                    + cantidad
                    + ") excede la existencia en Almacén de "
                    + cantMaxAlmacen
                    + " unidades."));
      }
      if (listAlmacenProductoBuscar == null) {
        getListAlmacenProductoBuscar();
      }
      AlmacenProductoDemanda prodEnDemanda = productoDemandaHT.get(productoIdAgregar);
      if (prodEnDemanda != null) {
        detalleVentaPedidoAgregar.setCantDemanda(prodEnDemanda.getSumDemanda());
        detalleVentaPedidoAgregar.setOtrosPedidos(prodEnDemanda.getOtrosPedidos());
      }

      detalleVentaPedidoAgregar.setCantMax(cantMaxAlmacen);
      detalleVentaPedidoAgregar.setProducto(producto);
      detalleVentaPedidoAgregar.setDescuentoAplicado(0.0);
      detalleVentaPedidoAgregar.setPrecioVenta(precioObjetivo);

      pedidoVentaDetalleList.add(detalleVentaPedidoAgregar);
      // pedidoVentaDetalleList.add(0, detalleVentaPedidoAgregar);
      logger.debug("-->> agregarProductoADetallePrevia: Ok, Add new");
    }
    return cantidadPrevia;
  }
  private void agregarProductoADetalle(Integer productoIdAgregar) {
    PedidoVentaDetalleWrapper detalleVentaPedidoAgregar = null;
    logger.debug(
        "################################ >> agregarProductoADetalle: productoIdAgregar="
            + productoIdAgregar);
    for (PedidoVentaDetalleWrapper dvp : pedidoVentaDetalleList) {
      if (dvp.getProducto().getId() == productoIdAgregar) {
        detalleVentaPedidoAgregar = dvp;
        break;
      }
    }
    try {
      if (detalleVentaPedidoAgregar != null) {
        if (detalleVentaPedidoAgregar.getCantidad() >= detalleVentaPedidoAgregar.getCantMax()) {
          logger.warn(
              "################################ >> agregarProductoADetalle: Cantidad Exedida, no se agregara");

          throw new ValidatorException(
              new FacesMessage(
                  FacesMessage.SEVERITY_ERROR,
                  "Sobrepasa cantidad Maxima de existencia en Almacenes",
                  "Sobrepasa cantidad Maxima de existencia en Almacenes"));
        } else {
          detalleVentaPedidoAgregar.setCantidad(detalleVentaPedidoAgregar.getCantidad() + 1);
          logger.debug("################################ >> agregarProductoADetalle: \t Ok, edit");
        }
      } else {
        detalleVentaPedidoAgregar = new PedidoVentaDetalleWrapper(new PedidoVentaDetalle());
        detalleVentaPedidoAgregar.setCantidad(1);

        Producto producto = productoJpaController.findProducto(productoIdAgregar);
        Collection<AlmacenProducto> almacenProductoCollection =
            producto.getAlmacenProductoCollection();
        int cantMaxAlmacenes = 0;
        for (AlmacenProducto almacenProducto : almacenProductoCollection) {
          cantMaxAlmacenes += almacenProducto.getCantidadActual();
        }

        if (cantMaxAlmacenes <= 0) {
          logger.warn(
              "################################ >> agregarProductoADetalle: Cantidad Exedida, No hay existencia en Almacenes");

          throw new ValidatorException(
              new FacesMessage(
                  FacesMessage.SEVERITY_ERROR,
                  "No hay existencia en Almacenes",
                  "No hay existencia en Almacenes"));
        }

        detalleVentaPedidoAgregar.setCantMax(cantMaxAlmacenes);
        detalleVentaPedidoAgregar.setProducto(producto);
        detalleVentaPedidoAgregar.setDescuentoAplicado(0.0);

        detalleVentaPedidoAgregar.setPrecioVenta(
            detalleVentaPedidoAgregar.getProducto().getPrecioBase()
                * (1.0 + LogicaFinaciera.getImpuestoIVA()));

        pedidoVentaDetalleList.add(detalleVentaPedidoAgregar);
        logger.debug("################################ >> agregarProductoADetalle: \t Ok, Add new");
      }
    } catch (ValidatorException ve) {
      logger.debug("<<!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
      FacesContext.getCurrentInstance().addMessage(null, ve.getFacesMessage());
    }
  }