@Override
 public String toString() {
   StringBuilder resultado = new StringBuilder();
   resultado.append("Traspaso\n");
   MWarehouse warehouse = new MWarehouse(Env.getCtx(), origen, null);
   resultado.append(" " + warehouse.getValue());
   warehouse = new MWarehouse(Env.getCtx(), destino, null);
   resultado.append(" -> " + warehouse.getValue() + "\n");
   MProduct product = null;
   resultado.append("[");
   for (int i = 0; i < cantidades.size(); i++) {
     product = new MProduct(Env.getCtx(), this.productos.get(i), null);
     resultado.append(product.getValue() + "-" + product.getName());
     resultado.append(" - " + cantidades.get(i) + "\n");
   }
   resultado.append("]");
   return resultado.toString();
 }
  /** Dado un codigo de tienda retorna un m_warehouse_id */
  private MWarehouse getStore(String cellValue) {

    Iterator<MWarehouse> storesIt = stores.iterator();
    MWarehouse returned = null, actual = null;

    if (cellValue == null) return returned;

    while (storesIt.hasNext()) {
      actual = storesIt.next();
      if (actual.getValue().equals(cellValue)) {
        returned = actual;
      }
    }
    return returned;
  }
  /** Envia correos al personal de tienda en caso de la aprobación de un traspaso */
  private void enviarCorreoATienda(MMovement movimiento, int plantillaDeCorreo) {

    MWarehouse almaSalida = new MWarehouse(getCtx(), movimiento.getM_WarehouseFrom_ID(), null);
    MWarehouse almaLleada = new MWarehouse(getCtx(), movimiento.getM_WarehouseTo_ID(), null);
    X_XX_VMR_Department departamento =
        new X_XX_VMR_Department(getCtx(), movimiento.getXX_VMR_Department_ID(), null);

    // Mensaje debe indicar departamento, origen, destino y traspaso
    String mensaje =
        Msg.getMsg(
            getCtx(),
            "XX_PTransferApproval",
            new String[] {
              movimiento.getDocumentNo(),
              departamento.getValue() + "-" + departamento.getName(),
              almaSalida.getValue() + "-" + almaSalida.getName(),
              almaLleada.getValue() + "-" + almaLleada.getName(),
              movimiento.getXX_StatusName()
            });

    // Al Gerente de Tienda
    // Selecciono el o los gerentes de Tienda
    String SQL =
        "SELECT AD_USER_ID FROM AD_USER WHERE ISACTIVE='Y' "
            + " AND C_BPARTNER_ID IN "
            + "("
            + "SELECT C_BPARTNER_ID "
            + "FROM C_BPARTNER WHERE isActive='Y' "
            + "AND C_JOB_ID ="
            + Env.getCtx().getContextAsInt("#XX_L_JOBPOSITION_STOREMAN_ID")
            + " "
            + "AND (M_WAREHOUSE_ID = "
            + almaLleada.get_ID()
            + " "
            + "OR M_WAREHOUSE_ID = "
            + almaSalida.get_ID()
            + ") "
            + "AND AD_Client_ID IN (0,"
            + Env.getCtx().getAD_Client_ID()
            + ")"
            + ") "
            + "AND AD_Client_ID IN (0,"
            + Env.getCtx().getAD_Client_ID()
            + ")";

    Vector<Integer> storeManagers = new Vector<Integer>();
    try {
      PreparedStatement pstmt = DB.prepareStatement(SQL, null);
      ResultSet rs = pstmt.executeQuery();

      while (rs.next()) {
        storeManagers.add(rs.getInt("AD_USER_ID"));
      }

      rs.close();
      pstmt.close();

    } catch (Exception a) {
      log.log(Level.SEVERE, SQL, a);
    }

    // Envio correos a los gerentes
    Utilities f = null;
    for (int i = 0; i < storeManagers.size(); i++) {

      f =
          new Utilities(
              Env.getCtx(),
              null,
              plantillaDeCorreo,
              mensaje,
              -1,
              Env.getCtx().getContextAsInt("#XX_L_USERFROMMAIL_ID"),
              -1,
              storeManagers.get(i),
              null);
      try {
        f.ejecutarMail();
      } catch (Exception e) {
        e.printStackTrace();
      }
      f = null;
    }

    // *********************************
    // Selecciono los asesores de almacen
    SQL =
        "SELECT AD_USER_ID FROM AD_USER WHERE  ISACTIVE='Y' "
            + "AND C_BPARTNER_ID IN "
            + "("
            + "SELECT C_BPARTNER_ID FROM C_BPARTNER WHERE isActive='Y' "
            + "AND C_JOB_ID ="
            + Env.getCtx().getContextAsInt("#XX_L_JOBPOSITION_DEPASE_ID")
            + " "
            + "AND (M_WAREHOUSE_ID = "
            + almaLleada.get_ID()
            + " "
            + "OR M_WAREHOUSE_ID = "
            + almaSalida.get_ID()
            + ") "
            + "AND AD_Client_ID IN (0,"
            + Env.getCtx().getAD_Client_ID()
            + ")"
            + ") "
            + "AND AD_Client_ID IN (0,"
            + Env.getCtx().getAD_Client_ID()
            + ")";

    Vector<Integer> warehouseAsessors = new Vector<Integer>();
    try {
      PreparedStatement pstmt = DB.prepareStatement(SQL, null);
      ResultSet rs = pstmt.executeQuery();

      while (rs.next()) {
        warehouseAsessors.add(rs.getInt("AD_USER_ID"));
      }

      rs.close();
      pstmt.close();

    } catch (Exception a) {
      log.log(Level.SEVERE, SQL, a);
    }

    // Envio correos a los asesores
    Utilities m = null;
    for (int i = 0; i < warehouseAsessors.size(); i++) {

      m =
          new Utilities(
              Env.getCtx(),
              null,
              plantillaDeCorreo,
              mensaje,
              -1,
              Env.getCtx().getContextAsInt("#XX_L_USERFROMMAIL_ID"),
              -1,
              warehouseAsessors.get(i),
              null);
      try {
        m.ejecutarMail();
      } catch (Exception e) {
        e.printStackTrace();
      }
      m = null;
    }

    // *********************************
    // Selecciono los Gerentes de Area ADMIN y MERCA, Asesor de Inventario
    SQL =
        "SELECT AD_USER_ID FROM AD_USER WHERE  ISACTIVE='Y' "
            + "AND C_BPARTNER_ID IN "
            + "("
            + "SELECT C_BPARTNER_ID FROM C_BPARTNER WHERE isActive='Y' "
            + "AND C_JOB_ID IN ("
            + " "
            + Env.getCtx().getContextAsInt("#XX_L_JOBPOSITION_ADMINMANAG_ID")
            + ","
            + " "
            + Env.getCtx().getContextAsInt("#XX_L_JOBPOSITION_GAMERC_ID")
            + ","
            + " "
            + Env.getCtx().getContextAsInt("#XX_L_JOBPOSITION_INVASSES_ID")
            + ") "
            + "AND (M_WAREHOUSE_ID = "
            + almaLleada.get_ID()
            + " "
            + "OR M_WAREHOUSE_ID = "
            + almaSalida.get_ID()
            + ") "
            + "AND AD_Client_ID IN (0,"
            + Env.getCtx().getAD_Client_ID()
            + ")"
            + ") "
            + "AND AD_Client_ID IN (0,"
            + Env.getCtx().getAD_Client_ID()
            + ")";

    Vector<Integer> managerArea = new Vector<Integer>();
    try {
      PreparedStatement pstmt = DB.prepareStatement(SQL, null);
      ResultSet rs = pstmt.executeQuery();

      while (rs.next()) {
        managerArea.add(rs.getInt("AD_USER_ID"));
      }

      rs.close();
      pstmt.close();

    } catch (Exception a) {
      log.log(Level.SEVERE, SQL, a);
    }

    // Envio correos a gerentes de area
    Utilities u = null;
    for (int i = 0; i < managerArea.size(); i++) {

      u =
          new Utilities(
              Env.getCtx(),
              null,
              plantillaDeCorreo,
              mensaje,
              -1,
              Env.getCtx().getContextAsInt("#XX_L_USERFROMMAIL_ID"),
              -1,
              managerArea.get(i),
              null);
      try {
        u.ejecutarMail();
      } catch (Exception e) {
        e.printStackTrace();
      }
      u = null;
    }
  }
  public void print_labels(PrintService psZebra, int row, boolean glued) {
    try {

      IDColumn column = (IDColumn) xProductTable.getValueAt(row, 0);
      KeyNamePair knp_product = (KeyNamePair) xProductTable.getValueAt(row, 3);
      KeyNamePair knp_att = (KeyNamePair) xProductTable.getValueAt(row, 11);

      MVMRDiscountAppliDetail detail =
          new MVMRDiscountAppliDetail(Env.getCtx(), column.getRecord_ID(), null);

      int cantidadEtiquetas = ((Number) xProductTable.getValueAt(row, 6)).intValue();

      MProduct producto = new MProduct(Env.getCtx(), knp_product.getKey(), null);
      String name = producto.getName();
      /*
       * Caracteristica larga
       * */
      X_XX_VMR_LongCharacteristic caracLarga =
          new X_XX_VMR_LongCharacteristic(
              Env.getCtx(), producto.getXX_VMR_LongCharacteristic_ID(), null);
      X_M_AttributeSet attrSet =
          new X_M_AttributeSet(Env.getCtx(), producto.getM_AttributeSet_ID(), null);

      DecimalFormat formato = new DecimalFormat(".##");

      // String attr = "AMARILLO T=G                  ";
      // "CHEMISE CABALLERO             "

      X_XX_VMR_Department dep =
          new X_XX_VMR_Department(Env.getCtx(), producto.getXX_VMR_Department_ID(), null);
      String departmentCode = dep.getValue();

      X_XX_VMR_Line lin = new X_XX_VMR_Line(Env.getCtx(), producto.getXX_VMR_Line_ID(), null);
      String lineCode = lin.getValue();

      X_XX_VMR_Section sec =
          new X_XX_VMR_Section(Env.getCtx(), producto.getXX_VMR_Section_ID(), null);
      String seccionCode = sec.getValue();
      String precio = formato.format(detail.getXX_PriceBeforeDiscount());

      MVMRDiscountRequest headerDiscount =
          new MVMRDiscountRequest(Env.getCtx(), detail.getXX_VMR_DiscountRequest_ID(), null);
      MWarehouse tienda = new MWarehouse(Env.getCtx(), headerDiscount.getM_Warehouse_ID(), null);

      X_XX_VMR_PriceConsecutive consecutivoViejo =
          new X_XX_VMR_PriceConsecutive(Env.getCtx(), detail.getXX_VMR_PriceConsecutive_ID(), null);
      // Debo buscar semana, mes y año de la fecha de creacion del consecutivo

      Date date = (Date) consecutivoViejo.getCreated();
      Calendar cal = new GregorianCalendar();
      cal.setTime(date);
      int mes = cal.get(Calendar.MONTH) + 1;
      int año = cal.get(Calendar.YEAR);
      int semana = cal.get(Calendar.WEEK_OF_YEAR);

      BigDecimal impuesto = new BigDecimal(0);

      if (producto.getC_TaxCategory_ID() != 0) {

        String sql_rate =
            " SELECT (RATE) FROM C_TAX "
                + " WHERE C_TaxCategory_ID= "
                + producto.getC_TaxCategory_ID()
                + " AND ValidFrom <= to_date('"
                + date.toString().substring(0, 10)
                + "','yyyy-mm-dd')"
                + " and rownum = 1 "
                + " order by ValidFrom desc ";
        try {
          PreparedStatement prst_tax = DB.prepareStatement(sql_rate, null);
          ResultSet rs_tax = prst_tax.executeQuery();
          if (rs_tax.next()) {

            impuesto = rs_tax.getBigDecimal(1).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
          }
          rs_tax.close();
          prst_tax.close();
        } catch (Exception e) {
          System.out.println("error al calcular el impuesto");
        }
      }

      String product_plus_correlative =
          "" + producto.getValue() + consecutivoTostring(consecutivoViejo.getXX_PriceConsecutive());

      String s = "";
      DocPrintJob job = psZebra.createPrintJob();

      if (impuesto.compareTo(new BigDecimal(0)) > 0) {
        precio =
            formato.format(
                (detail
                        .getXX_PriceBeforeDiscount()
                        .add((detail.getXX_PriceBeforeDiscount()).multiply(impuesto)))
                    .setScale(2, BigDecimal.ROUND_HALF_UP));
        s =
            "^XA^PRD^XZ\n"
                + "^XA^JMA^\n"
                + "^LH07,02^FS\n"
                + "^FO10,03^BE,25,N^BY3, 0.5,45^FD"
                + product_plus_correlative
                + "^FS\n"
                + "^FO10,62^AA,15,12^FD"
                + departmentCode
                + "-"
                + lineCode
                + "-"
                + seccionCode
                + "-"
                + product_plus_correlative
                + "       ^FS\n"
                + "^FO10,82^AA,20,10^FD"
                + name
                + "^FS\n";
        if (!attrSet.getName().isEmpty()
            && attrSet.get_ID() != Env.getCtx().getContextAsInt("#XX_L_P_ATTRIBUTESETST_ID")) {
          s =
              s
                  + "^FO10,97^AA,20,10^FD"
                  + (attrSet.getName().length() > 30
                      ? attrSet.getName().substring(0, 29)
                      : attrSet.getName())
                  + "^FS\n";
        } else if (caracLarga != null
            && caracLarga.getName() != null
            && !caracLarga.getName().isEmpty()) {
          s =
              s
                  + "^FO10,97^AA,20,10^FD"
                  + (caracLarga.getName().length() > 30
                      ? caracLarga.getName().substring(0, 29)
                      : caracLarga.getName())
                  + "^FS\n";
        }
        s =
            s
                + "^FO10,116^AA,14,10^FDPRECIO BS^FS\n"
                + "^FO10,170^AB,11,07^FDRIF J-00046517-7   Incluye IVA "
                + impuesto.multiply(new BigDecimal(100))
                + "%^FS\n"
                + "^FO10,153^AB,11,07^CI10^FD"
                + semana
                + " "
                + mes
                + " "
                + año
                + "^FS\n"
                + "^FO10,138^AA,11,09^FDBsF.^FS\n"
                + "^FO35,136^AB,11,07^CI10^FD         "
                + precio
                + "^FS\n"
                + "^PQ"
                + cantidadEtiquetas
                + "^FS\n"
                + "^XZ\n"
                +
                // Control label
                "^XA^PRD^XZ\n"
                + "^XA^JMA^\n"
                + "^LH00,15^FS\n"
                + "^FO2,5^AD,38,10^FD*CONTROL*     "
                + semana
                + " "
                + mes
                + ""
                + año
                + "^FS\n"
                + "^FO05,45^A0,30,07^FD                  TDA:  "
                + tienda.getValue()
                + "^FS\n"
                + "^FO28,48^A0,15,14^FDCANT:     "
                + cantidadEtiquetas
                + "      PRECIO      "
                + precio
                + "^FS\n"
                + "^FO05,95^A0,18,10^FD"
                + departmentCode
                + "-"
                + lineCode
                + "-"
                + seccionCode
                + "- "
                + product_plus_correlative
                + "^FS\n"
                + "^FO05,120^A0,18,10^FD"
                + name
                + "^FS\n"
                + "^FO05,140^A0,18,10^FD                                                  ^FS\n"
                + "^PQ1^FS\n"
                + "^XZ";
      } else {
        s =
            "^XA^PRD^XZ\n"
                + "^XA^JMA^\n"
                + "^LH07,02^FS\n"
                + "^FO10,03^BE,25,N^BY3, 0.5,45^FD"
                + product_plus_correlative
                + "^FS\n"
                + "^FO10,62^AA,15,12^FD"
                + departmentCode
                + "-"
                + lineCode
                + "-"
                + seccionCode
                + "-"
                + product_plus_correlative
                + "       ^FS\n"
                + "^FO10,82^AA,20,10^FD"
                + name
                + "^FS\n"
                + "^FO10,97^AA,20,10^FD                                                  ^FS\n"
                + "^FO10,116^AA,14,10^FDPRECIO BS^FS\n"
                + "^FO10,170^AB,11,07^FDRIF J-00046517-7   Exento de Iva%^FS\n"
                + "^FO10,153^AB,11,07^CI10^FD"
                + semana
                + " "
                + mes
                + " "
                + año
                + "^FS\n"
                + "^FO10,138^AA,11,09^FDBsF.^FS\n"
                + "^FO35,136^AB,11,07^CI10^FD         "
                + precio
                + "^FS\n"
                + "^PQ"
                + cantidadEtiquetas
                + "^FS\n"
                + "^XZ\n"
                +
                // Control label
                "^XA^PRD^XZ\n"
                + "^XA^JMA^\n"
                + "^LH00,15^FS\n"
                + "^FO2,5^AD,38,10^FD*CONTROL*     "
                + semana
                + " "
                + mes
                + ""
                + año
                + "^FS\n"
                + "^FO05,45^A0,30,07^FD                  TDA:  "
                + tienda.getValue()
                + "^FS\n"
                + "^FO28,48^A0,15,14^FDCANT:     "
                + cantidadEtiquetas
                + "      PRECIO      "
                + precio
                + "^FS\n"
                + "^FO05,95^A0,18,10^FD"
                + departmentCode
                + "-"
                + lineCode
                + "-"
                + seccionCode
                + "- "
                + product_plus_correlative
                + "^FS\n"
                + "^FO05,120^A0,18,10^FD"
                + name
                + "^FS\n"
                + "^FO05,140^A0,18,10^FD                                                  ^FS\n"
                + "^PQ1^FS\n"
                + "^XZ";
      }

      byte[] by = s.getBytes();
      DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
      Doc doc = new SimpleDoc(by, flavor, null);
      job.print(doc, null);

    } catch (Exception e) {
      e.printStackTrace();
    }
  }